Merge pull request #3044 from sbutcher-arm/merge-2.16-sprint27

[baremetal] Update `baremetal` branch with updates from `mbedtls-2.16` branch
This commit is contained in:
Simon Butcher 2020-04-03 15:31:46 +01:00 committed by GitHub
commit 2d21e3e47b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 1225 additions and 333 deletions

View file

@ -63,16 +63,64 @@ Changes
* Reduce RAM consumption during session renegotiation by not storing * Reduce RAM consumption during session renegotiation by not storing
the peer CRT chain and session ticket twice. the peer CRT chain and session ticket twice.
= mbed TLS 2.16.x branch released xxxx-xx-xx = mbed TLS 2.16.X branch released XXXX-XX-XX
Security
* Fix potential memory overread when performing an ECDSA signature
operation. The overread only happens with cryptographically low
probability (of the order of 2^-n where n is the bitsize of the curve)
unless the RNG is broken, and could result in information disclosure or
denial of service (application crash or extra resource consumption).
Found by Auke Zeilstra and Peter Schwabe, using static analysis.
* To avoid a side channel vulnerability when parsing an RSA private key,
read all the CRT parameters from the DER structure rather than
reconstructing them. Found by Alejandro Cabrera Aldaya and Billy Bob
Brumley. Reported and fix contributed by Jack Lloyd.
ARMmbed/mbed-crypto#352
Bugfix
* Fix an unchecked call to mbedtls_md() in the x509write module.
= mbed TLS 2.16.4 branch released 2020-01-15
Security
* Fix side channel vulnerability in ECDSA. Our bignum implementation is not
constant time/constant trace, so side channel attacks can retrieve the
blinded value, factor it (as it is smaller than RSA keys and not guaranteed
to have only large prime factors), and then, by brute force, recover the
key. Reported by Alejandro Cabrera Aldaya and Billy Brumley.
* Zeroize local variables in mbedtls_internal_aes_encrypt() and
mbedtls_internal_aes_decrypt() before exiting the function. The value of
these variables can be used to recover the last round key. To follow best
practice and to limit the impact of buffer overread vulnerabilities (like
Heartbleed) we need to zeroize them before exiting the function.
Issue reported by Tuba Yavuz, Farhaan Fowze, Ken (Yihang) Bai,
Grant Hernandez, and Kevin Butler (University of Florida) and
Dave Tian (Purdue University).
* Fix side channel vulnerability in ECDSA key generation. Obtaining precise
timings on the comparison in the key generation enabled the attacker to
learn leading bits of the ephemeral key used during ECDSA signatures and to
recover the private key. Reported by Jeremy Dubeuf.
* Catch failure of AES functions in mbedtls_ctr_drbg_random(). Uncaught
failures could happen with alternative implementations of AES. Bug
reported and fix proposed by Johan Uppman Bruce and Christoffer Lauri,
Sectra.
Bugfix Bugfix
* Remove redundant line for getting the bitlen of a bignum, since the variable * Remove redundant line for getting the bitlen of a bignum, since the variable
holding the returned value is overwritten a line after. holding the returned value is overwritten a line after.
Found by irwir in #2377. Found by irwir in #2377.
* Support mbedtls_hmac_drbg_set_entropy_len() and
mbedtls_ctr_drbg_set_entropy_len() before the DRBG is seeded. Before,
the initial seeding always reset the entropy length to the compile-time
default.
Changes Changes
* Add unit tests for AES-GCM when called through mbedtls_cipher_auth_xxx() * Add unit tests for AES-GCM when called through mbedtls_cipher_auth_xxx()
from the cipher abstraction layer. Fixes #2198. from the cipher abstraction layer. Fixes #2198.
* Clarify how the interface of the CTR_DRBG and HMAC modules relates to
NIST SP 800-90A. In particular CTR_DRBG requires an explicit nonce
to achieve a 256-bit strength if MBEDTLS_ENTROPY_FORCE_SHA256 is set.
= mbed TLS 2.16.3 branch released 2019-09-06 = mbed TLS 2.16.3 branch released 2019-09-06

View file

@ -24,7 +24,7 @@
*/ */
/** /**
* @mainpage mbed TLS v2.16.3 source code documentation * @mainpage mbed TLS v2.16.4 source code documentation
* *
* This documentation describes the internal structure of mbed TLS. It was * This documentation describes the internal structure of mbed TLS. It was
* automatically generated from specially formatted comment blocks in * automatically generated from specially formatted comment blocks in

View file

@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8
# identify the project. Note that if you do not use Doxywizard you need # identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces. # to put quotes around the project name if it contains spaces.
PROJECT_NAME = "mbed TLS v2.16.3" PROJECT_NAME = "mbed TLS v2.16.4"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. # The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or

View file

@ -184,7 +184,7 @@ extern "C" {
*/ */
typedef struct mbedtls_mpi typedef struct mbedtls_mpi
{ {
int s; /*!< integer sign */ int s; /*!< Sign: -1 if the mpi is negative, 1 otherwise */
size_t n; /*!< total # of limbs */ size_t n; /*!< total # of limbs */
mbedtls_mpi_uint *p; /*!< pointer to limbs */ mbedtls_mpi_uint *p; /*!< pointer to limbs */
} }
@ -559,6 +559,24 @@ int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y );
*/ */
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ); int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Check if an MPI is less than the other in constant time.
*
* \param X The left-hand MPI. This must point to an initialized MPI
* with the same allocated length as Y.
* \param Y The right-hand MPI. This must point to an initialized MPI
* with the same allocated length as X.
* \param ret The result of the comparison:
* \c 1 if \p X is less than \p Y.
* \c 0 if \p X is greater than or equal to \p Y.
*
* \return 0 on success.
* \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of
* the two input MPIs is not the same.
*/
int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
unsigned *ret );
/** /**
* \brief Compare an MPI with an integer. * \brief Compare an MPI with an integer.
* *

View file

@ -747,6 +747,13 @@
#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN #define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
#define MBEDTLS_CIPHER_PADDING_ZEROS #define MBEDTLS_CIPHER_PADDING_ZEROS
/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
*
* Uncomment this macro to use a 128-bit key in the CTR_DRBG module.
* By default, CTR_DRBG uses a 256-bit key.
*/
//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
/** /**
* \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
* *
@ -2516,7 +2523,11 @@
* *
* Enable the CTR_DRBG AES-based random generator. * Enable the CTR_DRBG AES-based random generator.
* The CTR_DRBG generator uses AES-256 by default. * The CTR_DRBG generator uses AES-256 by default.
* To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below. * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
*
* \note To achieve a 256-bit security strength with CTR_DRBG,
* you must use AES-256 *and* use sufficient entropy.
* See ctr_drbg.h for more details.
* *
* Module: library/ctr_drbg.c * Module: library/ctr_drbg.c
* Caller: * Caller:
@ -3434,7 +3445,6 @@
//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ //#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ //#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ //#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */
/* HMAC_DRBG options */ /* HMAC_DRBG options */
//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ //#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */

View file

@ -1,7 +1,8 @@
/** /**
* \file ctr_drbg.h * \file ctr_drbg.h
* *
* \brief This file contains CTR_DRBG definitions and functions. * \brief This file contains definitions and functions for the
* CTR_DRBG pseudorandom generator.
* *
* CTR_DRBG is a standardized way of building a PRNG from a block-cipher * CTR_DRBG is a standardized way of building a PRNG from a block-cipher
* in counter mode operation, as defined in <em>NIST SP 800-90A: * in counter mode operation, as defined in <em>NIST SP 800-90A:
@ -9,13 +10,35 @@
* Bit Generators</em>. * Bit Generators</em>.
* *
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
* as the underlying block cipher. * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
* as the underlying block cipher, with a derivation function.
* The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy.
* See the documentation of mbedtls_ctr_drbg_seed() for more details.
* *
* \warning Using 128-bit keys for CTR_DRBG limits the security of generated * Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2,
* keys and operations that use random values generated to 128-bit security. * here are the security strengths achieved in typical configuration:
* - 256 bits under the default configuration of the library, with AES-256
* and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more.
* - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
* to 32 or more, and the DRBG is initialized with an explicit
* nonce in the \c custom parameter to mbedtls_ctr_drbg_seed().
* - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
* between 24 and 47 and the DRBG is not initialized with an explicit
* nonce (see mbedtls_ctr_drbg_seed()).
* - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
* and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is
* always the case unless it is explicitly set to a different value
* in config.h).
*
* Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to:
* - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time.
* This is the default configuration of the library.
* - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time.
* - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
*/ */
/* /*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -56,9 +79,19 @@
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */ #define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
#define MBEDTLS_CTR_DRBG_KEYSIZE 16 /**< The key size used by the cipher (compile-time choice: 128 bits). */ #define MBEDTLS_CTR_DRBG_KEYSIZE 16
/**< The key size in bytes used by the cipher.
*
* Compile-time choice: 16 bytes (128 bits)
* because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled.
*/
#else #else
#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher (compile-time choice: 256 bits). */ #define MBEDTLS_CTR_DRBG_KEYSIZE 32
/**< The key size in bytes used by the cipher.
*
* Compile-time choice: 32 bytes (256 bits)
* because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled.
*/
#endif #endif
#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */ #define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
@ -73,21 +106,31 @@
* \{ * \{
*/ */
/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN
*
* \brief The amount of entropy used per seed by default, in bytes.
*/
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
/** This is 48 bytes because the entropy module uses SHA-512
* (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled).
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48
/**< The amount of entropy used per seed by default:
* <ul><li>48 with SHA-512.</li> #else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
* <li>32 with SHA-256.</li></ul>
/** This is 32 bytes because the entropy module uses SHA-256
* (the SHA512 module is disabled or
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled).
*/ */
#else #if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
/** \warning To achieve a 256-bit security strength, you must pass a nonce
* to mbedtls_ctr_drbg_seed().
*/
#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
/**< Amount of entropy used per seed by default: #endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
* <ul><li>48 with SHA-512.</li> #endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
* <li>32 with SHA-256.</li></ul>
*/
#endif
#endif
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000
@ -106,7 +149,7 @@
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 #define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384
/**< The maximum size of seed or reseed buffer. */ /**< The maximum size of seed or reseed buffer in bytes. */
#endif #endif
/* \} name SECTION: Module settings */ /* \} name SECTION: Module settings */
@ -164,17 +207,68 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* \brief This function seeds and sets up the CTR_DRBG * \brief This function seeds and sets up the CTR_DRBG
* entropy source for future reseeds. * entropy source for future reseeds.
* *
* \note Personalization data can be provided in addition to the more generic * A typical choice for the \p f_entropy and \p p_entropy parameters is
* to use the entropy module:
* - \p f_entropy is mbedtls_entropy_func();
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
* with mbedtls_entropy_init() (which registers the platform's default
* entropy sources).
*
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
*
* You can provide a personalization string in addition to the
* entropy source, to make this instantiation as unique as possible. * entropy source, to make this instantiation as unique as possible.
* *
* \note The _seed_material_ value passed to the derivation
* function in the CTR_DRBG Instantiate Process
* described in NIST SP 800-90A §10.2.1.3.2
* is the concatenation of the string obtained from
* calling \p f_entropy and the \p custom string.
* The origin of the nonce depends on the value of
* the entropy length relative to the security strength.
* - If the entropy length is at least 1.5 times the
* security strength then the nonce is taken from the
* string obtained with \p f_entropy.
* - If the entropy length is less than the security
* strength, then the nonce is taken from \p custom.
* In this case, for compliance with SP 800-90A,
* you must pass a unique value of \p custom at
* each invocation. See SP 800-90A §8.6.7 for more
* details.
*/
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than
* #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the
* maximum security strength permitted by CTR_DRBG,
* you must pass a value of \p custom that is a nonce:
* this value must never be repeated in subsequent
* runs of the same application or on a different
* device.
*/
#endif
/**
* \param ctx The CTR_DRBG context to seed. * \param ctx The CTR_DRBG context to seed.
* It must have been initialized with
* mbedtls_ctr_drbg_init().
* After a successful call to mbedtls_ctr_drbg_seed(),
* you may not call mbedtls_ctr_drbg_seed() again on
* the same context unless you call
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
* again first.
* \param f_entropy The entropy callback, taking as arguments the * \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the * \p p_entropy context, the buffer to fill, and the
length of the buffer. * length of the buffer.
* \param p_entropy The entropy context. * \p f_entropy is always called with a buffer size
* \param custom Personalization data, that is device-specific * equal to the entropy length.
identifiers. Can be NULL. * \param p_entropy The entropy context to pass to \p f_entropy.
* \param len The length of the personalization data. * \param custom The personalization string.
* This can be \c NULL, in which case the personalization
* string is empty regardless of the value of \p len.
* \param len The length of the personalization string.
* This must be at most
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
* - #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
@ -197,7 +291,8 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
* The default value is off. * The default value is off.
* *
* \note If enabled, entropy is gathered at the beginning of * \note If enabled, entropy is gathered at the beginning of
* every call to mbedtls_ctr_drbg_random_with_add(). * every call to mbedtls_ctr_drbg_random_with_add()
* or mbedtls_ctr_drbg_random().
* Only use this if your entropy source has sufficient * Only use this if your entropy source has sufficient
* throughput. * throughput.
* *
@ -209,17 +304,36 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
/** /**
* \brief This function sets the amount of entropy grabbed on each * \brief This function sets the amount of entropy grabbed on each
* seed or reseed. The default value is * seed or reseed.
* #MBEDTLS_CTR_DRBG_ENTROPY_LEN. *
* The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
*
* \note The security strength of CTR_DRBG is bounded by the
* entropy length. Thus:
* - When using AES-256
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled,
* which is the default),
* \p len must be at least 32 (in bytes)
* to achieve a 256-bit strength.
* - When using AES-128
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled)
* \p len must be at least 16 (in bytes)
* to achieve a 128-bit strength.
* *
* \param ctx The CTR_DRBG context. * \param ctx The CTR_DRBG context.
* \param len The amount of entropy to grab. * \param len The amount of entropy to grab, in bytes.
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
*/ */
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
size_t len ); size_t len );
/** /**
* \brief This function sets the reseed interval. * \brief This function sets the reseed interval.
*
* The reseed interval is the number of calls to mbedtls_ctr_drbg_random()
* or mbedtls_ctr_drbg_random_with_add() after which the entropy function
* is called again.
*
* The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
* *
* \param ctx The CTR_DRBG context. * \param ctx The CTR_DRBG context.
@ -233,8 +347,12 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
* extracts data from the entropy source. * extracts data from the entropy source.
* *
* \param ctx The CTR_DRBG context. * \param ctx The CTR_DRBG context.
* \param additional Additional data to add to the state. Can be NULL. * \param additional Additional data to add to the state. Can be \c NULL.
* \param len The length of the additional data. * \param len The length of the additional data.
* This must be less than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* configured for the context.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
@ -246,7 +364,8 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
* \brief This function updates the state of the CTR_DRBG context. * \brief This function updates the state of the CTR_DRBG context.
* *
* \param ctx The CTR_DRBG context. * \param ctx The CTR_DRBG context.
* \param additional The data to update the state with. * \param additional The data to update the state with. This must not be
* \c NULL unless \p add_len is \c 0.
* \param add_len Length of \p additional in bytes. This must be at * \param add_len Length of \p additional in bytes. This must be at
* most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* *
@ -264,14 +383,23 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
* \brief This function updates a CTR_DRBG instance with additional * \brief This function updates a CTR_DRBG instance with additional
* data and uses it to generate random data. * data and uses it to generate random data.
* *
* \note The function automatically reseeds if the reseed counter is exceeded. * This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
* *
* \param p_rng The CTR_DRBG context. This must be a pointer to a * \param p_rng The CTR_DRBG context. This must be a pointer to a
* #mbedtls_ctr_drbg_context structure. * #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill. * \param output The buffer to fill.
* \param output_len The length of the buffer. * \param output_len The length of the buffer in bytes.
* \param additional Additional data to update. Can be NULL. * \param additional Additional data to update. Can be \c NULL, in which
* \param add_len The length of the additional data. * case the additional data is empty regardless of
* the value of \p add_len.
* \param add_len The length of the additional data
* if \p additional is not \c NULL.
* This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT
* and less than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* configured for the context.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
@ -284,12 +412,14 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
/** /**
* \brief This function uses CTR_DRBG to generate random data. * \brief This function uses CTR_DRBG to generate random data.
* *
* \note The function automatically reseeds if the reseed counter is exceeded. * This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
* *
* \param p_rng The CTR_DRBG context. This must be a pointer to a * \param p_rng The CTR_DRBG context. This must be a pointer to a
* #mbedtls_ctr_drbg_context structure. * #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill. * \param output The buffer to fill.
* \param output_len The length of the buffer. * \param output_len The length of the buffer in bytes.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
@ -336,7 +466,7 @@ MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed
* failure. * failure.
*/ */
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
@ -350,8 +480,10 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
* #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure. * reseed failure.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing
* seed file is too large.
*/ */
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */

View file

@ -1,10 +1,14 @@
/** /**
* \file hmac_drbg.h * \file hmac_drbg.h
* *
* \brief HMAC_DRBG (NIST SP 800-90A) * \brief The HMAC_DRBG pseudorandom generator.
*
* This module implements the HMAC_DRBG pseudorandom generator described
* in <em>NIST SP 800-90A: Recommendation for Random Number Generation Using
* Deterministic Random Bit Generators</em>.
*/ */
/* /*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -104,38 +108,72 @@ typedef struct mbedtls_hmac_drbg_context
} mbedtls_hmac_drbg_context; } mbedtls_hmac_drbg_context;
/** /**
* \brief HMAC_DRBG context initialization * \brief HMAC_DRBG context initialization.
* Makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or
* mbedtls_hmac_drbg_free().
* *
* \param ctx HMAC_DRBG context to be initialized * This function makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
*
* \param ctx HMAC_DRBG context to be initialized.
*/ */
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
/** /**
* \brief HMAC_DRBG initial seeding * \brief HMAC_DRBG initial seeding.
* Seed and setup entropy source for future reseeds.
* *
* \param ctx HMAC_DRBG context to be seeded * Set the initial seed and set up the entropy source for future reseeds.
* \param md_info MD algorithm to use for HMAC_DRBG
* \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer
* length)
* \param p_entropy Entropy context
* \param custom Personalization data (Device specific identifiers)
* (Can be NULL)
* \param len Length of personalization data
* *
* \note The "security strength" as defined by NIST is set to: * A typical choice for the \p f_entropy and \p p_entropy parameters is
* 128 bits if md_alg is SHA-1, * to use the entropy module:
* 192 bits if md_alg is SHA-224, * - \p f_entropy is mbedtls_entropy_func();
* 256 bits if md_alg is SHA-256 or higher. * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
* with mbedtls_entropy_init() (which registers the platform's default
* entropy sources).
*
* You can provide a personalization string in addition to the
* entropy source, to make this instantiation as unique as possible.
*
* \note By default, the security strength as defined by NIST is:
* - 128 bits if \p md_info is SHA-1;
* - 192 bits if \p md_info is SHA-224;
* - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512.
* Note that SHA-256 is just as efficient as SHA-224. * Note that SHA-256 is just as efficient as SHA-224.
* The security strength can be reduced if a smaller
* entropy length is set with
* mbedtls_hmac_drbg_set_entropy_len().
* *
* \return 0 if successful, or * \note The default entropy length is the security strength
* MBEDTLS_ERR_MD_BAD_INPUT_DATA, or * (converted from bits to bytes). You can override
* MBEDTLS_ERR_MD_ALLOC_FAILED, or * it by calling mbedtls_hmac_drbg_set_entropy_len().
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED. *
* \note During the initial seeding, this function calls
* the entropy source to obtain a nonce
* whose length is half the entropy length.
*
* \param ctx HMAC_DRBG context to be seeded.
* \param md_info MD algorithm to use for HMAC_DRBG.
* \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
* \p f_entropy is always called with a length that is
* less than or equal to the entropy length.
* \param p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string.
* This can be \c NULL, in which case the personalization
* string is empty regardless of the value of \p len.
* \param len The length of the personalization string.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2
* where \p entropy_len is the entropy length
* described above.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
* invalid.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
* memory to allocate context data.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if the call to \p f_entropy failed.
*/ */
int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
mbedtls_md_handle_t md_info, mbedtls_md_handle_t md_info,
@ -146,100 +184,134 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
/** /**
* \brief Initilisation of simpified HMAC_DRBG (never reseeds). * \brief Initilisation of simpified HMAC_DRBG (never reseeds).
* (For use with deterministic ECDSA.)
* *
* \param ctx HMAC_DRBG context to be initialised * This function is meant for use in algorithms that need a pseudorandom
* \param md_info MD algorithm to use for HMAC_DRBG * input such as deterministic ECDSA.
* \param data Concatenation of entropy string and additional data
* \param data_len Length of data in bytes
* *
* \return 0 if successful, or * \param ctx HMAC_DRBG context to be initialised.
* MBEDTLS_ERR_MD_BAD_INPUT_DATA, or * \param md_info MD algorithm to use for HMAC_DRBG.
* MBEDTLS_ERR_MD_ALLOC_FAILED. * \param data Concatenation of the initial entropy string and
* the additional data.
* \param data_len Length of \p data in bytes.
*
* \return \c 0 if successful. or
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
* invalid.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
* memory to allocate context data.
*/ */
int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
mbedtls_md_handle_t md_info, mbedtls_md_handle_t md_info,
const unsigned char *data, size_t data_len ); const unsigned char *data, size_t data_len );
/** /**
* \brief Enable / disable prediction resistance (Default: Off) * \brief This function turns prediction resistance on or off.
* The default value is off.
* *
* Note: If enabled, entropy is used for ctx->entropy_len before each call! * \note If enabled, entropy is gathered at the beginning of
* Only use this if you have ample supply of good entropy! * every call to mbedtls_hmac_drbg_random_with_add()
* or mbedtls_hmac_drbg_random().
* Only use this if your entropy source has sufficient
* throughput.
* *
* \param ctx HMAC_DRBG context * \param ctx The HMAC_DRBG context.
* \param resistance MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF * \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF.
*/ */
void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
int resistance ); int resistance );
/** /**
* \brief Set the amount of entropy grabbed on each reseed * \brief This function sets the amount of entropy grabbed on each
* (Default: given by the security strength, which * seed or reseed.
* depends on the hash used, see \c mbedtls_hmac_drbg_init() )
* *
* \param ctx HMAC_DRBG context * See the documentation of mbedtls_hmac_drbg_seed() for the default value.
* \param len Amount of entropy to grab, in bytes *
* \param ctx The HMAC_DRBG context.
* \param len The amount of entropy to grab, in bytes.
*/ */
void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
size_t len ); size_t len );
/** /**
* \brief Set the reseed interval * \brief Set the reseed interval.
* (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
* *
* \param ctx HMAC_DRBG context * The reseed interval is the number of calls to mbedtls_hmac_drbg_random()
* \param interval Reseed interval * or mbedtls_hmac_drbg_random_with_add() after which the entropy function
* is called again.
*
* The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL.
*
* \param ctx The HMAC_DRBG context.
* \param interval The reseed interval.
*/ */
void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
int interval ); int interval );
/** /**
* \brief HMAC_DRBG update state * \brief This function updates the state of the HMAC_DRBG context.
* *
* \param ctx HMAC_DRBG context * \param ctx The HMAC_DRBG context.
* \param additional Additional data to update state with, or NULL * \param additional The data to update the state with.
* \param add_len Length of additional data, or 0 * If this is \c NULL, there is no additional data.
* \param add_len Length of \p additional in bytes.
* Unused if \p additional is \c NULL.
* *
* \return \c 0 on success, or an error from the underlying * \return \c 0 on success, or an error from the underlying
* hash calculation or * hash calculation or
* MBEDTLS_ERR_PLATFORM_FAULT_DETECTED. * MBEDTLS_ERR_PLATFORM_FAULT_DETECTED.
*
* \note Additional data is optional, pass NULL and 0 as second
* third argument if no additional data is being used.
*/ */
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len ); const unsigned char *additional, size_t add_len );
/** /**
* \brief HMAC_DRBG reseeding (extracts data from entropy source) * \brief This function reseeds the HMAC_DRBG context, that is
* extracts data from the entropy source.
* *
* \param ctx HMAC_DRBG context * \param ctx The HMAC_DRBG context.
* \param additional Additional data to add to state (Can be NULL) * \param additional Additional data to add to the state.
* \param len Length of additional data * If this is \c NULL, there is no additional data
* and \p len should be \c 0.
* \param len The length of the additional data.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len
* where \p entropy_len is the entropy length
* (see mbedtls_hmac_drbg_set_entropy_len()).
* *
* \return 0 if successful, or * \return \c 0 if successful.
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if a call to the entropy function failed.
*/ */
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t len ); const unsigned char *additional, size_t len );
/** /**
* \brief HMAC_DRBG generate random with additional update input * \brief This function updates an HMAC_DRBG instance with additional
* data and uses it to generate random data.
* *
* Note: Automatically reseeds if reseed_counter is reached or PR is enabled. * This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
* *
* \param p_rng HMAC_DRBG context * \param p_rng The HMAC_DRBG context. This must be a pointer to a
* \param output Buffer to fill * #mbedtls_hmac_drbg_context structure.
* \param output_len Length of the buffer * \param output The buffer to fill.
* \param additional Additional data to update with (can be NULL) * \param output_len The length of the buffer in bytes.
* \param add_len Length of additional data (can be 0) * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \param additional Additional data to update with.
* If this is \c NULL, there is no additional data
* and \p add_len should be \c 0.
* \param add_len The length of the additional data.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT.
* *
* \return 0 if successful, or * \return \c 0 if successful.
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or * if a call to the entropy source failed.
* MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG, or * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
* MBEDTLS_ERR_PLATFORM_FAULT_DETECTED. * \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if
* \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT.
* \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED if
* a logical fault is detected.
*/ */
int mbedtls_hmac_drbg_random_with_add( void *p_rng, int mbedtls_hmac_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len, unsigned char *output, size_t output_len,
@ -247,26 +319,31 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
size_t add_len ); size_t add_len );
/** /**
* \brief HMAC_DRBG generate random * \brief This function uses HMAC_DRBG to generate random data.
* *
* Note: Automatically reseeds if reseed_counter is reached or PR is enabled. * This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
* *
* \param p_rng HMAC_DRBG context * \param p_rng The HMAC_DRBG context. This must be a pointer to a
* \param output Buffer to fill * #mbedtls_hmac_drbg_context structure.
* \param out_len Length of the buffer * \param output The buffer to fill.
* \param out_len The length of the buffer in bytes.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* *
* \return 0 if successful, or * \return \c 0 if successful.
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, * if a call to the entropy source failed.
* MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG, or * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
* MBEDTLS_ERR_PLATFORM_FAULT_DETECTED. * \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED if
* a logical fault is detected.
*/ */
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
/** /**
* \brief Free an HMAC_DRBG context * \brief Free an HMAC_DRBG context
* *
* \param ctx HMAC_DRBG context to free. * \param ctx The HMAC_DRBG context to free.
*/ */
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
@ -277,17 +354,16 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
#define MBEDTLS_DEPRECATED #define MBEDTLS_DEPRECATED
#endif #endif
/** /**
* \brief HMAC_DRBG update state * \brief This function updates the state of the HMAC_DRBG context.
* *
* \deprecated Superseded by mbedtls_hmac_drbg_update_ret() * \deprecated Superseded by mbedtls_hmac_drbg_update_ret()
* in 2.16.0. * in 2.16.0.
* *
* \param ctx HMAC_DRBG context * \param ctx The HMAC_DRBG context.
* \param additional Additional data to update state with, or NULL * \param additional The data to update the state with.
* \param add_len Length of additional data, or 0 * If this is \c NULL, there is no additional data.
* * \param add_len Length of \p additional in bytes.
* \note Additional data is optional, pass NULL and 0 as second * Unused if \p additional is \c NULL.
* third argument if no additional data is being used.
*/ */
MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
mbedtls_hmac_drbg_context *ctx, mbedtls_hmac_drbg_context *ctx,
@ -297,26 +373,31 @@ MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
#if defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_FS_IO)
/** /**
* \brief Write a seed file * \brief This function writes a seed file.
* *
* \param ctx HMAC_DRBG context * \param ctx The HMAC_DRBG context.
* \param path Name of the file * \param path The name of the file.
* *
* \return 0 if successful, 1 on file error, or * \return \c 0 on success.
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed
* failure.
*/ */
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
/** /**
* \brief Read and update a seed file. Seed is added to this * \brief This function reads and updates a seed file. The seed
* instance * is added to this instance.
* *
* \param ctx HMAC_DRBG context * \param ctx The HMAC_DRBG context.
* \param path Name of the file * \param path The name of the file.
* *
* \return 0 if successful, 1 on file error, * \return \c 0 on success.
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
* MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on
* reseed failure.
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing
* seed file is too large.
*/ */
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */
@ -324,9 +405,10 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
/** /**
* \brief Checkup routine * \brief The HMAC_DRBG Checkup routine.
* *
* \return 0 if successful, or 1 if the test failed * \return \c 0 if successful.
* \return \c 1 if the test failed.
*/ */
int mbedtls_hmac_drbg_self_test( int verbose ); int mbedtls_hmac_drbg_self_test( int verbose );
#endif #endif

View file

@ -40,16 +40,16 @@
*/ */
#define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 16 #define MBEDTLS_VERSION_MINOR 16
#define MBEDTLS_VERSION_PATCH 3 #define MBEDTLS_VERSION_PATCH 4
/** /**
* The single version number has the following structure: * The single version number has the following structure:
* MMNNPP00 * MMNNPP00
* Major version | Minor version | Patch version * Major version | Minor version | Patch version
*/ */
#define MBEDTLS_VERSION_NUMBER 0x02100300 #define MBEDTLS_VERSION_NUMBER 0x02100400
#define MBEDTLS_VERSION_STRING "2.16.3" #define MBEDTLS_VERSION_STRING "2.16.4"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.3" #define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.4"
#if defined(MBEDTLS_VERSION_C) #if defined(MBEDTLS_VERSION_C)

View file

@ -162,15 +162,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY)
add_library(mbedcrypto SHARED ${src_crypto}) add_library(mbedcrypto SHARED ${src_crypto})
set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.3 SOVERSION 3) set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.4 SOVERSION 3)
target_link_libraries(mbedcrypto ${libs}) target_link_libraries(mbedcrypto ${libs})
add_library(mbedx509 SHARED ${src_x509}) add_library(mbedx509 SHARED ${src_x509})
set_target_properties(mbedx509 PROPERTIES VERSION 2.16.3 SOVERSION 0) set_target_properties(mbedx509 PROPERTIES VERSION 2.16.4 SOVERSION 0)
target_link_libraries(mbedx509 ${libs} mbedcrypto) target_link_libraries(mbedx509 ${libs} mbedcrypto)
add_library(mbedtls SHARED ${src_tls}) add_library(mbedtls SHARED ${src_tls})
set_target_properties(mbedtls PROPERTIES VERSION 2.16.3 SOVERSION 12) set_target_properties(mbedtls PROPERTIES VERSION 2.16.4 SOVERSION 12)
target_link_libraries(mbedtls ${libs} mbedx509) target_link_libraries(mbedtls ${libs} mbedx509)
install(TARGETS mbedtls mbedx509 mbedcrypto install(TARGETS mbedtls mbedx509 mbedcrypto

View file

@ -1246,6 +1246,18 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
PUT_UINT32_LE( X2, output, 8 ); PUT_UINT32_LE( X2, output, 8 );
PUT_UINT32_LE( X3, output, 12 ); PUT_UINT32_LE( X3, output, 12 );
mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
mbedtls_platform_zeroize( &RK, sizeof( RK ) );
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */ #endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
@ -1513,6 +1525,18 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
PUT_UINT32_LE( X2, output, 8 ); PUT_UINT32_LE( X2, output, 8 );
PUT_UINT32_LE( X3, output, 12 ); PUT_UINT32_LE( X3, output, 12 );
mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
mbedtls_platform_zeroize( &RK, sizeof( RK ) );
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */ #endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */

View file

@ -157,9 +157,10 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
/* Actually resize up in this case */ /* Actually resize up if there are currently fewer than nblimbs limbs. */
if( X->n <= nblimbs ) if( X->n <= nblimbs )
return( mbedtls_mpi_grow( X, nblimbs ) ); return( mbedtls_mpi_grow( X, nblimbs ) );
/* After this point, then X->n > nblimbs and in particular X->n > 0. */
for( i = X->n - 1; i > 0; i-- ) for( i = X->n - 1; i > 0; i-- )
if( X->p[i] != 0 ) if( X->p[i] != 0 )
@ -198,7 +199,7 @@ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
if( X == Y ) if( X == Y )
return( 0 ); return( 0 );
if( Y->p == NULL ) if( Y->n == 0 )
{ {
mbedtls_mpi_free( X ); mbedtls_mpi_free( X );
return( 0 ); return( 0 );
@ -1071,6 +1072,107 @@ int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
return( 0 ); return( 0 );
} }
/** Decide if an integer is less than the other, without branches.
*
* \param x First integer.
* \param y Second integer.
*
* \return 1 if \p x is less than \p y, 0 otherwise
*/
static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
const mbedtls_mpi_uint y )
{
mbedtls_mpi_uint ret;
mbedtls_mpi_uint cond;
/*
* Check if the most significant bits (MSB) of the operands are different.
*/
cond = ( x ^ y );
/*
* If the MSB are the same then the difference x-y will be negative (and
* have its MSB set to 1 during conversion to unsigned) if and only if x<y.
*/
ret = ( x - y ) & ~cond;
/*
* If the MSB are different, then the operand with the MSB of 1 is the
* bigger. (That is if y has MSB of 1, then x<y is true and it is false if
* the MSB of y is 0.)
*/
ret |= y & cond;
ret = ret >> ( biL - 1 );
return (unsigned) ret;
}
/*
* Compare signed values in constant time
*/
int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
unsigned *ret )
{
size_t i;
/* The value of any of these variables is either 0 or 1 at all times. */
unsigned cond, done, X_is_negative, Y_is_negative;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( Y != NULL );
MPI_VALIDATE_RET( ret != NULL );
if( X->n != Y->n )
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
/*
* Set sign_N to 1 if N >= 0, 0 if N < 0.
* We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
*/
X_is_negative = ( X->s & 2 ) >> 1;
Y_is_negative = ( Y->s & 2 ) >> 1;
/*
* If the signs are different, then the positive operand is the bigger.
* That is if X is negative (X_is_negative == 1), then X < Y is true and it
* is false if X is positive (X_is_negative == 0).
*/
cond = ( X_is_negative ^ Y_is_negative );
*ret = cond & X_is_negative;
/*
* This is a constant-time function. We might have the result, but we still
* need to go through the loop. Record if we have the result already.
*/
done = cond;
for( i = X->n; i > 0; i-- )
{
/*
* If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
* X and Y are negative.
*
* Again even if we can make a decision, we just mark the result and
* the fact that we are done and continue looping.
*/
cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
*ret |= cond & ( 1 - done ) & X_is_negative;
done |= cond;
/*
* If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
* X and Y are positive.
*
* Again even if we can make a decision, we just mark the result and
* the fact that we are done and continue looping.
*/
cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
*ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
done |= cond;
}
return( 0 );
}
/* /*
* Compare signed values * Compare signed values
*/ */

View file

@ -361,6 +361,10 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
*olen = 0; *olen = 0;
block_size = mbedtls_cipher_get_block_size( ctx ); block_size = mbedtls_cipher_get_block_size( ctx );
if ( 0 == block_size )
{
return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
}
if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
{ {
@ -396,11 +400,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
} }
#endif #endif
if ( 0 == block_size )
{
return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
}
if( input == output && if( input == output &&
( ctx->unprocessed_len != 0 || ilen % block_size ) ) ( ctx->unprocessed_len != 0 || ilen % block_size ) )
{ {
@ -459,11 +458,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
*/ */
if( 0 != ilen ) if( 0 != ilen )
{ {
if( 0 == block_size )
{
return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
}
/* Encryption: only cache partial blocks /* Encryption: only cache partial blocks
* Decryption w/ padding: always keep at least one whole block * Decryption w/ padding: always keep at least one whole block
* Decryption w/o padding: only cache partial blocks * Decryption w/o padding: only cache partial blocks

View file

@ -62,68 +62,6 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
#endif #endif
} }
/*
* Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
* NIST tests to succeed (which require known length fixed entropy)
*/
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_seed_entropy_len(ctx, f_entropy, p_entropy,
* custom, len, entropy_len)
* implements
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
* security_strength) -> initial_working_state
* with inputs
* custom[:len] = nonce || personalization_string
* where entropy_input comes from f_entropy for entropy_len bytes
* and with outputs
* ctx = initial_working_state
*/
int mbedtls_ctr_drbg_seed_entropy_len(
mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len,
size_t entropy_len )
{
int ret;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
mbedtls_platform_memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
mbedtls_aes_init( &ctx->aes_ctx );
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
ctx->entropy_len = entropy_len;
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
/*
* Initialize with an empty key
*/
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
{
return( ret );
}
return( 0 );
}
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len )
{
return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
}
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
{ {
if( ctx == NULL ) if( ctx == NULL )
@ -427,6 +365,63 @@ exit:
return( ret ); return( ret );
} }
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
* implements
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
* security_strength) -> initial_working_state
* with inputs
* custom[:len] = nonce || personalization_string
* where entropy_input comes from f_entropy for ctx->entropy_len bytes
* and with outputs
* ctx = initial_working_state
*/
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len )
{
int ret;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
mbedtls_aes_init( &ctx->aes_ctx );
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
if( ctx->entropy_len == 0 )
ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
/*
* Initialize with an empty key
*/
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
{
return( ret );
}
return( 0 );
}
/* Backward compatibility wrapper */
int mbedtls_ctr_drbg_seed_entropy_len(
mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
const unsigned char *custom, size_t len,
size_t entropy_len )
{
mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len );
return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
}
/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2) /* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
* mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len) * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
* implements * implements
@ -517,7 +512,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
exit: exit:
mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
return( 0 ); return( ret );
} }
int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
@ -678,8 +673,11 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
test_offset = 0; test_offset = 0;
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
(void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) ); CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_pr,
nonce_pers_pr, 16 ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
@ -699,8 +697,11 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_ctr_drbg_init( &ctx ); mbedtls_ctr_drbg_init( &ctx );
test_offset = 0; test_offset = 0;
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
(void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_nopr,
nonce_pers_nopr, 16 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );

View file

@ -297,7 +297,7 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
*p_sign_tries = 0; *p_sign_tries = 0;
do do
{ {
if( *p_sign_tries++ > 10 ) if( (*p_sign_tries)++ > 10 )
{ {
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup; goto cleanup;
@ -310,7 +310,7 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
*p_key_tries = 0; *p_key_tries = 0;
do do
{ {
if( *p_key_tries++ > 10 ) if( (*p_key_tries)++ > 10 )
{ {
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup; goto cleanup;
@ -363,6 +363,7 @@ modn:
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pk, pk, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );

View file

@ -2724,6 +2724,7 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
{ {
/* SEC1 3.2.1: Generate d such that 1 <= n < N */ /* SEC1 3.2.1: Generate d such that 1 <= n < N */
int count = 0; int count = 0;
unsigned cmp = 0;
/* /*
* Match the procedure given in RFC 6979 (deterministic ECDSA): * Match the procedure given in RFC 6979 (deterministic ECDSA):
@ -2748,9 +2749,14 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
*/ */
if( ++count > 30 ) if( ++count > 30 )
return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
ret = mbedtls_mpi_lt_mpi_ct( d, &grp->N, &cmp );
if( ret != 0 )
{
goto cleanup;
} }
while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || }
mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ); while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || cmp != 1 );
} }
#endif /* ECP_SHORTWEIERSTRASS */ #endif /* ECP_SHORTWEIERSTRASS */

View file

@ -320,6 +320,8 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
if( ctx->entropy_len == 0 )
{
/* /*
* See SP800-57 5.6.1 (p. 65-66) for the security strength provided by * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
* each hash function, then according to SP800-90A rev1 10.1 table 2, * each hash function, then according to SP800-90A rev1 10.1 table 2,
@ -330,6 +332,7 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
32; /* better (256+) -> 256 bits */ 32; /* better (256+) -> 256 bits */
}
if( ( ret = hmac_drbg_reseed_core( ctx, custom, len, HMAC_NONCE_YES ) ) != 0 ) if( ( ret = hmac_drbg_reseed_core( ctx, custom, len, HMAC_NONCE_YES ) ) != 0 )
{ {
@ -349,7 +352,7 @@ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx
} }
/* /*
* Set entropy length grabbed for reseeds * Set entropy length grabbed for seeding
*/ */
void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
{ {

View file

@ -843,15 +843,41 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
goto cleanup; goto cleanup;
p += len; p += len;
/* Complete the RSA private key */ #if !defined(MBEDTLS_RSA_NO_CRT)
if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 ) /*
* The RSA CRT parameters DP, DQ and QP are nominally redundant, in
* that they can be easily recomputed from D, P and Q. However by
* parsing them from the PKCS1 structure it is possible to avoid
* recalculating them which both reduces the overhead of loading
* RSA private keys into memory and also avoids side channels which
* can arise when computing those values, since all of D, P, and Q
* are secret. See https://eprint.iacr.org/2020/055 for a
* description of one such attack.
*/
/* Import DP */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0)
goto cleanup; goto cleanup;
/* Check optional parameters */ /* Import DQ */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0)
goto cleanup;
/* Import QP */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0)
goto cleanup;
#else
/* Verify existance of the CRT params */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 || if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 || ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ) ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 )
goto cleanup; goto cleanup;
#endif
/* Complete the RSA private key */
if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
goto cleanup;
if( p != end ) if( p != end )
{ {

View file

@ -249,6 +249,9 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
{ {
int ret = 0; int ret = 0;
int have_N, have_P, have_Q, have_D, have_E; int have_N, have_P, have_Q, have_D, have_E;
#if !defined(MBEDTLS_RSA_NO_CRT)
int have_DP, have_DQ, have_QP;
#endif
int n_missing, pq_missing, d_missing, is_pub, is_priv; int n_missing, pq_missing, d_missing, is_pub, is_priv;
RSA_VALIDATE_RET( ctx != NULL ); RSA_VALIDATE_RET( ctx != NULL );
@ -259,6 +262,12 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
#if !defined(MBEDTLS_RSA_NO_CRT)
have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 );
have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 );
have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 );
#endif
/* /*
* Check whether provided parameters are enough * Check whether provided parameters are enough
* to deduce all others. The following incomplete * to deduce all others. The following incomplete
@ -324,7 +333,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
*/ */
#if !defined(MBEDTLS_RSA_NO_CRT) #if !defined(MBEDTLS_RSA_NO_CRT)
if( is_priv ) if( is_priv && ! ( have_DP && have_DQ && have_QP ) )
{ {
ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
&ctx->DP, &ctx->DQ, &ctx->QP ); &ctx->DP, &ctx->DQ, &ctx->QP );

View file

@ -306,6 +306,9 @@ static const char *features[] = {
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
"MBEDTLS_CIPHER_PADDING_ZEROS", "MBEDTLS_CIPHER_PADDING_ZEROS",
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
"MBEDTLS_CTR_DRBG_USE_128_BIT_KEY",
#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) #if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES)
"MBEDTLS_ENABLE_WEAK_CIPHERSUITES", "MBEDTLS_ENABLE_WEAK_CIPHERSUITES",
#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ #endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */

View file

@ -227,7 +227,9 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s
/* /*
* Prepare signature * Prepare signature
*/ */
mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
if( ret != 0 )
return( ret );
if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
f_rng, p_rng ) ) != 0 ) f_rng, p_rng ) ) != 0 )

View file

@ -858,6 +858,14 @@ int query_config( const char *config )
} }
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
if( strcmp( "MBEDTLS_CTR_DRBG_USE_128_BIT_KEY", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_CTR_DRBG_USE_128_BIT_KEY );
return( 0 );
}
#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) #if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES)
if( strcmp( "MBEDTLS_ENABLE_WEAK_CIPHERSUITES", config ) == 0 ) if( strcmp( "MBEDTLS_ENABLE_WEAK_CIPHERSUITES", config ) == 0 )
{ {
@ -2266,14 +2274,6 @@ int query_config( const char *config )
} }
#endif /* MBEDTLS_CTR_DRBG_MAX_SEED_INPUT */ #endif /* MBEDTLS_CTR_DRBG_MAX_SEED_INPUT */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
if( strcmp( "MBEDTLS_CTR_DRBG_USE_128_BIT_KEY", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_CTR_DRBG_USE_128_BIT_KEY );
return( 0 );
}
#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
#if defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) #if defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
if( strcmp( "MBEDTLS_HMAC_DRBG_RESEED_INTERVAL", config ) == 0 ) if( strcmp( "MBEDTLS_HMAC_DRBG_RESEED_INTERVAL", config ) == 0 )
{ {

View file

@ -686,12 +686,13 @@ int main( int argc, char *argv[] )
mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_ctr_drbg_init( &ctr_drbg );
if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 ) if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
mbedtls_exit(1); mbedtls_exit(1);
TIME_AND_TSC( "CTR_DRBG (NOPR)", TIME_AND_TSC( "CTR_DRBG (NOPR)",
mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) ); mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_ctr_drbg_init( &ctr_drbg );
if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 ) if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
mbedtls_exit(1); mbedtls_exit(1);
mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON ); mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON );

View file

@ -66,6 +66,8 @@
#else #else
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#define mbedtls_printf printf #define mbedtls_printf printf
#define mbedtls_snprintf snprintf #define mbedtls_snprintf snprintf
#define mbedtls_exit exit #define mbedtls_exit exit
@ -78,6 +80,86 @@
#endif #endif
#if defined MBEDTLS_SELF_TEST
/* Sanity check for malloc. This is not expected to fail, and is rather
* intended to display potentially useful information about the platform,
* in particular the behavior of malloc(0). */
static int calloc_self_test( int verbose )
{
int failures = 0;
void *empty1 = mbedtls_calloc( 0, 1 );
void *empty2 = mbedtls_calloc( 0, 1 );
void *buffer1 = mbedtls_calloc( 1, 1 );
void *buffer2 = mbedtls_calloc( 1, 1 );
uintptr_t old_buffer1;
if( empty1 == NULL && empty2 == NULL )
{
if( verbose )
mbedtls_printf( " CALLOC(0): passed (NULL)\n" );
}
else if( empty1 == NULL || empty2 == NULL )
{
if( verbose )
mbedtls_printf( " CALLOC(0): failed (mix of NULL and non-NULL)\n" );
++failures;
}
else if( empty1 == empty2 )
{
if( verbose )
mbedtls_printf( " CALLOC(0): passed (same non-null)\n" );
}
else
{
if( verbose )
mbedtls_printf( " CALLOC(0): passed (distinct non-null)\n" );
}
if( buffer1 == NULL || buffer2 == NULL )
{
if( verbose )
mbedtls_printf( " CALLOC(1): failed (NULL)\n" );
++failures;
}
else if( buffer1 == buffer2 )
{
if( verbose )
mbedtls_printf( " CALLOC(1): failed (same buffer twice)\n" );
++failures;
}
else
{
if( verbose )
mbedtls_printf( " CALLOC(1): passed\n" );
}
old_buffer1 = (uintptr_t) buffer1;
mbedtls_free( buffer1 );
buffer1 = mbedtls_calloc( 1, 1 );
if( buffer1 == NULL )
{
if( verbose )
mbedtls_printf( " CALLOC(1 again): failed (NULL)\n" );
++failures;
}
else
{
if( verbose )
mbedtls_printf( " CALLOC(1 again): passed (%s address)\n",
(uintptr_t) old_buffer1 == (uintptr_t) buffer1 ?
"same" : "different" );
}
if( verbose )
mbedtls_printf( "\n" );
mbedtls_free( empty1 );
mbedtls_free( empty2 );
mbedtls_free( buffer1 );
mbedtls_free( buffer2 );
return( failures );
}
#endif /* MBEDTLS_SELF_TEST */
static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret ) static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
{ {
int ret; int ret;
@ -174,6 +256,7 @@ typedef struct
const selftest_t selftests[] = const selftest_t selftests[] =
{ {
{"calloc", calloc_self_test},
#if defined(MBEDTLS_MD2_C) #if defined(MBEDTLS_MD2_C)
{"md2", mbedtls_md2_self_test}, {"md2", mbedtls_md2_self_test},
#endif #endif

View file

@ -100,6 +100,7 @@ MBEDTLS_TEST_NULL_ENTROPY
MBEDTLS_DEPRECATED_REMOVED MBEDTLS_DEPRECATED_REMOVED
MBEDTLS_HAVE_SSE2 MBEDTLS_HAVE_SSE2
MBEDTLS_PLATFORM_NO_STD_FUNCTIONS MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
MBEDTLS_ECP_DP_M221_ENABLED MBEDTLS_ECP_DP_M221_ENABLED
MBEDTLS_ECP_DP_M383_ENABLED MBEDTLS_ECP_DP_M383_ENABLED
MBEDTLS_ECP_DP_M511_ENABLED MBEDTLS_ECP_DP_M511_ENABLED

View file

@ -0,0 +1,39 @@
/* config.h wrapper that forces calloc(0) to return NULL.
* Used for testing.
*/
/*
* Copyright (C) 2019, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CONFIG_H
/* Don't #define MBEDTLS_CONFIG_H, let config.h do it. */
#include "mbedtls/config.h"
#include <stdlib.h>
static inline void *custom_calloc( size_t nmemb, size_t size )
{
if( nmemb == 0 || size == 0 )
return( NULL );
return( calloc( nmemb, size ) );
}
#define MBEDTLS_PLATFORM_MEMORY
#define MBEDTLS_PLATFORM_STD_CALLOC custom_calloc
#endif /* MBEDTLS_CONFIG_H */

View file

@ -137,6 +137,9 @@ pre_initialize_variables () {
export MAKEFLAGS="-j" export MAKEFLAGS="-j"
fi fi
# CFLAGS and LDFLAGS for Asan builds that don't use CMake
ASAN_CFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all'
# Gather the list of available components. These are the functions # Gather the list of available components. These are the functions
# defined in this script whose name starts with "component_". # defined in this script whose name starts with "component_".
# Parse the script with sed, because in sh there is no way to list # Parse the script with sed, because in sh there is no way to list
@ -1106,8 +1109,8 @@ component_test_no_platform () {
scripts/config.pl unset MBEDTLS_FS_IO scripts/config.pl unset MBEDTLS_FS_IO
# Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19, # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19,
# to re-enable platform integration features otherwise disabled in C99 builds # to re-enable platform integration features otherwise disabled in C99 builds
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -Os -D_DEFAULT_SOURCE' lib programs
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' test make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -Os' test
} }
component_build_no_std_function () { component_build_no_std_function () {
@ -1116,21 +1119,21 @@ component_build_no_std_function () {
scripts/config.pl full scripts/config.pl full
scripts/config.pl set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS scripts/config.pl set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -Os'
} }
component_build_no_ssl_srv () { component_build_no_ssl_srv () {
msg "build: full config except ssl_srv.c, make, gcc" # ~ 30s msg "build: full config except ssl_srv.c, make, gcc" # ~ 30s
scripts/config.pl full scripts/config.pl full
scripts/config.pl unset MBEDTLS_SSL_SRV_C scripts/config.pl unset MBEDTLS_SSL_SRV_C
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O1'
} }
component_build_no_ssl_cli () { component_build_no_ssl_cli () {
msg "build: full config except ssl_cli.c, make, gcc" # ~ 30s msg "build: full config except ssl_cli.c, make, gcc" # ~ 30s
scripts/config.pl full scripts/config.pl full
scripts/config.pl unset MBEDTLS_SSL_CLI_C scripts/config.pl unset MBEDTLS_SSL_CLI_C
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O1'
} }
component_build_no_sockets () { component_build_no_sockets () {
@ -1140,7 +1143,7 @@ component_build_no_sockets () {
scripts/config.pl full scripts/config.pl full
scripts/config.pl unset MBEDTLS_NET_C # getaddrinfo() undeclared, etc. scripts/config.pl unset MBEDTLS_NET_C # getaddrinfo() undeclared, etc.
scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0 -std=c99 -pedantic' lib make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O1 -std=c99 -pedantic' lib
} }
component_test_memory_buffer_allocator_backtrace () { component_test_memory_buffer_allocator_backtrace () {
@ -1284,6 +1287,21 @@ component_test_platform_calloc_macro () {
make test make test
} }
component_test_malloc_0_null () {
msg "build: malloc(0) returns NULL (ASan+UBSan build)"
scripts/config.pl full
scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
make CC=gcc CFLAGS="'-DMBEDTLS_CONFIG_FILE=\"$PWD/tests/configs/config-wrapper-malloc-0-null.h\"' -O -Werror -Wall -Wextra -fsanitize=address,undefined" LDFLAGS='-fsanitize=address,undefined'
msg "test: malloc(0) returns NULL (ASan+UBSan build)"
make test
msg "selftest: malloc(0) returns NULL (ASan+UBSan build)"
# Just the calloc selftest. "make test" ran the others as part of the
# test suites.
if_build_succeeded programs/test/selftest calloc
}
component_test_aes_fewer_tables () { component_test_aes_fewer_tables () {
msg "build: default config with AES_FEWER_TABLES enabled" msg "build: default config with AES_FEWER_TABLES enabled"
scripts/config.pl set MBEDTLS_AES_FEWER_TABLES scripts/config.pl set MBEDTLS_AES_FEWER_TABLES
@ -1357,6 +1375,30 @@ component_test_cmake_shared () {
make test make test
} }
test_build_opt () {
info=$1 cc=$2; shift 2
for opt in "$@"; do
msg "build/test: $cc $opt, $info" # ~ 30s
make CC="$cc" CFLAGS="$opt -Wall -Wextra -Werror"
# We're confident enough in compilers to not run _all_ the tests,
# but at least run the unit tests. In particular, runs with
# optimizations use inline assembly whereas runs with -O0
# skip inline assembly.
make test # ~30s
make clean
done
}
component_test_clang_opt () {
scripts/config.pl full
test_build_opt 'full config' clang -O0 -Os -O2
}
component_test_gcc_opt () {
scripts/config.pl full
test_build_opt 'full config' gcc -O0 -Os -O2
}
component_build_mbedtls_config_file () { component_build_mbedtls_config_file () {
msg "build: make with MBEDTLS_CONFIG_FILE" # ~40s msg "build: make with MBEDTLS_CONFIG_FILE" # ~40s
# Use the full config so as to catch a maximum of places where # Use the full config so as to catch a maximum of places where
@ -1372,7 +1414,7 @@ component_test_m32_o0 () {
# Build once with -O0, to compile out the i386 specific inline assembly # Build once with -O0, to compile out the i386 specific inline assembly
msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s
scripts/config.pl full scripts/config.pl full
make CC=gcc PTHREAD=1 CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32' make CC=gcc PTHREAD=1 CFLAGS="$ASAN_CFLAGS -m32 -O0" LDFLAGS="-m32 $ASAN_CFLAGS"
msg "test: i386, make, gcc -O0 (ASan build)" msg "test: i386, make, gcc -O0 (ASan build)"
make test make test
@ -1388,7 +1430,7 @@ component_test_m32_o1 () {
# Build again with -O1, to compile in the i386 specific inline assembly # Build again with -O1, to compile in the i386 specific inline assembly
msg "build: i386, make, gcc -O1 (ASan build)" # ~ 30s msg "build: i386, make, gcc -O1 (ASan build)" # ~ 30s
scripts/config.pl full scripts/config.pl full
make CC=gcc PTHREAD=1 CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32' make CC=gcc PTHREAD=1 CFLAGS="$ASAN_CFLAGS -m32 -O1" LDFLAGS="-m32 $ASAN_CFLAGS"
msg "test: i386, make, gcc -O1 (ASan build)" msg "test: i386, make, gcc -O1 (ASan build)"
make test make test

View file

@ -93,7 +93,7 @@ for my $suite (@suites)
$suite_cases_failed = () = $result =~ /.. FAILED/g; $suite_cases_failed = () = $result =~ /.. FAILED/g;
$suite_cases_skipped = () = $result =~ /.. ----/g; $suite_cases_skipped = () = $result =~ /.. ----/g;
if( $result =~ /PASSED/ ) { if( $? == 0 ) {
print "PASS\n"; print "PASS\n";
if( $verbose > 2 ) { if( $verbose > 2 ) {
pad_print_center( 72, '-', "Begin $suite" ); pad_print_center( 72, '-', "Begin $suite" );

View file

@ -1162,6 +1162,18 @@ run_test "Default (compression enabled)" \
-S "error" \ -S "error" \
-C "error" -C "error"
requires_config_enabled MBEDTLS_ZLIB_SUPPORT
run_test "Default (compression enabled)" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3" \
0 \
-s "Allocating compression buffer" \
-c "Allocating compression buffer" \
-s "Record expansion is unknown (compression)" \
-c "Record expansion is unknown (compression)" \
-S "error" \
-C "error"
# Test current time in ServerHello # Test current time in ServerHello
requires_config_enabled MBEDTLS_HAVE_TIME requires_config_enabled MBEDTLS_HAVE_TIME
run_test "ServerHello contains gmt_unix_time" \ run_test "ServerHello contains gmt_unix_time" \
@ -5380,15 +5392,8 @@ run_test "Per-version suites: TLS 1.2" \
# Test for ClientHello without extensions # Test for ClientHello without extensions
requires_gnutls requires_gnutls
run_test "ClientHello without extensions, SHA-1 allowed" \ run_test "ClientHello without extensions" \
"$P_SRV debug_level=3 key_file=data_files/server2.key crt_file=data_files/server2.crt" \ "$P_SRV debug_level=3" \
"$G_CLI --priority=NORMAL:%NO_EXTENSIONS:%DISABLE_SAFE_RENEGOTIATION localhost" \
0 \
-s "dumping 'client hello extensions' (0 bytes)"
requires_gnutls
run_test "ClientHello without extensions, SHA-1 forbidden in certificates on server" \
"$P_SRV debug_level=3 key_file=data_files/server2.key crt_file=data_files/server2.crt allow_sha1=0" \
"$G_CLI --priority=NORMAL:%NO_EXTENSIONS:%DISABLE_SAFE_RENEGOTIATION localhost" \ "$G_CLI --priority=NORMAL:%NO_EXTENSIONS:%DISABLE_SAFE_RENEGOTIATION localhost" \
0 \ 0 \
-s "dumping 'client hello extensions' (0 bytes)" -s "dumping 'client hello extensions' (0 bytes)"

View file

@ -44,11 +44,11 @@ static void ctr_drbg_validate_internal( int reseed_mode, data_t * nonce,
/* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>) /* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>)
* where nonce||perso = nonce[nonce->len] */ * where nonce||perso = nonce[nonce->len] */
TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_set_entropy_len( &ctx, entropy_chunk_len );
TEST_ASSERT( mbedtls_ctr_drbg_seed(
&ctx, &ctx,
mbedtls_test_entropy_func, entropy->x, mbedtls_test_entropy_func, entropy->x,
nonce->x, nonce->len, nonce->x, nonce->len ) == 0 );
entropy_chunk_len ) == 0 );
if( reseed_mode == RESEED_ALWAYS ) if( reseed_mode == RESEED_ALWAYS )
mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_set_prediction_resistance(
&ctx, &ctx,

View file

@ -527,7 +527,9 @@ void ecdsa_write_restart( int id, char *d_str, int md_alg,
TEST_ASSERT( md_info != MBEDTLS_MD_INVALID_HANDLE ); TEST_ASSERT( md_info != MBEDTLS_MD_INVALID_HANDLE );
hlen = mbedtls_md_get_size( md_info ); hlen = mbedtls_md_get_size( md_info );
mbedtls_md( md_info, (const unsigned char *) msg, strlen( msg ), hash ); TEST_ASSERT( mbedtls_md( md_info,
(const unsigned char *) msg, strlen( msg ),
hash ) == 0 );
mbedtls_ecp_set_max_ops( max_ops ); mbedtls_ecp_set_max_ops( max_ops );

View file

@ -16,8 +16,8 @@ memory_buffer_alloc_free_alloc:100:64:100:100:0:0:0:1:200:0
Memory buffer alloc - Out of Memory test Memory buffer alloc - Out of Memory test
memory_buffer_alloc_oom_test: memory_buffer_alloc_oom_test:
Memory buffer small buffer Memory buffer: heap too small (header verification should fail)
memory_buffer_small_buffer: memory_buffer_heap_too_small:
Memory buffer underalloc Memory buffer: attempt to allocate SIZE_MAX
memory_buffer_underalloc: memory_buffer_underalloc:

View file

@ -29,7 +29,7 @@ void mbedtls_memory_buffer_alloc_self_test( )
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */ /* BEGIN_CASE */
void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes, void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes,
int d_bytes, int free_a, int free_b, int d_bytes, int free_a, int free_b,
int free_c, int free_d, int e_bytes, int free_c, int free_d, int e_bytes,
@ -39,8 +39,11 @@ void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes,
unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL, *ptr_d = NULL, unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL, *ptr_d = NULL,
*ptr_e = NULL, *ptr_f = NULL; *ptr_e = NULL, *ptr_f = NULL;
#if defined(MBEDTLS_MEMORY_DEBUG)
size_t reported_blocks; size_t reported_blocks;
size_t allocated_bytes = 0, reported_bytes; size_t reported_bytes;
#endif
size_t allocated_bytes = 0;
mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
@ -78,8 +81,10 @@ void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes,
allocated_bytes += d_bytes * sizeof(char); allocated_bytes += d_bytes * sizeof(char);
} }
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks ); mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
TEST_ASSERT( reported_bytes == allocated_bytes ); TEST_ASSERT( reported_bytes == allocated_bytes );
#endif
if( free_a ) if( free_a )
{ {
@ -117,8 +122,10 @@ void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes,
allocated_bytes -= d_bytes * sizeof(char); allocated_bytes -= d_bytes * sizeof(char);
} }
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks ); mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
TEST_ASSERT( reported_bytes == allocated_bytes ); TEST_ASSERT( reported_bytes == allocated_bytes );
#endif
if( e_bytes > 0 ) if( e_bytes > 0 )
{ {
@ -178,8 +185,10 @@ void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes,
ptr_f = NULL; ptr_f = NULL;
} }
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks ); mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
TEST_ASSERT( reported_bytes == 0 ); TEST_ASSERT( reported_bytes == 0 );
#endif
TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 ); TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
@ -188,12 +197,14 @@ exit:
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */ /* BEGIN_CASE */
void memory_buffer_alloc_oom_test( ) void memory_buffer_alloc_oom_test( )
{ {
unsigned char buf[1024]; unsigned char buf[1024];
unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL; unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL;
#if defined(MBEDTLS_MEMORY_DEBUG)
size_t reported_blocks, reported_bytes; size_t reported_blocks, reported_bytes;
#endif
(void)ptr_c; (void)ptr_c;
@ -210,8 +221,10 @@ void memory_buffer_alloc_oom_test( )
ptr_c = mbedtls_calloc( 431, sizeof(char) ); ptr_c = mbedtls_calloc( 431, sizeof(char) );
TEST_ASSERT( ptr_c == NULL ); TEST_ASSERT( ptr_c == NULL );
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks ); mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
TEST_ASSERT( reported_bytes >= 864 && reported_bytes <= sizeof(buf) ); TEST_ASSERT( reported_bytes >= 864 && reported_bytes <= sizeof(buf) );
#endif
mbedtls_free( ptr_a ); mbedtls_free( ptr_a );
ptr_a = NULL; ptr_a = NULL;
@ -221,8 +234,10 @@ void memory_buffer_alloc_oom_test( )
ptr_b = NULL; ptr_b = NULL;
TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 ); TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks ); mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
TEST_ASSERT( reported_bytes == 0 ); TEST_ASSERT( reported_bytes == 0 );
#endif
TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 ); TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
@ -231,17 +246,20 @@ exit:
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */ /* BEGIN_CASE */
void memory_buffer_small_buffer( ) void memory_buffer_heap_too_small( )
{ {
unsigned char buf[1]; unsigned char buf[1];
mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
/* With MBEDTLS_MEMORY_DEBUG enabled, this prints a message
* "FATAL: verification of first header failed".
*/
TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() != 0 ); TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() != 0 );
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */ /* BEGIN_CASE */
void memory_buffer_underalloc( ) void memory_buffer_underalloc( )
{ {
unsigned char buf[100]; unsigned char buf[100];

View file

@ -163,6 +163,93 @@ mbedtls_mpi_cmp_mpi:10:"2":10:"-3":1
Base test mbedtls_mpi_cmp_mpi (Mixed values) #6 Base test mbedtls_mpi_cmp_mpi (Mixed values) #6
mbedtls_mpi_cmp_mpi:10:"-2":10:"31231231289798":-1 mbedtls_mpi_cmp_mpi:10:"-2":10:"31231231289798":-1
Base test mbedtls_mpi_lt_mpi_ct #1
mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B5":0:0
Base test mbedtls_mpi_lt_mpi_ct #2
mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B4":0:0
Base test mbedtls_mpi_lt_mpi_ct #3
mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B6":1:0
Base test mbedtls_mpi_lt_mpi_ct (Negative values) #1
mbedtls_mpi_lt_mpi_ct:1:"-2":1:"-2":0:0
Base test mbedtls_mpi_lt_mpi_ct (Negative values) #2
mbedtls_mpi_lt_mpi_ct:1:"-2":1:"-3":0:0
Base test mbedtls_mpi_lt_mpi_ct (Negative values) #3
mbedtls_mpi_lt_mpi_ct:1:"-2":1:"-1":1:0
Base test mbedtls_mpi_lt_mpi_ct (Mixed values) #1
mbedtls_mpi_lt_mpi_ct:1:"-3":1:"2":1:0
Base test mbedtls_mpi_lt_mpi_ct (Mixed values) #2
mbedtls_mpi_lt_mpi_ct:1:"2":1:"-3":0:0
Base test mbedtls_mpi_lt_mpi_ct (Mixed values) #3
mbedtls_mpi_lt_mpi_ct:2:"-2":2:"1C67967269C6":1:0
Base test mbedtls_mpi_lt_mpi_ct (X is longer in storage)
mbedtls_mpi_lt_mpi_ct:3:"2B5":2:"2B5":0:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Base test mbedtls_mpi_lt_mpi_ct (Y is longer in storage)
mbedtls_mpi_lt_mpi_ct:3:"2B5":4:"2B5":0:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #1
mbedtls_mpi_lt_mpi_ct:2:"7FFFFFFFFFFFFFFF":2:"FF":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #2
mbedtls_mpi_lt_mpi_ct:2:"8000000000000000":2:"7FFFFFFFFFFFFFFF":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #3
mbedtls_mpi_lt_mpi_ct:2:"8000000000000000":2:"1":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #4
mbedtls_mpi_lt_mpi_ct:2:"8000000000000000":2:"0":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #5
mbedtls_mpi_lt_mpi_ct:2:"FFFFFFFFFFFFFFFF":2:"FF":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #1
mbedtls_mpi_lt_mpi_ct:1:"7FFFFFFF":1:"FF":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #2
mbedtls_mpi_lt_mpi_ct:1:"80000000":1:"7FFFFFFF":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #3
mbedtls_mpi_lt_mpi_ct:1:"80000000":1:"1":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #4
mbedtls_mpi_lt_mpi_ct:1:"80000000":1:"0":0:0
Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #5
mbedtls_mpi_lt_mpi_ct:1:"FFFFFFFF":1:"FF":0:0
Multi-limb mbedtls_mpi_lt_mpi_ct (X<Y, zero vs non-zero MS limb)
mbedtls_mpi_lt_mpi_ct:2:"0FFFFFFFFFFFFFFFF":2:"1FFFFFFFFFFFFFFFF":1:0
Multi-limb mbedtls_mpi_lt_mpi_ct (X>Y, equal MS limbs)
mbedtls_mpi_lt_mpi_ct:2:"-EEFFFFFFFFFFFFFFF1":2:"-EEFFFFFFFFFFFFFFFF":0:0
Multi-limb mbedtls_mpi_lt_mpi_ct (X=Y)
mbedtls_mpi_lt_mpi_ct:2:"EEFFFFFFFFFFFFFFFF":2:"EEFFFFFFFFFFFFFFFF":0:0
Multi-limb mbedtls_mpi_lt_mpi_ct (X=-Y)
mbedtls_mpi_lt_mpi_ct:2:"-EEFFFFFFFFFFFFFFFF":2:"EEFFFFFFFFFFFFFFFF":1:0
Multi-limb mbedtls_mpi_lt_mpi_ct (Alternating limbs) #1
mbedtls_mpi_lt_mpi_ct:2:"11FFFFFFFFFFFFFFFF":2:"FF1111111111111111":1:0
Multi-limb mbedtls_mpi_lt_mpi_ct (Alternating limbs) #2
mbedtls_mpi_lt_mpi_ct:2:"FF1111111111111111":2:"11FFFFFFFFFFFFFFFF":0:0
Multi-limb mbedtls_mpi_lt_mpi_ct (Alternating limbs) #3
mbedtls_mpi_lt_mpi_ct:2:"-11FFFFFFFFFFFFFFFF":2:"-FF1111111111111111":0:0
Multi-limb mbedtls_mpi_lt_mpi_ct (Alternating limbs) #4
mbedtls_mpi_lt_mpi_ct:2:"-FF1111111111111111":2:"-11FFFFFFFFFFFFFFFF":1:0
Base test mbedtls_mpi_cmp_abs #1 Base test mbedtls_mpi_cmp_abs #1
mbedtls_mpi_cmp_abs:10:"693":10:"693":0 mbedtls_mpi_cmp_abs:10:"693":10:"693":0
@ -193,37 +280,106 @@ mbedtls_mpi_cmp_abs:10:"2":10:"-3":-1
Base test mbedtls_mpi_cmp_abs (Mix values) #3 Base test mbedtls_mpi_cmp_abs (Mix values) #3
mbedtls_mpi_cmp_abs:10:"-2":10:"1":1 mbedtls_mpi_cmp_abs:10:"-2":10:"1":1
Base test mbedtls_mpi_copy #1 Copy zero (1 limb) to positive (1 limb)
mbedtls_mpi_copy:0:1500 mbedtls_mpi_copy_sint:0:1500
Base test mpi_copy_self #1 Copy zero (1 limb) to negative (1 limb)
mbedtls_mpi_copy_sint:0:-1500
Copy positive (1 limb) to zero (1 limb)
mbedtls_mpi_copy_sint:1500:0
Copy negative (1 limb) to zero (1 limb)
mbedtls_mpi_copy_sint:-1500:0
Copy positive (1 limb) to negative (1 limb)
mbedtls_mpi_copy_sint:1500:-42
Copy negative (1 limb) to positive (1 limb)
mbedtls_mpi_copy_sint:-42:1500
Copy zero (null) to zero (null)
mbedtls_mpi_copy_binary:"":""
Copy zero (null) to positive (1 limb)
mbedtls_mpi_copy_binary:"":"1234"
Copy positive (1 limb) to zero (null)
mbedtls_mpi_copy_binary:"1234":""
Copy positive to larger
mbedtls_mpi_copy_binary:"bead":"ca5cadedb01dfaceacc01ade"
Copy positive to smaller
mbedtls_mpi_copy_binary:"ca5cadedb01dfaceacc01ade":"bead"
Copy self: positive (1 limb)
mpi_copy_self:14 mpi_copy_self:14
Base test mbedtls_mpi_swap #1 Copy self: zero (1 limb)
mbedtls_mpi_swap:0:1500 mpi_copy_self:0
Test mbedtls_mpi_shrink #1 Swap zero (1 limb) with positive (1 limb)
mbedtls_mpi_swap_sint:0:1500
Swap zero (1 limb) with negative (1 limb)
mbedtls_mpi_swap_sint:0:-1500
Swap positive (1 limb) with zero (1 limb)
mbedtls_mpi_swap_sint:1500:0
Swap negative (1 limb) with zero (1 limb)
mbedtls_mpi_swap_sint:-1500:0
Swap positive (1 limb) with negative (1 limb)
mbedtls_mpi_swap_sint:1500:-42
Swap negative (1 limb) with positive (1 limb)
mbedtls_mpi_swap_sint:-42:1500
Swap zero (null) with zero (null)
mbedtls_mpi_swap_binary:"":""
Swap zero (null) with positive (1 limb)
mbedtls_mpi_swap_binary:"":"1234"
Swap positive (1 limb) with zero (null)
mbedtls_mpi_swap_binary:"1234":""
Swap positive with larger
mbedtls_mpi_swap_binary:"bead":"ca5cadedb01dfaceacc01ade"
Swap positive with smaller
mbedtls_mpi_swap_binary:"ca5cadedb01dfaceacc01ade":"bead"
Swap self: 1 limb
mpi_swap_self:"face"
Swap self: null
mpi_swap_self:""
Shrink 2 limbs in a buffer of size 2 to 4
mbedtls_mpi_shrink:2:2:4:4 mbedtls_mpi_shrink:2:2:4:4
Test mbedtls_mpi_shrink #2 Shrink 2 limbs in a buffer of size 4 to 4
mbedtls_mpi_shrink:4:2:4:4 mbedtls_mpi_shrink:4:2:4:4
Test mbedtls_mpi_shrink #3 Shrink 2 limbs in a buffer of size 8 to 4
mbedtls_mpi_shrink:8:2:4:4 mbedtls_mpi_shrink:8:2:4:4
Test mbedtls_mpi_shrink #4 Shrink 4 limbs in a buffer of size 8 to 4
mbedtls_mpi_shrink:8:4:4:4 mbedtls_mpi_shrink:8:4:4:4
Test mbedtls_mpi_shrink #5 Shrink 6 limbs in a buffer of size 8 to 4 yielding 6
mbedtls_mpi_shrink:8:6:4:6 mbedtls_mpi_shrink:8:6:4:6
Test mbedtls_mpi_shrink #6 Shrink 2 limbs in a buffer of size 4 to 0 yielding 2
mbedtls_mpi_shrink:4:2:0:2 mbedtls_mpi_shrink:4:2:0:2
Test mbedtls_mpi_shrink #7 Shrink 1 limbs in a buffer of size 4 to 0 yielding 1
mbedtls_mpi_shrink:4:1:0:1 mbedtls_mpi_shrink:4:1:0:1
Test mbedtls_mpi_shrink #8 Shrink 0 limbs in a buffer of size 4 to 0 yielding 1
mbedtls_mpi_shrink:4:0:0:1 mbedtls_mpi_shrink:4:0:0:1
Test mbedtls_mpi_safe_cond_assign #1 Test mbedtls_mpi_safe_cond_assign #1

View file

@ -537,6 +537,31 @@ exit:
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE */
void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
int size_Y, char * input_Y,
int input_ret, int input_err )
{
unsigned ret;
unsigned input_uret = input_ret;
mbedtls_mpi X, Y;
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, input_X ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, input_Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
if( input_err == 0 )
TEST_ASSERT( ret == input_uret );
exit:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
}
/* END_CASE */
/* BEGIN_CASE */ /* BEGIN_CASE */
void mbedtls_mpi_cmp_abs( int radix_X, char * input_X, int radix_Y, void mbedtls_mpi_cmp_abs( int radix_X, char * input_X, int radix_Y,
char * input_Y, int input_A ) char * input_Y, int input_A )
@ -554,22 +579,40 @@ exit:
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE */ /* BEGIN_CASE */
void mbedtls_mpi_copy( int input_X, int input_A ) void mbedtls_mpi_copy_sint( int input_X, int input_Y )
{ {
mbedtls_mpi X, Y, A; mbedtls_mpi X, Y;
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 ); TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
TEST_ASSERT( mbedtls_mpi_lset( &Y, input_A ) == 0 ); TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_lset( &A, input_A ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) != 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 ); TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 ); TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) != 0 ); TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
exit: exit:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_mpi_copy_binary( data_t *input_X, data_t *input_Y )
{
mbedtls_mpi X, Y, X0;
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &X0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
exit:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &X0 );
} }
/* END_CASE */ /* END_CASE */
@ -661,22 +704,61 @@ exit:
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE */ /* BEGIN_CASE */
void mbedtls_mpi_swap( int input_X, int input_Y ) void mbedtls_mpi_swap_sint( int input_X, int input_Y )
{ {
mbedtls_mpi X, Y, A; mbedtls_mpi X, Y;
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 ); TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 ); TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_lset( &A, input_X ) == 0 ); TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) != 0 ); TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
mbedtls_mpi_swap( &X, &Y ); mbedtls_mpi_swap( &X, &Y );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) != 0 ); TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 ); TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
exit: exit:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_mpi_swap_binary( data_t *input_X, data_t *input_Y )
{
mbedtls_mpi X, Y, X0, Y0;
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &Y0, input_Y->x, input_Y->len ) == 0 );
mbedtls_mpi_swap( &X, &Y );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
exit:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_swap_self( data_t *input_X )
{
mbedtls_mpi X, X0;
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
mbedtls_mpi_swap( &X, &X );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
exit:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
} }
/* END_CASE */ /* END_CASE */

View file

@ -735,7 +735,9 @@ void pk_sign_verify_restart( int pk_type, int grp_id, char *d_str,
TEST_ASSERT( md_info != MBEDTLS_MD_INVALID_HANDLE ); TEST_ASSERT( md_info != MBEDTLS_MD_INVALID_HANDLE );
hlen = mbedtls_md_get_size( md_info ); hlen = mbedtls_md_get_size( md_info );
mbedtls_md( md_info, (const unsigned char *) msg, strlen( msg ), hash ); TEST_ASSERT( mbedtls_md( md_info,
(const unsigned char *) msg, strlen( msg ),
hash ) == 0 );
mbedtls_ecp_set_max_ops( max_ops ); mbedtls_ecp_set_max_ops( max_ops );

View file

@ -1,8 +1,8 @@
Check compiletime library version Check compiletime library version
check_compiletime_version:"2.16.3" check_compiletime_version:"2.16.4"
Check runtime library version Check runtime library version
check_runtime_version:"2.16.3" check_runtime_version:"2.16.4"
Check for MBEDTLS_VERSION_C Check for MBEDTLS_VERSION_C
check_feature:"MBEDTLS_VERSION_C":0 check_feature:"MBEDTLS_VERSION_C":0