提交 77352432 编写于 作者: M maoyufeng

Update mbed-tls version to 2.16.10

Signed-off-by: Nmaoyufeng <maoyufeng3@huawei.com>
上级 40791cee
......@@ -40,4 +40,5 @@ massif-*
/GSYMS
/GTAGS
/TAGS
/cscope*.out
/tags
mbed TLS ChangeLog (Sorted per branch, date)
= mbed TLS 2.16.10 branch released 2021-03-12
Default behavior changes
* In mbedtls_rsa_context objects, the ver field was formerly documented
as always 0. It is now reserved for internal purposes and may take
different values.
Security
* Fix a buffer overflow in mbedtls_mpi_sub_abs() when calculating
|A| - |B| where |B| is larger than |A| and has more limbs (so the
function should return MBEDTLS_ERR_MPI_NEGATIVE_VALUE). Only
applications calling mbedtls_mpi_sub_abs() directly are affected:
all calls inside the library were safe since this function is
only called with |A| >= |B|. Reported by Guido Vranken in #4042.
* Fix an errorneous estimation for an internal buffer in
mbedtls_pk_write_key_pem(). If MBEDTLS_MPI_MAX_SIZE is set to an odd
value the function might fail to write a private RSA keys of the largest
supported size.
Found by Daniel Otte, reported in #4093 and fixed in #4094,
backported in #4100.
* Fix a stack buffer overflow with mbedtls_net_poll() and
mbedtls_net_recv_timeout() when given a file descriptor that is
beyond FD_SETSIZE. Reported by FigBug in #4169.
* Guard against strong local side channel attack against base64 tables by
making access aceess to them use constant flow code.
Bugfix
* Fix an incorrect error code if an RSA private operation glitched.
* Fix a resource leak in CTR_DRBG and HMAC_DRBG when MBEDTLS_THREADING_C
is enabled, on platforms where initializing a mutex allocates resources.
This was a regression introduced in the previous release. Reported in
#4017, #4045 and #4071.
* Ensure that calling mbedtls_rsa_free() or mbedtls_entropy_free()
twice is safe. This happens for RSA when some Mbed TLS library functions
fail. Such a double-free was not safe when MBEDTLS_THREADING_C was
enabled on platforms where freeing a mutex twice is not safe.
* Fix a resource leak in a bad-arguments case of mbedtls_rsa_gen_key()
when MBEDTLS_THREADING_C is enabled on platforms where initializing
a mutex allocates resources.
* This change makes 'mbedtls_x509write_crt_set_basic_constraints'
consistent with RFC 5280 4.2.1.9 which says: "Conforming CAs MUST
include this extension in all CA certificates that contain public keys
used to validate digital signatures on certificates and MUST mark the
extension as critical in such certificates." Previous to this change,
the extension was always marked as non-critical. This was fixed by
#4044.
= mbed TLS 2.16.9 branch released 2020-12-11
Security
* Limit the size of calculations performed by mbedtls_mpi_exp_mod to
MBEDTLS_MPI_MAX_SIZE to prevent a potential denial of service when
generating Diffie-Hellman key pairs. Credit to OSS-Fuzz.
* A failure of the random generator was ignored in mbedtls_mpi_fill_random(),
which is how most uses of randomization in asymmetric cryptography
(including key generation, intermediate value randomization and blinding)
are implemented. This could cause failures or the silent use of non-random
values. A random generator can fail if it needs reseeding and cannot not
obtain entropy, or due to an internal failure (which, for Mbed TLS's own
CTR_DRBG or HMAC_DRBG, can only happen due to a misconfiguration).
* Fix a compliance issue whereby we were not checking the tag on the
algorithm parameters (only the size) when comparing the signature in the
description part of the cert to the real signature. This meant that a
NULL algorithm parameters entry would look identical to an array of REAL
(size zero) to the library and thus the certificate would be considered
valid. However, if the parameters do not match in *any* way then the
certificate should be considered invalid, and indeed OpenSSL marks these
certs as invalid when mbedtls did not.
Many thanks to guidovranken who found this issue via differential fuzzing
and reported it in #3629.
* Zeroising of local buffers and variables which are used for calculations
in mbedtls_pkcs5_pbkdf2_hmac(), mbedtls_internal_sha*_process(),
mbedtls_internal_md*_process() and mbedtls_internal_ripemd160_process()
functions to erase sensitive data from memory. Reported by
Johan Malmgren and Johan Uppman Bruce from Sectra.
Bugfix
* Fix an invalid (but nonzero) return code from mbedtls_pk_parse_subpubkey()
when the input has trailing garbage. Fixes #2512.
* Fix rsa_prepare_blinding() to retry when the blinding value is not
invertible (mod N), instead of returning MBEDTLS_ERR_RSA_RNG_FAILED. This
addresses a regression but is rare in practice (approx. 1 in 2/sqrt(N)).
Found by Synopsys Coverity, fix contributed by Peter Kolbus (Garmin).
Fixes #3647.
* Fix the build when the macro _GNU_SOURCE is defined to a non-empty value.
Fix #3432.
* Correct the default IV size for mbedtls_cipher_info_t structures using
MBEDTLS_MODE_ECB to 0, since ECB mode ciphers don't use IVs.
* Make arc4random_buf available on NetBSD and OpenBSD when _POSIX_C_SOURCE is
defined. Fix contributed in #3571. Adopted for LTS branch 2.16 in #3602.
* Fix build failures on GCC 11. Fixes #3782.
* Fix a memory leak in mbedtls_mpi_sub_abs() when the result was negative
(an error condition) and the second operand was aliased to the result.
* Fix a case in elliptic curve arithmetic where an out-of-memory condition
could go undetected, resulting in an incorrect result.
* In CTR_DRBG and HMAC_DRBG, don't reset the reseed interval in seed().
Fixes #2927.
* In PEM writing functions, fill the trailing part of the buffer with null
bytes. This guarantees that the corresponding parsing function can read
the buffer back, which was the case for mbedtls_x509write_{crt,csr}_pem
until this property was inadvertently broken in Mbed TLS 2.19.0.
Fixes #3682.
* Fix a build failure that occurred with the MBEDTLS_AES_SETKEY_DEC_ALT
option on. In this configuration key management methods that are required
for MBEDTLS_CIPHER_MODE_XTS were excluded from the build and made it fail.
Fixes #3818. Reported by John Stroebel.
Changes
* Reduce stack usage significantly during sliding window exponentiation.
Reported in #3591 and fix contributed in #3592 by Daniel Otte.
* Remove the zeroization of a pointer variable in AES rounds. It was valid
but spurious and misleading since it looked like a mistaken attempt to
zeroize the pointed-to buffer. Reported by Antonio de la Piedra, CEA
Leti, France.
= mbed TLS 2.16.8 branch released 2020-09-01
Features
......
......@@ -3,6 +3,29 @@
This directory contains changelog entries that have not yet been merged
to the changelog file ([`../ChangeLog`](../ChangeLog)).
## What requires a changelog entry?
Write a changelog entry if there is a user-visible change. This includes:
* Bug fixes in the library or in sample programs: fixing a security hole,
fixing broken behavior, fixing the build in some configuration or on some
platform, etc.
* New features in the library, new sample programs, or new platform support.
* Changes in existing behavior. These should be rare. Changes in features
that are documented as experimental may or may not be announced, depending
on the extent of the change and how widely we expect the feature to be used.
We generally don't include changelog entries for:
* Documentation improvements.
* Performance improvements, unless they are particularly significant.
* Changes to parts of the code base that users don't interact with directly,
such as test code and test data.
Until Mbed TLS 2.16.8, we required changelog entries in more cases.
Looking at older changelog entries is good practice for how to write a
changelog entry, but not for deciding whether to write one.
## Changelog entry file format
A changelog entry file must have the extension `*.txt` and must have the
......@@ -33,8 +56,7 @@ The permitted changelog entry categories are as follows:
Bugfix
Changes
Use “Changes” for anything that doesn't fit in the other categories, such as
performance, documentation and test improvements.
Use “Changes” for anything that doesn't fit in the other categories.
## How to write a changelog entry
......@@ -49,8 +71,7 @@ Include GitHub issue numbers where relevant. Use the format “#1234” for an
Mbed TLS issue. Add other external references such as CVE numbers where
applicable.
Credit the author of the contribution if the contribution is not a member of
the Mbed TLS development team. Also credit bug reporters where applicable.
Credit bug reporters where applicable.
**Explain why, not how**. Remember that the audience is the users of the
library, not its developers. In particular, for a bug fix, explain the
......
......@@ -129,5 +129,10 @@ tags: $(C_SOURCE_FILES)
$(CTAGS) $@ $(C_SOURCE_FILES)
TAGS: $(C_SOURCE_FILES)
etags -o $@ $(C_SOURCE_FILES)
global: GPATH GRTAGS GSYMS GTAGS
GPATH GRTAGS GSYMS GTAGS: $(C_SOURCE_FILES)
ls $(C_SOURCE_FILES) | gtags -f - --gtagsconf .globalrc
cscope: cscope.in.out cscope.po.out cscope.out
cscope.in.out cscope.po.out cscope.out: $(C_SOURCE_FILES)
cscope -bq -u -Iinclude -Ilibrary $(patsubst %,-I%,$(wildcard 3rdparty/*/include)) -Itests/include $(C_SOURCE_FILES)
.PHONY: cscope global
......@@ -49,7 +49,7 @@
*/
/**
* @mainpage mbed TLS v2.16.8 source code documentation
* @mainpage mbed TLS v2.16.10 source code documentation
*
* This documentation describes the internal structure of mbed TLS. It was
* automatically generated from specially formatted comment blocks in
......
......@@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.
PROJECT_NAME = "mbed TLS v2.16.8"
PROJECT_NAME = "mbed TLS v2.16.10"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
......
......@@ -88,12 +88,12 @@
* Maximum window size used for modular exponentiation. Default: 6
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
* Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
*
* Reduction in size, reduces speed.
*/
#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)
......
......@@ -175,7 +175,7 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* writable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication field to generate in Bytes:
* 4, 6, 8, 10, 12, 14 or 16.
*
......@@ -220,7 +220,7 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* writable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication field to generate in Bytes:
* 0, 4, 6, 8, 10, 12, 14 or 16.
*
......
此差异已折叠。
......@@ -214,6 +214,13 @@ typedef struct mbedtls_ctr_drbg_context
void *p_entropy; /*!< The context for the entropy function. */
#if defined(MBEDTLS_THREADING_C)
/* Invariant: the mutex is initialized if and only if f_entropy != NULL.
* This means that the mutex is initialized during the initial seeding
* in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free().
*
* Note that this invariant may change without notice. Do not rely on it
* and do not access the mutex directly in application code.
*/
mbedtls_threading_mutex_t mutex;
#endif
}
......@@ -224,6 +231,11 @@ mbedtls_ctr_drbg_context;
* and prepares it for mbedtls_ctr_drbg_seed()
* or mbedtls_ctr_drbg_free().
*
* \note The reseed interval is
* #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default.
* You can override it by calling
* mbedtls_ctr_drbg_set_reseed_interval().
*
* \param ctx The CTR_DRBG context to initialize.
*/
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
......@@ -272,6 +284,15 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* device.
*/
#endif
#if defined(MBEDTLS_THREADING_C)
/**
* \note When Mbed TLS is built with threading support,
* after this function returns successfully,
* it is safe to call mbedtls_ctr_drbg_random()
* from multiple threads. Other operations, including
* reseeding, are not thread-safe.
*/
#endif /* MBEDTLS_THREADING_C */
/**
* \param ctx The CTR_DRBG context to seed.
* It must have been initialized with
......@@ -281,6 +302,8 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* the same context unless you call
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
* again first.
* After a failed call to mbedtls_ctr_drbg_seed(),
* you must call mbedtls_ctr_drbg_free().
* \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
......@@ -305,7 +328,8 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
size_t len );
/**
* \brief This function clears CTR_CRBG context data.
* \brief This function resets CTR_DRBG context to the state immediately
* after initial call of mbedtls_ctr_drbg_init().
*
* \param ctx The CTR_DRBG context to clear.
*/
......@@ -371,6 +395,11 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
* \brief This function reseeds the CTR_DRBG context, that is
* extracts data from the entropy source.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param ctx The CTR_DRBG context.
* \param additional Additional data to add to the state. Can be \c NULL.
* \param len The length of the additional data.
......@@ -388,6 +417,11 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
/**
* \brief This function updates the state of the CTR_DRBG context.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with. This must not be
* \c NULL unless \p add_len is \c 0.
......@@ -411,6 +445,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param p_rng The CTR_DRBG context. This must be a pointer to a
* #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill.
......@@ -439,8 +478,16 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
*
*/
#if defined(MBEDTLS_THREADING_C)
/**
* \note When Mbed TLS is built with threading support,
* it is safe to call mbedtls_ctr_drbg_random()
* from multiple threads. Other operations, including
* reseeding, are not thread-safe.
*/
#endif /* MBEDTLS_THREADING_C */
/**
* \param p_rng The CTR_DRBG context. This must be a pointer to a
* #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill.
......
......@@ -147,13 +147,15 @@ mbedtls_entropy_source_state;
*/
typedef struct mbedtls_entropy_context
{
int accumulator_started;
int accumulator_started; /* 0 after init.
* 1 after the first update.
* -1 after free. */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_context accumulator;
#else
mbedtls_sha256_context accumulator;
#endif
int source_count;
int source_count; /* Number of entries used in source. */
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES];
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_state havege_data;
......
......@@ -182,7 +182,7 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
* than zero, this must be a writable buffer of at least that
* size in Bytes.
* \param tag_len The length of the tag to generate.
* \param tag The buffer for holding the tag. This must be a readable
* \param tag The buffer for holding the tag. This must be a writable
* buffer of at least \p tag_len Bytes.
*
* \return \c 0 if the encryption or decryption was performed
......@@ -310,7 +310,7 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
* tag. The tag can have a maximum length of 16 Bytes.
*
* \param ctx The GCM context. This must be initialized.
* \param tag The buffer for holding the tag. This must be a readable
* \param tag The buffer for holding the tag. This must be a writable
* buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to generate. This must be at least
* four.
......
......@@ -128,6 +128,14 @@ typedef struct mbedtls_hmac_drbg_context
void *p_entropy; /*!< context for the entropy function */
#if defined(MBEDTLS_THREADING_C)
/* Invariant: the mutex is initialized if and only if
* md_ctx->md_info != NULL. This means that the mutex is initialized
* during the initial seeding in mbedtls_hmac_drbg_seed() or
* mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free().
*
* Note that this invariant may change without notice. Do not rely on it
* and do not access the mutex directly in application code.
*/
mbedtls_threading_mutex_t mutex;
#endif
} mbedtls_hmac_drbg_context;
......@@ -138,6 +146,10 @@ typedef struct mbedtls_hmac_drbg_context
* This function makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
*
* \note The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
* by default. Override this value by calling
* mbedtls_hmac_drbg_set_reseed_interval().
*
* \param ctx HMAC_DRBG context to be initialized.
*/
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
......@@ -173,7 +185,17 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
* \note During the initial seeding, this function calls
* the entropy source to obtain a nonce
* whose length is half the entropy length.
*
*/
#if defined(MBEDTLS_THREADING_C)
/**
* \note When Mbed TLS is built with threading support,
* after this function returns successfully,
* it is safe to call mbedtls_hmac_drbg_random()
* from multiple threads. Other operations, including
* reseeding, are not thread-safe.
*/
#endif /* MBEDTLS_THREADING_C */
/**
* \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
......@@ -212,7 +234,17 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
*
* This function is meant for use in algorithms that need a pseudorandom
* input such as deterministic ECDSA.
*
*/
#if defined(MBEDTLS_THREADING_C)
/**
* \note When Mbed TLS is built with threading support,
* after this function returns successfully,
* it is safe to call mbedtls_hmac_drbg_random()
* from multiple threads. Other operations, including
* reseeding, are not thread-safe.
*/
#endif /* MBEDTLS_THREADING_C */
/**
* \param ctx HMAC_DRBG context to be initialised.
* \param md_info MD algorithm to use for HMAC_DRBG.
* \param data Concatenation of the initial entropy string and
......@@ -275,6 +307,11 @@ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
/**
* \brief This function updates the state of the HMAC_DRBG context.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param ctx The HMAC_DRBG context.
* \param additional The data to update the state with.
* If this is \c NULL, there is no additional data.
......@@ -291,6 +328,11 @@ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
* \brief This function reseeds the HMAC_DRBG context, that is
* extracts data from the entropy source.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param ctx The HMAC_DRBG context.
* \param additional Additional data to add to the state.
* If this is \c NULL, there is no additional data
......@@ -316,6 +358,11 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
* #mbedtls_hmac_drbg_context structure.
* \param output The buffer to fill.
......@@ -345,7 +392,16 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
*/
#if defined(MBEDTLS_THREADING_C)
/**
* \note When Mbed TLS is built with threading support,
* it is safe to call mbedtls_ctr_drbg_random()
* from multiple threads. Other operations, including
* reseeding, are not thread-safe.
*/
#endif /* MBEDTLS_THREADING_C */
/**
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
* #mbedtls_hmac_drbg_context structure.
* \param output The buffer to fill.
......@@ -361,7 +417,8 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
/**
* \brief Free an HMAC_DRBG context
* \brief This function resets HMAC_DRBG context to the state immediately
* after initial call of mbedtls_hmac_drbg_init().
*
* \param ctx The HMAC_DRBG context to free.
*/
......
......@@ -151,6 +151,7 @@ int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char
*
* \return 0 if successful, or one of:
* MBEDTLS_ERR_NET_SOCKET_FAILED,
* MBEDTLS_ERR_NET_UNKNOWN_HOST,
* MBEDTLS_ERR_NET_BIND_FAILED,
* MBEDTLS_ERR_NET_LISTEN_FAILED
*
......@@ -170,6 +171,8 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
* can be NULL if client_ip is null
*
* \return 0 if successful, or
* MBEDTLS_ERR_NET_SOCKET_FAILED,
* MBEDTLS_ERR_NET_BIND_FAILED,
* MBEDTLS_ERR_NET_ACCEPT_FAILED, or
* MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
* MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
......@@ -182,6 +185,10 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
/**
* \brief Check and wait for the context to be ready for read/write
*
* \note The current implementation of this function uses
* select() and returns an error if the file descriptor
* is \c FD_SETSIZE or greater.
*
* \param ctx Socket to check
* \param rw Bitflag composed of MBEDTLS_NET_POLL_READ and
* MBEDTLS_NET_POLL_WRITE specifying the events
......@@ -263,16 +270,21 @@ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
* 'timeout' seconds. If no error occurs, the actual amount
* read is returned.
*
* \note The current implementation of this function uses
* select() and returns an error if the file descriptor
* is \c FD_SETSIZE or greater.
*
* \param ctx Socket
* \param buf The buffer to write to
* \param len Maximum length of the buffer
* \param timeout Maximum number of milliseconds to wait for data
* 0 means no timeout (wait forever)
*
* \return the number of bytes received,
* or a non-zero error code:
* MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
* \return The number of bytes received if successful.
* MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out.
* MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
* Another negative error code (MBEDTLS_ERR_NET_xxx)
* for other failures.
*
* \note This function will block (until data becomes available or
* timeout is reached) even if the socket is set to
......
......@@ -124,7 +124,10 @@ extern "C" {
*/
typedef struct mbedtls_rsa_context
{
int ver; /*!< Always 0.*/
int ver; /*!< Reserved for internal purposes.
* Do not set this field in application
* code. Its meaning might change without
* notice. */
size_t len; /*!< The size of \p N in Bytes. */
mbedtls_mpi N; /*!< The public modulus. */
......@@ -154,6 +157,7 @@ typedef struct mbedtls_rsa_context
mask generating function used in the
EME-OAEP and EMSA-PSS encodings. */
#if defined(MBEDTLS_THREADING_C)
/* Invariant: the mutex is initialized iff ver != 0. */
mbedtls_threading_mutex_t mutex; /*!< Thread-safety mutex. */
#endif
}
......
......@@ -152,8 +152,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
/**
* \brief This function finishes the SHA-512 operation, and writes
* the result to the output buffer. This function is for
* internal use only.
* the result to the output buffer.
*
* \param ctx The SHA-512 context. This must be initialized
* and have a hash operation started.
......@@ -169,6 +168,7 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
/**
* \brief This function processes a single data block within
* the ongoing SHA-512 computation.
* This function is for internal use only.
*
* \param ctx The SHA-512 context. This must be initialized.
* \param data The buffer holding one block of data. This
......
......@@ -1409,7 +1409,7 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
* \note For DTLS, you need to provide either a non-NULL
* f_recv_timeout callback, or a f_recv that doesn't block.
*
* \note See the documentations of \c mbedtls_ssl_sent_t,
* \note See the documentations of \c mbedtls_ssl_send_t,
* \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for
* the conventions those callbacks must follow.
*
......
......@@ -73,6 +73,9 @@ extern "C" {
typedef struct mbedtls_threading_mutex_t
{
pthread_mutex_t mutex;
/* is_valid is 0 after a failed init or a free, and nonzero after a
* successful init. This field is not considered part of the public
* API of Mbed TLS and may change without notice. */
char is_valid;
} mbedtls_threading_mutex_t;
#endif
......
......@@ -65,16 +65,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 16
#define MBEDTLS_VERSION_PATCH 8
#define MBEDTLS_VERSION_PATCH 10
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define MBEDTLS_VERSION_NUMBER 0x02100800
#define MBEDTLS_VERSION_STRING "2.16.8"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.8"
#define MBEDTLS_VERSION_NUMBER 0x02100A00
#define MBEDTLS_VERSION_STRING "2.16.10"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.10"
#if defined(MBEDTLS_VERSION_C)
......
......@@ -165,15 +165,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY)
add_library(mbedcrypto SHARED ${src_crypto})
set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.8 SOVERSION 3)
set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.10 SOVERSION 3)
target_link_libraries(mbedcrypto ${libs})
add_library(mbedx509 SHARED ${src_x509})
set_target_properties(mbedx509 PROPERTIES VERSION 2.16.8 SOVERSION 0)
set_target_properties(mbedx509 PROPERTIES VERSION 2.16.10 SOVERSION 0)
target_link_libraries(mbedx509 ${libs} mbedcrypto)
add_library(mbedtls SHARED ${src_tls})
set_target_properties(mbedtls PROPERTIES VERSION 2.16.8 SOVERSION 12)
set_target_properties(mbedtls PROPERTIES VERSION 2.16.10 SOVERSION 12)
target_link_libraries(mbedtls ${libs} mbedx509)
install(TARGETS mbedtls mbedx509 mbedcrypto
......
......@@ -760,6 +760,7 @@ exit:
return( ret );
}
#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
......@@ -838,8 +839,6 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
do \
{ \
......@@ -897,63 +896,56 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
unsigned char output[16] )
{
int i;
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
RK = ctx->rk;
uint32_t *RK = ctx->rk;
struct
{
uint32_t X[4];
uint32_t Y[4];
} t;
GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++;
GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++;
GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++;
GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
{
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
AES_FROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] );
}
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
X0 = *RK++ ^ \
( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
X1 = *RK++ ^ \
( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
X2 = *RK++ ^ \
( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
X3 = *RK++ ^ \
( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
PUT_UINT32_LE( X0, output, 0 );
PUT_UINT32_LE( X1, output, 4 );
PUT_UINT32_LE( X2, output, 8 );
PUT_UINT32_LE( X3, output, 12 );
mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
mbedtls_platform_zeroize( &RK, sizeof( RK ) );
AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
t.X[0] = *RK++ ^ \
( (uint32_t) FSb[ ( t.Y[0] ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
t.X[1] = *RK++ ^ \
( (uint32_t) FSb[ ( t.Y[1] ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
t.X[2] = *RK++ ^ \
( (uint32_t) FSb[ ( t.Y[2] ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
t.X[3] = *RK++ ^ \
( (uint32_t) FSb[ ( t.Y[3] ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
PUT_UINT32_LE( t.X[0], output, 0 );
PUT_UINT32_LE( t.X[1], output, 4 );
PUT_UINT32_LE( t.X[2], output, 8 );
PUT_UINT32_LE( t.X[3], output, 12 );
mbedtls_platform_zeroize( &t, sizeof( t ) );
return( 0 );
}
......@@ -977,63 +969,56 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
unsigned char output[16] )
{
int i;
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
RK = ctx->rk;
uint32_t *RK = ctx->rk;
struct
{
uint32_t X[4];
uint32_t Y[4];
} t;
GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++;
GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++;
GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++;
GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
{
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
AES_RROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] );
}
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
X0 = *RK++ ^ \
( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
X1 = *RK++ ^ \
( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
X2 = *RK++ ^ \
( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
X3 = *RK++ ^ \
( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
PUT_UINT32_LE( X0, output, 0 );
PUT_UINT32_LE( X1, output, 4 );
PUT_UINT32_LE( X2, output, 8 );
PUT_UINT32_LE( X3, output, 12 );
mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
mbedtls_platform_zeroize( &RK, sizeof( RK ) );
AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
t.X[0] = *RK++ ^ \
( (uint32_t) RSb[ ( t.Y[0] ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
t.X[1] = *RK++ ^ \
( (uint32_t) RSb[ ( t.Y[1] ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
t.X[2] = *RK++ ^ \
( (uint32_t) RSb[ ( t.Y[2] ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
t.X[3] = *RK++ ^ \
( (uint32_t) RSb[ ( t.Y[3] ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
PUT_UINT32_LE( t.X[0], output, 0 );
PUT_UINT32_LE( t.X[1], output, 4 );
PUT_UINT32_LE( t.X[2], output, 8 );
PUT_UINT32_LE( t.X[3], output, 12 );
mbedtls_platform_zeroize( &t, sizeof( t ) );
return( 0 );
}
......
......@@ -96,6 +96,99 @@ static const unsigned char base64_dec_map[128] =
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
/*
* Constant flow conditional assignment to unsigned char
*/
static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
unsigned char condition )
{
/* MSVC has a warning about unary minus on unsigned integer types,
* but this is well-defined and precisely what we want to do here. */
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 )
#endif
/* Generate bitmask from condition, mask will either be 0xFF or 0 */
unsigned char mask = ( condition | -condition );
mask >>= 7;
mask = -mask;
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
*dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
}
/*
* Constant flow conditional assignment to uint_32
*/
static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src,
uint32_t condition )
{
/* MSVC has a warning about unary minus on unsigned integer types,
* but this is well-defined and precisely what we want to do here. */
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 )
#endif
/* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
uint32_t mask = ( condition | -condition );
mask >>= 31;
mask = -mask;
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
*dest = ( src & mask ) | ( ( *dest ) & ~mask );
}
/*
* Constant flow check for equality
*/
static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
{
size_t difference = in_a ^ in_b;
/* MSVC has a warning about unary minus on unsigned integer types,
* but this is well-defined and precisely what we want to do here. */
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 )
#endif
difference |= -difference;
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
/* cope with the varying size of size_t per platform */
difference >>= ( sizeof( difference ) * 8 - 1 );
return (unsigned char) ( 1 ^ difference );
}
/*
* Constant flow lookup into table.
*/
static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
const size_t table_size, const size_t table_index )
{
size_t i;
unsigned char result = 0;
for( i = 0; i < table_size; ++i )
{
mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) );
}
return result;
}
/*
* Encode a buffer into base64 format
*/
......@@ -136,10 +229,17 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
C2 = *src++;
C3 = *src++;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
( ( C1 >> 2 ) & 0x3F ) );
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
( C3 & 0x3F ) );
}
if( i < slen )
......@@ -147,11 +247,15 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
C1 = *src++;
C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
( ( C1 >> 2 ) & 0x3F ) );
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
if( ( i + 1 ) < slen )
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
*p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
else *p++ = '=';
*p++ = '=';
......@@ -172,6 +276,7 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
size_t i, n;
uint32_t j, x;
unsigned char *p;
unsigned char dec_map_lookup;
/* First pass: check for validity and get output length */
for( i = n = j = 0; i < slen; i++ )
......@@ -202,10 +307,12 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
if( src[i] == '=' && ++j > 2 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
if( src[i] > 127 || dec_map_lookup == 127 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
if( base64_dec_map[src[i]] < 64 && j != 0 )
if( dec_map_lookup < 64 && j != 0 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
n++;
......@@ -235,8 +342,10 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
if( *src == '\r' || *src == '\n' || *src == ' ' )
continue;
j -= ( base64_dec_map[*src] == 64 );
x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
x = ( x << 6 ) | ( dec_map_lookup & 0x3F );
if( ++n == 4 )
{
......
......@@ -1354,6 +1354,12 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
for( n = B->n; n > 0; n-- )
if( B->p[n - 1] != 0 )
break;
if( n > A->n )
{
/* B >= (2^ciL)^n > A */
ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
goto cleanup;
}
carry = mpi_sub_hlp( n, X->p, B->p );
if( carry != 0 )
......@@ -1364,7 +1370,10 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
/* If we ran out of space for the carry, it means that the result
* is negative. */
if( n == X->n )
return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
{
ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
goto cleanup;
}
--X->p[n];
}
......@@ -2044,7 +2053,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
size_t i, j, nblimbs;
size_t bufsize, nbits;
mbedtls_mpi_uint ei, mm, state;
mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
int neg;
MPI_VALIDATE_RET( X != NULL );
......@@ -2058,6 +2067,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( mbedtls_mpi_bitlen( E ) > MBEDTLS_MPI_MAX_BITS ||
mbedtls_mpi_bitlen( N ) > MBEDTLS_MPI_MAX_BITS )
return ( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
/*
* Init temps and window size
*/
......@@ -2334,7 +2347,7 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
Xp = (unsigned char*) X->p;
f_rng( p_rng, Xp + overhead, size );
MBEDTLS_MPI_CHK( f_rng( p_rng, Xp + overhead, size ) );
mpi_bigendian_to_host( X->p, limbs );
......
......@@ -779,7 +779,7 @@ static const mbedtls_cipher_info_t camellia_128_ecb_info = {
MBEDTLS_MODE_ECB,
128,
"CAMELLIA-128-ECB",
16,
0,
0,
16,
&camellia_info
......@@ -790,7 +790,7 @@ static const mbedtls_cipher_info_t camellia_192_ecb_info = {
MBEDTLS_MODE_ECB,
192,
"CAMELLIA-192-ECB",
16,
0,
0,
16,
&camellia_info
......@@ -801,7 +801,7 @@ static const mbedtls_cipher_info_t camellia_256_ecb_info = {
MBEDTLS_MODE_ECB,
256,
"CAMELLIA-256-ECB",
16,
0,
0,
16,
&camellia_info
......@@ -1155,7 +1155,7 @@ static const mbedtls_cipher_info_t aria_128_ecb_info = {
MBEDTLS_MODE_ECB,
128,
"ARIA-128-ECB",
16,
0,
0,
16,
&aria_info
......@@ -1166,7 +1166,7 @@ static const mbedtls_cipher_info_t aria_192_ecb_info = {
MBEDTLS_MODE_ECB,
192,
"ARIA-192-ECB",
16,
0,
0,
16,
&aria_info
......@@ -1177,7 +1177,7 @@ static const mbedtls_cipher_info_t aria_256_ecb_info = {
MBEDTLS_MODE_ECB,
256,
"ARIA-256-ECB",
16,
0,
0,
16,
&aria_info
......@@ -1579,7 +1579,7 @@ static const mbedtls_cipher_info_t des_ecb_info = {
MBEDTLS_MODE_ECB,
MBEDTLS_KEY_LENGTH_DES,
"DES-ECB",
8,
0,
0,
8,
&des_info
......@@ -1630,7 +1630,7 @@ static const mbedtls_cipher_info_t des_ede_ecb_info = {
MBEDTLS_MODE_ECB,
MBEDTLS_KEY_LENGTH_DES_EDE,
"DES-EDE-ECB",
8,
0,
0,
8,
&des_ede_info
......@@ -1681,7 +1681,7 @@ static const mbedtls_cipher_info_t des_ede3_ecb_info = {
MBEDTLS_MODE_ECB,
MBEDTLS_KEY_LENGTH_DES_EDE3,
"DES-EDE3-ECB",
8,
0,
0,
8,
&des_ede3_info
......@@ -1796,7 +1796,7 @@ static const mbedtls_cipher_info_t blowfish_ecb_info = {
MBEDTLS_MODE_ECB,
128,
"BLOWFISH-ECB",
8,
0,
MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
8,
&blowfish_info
......
......@@ -450,7 +450,7 @@ exit:
*/
int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
const unsigned char *input, size_t in_len,
unsigned char *output )
unsigned char output[16] )
{
int ret;
const mbedtls_cipher_info_t *cipher_info;
......
......@@ -82,21 +82,26 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
}
/*
* This function resets CTR_DRBG context to the state immediately
* after initial call of mbedtls_ctr_drbg_init().
*/
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
{
if( ctx == NULL )
return;
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &ctx->mutex );
/* The mutex is initialized iff f_entropy is set. */
if( ctx->f_entropy != NULL )
mbedtls_mutex_free( &ctx->mutex );
#endif
mbedtls_aes_free( &ctx->aes_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
}
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
......@@ -412,6 +417,11 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
/* The mutex is initialized iff f_entropy is set. */
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
mbedtls_aes_init( &ctx->aes_ctx );
ctx->f_entropy = f_entropy;
......@@ -419,7 +429,6 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
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
......
......@@ -247,6 +247,9 @@ static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
#endif /* MBEDTLS_ECP_RESTARTABLE */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \
!defined(MBEDTLS_ECDSA_SIGN_ALT) || \
!defined(MBEDTLS_ECDSA_VERIFY_ALT)
/*
* Derive a suitable integer for group grp from a buffer of length len
* SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
......@@ -269,6 +272,7 @@ static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
cleanup:
return( ret );
}
#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
/*
......@@ -780,6 +784,8 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
(void) md_alg;
#if defined(MBEDTLS_ECDSA_SIGN_ALT)
(void) rs_ctx;
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, f_rng, p_rng ) );
#else
......@@ -888,6 +894,8 @@ int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
goto cleanup;
}
#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
(void) rs_ctx;
if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
&ctx->Q, &r, &s ) ) != 0 )
goto cleanup;
......
......@@ -850,6 +850,8 @@ static const unsigned char ecjpake_test_password[] = {
0x65, 0x73, 0x74
};
#if !defined(MBEDTLS_ECJPAKE_ALT)
static const unsigned char ecjpake_test_x1[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
......@@ -994,6 +996,8 @@ cleanup:
return( ret );
}
#endif /* ! MBEDTLS_ECJPAKE_ALT */
/* For tests we don't need a secure RNG;
* use the LGC from Numerical Recipes for simplicity */
static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
......@@ -1089,6 +1093,12 @@ int mbedtls_ecjpake_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( "passed\n" );
#if !defined(MBEDTLS_ECJPAKE_ALT)
/* 'reference handshake' tests can only be run against implementations
* for which we have 100% control over how the random ephemeral keys
* are generated. This is only the case for the internal mbed TLS
* implementation, so these tests are skipped in case the internal
* implementation is swapped out for an alternative one. */
if( verbose != 0 )
mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
......@@ -1137,6 +1147,7 @@ int mbedtls_ecjpake_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( "passed\n" );
#endif /* ! MBEDTLS_ECJPAKE_ALT */
cleanup:
mbedtls_ecjpake_free( &cli );
......
......@@ -1044,7 +1044,7 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
STORE32; i++; \
cur = c > 0 ? c : 0; STORE32; \
cur = 0; while( ++i < MAX32 ) { STORE32; } \
if( c < 0 ) fix_negative( N, c, &C, bits );
if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
/*
* If the result is negative, we get it in the form
......
......@@ -146,6 +146,11 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
{
/* If the context was already free, don't call free() again.
* This is important for mutexes which don't allow double-free. */
if( ctx->accumulator_started == -1 )
return;
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_free( &ctx->havege_data );
#endif
......@@ -162,7 +167,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
#endif
ctx->source_count = 0;
mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
ctx->accumulator_started = 0;
ctx->accumulator_started = -1;
}
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
......
......@@ -44,7 +44,7 @@
* **********
*/
#if defined(__linux__)
#if defined(__linux__) && !defined(_GNU_SOURCE)
/* Ensure that syscall() is available even when compiling with -std=c99 */
#define _GNU_SOURCE
#endif
......@@ -140,12 +140,12 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
#endif /* __linux__ */
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int mbedtls_platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
FILE *file;
size_t read_len;
int ret;
((void) data);
......@@ -165,18 +165,18 @@ int mbedtls_platform_entropy_poll( void *data,
*olen = 0;
int fd = open("/dev/urandom", O_RDONLY);
if (fd == -1)
file = fopen( "/dev/urandom", "rb" );
if( file == NULL )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
ssize_t read_len = read(fd, output, len);
if ((read_len == -1) || ((size_t)read_len != len))
read_len = fread( output, 1, len, file );
if( read_len != len )
{
close(fd);
fclose( file );
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
}
close(fd);
fclose( file );
*olen = len;
return( 0 );
......
......@@ -51,20 +51,19 @@
#endif
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
#include "mbedtls/error.h"
#include <string.h>
#endif
#if defined(MBEDTLS_ERROR_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_snprintf snprintf
#define mbedtls_time_t time_t
#endif
#if defined(MBEDTLS_ERROR_C)
#include <stdio.h>
#include <string.h>
#if defined(MBEDTLS_AES_C)
#include "mbedtls/aes.h"
......@@ -929,8 +928,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
#else /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
/*
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
*/
......@@ -942,6 +939,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
buf[0] = '\0';
}
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
#endif /* MBEDTLS_ERROR_C */
#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
......@@ -83,9 +83,7 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
}
/*
......@@ -157,6 +155,10 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
return( ret );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
/*
* Set initial working state.
* Use the V memory location, which is currently all 0, to initialize the
......@@ -282,6 +284,11 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
return( ret );
/* The mutex is initialized iff the md context is set up. */
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
md_size = mbedtls_md_get_size( md_info );
/*
......@@ -296,8 +303,6 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
if( ctx->entropy_len == 0 )
{
/*
......@@ -442,7 +447,8 @@ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len
}
/*
* Free an HMAC_DRBG context
* This function resets HMAC_DRBG context to the state immediately
* after initial call of mbedtls_hmac_drbg_init().
*/
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
{
......@@ -450,10 +456,13 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
return;
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &ctx->mutex );
/* The mutex is initialized iff the md context is set up. */
if( ctx->md_ctx.md_info != NULL )
mbedtls_mutex_free( &ctx->mutex );
#endif
mbedtls_md_free( &ctx->md_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
}
#if defined(MBEDTLS_FS_IO)
......
......@@ -177,6 +177,9 @@ int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
t = ctx->cksum[i];
}
/* Zeroise variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &t, sizeof( t ) );
return( 0 );
}
......
......@@ -143,31 +143,34 @@ void mbedtls_md4_starts( mbedtls_md4_context *ctx )
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
struct
{
uint32_t X[16], A, B, C, D;
} local;
GET_UINT32_LE( local.X[ 0], data, 0 );
GET_UINT32_LE( local.X[ 1], data, 4 );
GET_UINT32_LE( local.X[ 2], data, 8 );
GET_UINT32_LE( local.X[ 3], data, 12 );
GET_UINT32_LE( local.X[ 4], data, 16 );
GET_UINT32_LE( local.X[ 5], data, 20 );
GET_UINT32_LE( local.X[ 6], data, 24 );
GET_UINT32_LE( local.X[ 7], data, 28 );
GET_UINT32_LE( local.X[ 8], data, 32 );
GET_UINT32_LE( local.X[ 9], data, 36 );
GET_UINT32_LE( local.X[10], data, 40 );
GET_UINT32_LE( local.X[11], data, 44 );
GET_UINT32_LE( local.X[12], data, 48 );
GET_UINT32_LE( local.X[13], data, 52 );
GET_UINT32_LE( local.X[14], data, 56 );
GET_UINT32_LE( local.X[15], data, 60 );
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
local.A = ctx->state[0];
local.B = ctx->state[1];
local.C = ctx->state[2];
local.D = ctx->state[3];
#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
#define P(a,b,c,d,x,s) \
......@@ -178,22 +181,22 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
} while( 0 )
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 1], 7 );
P( C, D, A, B, X[ 2], 11 );
P( B, C, D, A, X[ 3], 19 );
P( A, B, C, D, X[ 4], 3 );
P( D, A, B, C, X[ 5], 7 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[ 7], 19 );
P( A, B, C, D, X[ 8], 3 );
P( D, A, B, C, X[ 9], 7 );
P( C, D, A, B, X[10], 11 );
P( B, C, D, A, X[11], 19 );
P( A, B, C, D, X[12], 3 );
P( D, A, B, C, X[13], 7 );
P( C, D, A, B, X[14], 11 );
P( B, C, D, A, X[15], 19 );
P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 1], 7 );
P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
P( local.A, local.B, local.C, local.D, local.X[ 4], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 5], 7 );
P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
P( local.A, local.B, local.C, local.D, local.X[ 8], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 9], 7 );
P( local.C, local.D, local.A, local.B, local.X[10], 11 );
P( local.B, local.C, local.D, local.A, local.X[11], 19 );
P( local.A, local.B, local.C, local.D, local.X[12], 3 );
P( local.D, local.A, local.B, local.C, local.X[13], 7 );
P( local.C, local.D, local.A, local.B, local.X[14], 11 );
P( local.B, local.C, local.D, local.A, local.X[15], 19 );
#undef P
#undef F
......@@ -206,22 +209,22 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
(a) = S((a),(s)); \
} while( 0 )
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 4], 5 );
P( C, D, A, B, X[ 8], 9 );
P( B, C, D, A, X[12], 13 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 5], 5 );
P( C, D, A, B, X[ 9], 9 );
P( B, C, D, A, X[13], 13 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[ 6], 5 );
P( C, D, A, B, X[10], 9 );
P( B, C, D, A, X[14], 13 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[ 7], 5 );
P( C, D, A, B, X[11], 9 );
P( B, C, D, A, X[15], 13 );
P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 4], 5 );
P( local.C, local.D, local.A, local.B, local.X[ 8], 9 );
P( local.B, local.C, local.D, local.A, local.X[12], 13 );
P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 5], 5 );
P( local.C, local.D, local.A, local.B, local.X[ 9], 9 );
P( local.B, local.C, local.D, local.A, local.X[13], 13 );
P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 6], 5 );
P( local.C, local.D, local.A, local.B, local.X[10], 9 );
P( local.B, local.C, local.D, local.A, local.X[14], 13 );
P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 7], 5 );
P( local.C, local.D, local.A, local.B, local.X[11], 9 );
P( local.B, local.C, local.D, local.A, local.X[15], 13 );
#undef P
#undef F
......@@ -234,30 +237,33 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
(a) = S((a),(s)); \
} while( 0 )
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 8], 9 );
P( C, D, A, B, X[ 4], 11 );
P( B, C, D, A, X[12], 15 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[10], 9 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[14], 15 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 9], 9 );
P( C, D, A, B, X[ 5], 11 );
P( B, C, D, A, X[13], 15 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[11], 9 );
P( C, D, A, B, X[ 7], 11 );
P( B, C, D, A, X[15], 15 );
P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 8], 9 );
P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
P( local.B, local.C, local.D, local.A, local.X[12], 15 );
P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
P( local.D, local.A, local.B, local.C, local.X[10], 9 );
P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
P( local.B, local.C, local.D, local.A, local.X[14], 15 );
P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
P( local.D, local.A, local.B, local.C, local.X[ 9], 9 );
P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
P( local.B, local.C, local.D, local.A, local.X[13], 15 );
P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
P( local.D, local.A, local.B, local.C, local.X[11], 9 );
P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
P( local.B, local.C, local.D, local.A, local.X[15], 15 );
#undef F
#undef P
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[0] += local.A;
ctx->state[1] += local.B;
ctx->state[2] += local.C;
ctx->state[3] += local.D;
/* Zeroise variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
......
......@@ -142,128 +142,134 @@ void mbedtls_md5_starts( mbedtls_md5_context *ctx )
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
struct
{
uint32_t X[16], A, B, C, D;
} local;
GET_UINT32_LE( local.X[ 0], data, 0 );
GET_UINT32_LE( local.X[ 1], data, 4 );
GET_UINT32_LE( local.X[ 2], data, 8 );
GET_UINT32_LE( local.X[ 3], data, 12 );
GET_UINT32_LE( local.X[ 4], data, 16 );
GET_UINT32_LE( local.X[ 5], data, 20 );
GET_UINT32_LE( local.X[ 6], data, 24 );
GET_UINT32_LE( local.X[ 7], data, 28 );
GET_UINT32_LE( local.X[ 8], data, 32 );
GET_UINT32_LE( local.X[ 9], data, 36 );
GET_UINT32_LE( local.X[10], data, 40 );
GET_UINT32_LE( local.X[11], data, 44 );
GET_UINT32_LE( local.X[12], data, 48 );
GET_UINT32_LE( local.X[13], data, 52 );
GET_UINT32_LE( local.X[14], data, 56 );
GET_UINT32_LE( local.X[15], data, 60 );
#define S(x,n) \
( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) )
#define P(a,b,c,d,k,s,t) \
do \
{ \
(a) += F((b),(c),(d)) + X[(k)] + (t); \
(a) = S((a),(s)) + (b); \
#define P(a,b,c,d,k,s,t) \
do \
{ \
(a) += F((b),(c),(d)) + local.X[(k)] + (t); \
(a) = S((a),(s)) + (b); \
} while( 0 )
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
local.A = ctx->state[0];
local.B = ctx->state[1];
local.C = ctx->state[2];
local.D = ctx->state[3];
#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
P( A, B, C, D, 0, 7, 0xD76AA478 );
P( D, A, B, C, 1, 12, 0xE8C7B756 );
P( C, D, A, B, 2, 17, 0x242070DB );
P( B, C, D, A, 3, 22, 0xC1BDCEEE );
P( A, B, C, D, 4, 7, 0xF57C0FAF );
P( D, A, B, C, 5, 12, 0x4787C62A );
P( C, D, A, B, 6, 17, 0xA8304613 );
P( B, C, D, A, 7, 22, 0xFD469501 );
P( A, B, C, D, 8, 7, 0x698098D8 );
P( D, A, B, C, 9, 12, 0x8B44F7AF );
P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
P( B, C, D, A, 11, 22, 0x895CD7BE );
P( A, B, C, D, 12, 7, 0x6B901122 );
P( D, A, B, C, 13, 12, 0xFD987193 );
P( C, D, A, B, 14, 17, 0xA679438E );
P( B, C, D, A, 15, 22, 0x49B40821 );
P( local.A, local.B, local.C, local.D, 0, 7, 0xD76AA478 );
P( local.D, local.A, local.B, local.C, 1, 12, 0xE8C7B756 );
P( local.C, local.D, local.A, local.B, 2, 17, 0x242070DB );
P( local.B, local.C, local.D, local.A, 3, 22, 0xC1BDCEEE );
P( local.A, local.B, local.C, local.D, 4, 7, 0xF57C0FAF );
P( local.D, local.A, local.B, local.C, 5, 12, 0x4787C62A );
P( local.C, local.D, local.A, local.B, 6, 17, 0xA8304613 );
P( local.B, local.C, local.D, local.A, 7, 22, 0xFD469501 );
P( local.A, local.B, local.C, local.D, 8, 7, 0x698098D8 );
P( local.D, local.A, local.B, local.C, 9, 12, 0x8B44F7AF );
P( local.C, local.D, local.A, local.B, 10, 17, 0xFFFF5BB1 );
P( local.B, local.C, local.D, local.A, 11, 22, 0x895CD7BE );
P( local.A, local.B, local.C, local.D, 12, 7, 0x6B901122 );
P( local.D, local.A, local.B, local.C, 13, 12, 0xFD987193 );
P( local.C, local.D, local.A, local.B, 14, 17, 0xA679438E );
P( local.B, local.C, local.D, local.A, 15, 22, 0x49B40821 );
#undef F
#define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y))))
P( A, B, C, D, 1, 5, 0xF61E2562 );
P( D, A, B, C, 6, 9, 0xC040B340 );
P( C, D, A, B, 11, 14, 0x265E5A51 );
P( B, C, D, A, 0, 20, 0xE9B6C7AA );
P( A, B, C, D, 5, 5, 0xD62F105D );
P( D, A, B, C, 10, 9, 0x02441453 );
P( C, D, A, B, 15, 14, 0xD8A1E681 );
P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
P( A, B, C, D, 9, 5, 0x21E1CDE6 );
P( D, A, B, C, 14, 9, 0xC33707D6 );
P( C, D, A, B, 3, 14, 0xF4D50D87 );
P( B, C, D, A, 8, 20, 0x455A14ED );
P( A, B, C, D, 13, 5, 0xA9E3E905 );
P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
P( C, D, A, B, 7, 14, 0x676F02D9 );
P( B, C, D, A, 12, 20, 0x8D2A4C8A );
P( local.A, local.B, local.C, local.D, 1, 5, 0xF61E2562 );
P( local.D, local.A, local.B, local.C, 6, 9, 0xC040B340 );
P( local.C, local.D, local.A, local.B, 11, 14, 0x265E5A51 );
P( local.B, local.C, local.D, local.A, 0, 20, 0xE9B6C7AA );
P( local.A, local.B, local.C, local.D, 5, 5, 0xD62F105D );
P( local.D, local.A, local.B, local.C, 10, 9, 0x02441453 );
P( local.C, local.D, local.A, local.B, 15, 14, 0xD8A1E681 );
P( local.B, local.C, local.D, local.A, 4, 20, 0xE7D3FBC8 );
P( local.A, local.B, local.C, local.D, 9, 5, 0x21E1CDE6 );
P( local.D, local.A, local.B, local.C, 14, 9, 0xC33707D6 );
P( local.C, local.D, local.A, local.B, 3, 14, 0xF4D50D87 );
P( local.B, local.C, local.D, local.A, 8, 20, 0x455A14ED );
P( local.A, local.B, local.C, local.D, 13, 5, 0xA9E3E905 );
P( local.D, local.A, local.B, local.C, 2, 9, 0xFCEFA3F8 );
P( local.C, local.D, local.A, local.B, 7, 14, 0x676F02D9 );
P( local.B, local.C, local.D, local.A, 12, 20, 0x8D2A4C8A );
#undef F
#define F(x,y,z) ((x) ^ (y) ^ (z))
P( A, B, C, D, 5, 4, 0xFFFA3942 );
P( D, A, B, C, 8, 11, 0x8771F681 );
P( C, D, A, B, 11, 16, 0x6D9D6122 );
P( B, C, D, A, 14, 23, 0xFDE5380C );
P( A, B, C, D, 1, 4, 0xA4BEEA44 );
P( D, A, B, C, 4, 11, 0x4BDECFA9 );
P( C, D, A, B, 7, 16, 0xF6BB4B60 );
P( B, C, D, A, 10, 23, 0xBEBFBC70 );
P( A, B, C, D, 13, 4, 0x289B7EC6 );
P( D, A, B, C, 0, 11, 0xEAA127FA );
P( C, D, A, B, 3, 16, 0xD4EF3085 );
P( B, C, D, A, 6, 23, 0x04881D05 );
P( A, B, C, D, 9, 4, 0xD9D4D039 );
P( D, A, B, C, 12, 11, 0xE6DB99E5 );
P( C, D, A, B, 15, 16, 0x1FA27CF8 );
P( B, C, D, A, 2, 23, 0xC4AC5665 );
P( local.A, local.B, local.C, local.D, 5, 4, 0xFFFA3942 );
P( local.D, local.A, local.B, local.C, 8, 11, 0x8771F681 );
P( local.C, local.D, local.A, local.B, 11, 16, 0x6D9D6122 );
P( local.B, local.C, local.D, local.A, 14, 23, 0xFDE5380C );
P( local.A, local.B, local.C, local.D, 1, 4, 0xA4BEEA44 );
P( local.D, local.A, local.B, local.C, 4, 11, 0x4BDECFA9 );
P( local.C, local.D, local.A, local.B, 7, 16, 0xF6BB4B60 );
P( local.B, local.C, local.D, local.A, 10, 23, 0xBEBFBC70 );
P( local.A, local.B, local.C, local.D, 13, 4, 0x289B7EC6 );
P( local.D, local.A, local.B, local.C, 0, 11, 0xEAA127FA );
P( local.C, local.D, local.A, local.B, 3, 16, 0xD4EF3085 );
P( local.B, local.C, local.D, local.A, 6, 23, 0x04881D05 );
P( local.A, local.B, local.C, local.D, 9, 4, 0xD9D4D039 );
P( local.D, local.A, local.B, local.C, 12, 11, 0xE6DB99E5 );
P( local.C, local.D, local.A, local.B, 15, 16, 0x1FA27CF8 );
P( local.B, local.C, local.D, local.A, 2, 23, 0xC4AC5665 );
#undef F
#define F(x,y,z) ((y) ^ ((x) | ~(z)))
P( A, B, C, D, 0, 6, 0xF4292244 );
P( D, A, B, C, 7, 10, 0x432AFF97 );
P( C, D, A, B, 14, 15, 0xAB9423A7 );
P( B, C, D, A, 5, 21, 0xFC93A039 );
P( A, B, C, D, 12, 6, 0x655B59C3 );
P( D, A, B, C, 3, 10, 0x8F0CCC92 );
P( C, D, A, B, 10, 15, 0xFFEFF47D );
P( B, C, D, A, 1, 21, 0x85845DD1 );
P( A, B, C, D, 8, 6, 0x6FA87E4F );
P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
P( C, D, A, B, 6, 15, 0xA3014314 );
P( B, C, D, A, 13, 21, 0x4E0811A1 );
P( A, B, C, D, 4, 6, 0xF7537E82 );
P( D, A, B, C, 11, 10, 0xBD3AF235 );
P( C, D, A, B, 2, 15, 0x2AD7D2BB );
P( B, C, D, A, 9, 21, 0xEB86D391 );
P( local.A, local.B, local.C, local.D, 0, 6, 0xF4292244 );
P( local.D, local.A, local.B, local.C, 7, 10, 0x432AFF97 );
P( local.C, local.D, local.A, local.B, 14, 15, 0xAB9423A7 );
P( local.B, local.C, local.D, local.A, 5, 21, 0xFC93A039 );
P( local.A, local.B, local.C, local.D, 12, 6, 0x655B59C3 );
P( local.D, local.A, local.B, local.C, 3, 10, 0x8F0CCC92 );
P( local.C, local.D, local.A, local.B, 10, 15, 0xFFEFF47D );
P( local.B, local.C, local.D, local.A, 1, 21, 0x85845DD1 );
P( local.A, local.B, local.C, local.D, 8, 6, 0x6FA87E4F );
P( local.D, local.A, local.B, local.C, 15, 10, 0xFE2CE6E0 );
P( local.C, local.D, local.A, local.B, 6, 15, 0xA3014314 );
P( local.B, local.C, local.D, local.A, 13, 21, 0x4E0811A1 );
P( local.A, local.B, local.C, local.D, 4, 6, 0xF7537E82 );
P( local.D, local.A, local.B, local.C, 11, 10, 0xBD3AF235 );
P( local.C, local.D, local.A, local.B, 2, 15, 0x2AD7D2BB );
P( local.B, local.C, local.D, local.A, 9, 21, 0xEB86D391 );
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[0] += local.A;
ctx->state[1] += local.B;
ctx->state[2] += local.C;
ctx->state[3] += local.D;
/* Zeroise variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
......
......@@ -496,6 +496,13 @@ int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
/* A limitation of select() is that it only works with file descriptors
* that are strictly less than FD_SETSIZE. This is a limitation of the
* fd_set type. Error out early, because attempting to call FD_SET on a
* large file descriptor is a buffer overflow on typical platforms. */
if( fd >= FD_SETSIZE )
return( MBEDTLS_ERR_NET_POLL_FAILED );
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
/* Ensure that memory sanitizers consider read_fds and write_fds as
......@@ -615,6 +622,13 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
/* A limitation of select() is that it only works with file descriptors
* that are strictly less than FD_SETSIZE. This is a limitation of the
* fd_set type. Error out early, because attempting to call FD_SET on a
* large file descriptor is a buffer overflow on typical platforms. */
if( fd >= FD_SETSIZE )
return( MBEDTLS_ERR_NET_POLL_FAILED );
FD_ZERO( &read_fds );
FD_SET( fd, &read_fds );
......
......@@ -508,8 +508,12 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
*p++ = '\0';
*olen = p - buf;
/* Clean any remaining data previously written to the buffer */
memset( buf + *olen, 0, buf_len - *olen );
mbedtls_free( encode_buf );
return( 0 );
}
#endif /* MBEDTLS_PEM_WRITE_C */
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
......@@ -247,7 +247,7 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
unsigned int iteration_count,
uint32_t key_length, unsigned char *output )
{
int ret, j;
int ret = 0, j;
unsigned int i;
unsigned char md1[MBEDTLS_MD_MAX_SIZE];
unsigned char work[MBEDTLS_MD_MAX_SIZE];
......@@ -269,16 +269,16 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
// U1 ends up in work
//
if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
return( ret );
goto cleanup;
if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
return( ret );
goto cleanup;
if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 )
return( ret );
goto cleanup;
if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
return( ret );
goto cleanup;
memcpy( md1, work, md_size );
......@@ -287,13 +287,13 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
// U2 ends up in md1
//
if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
return( ret );
goto cleanup;
if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
return( ret );
goto cleanup;
if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
return( ret );
goto cleanup;
// U1 xor U2
//
......@@ -312,7 +312,12 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
break;
}
return( 0 );
cleanup:
/* Zeroise buffers to clear sensitive data from memory. */
mbedtls_platform_zeroize( work, MBEDTLS_MD_MAX_SIZE );
mbedtls_platform_zeroize( md1, MBEDTLS_MD_MAX_SIZE );
return( ret );
}
#if defined(MBEDTLS_SELF_TEST)
......
......@@ -692,7 +692,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
if( ret == 0 && *p != end )
ret = MBEDTLS_ERR_PK_INVALID_PUBKEY
ret = MBEDTLS_ERR_PK_INVALID_PUBKEY +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
if( ret != 0 )
......
......@@ -455,7 +455,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
* publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
* }
*/
#define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE
#define RSA_PUB_DER_MAX_BYTES ( 38 + 2 * MBEDTLS_MPI_MAX_SIZE )
/*
* RSA private keys:
......@@ -472,10 +472,10 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
* otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
* }
*/
#define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \
MBEDTLS_MPI_MAX_SIZE % 2
#define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
+ 5 * MPI_MAX_SIZE_2
#define MPI_MAX_SIZE_2 ( MBEDTLS_MPI_MAX_SIZE / 2 + \
MBEDTLS_MPI_MAX_SIZE % 2 )
#define RSA_PRV_DER_MAX_BYTES ( 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
+ 5 * MPI_MAX_SIZE_2 )
#else /* MBEDTLS_RSA_C */
......@@ -496,7 +496,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
* + 2 * ECP_MAX (coords) [1]
* }
*/
#define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES
#define ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES )
/*
* EC private keys:
......@@ -507,7 +507,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
* publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
* }
*/
#define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES
#define ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES )
#else /* MBEDTLS_ECP_C */
......@@ -516,10 +516,10 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
#endif /* MBEDTLS_ECP_C */
#define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
#define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
#define PUB_DER_MAX_BYTES ( RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES )
#define PRV_DER_MAX_BYTES ( RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES )
int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
......
......@@ -115,7 +115,7 @@ void mbedtls_platform_zeroize( void *buf, size_t len )
#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
_POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) )
/*
* This is a convenience shorthand macro to avoid checking the long
* preprocessor conditions above. Ideally, we could expose this macro in
......@@ -129,7 +129,7 @@ void mbedtls_platform_zeroize( void *buf, size_t len )
#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
_POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
struct tm *tm_buf )
......
......@@ -147,30 +147,33 @@ void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
const unsigned char data[64] )
{
uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
A = Ap = ctx->state[0];
B = Bp = ctx->state[1];
C = Cp = ctx->state[2];
D = Dp = ctx->state[3];
E = Ep = ctx->state[4];
struct
{
uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
} local;
GET_UINT32_LE( local.X[ 0], data, 0 );
GET_UINT32_LE( local.X[ 1], data, 4 );
GET_UINT32_LE( local.X[ 2], data, 8 );
GET_UINT32_LE( local.X[ 3], data, 12 );
GET_UINT32_LE( local.X[ 4], data, 16 );
GET_UINT32_LE( local.X[ 5], data, 20 );
GET_UINT32_LE( local.X[ 6], data, 24 );
GET_UINT32_LE( local.X[ 7], data, 28 );
GET_UINT32_LE( local.X[ 8], data, 32 );
GET_UINT32_LE( local.X[ 9], data, 36 );
GET_UINT32_LE( local.X[10], data, 40 );
GET_UINT32_LE( local.X[11], data, 44 );
GET_UINT32_LE( local.X[12], data, 48 );
GET_UINT32_LE( local.X[13], data, 52 );
GET_UINT32_LE( local.X[14], data, 56 );
GET_UINT32_LE( local.X[15], data, 60 );
local.A = local.Ap = ctx->state[0];
local.B = local.Bp = ctx->state[1];
local.C = local.Cp = ctx->state[2];
local.D = local.Dp = ctx->state[3];
local.E = local.Ep = ctx->state[4];
#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
......@@ -180,12 +183,12 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
#define P( a, b, c, d, e, r, s, f, k ) \
do \
{ \
(a) += f( (b), (c), (d) ) + X[r] + (k); \
(a) = S( (a), (s) ) + (e); \
(c) = S( (c), 10 ); \
#define P( a, b, c, d, e, r, s, f, k ) \
do \
{ \
(a) += f( (b), (c), (d) ) + local.X[r] + (k); \
(a) = S( (a), (s) ) + (e); \
(c) = S( (c), 10 ); \
} while( 0 )
#define P2( a, b, c, d, e, r, s, rp, sp ) \
......@@ -200,22 +203,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
#define K 0x00000000
#define Fp F5
#define Kp 0x50A28BE6
P2( A, B, C, D, E, 0, 11, 5, 8 );
P2( E, A, B, C, D, 1, 14, 14, 9 );
P2( D, E, A, B, C, 2, 15, 7, 9 );
P2( C, D, E, A, B, 3, 12, 0, 11 );
P2( B, C, D, E, A, 4, 5, 9, 13 );
P2( A, B, C, D, E, 5, 8, 2, 15 );
P2( E, A, B, C, D, 6, 7, 11, 15 );
P2( D, E, A, B, C, 7, 9, 4, 5 );
P2( C, D, E, A, B, 8, 11, 13, 7 );
P2( B, C, D, E, A, 9, 13, 6, 7 );
P2( A, B, C, D, E, 10, 14, 15, 8 );
P2( E, A, B, C, D, 11, 15, 8, 11 );
P2( D, E, A, B, C, 12, 6, 1, 14 );
P2( C, D, E, A, B, 13, 7, 10, 14 );
P2( B, C, D, E, A, 14, 9, 3, 12 );
P2( A, B, C, D, E, 15, 8, 12, 6 );
P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
#undef F
#undef K
#undef Fp
......@@ -225,22 +228,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
#define K 0x5A827999
#define Fp F4
#define Kp 0x5C4DD124
P2( E, A, B, C, D, 7, 7, 6, 9 );
P2( D, E, A, B, C, 4, 6, 11, 13 );
P2( C, D, E, A, B, 13, 8, 3, 15 );
P2( B, C, D, E, A, 1, 13, 7, 7 );
P2( A, B, C, D, E, 10, 11, 0, 12 );
P2( E, A, B, C, D, 6, 9, 13, 8 );
P2( D, E, A, B, C, 15, 7, 5, 9 );
P2( C, D, E, A, B, 3, 15, 10, 11 );
P2( B, C, D, E, A, 12, 7, 14, 7 );
P2( A, B, C, D, E, 0, 12, 15, 7 );
P2( E, A, B, C, D, 9, 15, 8, 12 );
P2( D, E, A, B, C, 5, 9, 12, 7 );
P2( C, D, E, A, B, 2, 11, 4, 6 );
P2( B, C, D, E, A, 14, 7, 9, 15 );
P2( A, B, C, D, E, 11, 13, 1, 13 );
P2( E, A, B, C, D, 8, 12, 2, 11 );
P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
#undef F
#undef K
#undef Fp
......@@ -250,22 +253,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
#define K 0x6ED9EBA1
#define Fp F3
#define Kp 0x6D703EF3
P2( D, E, A, B, C, 3, 11, 15, 9 );
P2( C, D, E, A, B, 10, 13, 5, 7 );
P2( B, C, D, E, A, 14, 6, 1, 15 );
P2( A, B, C, D, E, 4, 7, 3, 11 );
P2( E, A, B, C, D, 9, 14, 7, 8 );
P2( D, E, A, B, C, 15, 9, 14, 6 );
P2( C, D, E, A, B, 8, 13, 6, 6 );
P2( B, C, D, E, A, 1, 15, 9, 14 );
P2( A, B, C, D, E, 2, 14, 11, 12 );
P2( E, A, B, C, D, 7, 8, 8, 13 );
P2( D, E, A, B, C, 0, 13, 12, 5 );
P2( C, D, E, A, B, 6, 6, 2, 14 );
P2( B, C, D, E, A, 13, 5, 10, 13 );
P2( A, B, C, D, E, 11, 12, 0, 13 );
P2( E, A, B, C, D, 5, 7, 4, 7 );
P2( D, E, A, B, C, 12, 5, 13, 5 );
P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
#undef F
#undef K
#undef Fp
......@@ -275,22 +278,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
#define K 0x8F1BBCDC
#define Fp F2
#define Kp 0x7A6D76E9
P2( C, D, E, A, B, 1, 11, 8, 15 );
P2( B, C, D, E, A, 9, 12, 6, 5 );
P2( A, B, C, D, E, 11, 14, 4, 8 );
P2( E, A, B, C, D, 10, 15, 1, 11 );
P2( D, E, A, B, C, 0, 14, 3, 14 );
P2( C, D, E, A, B, 8, 15, 11, 14 );
P2( B, C, D, E, A, 12, 9, 15, 6 );
P2( A, B, C, D, E, 4, 8, 0, 14 );
P2( E, A, B, C, D, 13, 9, 5, 6 );
P2( D, E, A, B, C, 3, 14, 12, 9 );
P2( C, D, E, A, B, 7, 5, 2, 12 );
P2( B, C, D, E, A, 15, 6, 13, 9 );
P2( A, B, C, D, E, 14, 8, 9, 12 );
P2( E, A, B, C, D, 5, 6, 7, 5 );
P2( D, E, A, B, C, 6, 5, 10, 15 );
P2( C, D, E, A, B, 2, 12, 14, 8 );
P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
#undef F
#undef K
#undef Fp
......@@ -300,33 +303,36 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
#define K 0xA953FD4E
#define Fp F1
#define Kp 0x00000000
P2( B, C, D, E, A, 4, 9, 12, 8 );
P2( A, B, C, D, E, 0, 15, 15, 5 );
P2( E, A, B, C, D, 5, 5, 10, 12 );
P2( D, E, A, B, C, 9, 11, 4, 9 );
P2( C, D, E, A, B, 7, 6, 1, 12 );
P2( B, C, D, E, A, 12, 8, 5, 5 );
P2( A, B, C, D, E, 2, 13, 8, 14 );
P2( E, A, B, C, D, 10, 12, 7, 6 );
P2( D, E, A, B, C, 14, 5, 6, 8 );
P2( C, D, E, A, B, 1, 12, 2, 13 );
P2( B, C, D, E, A, 3, 13, 13, 6 );
P2( A, B, C, D, E, 8, 14, 14, 5 );
P2( E, A, B, C, D, 11, 11, 0, 15 );
P2( D, E, A, B, C, 6, 8, 3, 13 );
P2( C, D, E, A, B, 15, 5, 9, 11 );
P2( B, C, D, E, A, 13, 6, 11, 11 );
P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
#undef F
#undef K
#undef Fp
#undef Kp
C = ctx->state[1] + C + Dp;
ctx->state[1] = ctx->state[2] + D + Ep;
ctx->state[2] = ctx->state[3] + E + Ap;
ctx->state[3] = ctx->state[4] + A + Bp;
ctx->state[4] = ctx->state[0] + B + Cp;
ctx->state[0] = C;
local.C = ctx->state[1] + local.C + local.Dp;
ctx->state[1] = ctx->state[2] + local.D + local.Ep;
ctx->state[2] = ctx->state[3] + local.E + local.Ap;
ctx->state[3] = ctx->state[4] + local.A + local.Bp;
ctx->state[4] = ctx->state[0] + local.B + local.Cp;
ctx->state[0] = local.C;
/* Zeroise variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
......
......@@ -520,6 +520,9 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
mbedtls_rsa_set_padding( ctx, padding, hash_id );
#if defined(MBEDTLS_THREADING_C)
/* Set ctx->ver to nonzero to indicate that the mutex has been
* initialized and will need to be freed. */
ctx->ver = 1;
mbedtls_mutex_init( &ctx->mutex );
#endif
}
......@@ -567,9 +570,6 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( f_rng != NULL );
if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
/*
* If the modulus is 1024 bit long or shorter, then the security strength of
* the RSA algorithm is less than or equal to 80 bits and therefore an error
......@@ -582,6 +582,12 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
mbedtls_mpi_init( &G );
mbedtls_mpi_init( &L );
if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
{
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
goto cleanup;
}
/*
* find primes P and Q with Q < P so that:
* 1. |P-Q| > 2^( nbits / 2 - 100 )
......@@ -659,7 +665,9 @@ cleanup:
if( ret != 0 )
{
mbedtls_rsa_free( ctx );
return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
if( ( -ret & ~0x7f ) == 0 )
ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
return( ret );
}
return( 0 );
......@@ -841,15 +849,14 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
* which one, we just loop and choose new values for both of them.
* (Each iteration succeeds with overwhelming probability.) */
ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
continue;
if( ret != 0 )
if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
goto cleanup;
/* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
} while( 0 );
} while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
/* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
/* Blinding value: Vi = Vf^(-e) mod N
* (Vi already contains Vf^-1 at this point) */
......@@ -1107,10 +1114,10 @@ cleanup:
mbedtls_mpi_free( &C );
mbedtls_mpi_free( &I );
if( ret != 0 )
if( ret != 0 && ret >= -0x007f )
return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
return( 0 );
return( ret );
}
#if defined(MBEDTLS_PKCS1_V21)
......@@ -2503,7 +2510,6 @@ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
RSA_VALIDATE_RET( dst != NULL );
RSA_VALIDATE_RET( src != NULL );
dst->ver = src->ver;
dst->len = src->len;
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
......@@ -2562,7 +2568,12 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
#endif /* MBEDTLS_RSA_NO_CRT */
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &ctx->mutex );
/* Free the mutex, but only if it hasn't been freed already. */
if( ctx->ver != 0 )
{
mbedtls_mutex_free( &ctx->mutex );
ctx->ver = 0;
}
#endif
}
......
......@@ -155,35 +155,40 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
const unsigned char data[64] )
{
uint32_t temp, W[16], A, B, C, D, E;
struct
{
uint32_t temp, W[16], A, B, C, D, E;
} local;
SHA1_VALIDATE_RET( ctx != NULL );
SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
GET_UINT32_BE( W[ 0], data, 0 );
GET_UINT32_BE( W[ 1], data, 4 );
GET_UINT32_BE( W[ 2], data, 8 );
GET_UINT32_BE( W[ 3], data, 12 );
GET_UINT32_BE( W[ 4], data, 16 );
GET_UINT32_BE( W[ 5], data, 20 );
GET_UINT32_BE( W[ 6], data, 24 );
GET_UINT32_BE( W[ 7], data, 28 );
GET_UINT32_BE( W[ 8], data, 32 );
GET_UINT32_BE( W[ 9], data, 36 );
GET_UINT32_BE( W[10], data, 40 );
GET_UINT32_BE( W[11], data, 44 );
GET_UINT32_BE( W[12], data, 48 );
GET_UINT32_BE( W[13], data, 52 );
GET_UINT32_BE( W[14], data, 56 );
GET_UINT32_BE( W[15], data, 60 );
GET_UINT32_BE( local.W[ 0], data, 0 );
GET_UINT32_BE( local.W[ 1], data, 4 );
GET_UINT32_BE( local.W[ 2], data, 8 );
GET_UINT32_BE( local.W[ 3], data, 12 );
GET_UINT32_BE( local.W[ 4], data, 16 );
GET_UINT32_BE( local.W[ 5], data, 20 );
GET_UINT32_BE( local.W[ 6], data, 24 );
GET_UINT32_BE( local.W[ 7], data, 28 );
GET_UINT32_BE( local.W[ 8], data, 32 );
GET_UINT32_BE( local.W[ 9], data, 36 );
GET_UINT32_BE( local.W[10], data, 40 );
GET_UINT32_BE( local.W[11], data, 44 );
GET_UINT32_BE( local.W[12], data, 48 );
GET_UINT32_BE( local.W[13], data, 52 );
GET_UINT32_BE( local.W[14], data, 56 );
GET_UINT32_BE( local.W[15], data, 60 );
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
#define R(t) \
( \
temp = W[( (t) - 3 ) & 0x0F] ^ W[( (t) - 8 ) & 0x0F] ^ \
W[( (t) - 14 ) & 0x0F] ^ W[ (t) & 0x0F], \
( W[(t) & 0x0F] = S(temp,1) ) \
local.temp = local.W[( (t) - 3 ) & 0x0F] ^ \
local.W[( (t) - 8 ) & 0x0F] ^ \
local.W[( (t) - 14 ) & 0x0F] ^ \
local.W[ (t) & 0x0F], \
( local.W[(t) & 0x0F] = S(local.temp,1) ) \
)
#define P(a,b,c,d,e,x) \
......@@ -193,35 +198,35 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
(b) = S((b),30); \
} while( 0 )
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
local.A = ctx->state[0];
local.B = ctx->state[1];
local.C = ctx->state[2];
local.D = ctx->state[3];
local.E = ctx->state[4];
#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define K 0x5A827999
P( A, B, C, D, E, W[0] );
P( E, A, B, C, D, W[1] );
P( D, E, A, B, C, W[2] );
P( C, D, E, A, B, W[3] );
P( B, C, D, E, A, W[4] );
P( A, B, C, D, E, W[5] );
P( E, A, B, C, D, W[6] );
P( D, E, A, B, C, W[7] );
P( C, D, E, A, B, W[8] );
P( B, C, D, E, A, W[9] );
P( A, B, C, D, E, W[10] );
P( E, A, B, C, D, W[11] );
P( D, E, A, B, C, W[12] );
P( C, D, E, A, B, W[13] );
P( B, C, D, E, A, W[14] );
P( A, B, C, D, E, W[15] );
P( E, A, B, C, D, R(16) );
P( D, E, A, B, C, R(17) );
P( C, D, E, A, B, R(18) );
P( B, C, D, E, A, R(19) );
P( local.A, local.B, local.C, local.D, local.E, local.W[0] );
P( local.E, local.A, local.B, local.C, local.D, local.W[1] );
P( local.D, local.E, local.A, local.B, local.C, local.W[2] );
P( local.C, local.D, local.E, local.A, local.B, local.W[3] );
P( local.B, local.C, local.D, local.E, local.A, local.W[4] );
P( local.A, local.B, local.C, local.D, local.E, local.W[5] );
P( local.E, local.A, local.B, local.C, local.D, local.W[6] );
P( local.D, local.E, local.A, local.B, local.C, local.W[7] );
P( local.C, local.D, local.E, local.A, local.B, local.W[8] );
P( local.B, local.C, local.D, local.E, local.A, local.W[9] );
P( local.A, local.B, local.C, local.D, local.E, local.W[10] );
P( local.E, local.A, local.B, local.C, local.D, local.W[11] );
P( local.D, local.E, local.A, local.B, local.C, local.W[12] );
P( local.C, local.D, local.E, local.A, local.B, local.W[13] );
P( local.B, local.C, local.D, local.E, local.A, local.W[14] );
P( local.A, local.B, local.C, local.D, local.E, local.W[15] );
P( local.E, local.A, local.B, local.C, local.D, R(16) );
P( local.D, local.E, local.A, local.B, local.C, R(17) );
P( local.C, local.D, local.E, local.A, local.B, R(18) );
P( local.B, local.C, local.D, local.E, local.A, R(19) );
#undef K
#undef F
......@@ -229,26 +234,26 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
#define F(x,y,z) ((x) ^ (y) ^ (z))
#define K 0x6ED9EBA1
P( A, B, C, D, E, R(20) );
P( E, A, B, C, D, R(21) );
P( D, E, A, B, C, R(22) );
P( C, D, E, A, B, R(23) );
P( B, C, D, E, A, R(24) );
P( A, B, C, D, E, R(25) );
P( E, A, B, C, D, R(26) );
P( D, E, A, B, C, R(27) );
P( C, D, E, A, B, R(28) );
P( B, C, D, E, A, R(29) );
P( A, B, C, D, E, R(30) );
P( E, A, B, C, D, R(31) );
P( D, E, A, B, C, R(32) );
P( C, D, E, A, B, R(33) );
P( B, C, D, E, A, R(34) );
P( A, B, C, D, E, R(35) );
P( E, A, B, C, D, R(36) );
P( D, E, A, B, C, R(37) );
P( C, D, E, A, B, R(38) );
P( B, C, D, E, A, R(39) );
P( local.A, local.B, local.C, local.D, local.E, R(20) );
P( local.E, local.A, local.B, local.C, local.D, R(21) );
P( local.D, local.E, local.A, local.B, local.C, R(22) );
P( local.C, local.D, local.E, local.A, local.B, R(23) );
P( local.B, local.C, local.D, local.E, local.A, R(24) );
P( local.A, local.B, local.C, local.D, local.E, R(25) );
P( local.E, local.A, local.B, local.C, local.D, R(26) );
P( local.D, local.E, local.A, local.B, local.C, R(27) );
P( local.C, local.D, local.E, local.A, local.B, R(28) );
P( local.B, local.C, local.D, local.E, local.A, R(29) );
P( local.A, local.B, local.C, local.D, local.E, R(30) );
P( local.E, local.A, local.B, local.C, local.D, R(31) );
P( local.D, local.E, local.A, local.B, local.C, R(32) );
P( local.C, local.D, local.E, local.A, local.B, R(33) );
P( local.B, local.C, local.D, local.E, local.A, R(34) );
P( local.A, local.B, local.C, local.D, local.E, R(35) );
P( local.E, local.A, local.B, local.C, local.D, R(36) );
P( local.D, local.E, local.A, local.B, local.C, R(37) );
P( local.C, local.D, local.E, local.A, local.B, R(38) );
P( local.B, local.C, local.D, local.E, local.A, R(39) );
#undef K
#undef F
......@@ -256,26 +261,26 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
#define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R(40) );
P( E, A, B, C, D, R(41) );
P( D, E, A, B, C, R(42) );
P( C, D, E, A, B, R(43) );
P( B, C, D, E, A, R(44) );
P( A, B, C, D, E, R(45) );
P( E, A, B, C, D, R(46) );
P( D, E, A, B, C, R(47) );
P( C, D, E, A, B, R(48) );
P( B, C, D, E, A, R(49) );
P( A, B, C, D, E, R(50) );
P( E, A, B, C, D, R(51) );
P( D, E, A, B, C, R(52) );
P( C, D, E, A, B, R(53) );
P( B, C, D, E, A, R(54) );
P( A, B, C, D, E, R(55) );
P( E, A, B, C, D, R(56) );
P( D, E, A, B, C, R(57) );
P( C, D, E, A, B, R(58) );
P( B, C, D, E, A, R(59) );
P( local.A, local.B, local.C, local.D, local.E, R(40) );
P( local.E, local.A, local.B, local.C, local.D, R(41) );
P( local.D, local.E, local.A, local.B, local.C, R(42) );
P( local.C, local.D, local.E, local.A, local.B, R(43) );
P( local.B, local.C, local.D, local.E, local.A, R(44) );
P( local.A, local.B, local.C, local.D, local.E, R(45) );
P( local.E, local.A, local.B, local.C, local.D, R(46) );
P( local.D, local.E, local.A, local.B, local.C, R(47) );
P( local.C, local.D, local.E, local.A, local.B, R(48) );
P( local.B, local.C, local.D, local.E, local.A, R(49) );
P( local.A, local.B, local.C, local.D, local.E, R(50) );
P( local.E, local.A, local.B, local.C, local.D, R(51) );
P( local.D, local.E, local.A, local.B, local.C, R(52) );
P( local.C, local.D, local.E, local.A, local.B, R(53) );
P( local.B, local.C, local.D, local.E, local.A, R(54) );
P( local.A, local.B, local.C, local.D, local.E, R(55) );
P( local.E, local.A, local.B, local.C, local.D, R(56) );
P( local.D, local.E, local.A, local.B, local.C, R(57) );
P( local.C, local.D, local.E, local.A, local.B, R(58) );
P( local.B, local.C, local.D, local.E, local.A, R(59) );
#undef K
#undef F
......@@ -283,35 +288,38 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
#define F(x,y,z) ((x) ^ (y) ^ (z))
#define K 0xCA62C1D6
P( A, B, C, D, E, R(60) );
P( E, A, B, C, D, R(61) );
P( D, E, A, B, C, R(62) );
P( C, D, E, A, B, R(63) );
P( B, C, D, E, A, R(64) );
P( A, B, C, D, E, R(65) );
P( E, A, B, C, D, R(66) );
P( D, E, A, B, C, R(67) );
P( C, D, E, A, B, R(68) );
P( B, C, D, E, A, R(69) );
P( A, B, C, D, E, R(70) );
P( E, A, B, C, D, R(71) );
P( D, E, A, B, C, R(72) );
P( C, D, E, A, B, R(73) );
P( B, C, D, E, A, R(74) );
P( A, B, C, D, E, R(75) );
P( E, A, B, C, D, R(76) );
P( D, E, A, B, C, R(77) );
P( C, D, E, A, B, R(78) );
P( B, C, D, E, A, R(79) );
P( local.A, local.B, local.C, local.D, local.E, R(60) );
P( local.E, local.A, local.B, local.C, local.D, R(61) );
P( local.D, local.E, local.A, local.B, local.C, R(62) );
P( local.C, local.D, local.E, local.A, local.B, R(63) );
P( local.B, local.C, local.D, local.E, local.A, R(64) );
P( local.A, local.B, local.C, local.D, local.E, R(65) );
P( local.E, local.A, local.B, local.C, local.D, R(66) );
P( local.D, local.E, local.A, local.B, local.C, R(67) );
P( local.C, local.D, local.E, local.A, local.B, R(68) );
P( local.B, local.C, local.D, local.E, local.A, R(69) );
P( local.A, local.B, local.C, local.D, local.E, R(70) );
P( local.E, local.A, local.B, local.C, local.D, R(71) );
P( local.D, local.E, local.A, local.B, local.C, R(72) );
P( local.C, local.D, local.E, local.A, local.B, R(73) );
P( local.B, local.C, local.D, local.E, local.A, R(74) );
P( local.A, local.B, local.C, local.D, local.E, R(75) );
P( local.E, local.A, local.B, local.C, local.D, R(76) );
P( local.D, local.E, local.A, local.B, local.C, R(77) );
P( local.C, local.D, local.E, local.A, local.B, R(78) );
P( local.B, local.C, local.D, local.E, local.A, R(79) );
#undef K
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
ctx->state[0] += local.A;
ctx->state[1] += local.B;
ctx->state[2] += local.C;
ctx->state[3] += local.D;
ctx->state[4] += local.E;
/* Zeroise buffers and variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
......
......@@ -209,77 +209,104 @@ static const uint32_t K[] =
#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define R(t) \
( \
W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
S0(W[(t) - 15]) + W[(t) - 16] \
#define R(t) \
( \
local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
S0(local.W[(t) - 15]) + local.W[(t) - 16] \
)
#define P(a,b,c,d,e,f,g,h,x,K) \
do \
{ \
temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
temp2 = S2(a) + F0((a),(b),(c)); \
(d) += temp1; (h) = temp1 + temp2; \
#define P(a,b,c,d,e,f,g,h,x,K) \
do \
{ \
local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
local.temp2 = S2(a) + F0((a),(b),(c)); \
(d) += local.temp1; (h) = local.temp1 + local.temp2; \
} while( 0 )
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
const unsigned char data[64] )
{
uint32_t temp1, temp2, W[64];
uint32_t A[8];
struct
{
uint32_t temp1, temp2, W[64];
uint32_t A[8];
} local;
unsigned int i;
SHA256_VALIDATE_RET( ctx != NULL );
SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
for( i = 0; i < 8; i++ )
A[i] = ctx->state[i];
local.A[i] = ctx->state[i];
#if defined(MBEDTLS_SHA256_SMALLER)
for( i = 0; i < 64; i++ )
{
if( i < 16 )
GET_UINT32_BE( W[i], data, 4 * i );
GET_UINT32_BE( local.W[i], data, 4 * i );
else
R( i );
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
local.temp1 = local.A[7]; local.A[7] = local.A[6];
local.A[6] = local.A[5]; local.A[5] = local.A[4];
local.A[4] = local.A[3]; local.A[3] = local.A[2];
local.A[2] = local.A[1]; local.A[1] = local.A[0];
local.A[0] = local.temp1;
}
#else /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 16; i++ )
GET_UINT32_BE( W[i], data, 4 * i );
GET_UINT32_BE( local.W[i], data, 4 * i );
for( i = 0; i < 16; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7] );
}
for( i = 16; i < 64; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
}
#endif /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 8; i++ )
ctx->state[i] += A[i];
ctx->state[i] += local.A[i];
/* Zeroise buffers and variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
......
......@@ -243,8 +243,11 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
const unsigned char data[128] )
{
int i;
uint64_t temp1, temp2, W[80];
uint64_t A, B, C, D, E, F, G, H;
struct
{
uint64_t temp1, temp2, W[80];
uint64_t A, B, C, D, E, F, G, H;
} local;
SHA512_VALIDATE_RET( ctx != NULL );
SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
......@@ -261,56 +264,67 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define P(a,b,c,d,e,f,g,h,x,K) \
do \
{ \
temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
temp2 = S2(a) + F0((a),(b),(c)); \
(d) += temp1; (h) = temp1 + temp2; \
#define P(a,b,c,d,e,f,g,h,x,K) \
do \
{ \
local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
local.temp2 = S2(a) + F0((a),(b),(c)); \
(d) += local.temp1; (h) = local.temp1 + local.temp2; \
} while( 0 )
for( i = 0; i < 16; i++ )
{
GET_UINT64_BE( W[i], data, i << 3 );
GET_UINT64_BE( local.W[i], data, i << 3 );
}
for( ; i < 80; i++ )
{
W[i] = S1(W[i - 2]) + W[i - 7] +
S0(W[i - 15]) + W[i - 16];
local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
S0(local.W[i - 15]) + local.W[i - 16];
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
F = ctx->state[5];
G = ctx->state[6];
H = ctx->state[7];
local.A = ctx->state[0];
local.B = ctx->state[1];
local.C = ctx->state[2];
local.D = ctx->state[3];
local.E = ctx->state[4];
local.F = ctx->state[5];
local.G = ctx->state[6];
local.H = ctx->state[7];
i = 0;
do
{
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
P( local.A, local.B, local.C, local.D, local.E,
local.F, local.G, local.H, local.W[i], K[i] ); i++;
P( local.H, local.A, local.B, local.C, local.D,
local.E, local.F, local.G, local.W[i], K[i] ); i++;
P( local.G, local.H, local.A, local.B, local.C,
local.D, local.E, local.F, local.W[i], K[i] ); i++;
P( local.F, local.G, local.H, local.A, local.B,
local.C, local.D, local.E, local.W[i], K[i] ); i++;
P( local.E, local.F, local.G, local.H, local.A,
local.B, local.C, local.D, local.W[i], K[i] ); i++;
P( local.D, local.E, local.F, local.G, local.H,
local.A, local.B, local.C, local.W[i], K[i] ); i++;
P( local.C, local.D, local.E, local.F, local.G,
local.H, local.A, local.B, local.W[i], K[i] ); i++;
P( local.B, local.C, local.D, local.E, local.F,
local.G, local.H, local.A, local.W[i], K[i] ); i++;
}
while( i < 80 );
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
ctx->state[5] += F;
ctx->state[6] += G;
ctx->state[7] += H;
ctx->state[0] += local.A;
ctx->state[1] += local.B;
ctx->state[2] += local.C;
ctx->state[3] += local.D;
ctx->state[4] += local.E;
ctx->state[5] += local.F;
ctx->state[6] += local.G;
ctx->state[7] += local.H;
/* Zeroise buffers and variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
......
......@@ -3587,11 +3587,12 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
/* In case of a failure in decryption, the decryption may write less than
* 2 bytes of output, but we always read the first two bytes. It doesn't
* matter in the end because diff will be nonzero in that case due to
* peer_pmslen being less than 48, and we only care whether diff is 0.
* But do initialize peer_pms for robustness anyway. This also makes
* memory analyzers happy (don't access uninitialized memory, even
* if it's an unsigned char). */
* ret being nonzero, and we only care whether diff is 0.
* But do initialize peer_pms and peer_pmslen for robustness anyway. This
* also makes memory analyzers happy (don't access uninitialized memory,
* even if it's an unsigned char). */
peer_pms[0] = peer_pms[1] = ~0;
peer_pmslen = 0;
ret = ssl_decrypt_encrypted_pms( ssl, p, end,
peer_pms,
......
......@@ -621,7 +621,7 @@ static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int )
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * );
static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *, unsigned char * );
static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
#endif
......@@ -1142,7 +1142,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash )
{
mbedtls_md5_context md5;
mbedtls_sha1_context sha1;
......@@ -1191,7 +1191,7 @@ void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash )
{
mbedtls_md5_context md5;
mbedtls_sha1_context sha1;
......@@ -1219,7 +1219,7 @@ void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] )
void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *hash )
{
mbedtls_sha256_context sha256;
......@@ -1240,7 +1240,7 @@ void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] )
void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *hash )
{
mbedtls_sha512_context sha512;
......@@ -6363,6 +6363,9 @@ static void ssl_calc_finished_tls_sha256(
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
typedef int (*finish_sha384_t)(mbedtls_sha512_context*, unsigned char*);
static void ssl_calc_finished_tls_sha384(
mbedtls_ssl_context *ssl, unsigned char *buf, int from )
{
......@@ -6370,6 +6373,12 @@ static void ssl_calc_finished_tls_sha384(
const char *sender;
mbedtls_sha512_context sha512;
unsigned char padbuf[48];
/*
* For SHA-384, we can save 16 bytes by keeping padbuf 48 bytes long.
* However, to avoid stringop-overflow warning in gcc, we have to cast
* mbedtls_sha512_finish_ret().
*/
finish_sha384_t finish_sha384 = (finish_sha384_t)mbedtls_sha512_finish_ret;
mbedtls_ssl_session *session = ssl->session_negotiate;
if( !session )
......@@ -6396,7 +6405,7 @@ static void ssl_calc_finished_tls_sha384(
? "client finished"
: "server finished";
mbedtls_sha512_finish_ret( &sha512, padbuf );
finish_sha384( &sha512, padbuf );
ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 48, buf, len );
......
......@@ -73,7 +73,7 @@
#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
_POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) )
/*
* This is a convenience shorthand macro to avoid checking the long
* preprocessor conditions above. Ideally, we could expose this macro in
......@@ -88,7 +88,7 @@
#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
_POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */
#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
......@@ -98,6 +98,12 @@ static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
if( mutex == NULL )
return;
/* A nonzero value of is_valid indicates a successfully initialized
* mutex. This is a workaround for not being able to return an error
* code for this function. The lock/unlock functions return an error
* if is_valid is nonzero. The Mbed TLS unit test code uses this field
* to distinguish more states of the mutex; see helpers.function for
* details. */
mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
}
......
......@@ -553,6 +553,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
"MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
#if defined(MBEDTLS_TEST_HOOKS)
"MBEDTLS_TEST_HOOKS",
#endif /* MBEDTLS_TEST_HOOKS */
#if defined(MBEDTLS_THREADING_ALT)
"MBEDTLS_THREADING_ALT",
#endif /* MBEDTLS_THREADING_ALT */
......
......@@ -1088,6 +1088,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( crt->sig_oid.len != sig_oid2.len ||
memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
sig_params1.tag != sig_params2.tag ||
sig_params1.len != sig_params2.len ||
( sig_params1.len != 0 &&
memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
......
......@@ -37,8 +37,8 @@ target_link_libraries(mini_client ${libs})
add_executable(ssl_client1 ssl_client1.c)
target_link_libraries(ssl_client1 ${libs})
add_executable(ssl_client2 ssl_client2.c)
target_sources(ssl_client2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
add_executable(ssl_client2 ssl_client2.c
${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
target_link_libraries(ssl_client2 ${libs})
add_executable(ssl_fork_server ssl_fork_server.c)
......@@ -50,8 +50,8 @@ target_link_libraries(ssl_mail_client ${libs})
add_executable(ssl_server ssl_server.c)
target_link_libraries(ssl_server ${libs})
add_executable(ssl_server2 ssl_server2.c)
target_sources(ssl_server2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
add_executable(ssl_server2 ssl_server2.c
${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
target_link_libraries(ssl_server2 ${libs})
if(THREADS_FOUND)
......
......@@ -1475,6 +1475,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
#if defined(MBEDTLS_TEST_HOOKS)
if( strcmp( "MBEDTLS_TEST_HOOKS", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_TEST_HOOKS );
return( 0 );
}
#endif /* MBEDTLS_TEST_HOOKS */
#if defined(MBEDTLS_THREADING_ALT)
if( strcmp( "MBEDTLS_THREADING_ALT", config ) == 0 )
{
......
......@@ -27,8 +27,8 @@ target_link_libraries(udp_proxy ${libs})
add_executable(zeroize zeroize.c)
target_link_libraries(zeroize ${libs})
add_executable(query_compile_time_config query_compile_time_config.c)
target_sources(query_compile_time_config PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../ssl/query_config.c)
add_executable(query_compile_time_config query_compile_time_config.c
${CMAKE_CURRENT_SOURCE_DIR}/../ssl/query_config.c)
target_link_libraries(query_compile_time_config ${libs})
install(TARGETS selftest benchmark udp_proxy query_compile_time_config
......
......@@ -185,7 +185,7 @@ static int calloc_self_test( int verbose )
}
#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, int ref_ret )
{
int ret;
char buf[10] = "xxxxxxxxx";
......
......@@ -127,9 +127,8 @@ int main( void )
" Add NsCertType even if it is empty\n" \
" md=%%s default: SHA256\n" \
" possible values:\n" \
" MD2, MD4, MD5, SHA1\n" \
" SHA224, SHA256\n" \
" SHA384, SHA512\n" \
" MD2, MD4, MD5, RIPEMD160, SHA1,\n" \
" SHA224, SHA256, SHA384, SHA512\n" \
"\n"
......@@ -244,58 +243,14 @@ int main( int argc, char *argv[] )
}
else if( strcmp( p, "md" ) == 0 )
{
if( strcmp( q, "SHA256" ) == 0 )
{
opt.md_alg = MBEDTLS_MD_SHA256;
}
else if( strcmp( q, "SHA224" ) == 0 )
{
opt.md_alg = MBEDTLS_MD_SHA224;
}
else
#if defined(MBEDTLS_MD5_C)
if( strcmp( q, "MD5" ) == 0 )
{
opt.md_alg = MBEDTLS_MD_MD5;
}
else
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_MD4_C)
if( strcmp( q, "MD4" ) == 0 )
{
opt.md_alg = MBEDTLS_MD_MD4;
}
else
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_MD2_C)
if( strcmp( q, "MD2" ) == 0 )
{
opt.md_alg = MBEDTLS_MD_MD2;
}
else
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_SHA1_C)
if( strcmp( q, "SHA1" ) == 0 )
{
opt.md_alg = MBEDTLS_MD_SHA1;
}
else
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA512_C)
if( strcmp( q, "SHA384" ) == 0 )
{
opt.md_alg = MBEDTLS_MD_SHA384;
}
else
if( strcmp( q, "SHA512" ) == 0 )
{
opt.md_alg = MBEDTLS_MD_SHA512;
}
else
#endif /* MBEDTLS_SHA512_C */
const mbedtls_md_info_t *md_info =
mbedtls_md_info_from_string( q );
if( md_info == NULL )
{
mbedtls_printf( "Invalid argument for option %s\n", p );
goto usage;
}
opt.md_alg = mbedtls_md_get_type( md_info );
}
else if( strcmp( p, "key_usage" ) == 0 )
{
......
......@@ -145,8 +145,9 @@ int main( void )
" is_ca=%%d default: 0 (disabled)\n" \
" max_pathlen=%%d default: -1 (none)\n" \
" md=%%s default: SHA256\n" \
" Supported values:\n" \
" MD2, MD4, MD5, SHA1, SHA256, SHA512\n"\
" Supported values (if enabled):\n" \
" MD2, MD4, MD5, RIPEMD160, SHA1,\n" \
" SHA224, SHA256, SHA384, SHA512\n" \
" version=%%d default: 3\n" \
" Possible values: 1, 2, 3\n"\
" subject_identifier=%%s default: 1\n" \
......@@ -380,23 +381,14 @@ int main( int argc, char *argv[] )
}
else if( strcmp( p, "md" ) == 0 )
{
if( strcmp( q, "SHA1" ) == 0 )
opt.md = MBEDTLS_MD_SHA1;
else if( strcmp( q, "SHA256" ) == 0 )
opt.md = MBEDTLS_MD_SHA256;
else if( strcmp( q, "SHA512" ) == 0 )
opt.md = MBEDTLS_MD_SHA512;
else if( strcmp( q, "MD2" ) == 0 )
opt.md = MBEDTLS_MD_MD2;
else if( strcmp( q, "MD4" ) == 0 )
opt.md = MBEDTLS_MD_MD4;
else if( strcmp( q, "MD5" ) == 0 )
opt.md = MBEDTLS_MD_MD5;
else
const mbedtls_md_info_t *md_info =
mbedtls_md_info_from_string( q );
if( md_info == NULL )
{
mbedtls_printf( "Invalid argument for option %s\n", p );
goto usage;
}
opt.md = mbedtls_md_get_type( md_info );
}
else if( strcmp( p, "version" ) == 0 )
{
......
......@@ -51,20 +51,19 @@
#endif
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
#include "mbedtls/error.h"
#include <string.h>
#endif
#if defined(MBEDTLS_ERROR_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_snprintf snprintf
#define mbedtls_time_t time_t
#endif
#if defined(MBEDTLS_ERROR_C)
#include <stdio.h>
#include <string.h>
HEADER_INCLUDED
......@@ -130,8 +129,6 @@ LOW_LEVEL_CODE_CHECKS
#else /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
/*
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
*/
......@@ -143,6 +140,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
buf[0] = '\0';
}
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
#endif /* MBEDTLS_ERROR_C */
#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
......@@ -117,12 +117,12 @@ PEERS="OpenSSL$PEER_GNUTLS mbedTLS"
print_usage() {
echo "Usage: $0"
printf " -h|--help\tPrint this help.\n"
printf " -f|--filter\tOnly matching ciphersuites are tested (Default: '$FILTER')\n"
printf " -e|--exclude\tMatching ciphersuites are excluded (Default: '$EXCLUDE')\n"
printf " -m|--modes\tWhich modes to perform (Default: '$MODES')\n"
printf " -t|--types\tWhich key exchange type to perform (Default: '$TYPES')\n"
printf " -V|--verify\tWhich verification modes to perform (Default: '$VERIFIES')\n"
printf " -p|--peers\tWhich peers to use (Default: '$PEERS')\n"
printf " -f|--filter\tOnly matching ciphersuites are tested (Default: '%s')\n" "$FILTER"
printf " -e|--exclude\tMatching ciphersuites are excluded (Default: '%s')\n" "$EXCLUDE"
printf " -m|--modes\tWhich modes to perform (Default: '%s')\n" "$MODES"
printf " -t|--types\tWhich key exchange type to perform (Default: '%s')\n" "$TYPES"
printf " -V|--verify\tWhich verification modes to perform (Default: '%s')\n" "$VERIFIES"
printf " -p|--peers\tWhich peers to use (Default: '%s')\n" "$PEERS"
printf " \tAlso available: GnuTLS (needs v3.2.15 or higher)\n"
printf " -M|--memcheck\tCheck memory leaks and errors.\n"
printf " -v|--verbose\tSet verbose output.\n"
......@@ -1134,7 +1134,7 @@ run_client() {
VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
TITLE="`echo $1 | head -c1`->`echo $SERVER_NAME | head -c1`"
TITLE="$TITLE $MODE,$VERIF $2"
printf "$TITLE "
printf "%s " "$TITLE"
LEN=$(( 72 - `echo "$TITLE" | wc -c` ))
for i in `seq 1 $LEN`; do printf '.'; done; printf ' '
......
......@@ -13,8 +13,10 @@
## Tools
OPENSSL ?= openssl
FAKETIME ?= faketime
MBEDTLS_CERT_WRITE ?= $(PWD)/../../programs/x509/cert_write
MBEDTLS_CERT_REQ ?= $(PWD)/../../programs/x509/cert_req
TOP_DIR = ../..
MBEDTLS_CERT_WRITE ?= $(TOP_DIR)/programs/x509/cert_write
MBEDTLS_CERT_REQ ?= $(TOP_DIR)/programs/x509/cert_req
## Build the generated test data. Note that since the final outputs
## are committed to the repository, this target should do nothing on a
......@@ -155,7 +157,11 @@ cli-rsa-sha256.crt.der: cli-rsa-sha256.crt
$(OPENSSL) x509 -in $< -out $@ -inform PEM -outform DER
all_final += cli-rsa-sha256.crt.der
cli-rsa.key.der: $(cli_crt_key_file_rsa)
cli-rsa-sha256-badalg.crt.der: cli-rsa-sha256.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/06092A864886F70D01010B0500/06092A864886F70D01010B0900/2" | xxd -r -p > $@
all_final += cli-rsa-sha256-badalg.crt.der
cli-rsa.key.der: $(cli_crt_key_file_rsa)
$(OPENSSL) pkey -in $< -out $@ -inform PEM -outform DER
all_final += cli-rsa.key.der
......
-----BEGIN CERTIFICATE REQUEST-----
MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1EMjCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
+CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBAgUA
A4IBAQBPUqodRcH2ZUa8A3fQX/nxrIwWiLmQ9BaOI6G7vzEWVE1sxmkrHP+pXgi9
1eFceN9xUBKEd+LmUPmHpObZ4nwRSprFj3DeIXpn9aSBr+jGY8RaaC9cMkaSq5Mb
q65THEJ1xemIfZvbhjvNi/ycXXu/v1Gpj62dpIFGbm+o4AXQF2ocYGEM+X1u2eVn
mnuuvPAHTllGjB0daTSYoQtMy3luPUEj0Yct3iVR1pUeTrHchOs9p5ACDZcf6D3x
sm9atH2ZIaXo1c9SqHzdk/uLt/CwxQrn1WU1inwOkzjim2Yq9vWgpQypfGZdScXV
oHOmuGG901WMMemzZXjoLi+8ZpVL
-----END CERTIFICATE REQUEST-----
-----BEGIN CERTIFICATE REQUEST-----
MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1ENDCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
+CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBAwUA
A4IBAQAztRb+vAecvhelhszzCctzmhGs4TGmr9h4zddZoQ8dTdy1OCsnmU+yz3oh
oiQjy7UPLt8DS2ZKhGhvwPvtwFh5icMWQVnv2kE4Evz8xJT12VRw+U6L5rfKmf/L
mVNxsuk17MDyBcMlwuNk+CHrYVdrXhSWUH3UCQQUH1iqqBMKmNiPa1UGU0budZ9X
HZjn9uqyyOGy8l3hffqjDxsDjZyBDf5aqKIdnvukdrUiacPdUYVF0fwK8d1/1PA9
dA4JjTvz+tTK6mL9Ic9Pv+64v1vwMU4Qu8IJHk5x3I0e7KuK2A/lK6az2Vb6FAh6
MkGpWB68T8FRBoVrWLOh+a9yNwyp
-----END CERTIFICATE REQUEST-----
......@@ -3,18 +3,18 @@ MIIDPzCCAiegAwIBAgIBBjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENlcnQgTUQ1MIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAf
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f
M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu
1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw
MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v
4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/
/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB
o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf
BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQQFAAOC
AQEAPO/yXYVCQfm1gRzYoPP4T8Dd7jfpS0Yz5hAWMDi73aXufk9ltGdXauQxA4Pu
NQLWBMFMtJyO2OUb0p+oPGCxQayLx1sIjS9Gfy70xHlL3jnZy4kLXtkiARz8ZptW
krxzQh017mXIn8W2VGYWA1gCNrg/Xb3VtlxVCzPa2zGCkIJHKe/dqNtKY3xx/SEQ
gsVvdT8lpI8HfeElBfWvFxGps77pvE2HDcAdrIkjrsBWoSIq6CqIQjyW7WSN7UgI
bTczqejHkrggI8yWIIoDAiUX9OGT76Mv4wpmOPww8hqoVfpvvPQ2l6byVNJYPj/L
oiUV6sDYenOgMJ3Tf7UzTR91MA==
AQEANsxVCbbev5mngG0+PvQ4y/s0jNjz6i+tn4fTOtMNBOC77clNju65vlHWqD9Y
rZP6wqGSzdYbOoojCq0l65T6os1CFcaygIpUSFF57MbfTiiwZaLF93qf9Jf+VHln
CQA/tQolZJDjef8LXAYK68GVVxenZI9ITnMIg6Qd9vpHqK44a6xWU226pG7g+6ae
97dhpLsYMxggv6t/ATFt7KiIXC4cOQBzQobRfsRcxWlaOxlFEXeCFoonQaHHaU9c
KqLO1sqygLIhP7ZA2qmfodVLc5B3WxrogaupPCbpKNdieR43HvGZ+3ig/gLjyLg1
L8qiSesxaHvjtkW9N7sjPxRS8Q==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE REQUEST-----
MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1ENTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
+CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBBAUA
A4IBAQBNEvxgn3Pc62hsMgMz33IdeNpazeK3ae2gwQQFgL7qMp/kskfpIKF4m8eB
YrmjKn9cqszRD606/ZtWYDwINUUc6O7bQGmpGIFd7bSPm/pbsajc6R7kzA/tD/bk
G5zqu9Bj0x92hEwdku0zY+Hx9PgT2dK8M72iFylHBwT3X1tNyXhh7xWJ9RlAfSvN
KdS6s3kRjK4qcir0MnflV5f2HD6r1v9cSVyme6eVLvOmup89z0cihH7NDwDJaYbi
oqcKXFbro8/2ruEzPUS6U8NA9cjlX9DW8buIu4cQACVx5YevlwKoayYfXcRRvIFo
OLiPq14TuZj3c0+HFOxWj4UBAjvI
-----END CERTIFICATE REQUEST-----
......@@ -185,6 +185,9 @@ pre_initialize_variables () {
export MAKEFLAGS="-j"
fi
# Include more verbose output for failing tests run by CMake
export CTEST_OUTPUT_ON_FAILURE=1
# CFLAGS and LDFLAGS for Asan builds that don't use CMake
ASAN_CFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all'
......@@ -887,11 +890,21 @@ component_test_no_hmac_drbg () {
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
msg "test: no HMAC_DRBG"
msg "test: Full minus HMAC_DRBG - main suites"
make test
# No ssl-opt.sh/compat.sh as they never use HMAC_DRBG so far,
# so there's little value in running those lengthy tests here.
# Normally our ECDSA implementation uses deterministic ECDSA. But since
# HMAC_DRBG is disabled in this configuration, randomized ECDSA is used
# instead.
# Test SSL with non-deterministic ECDSA. Only test features that
# might be affected by how ECDSA signature is performed.
msg "test: Full minus HMAC_DRBG - ssl-opt.sh (subset)"
if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
# To save time, only test one protocol version, since this part of
# the protocol is identical in (D)TLS up to 1.2.
msg "test: Full minus HMAC_DRBG - compat.sh (ECDSA)"
if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA'
}
component_test_no_drbg_all_hashes () {
......@@ -1311,7 +1324,7 @@ 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'
make CC=gcc CFLAGS="'-DMBEDTLS_CONFIG_FILE=\"$PWD/tests/configs/config-wrapper-malloc-0-null.h\"' -O $ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
msg "test: malloc(0) returns NULL (ASan+UBSan build)"
make test
......@@ -1498,6 +1511,20 @@ component_test_no_64bit_multiplication () {
make test
}
component_test_no_strings () {
msg "build: no strings" # ~10s
scripts/config.pl full
# Disable options that activate a large amount of string constants.
scripts/config.pl unset MBEDTLS_DEBUG_C
scripts/config.pl unset MBEDTLS_ERROR_C
scripts/config.pl set MBEDTLS_ERROR_STRERROR_DUMMY
scripts/config.pl unset MBEDTLS_VERSION_FEATURES
make CFLAGS='-Werror -Os'
msg "test: no strings" # ~ 10s
make test
}
component_build_arm_none_eabi_gcc () {
msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1" # ~ 10s
scripts/config.pl baremetal
......
......@@ -92,7 +92,7 @@ fi
diff macros identifiers | sed -n -e 's/< //p' > actual-macros
for THING in actual-macros enum-consts; do
printf "Names of $THING: "
printf 'Names of %s: ' "$THING"
test -r $THING
BAD=$( grep -v '^MBEDTLS_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
if [ "x$BAD" = "x" ]; then
......@@ -105,7 +105,7 @@ for THING in actual-macros enum-consts; do
done
for THING in identifiers; do
printf "Names of $THING: "
printf 'Names of %s: ' "$THING"
test -r $THING
BAD=$( grep -v '^mbedtls_[0-9a-z_]*[0-9a-z]$' $THING || true )
if [ "x$BAD" = "x" ]; then
......
......@@ -55,15 +55,17 @@ use warnings;
use strict;
my %configs = (
'config-ccm-psk-tls1_2.h' => {
'compat' => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
},
'config-mini-tls1_1.h' => {
'compat' => '-m tls1_1 -f \'^DES-CBC3-SHA$\|^TLS-RSA-WITH-3DES-EDE-CBC-SHA$\'',
},
'config-no-entropy.h' => {
},
'config-suite-b.h' => {
'compat' => "-m tls1_2 -f 'ECDHE-ECDSA.*AES.*GCM' -p mbedTLS",
},
'config-ccm-psk-tls1_2.h' => {
'compat' => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
},
'config-thread.h' => {
'opt' => '-f ECJPAKE.*nolog',
},
......
......@@ -130,8 +130,8 @@ print_usage() {
echo "Usage: $0 [options]"
printf " -h|--help\tPrint this help.\n"
printf " -m|--memcheck\tCheck memory leaks and errors.\n"
printf " -f|--filter\tOnly matching tests are executed (BRE; default: '$FILTER')\n"
printf " -e|--exclude\tMatching tests are excluded (BRE; default: '$EXCLUDE')\n"
printf " -f|--filter\tOnly matching tests are executed (BRE)\n"
printf " -e|--exclude\tMatching tests are excluded (BRE)\n"
printf " -n|--number\tExecute only numbered test (comma-separated, e.g. '245,256')\n"
printf " -s|--show-numbers\tShow test numbers in front of test names\n"
printf " -p|--preserve-logs\tPreserve logs of successful tests as well\n"
......@@ -384,7 +384,7 @@ print_name() {
fi
LINE="$LINE$1"
printf "$LINE "
printf "%s " "$LINE"
LEN=$(( 72 - `echo "$LINE" | wc -c` ))
for i in `seq 1 $LEN`; do printf '.'; done
printf ' '
......@@ -662,12 +662,12 @@ run_test() {
fi
check_osrv_dtls
printf "# $NAME\n$SRV_CMD\n" > $SRV_OUT
printf '# %s\n%s\n' "$NAME" "$SRV_CMD" > $SRV_OUT
provide_input | $SRV_CMD >> $SRV_OUT 2>&1 &
SRV_PID=$!
wait_server_start "$SRV_PORT" "$SRV_PID"
printf "# $NAME\n$CLI_CMD\n" > $CLI_OUT
printf '# %s\n%s\n' "$NAME" "$CLI_CMD" > $CLI_OUT
eval "$CLI_CMD" >> $CLI_OUT 2>&1 &
wait_client_done
......@@ -676,6 +676,7 @@ run_test() {
# terminate the server (and the proxy)
kill $SRV_PID
wait $SRV_PID
SRV_RET=$?
if [ -n "$PXY_CMD" ]; then
kill $PXY_PID >/dev/null 2>&1
......@@ -709,9 +710,11 @@ run_test() {
fi
fi
# check server exit code
if [ $? != 0 ]; then
fail "server fail"
# Check server exit code (only for Mbed TLS: GnuTLS and OpenSSL don't
# exit with status 0 when interrupted by a signal, and we don't really
# care anyway), in case e.g. the server reports a memory leak.
if [ $SRV_RET != 0 ] && is_polar "$SRV_CMD"; then
fail "Server exited with status $SRV_RET"
return
fi
......@@ -1877,12 +1880,12 @@ run_test "Session resume using cache, DTLS: openssl server" \
# Tests for Max Fragment Length extension
if [ "$MAX_CONTENT_LEN" -lt "4096" ]; then
printf "${CONFIG_H} defines MBEDTLS_SSL_MAX_CONTENT_LEN to be less than 4096. Fragment length tests will fail.\n"
printf '%s defines MBEDTLS_SSL_MAX_CONTENT_LEN to be less than 4096. Fragment length tests will fail.\n' "${CONFIG_H}"
exit 1
fi
if [ $MAX_CONTENT_LEN -ne 16384 ]; then
printf "Using non-default maximum content length $MAX_CONTENT_LEN\n"
echo "Using non-default maximum content length $MAX_CONTENT_LEN"
fi
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
......@@ -2823,14 +2826,14 @@ MAX_IM_CA='8'
MAX_IM_CA_CONFIG=$( ../scripts/config.pl get MBEDTLS_X509_MAX_INTERMEDIATE_CA)
if [ -n "$MAX_IM_CA_CONFIG" ] && [ "$MAX_IM_CA_CONFIG" -ne "$MAX_IM_CA" ]; then
printf "The ${CONFIG_H} file contains a value for the configuration of\n"
printf "MBEDTLS_X509_MAX_INTERMEDIATE_CA that is different from the script’s\n"
printf "test value of ${MAX_IM_CA}. \n"
printf "\n"
printf "The tests assume this value and if it changes, the tests in this\n"
printf "script should also be adjusted.\n"
printf "\n"
cat <<EOF
${CONFIG_H} contains a value for the configuration of
MBEDTLS_X509_MAX_INTERMEDIATE_CA that is different from the script's
test value of ${MAX_IM_CA}.
The tests assume this value and if it changes, the tests in this
script should also be adjusted.
EOF
exit 1
fi
......
......@@ -46,6 +46,12 @@ typedef UINT32 uint32_t;
#include <strings.h>
#endif
#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_PTHREAD) && \
defined(MBEDTLS_TEST_HOOKS)
#include "mbedtls/threading.h"
#define MBEDTLS_TEST_MUTEX_USAGE
#endif
/*
* Define the two macros
*
......@@ -154,6 +160,27 @@ typedef enum
} \
} while( 0 )
/** Compare two buffers and fail the test case if they differ.
*
* This macro expands to an instruction, not an expression.
* It may jump to the \c exit label.
*
* \param p1 Pointer to the start of the first buffer.
* \param size1 Size of the first buffer in bytes.
* This expression may be evaluated multiple times.
* \param p2 Pointer to the start of the second buffer.
* \param size2 Size of the second buffer in bytes.
* This expression may be evaluated multiple times.
*/
#define ASSERT_COMPARE( p1, size1, p2, size2 ) \
do \
{ \
TEST_ASSERT( ( size1 ) == ( size2 ) ); \
if( ( size1 ) != 0 ) \
TEST_ASSERT( memcmp( ( p1 ), ( p2 ), ( size1 ) ) == 0 ); \
} \
while( 0 )
/**
* \brief This macro tests the expression passed to it and skips the
* running test if it doesn't evaluate to 'true'.
......@@ -350,6 +377,9 @@ static struct
const char *test;
const char *filename;
int line_no;
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
const char *mutex_usage_error;
#endif
}
test_info;
......@@ -382,6 +412,12 @@ jmp_buf jmp_tmp;
void test_fail( const char *test, int line_no, const char* filename )
{
if( test_info.result == TEST_RESULT_FAILED )
{
/* We've already recorded the test as having failed. Don't
* overwrite any previous information about the failure. */
return;
}
test_info.result = TEST_RESULT_FAILED;
test_info.test = test;
test_info.line_no = line_no;
......@@ -732,7 +768,7 @@ int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
return( 0 );
}
int hexcmp( uint8_t * a, uint8_t * b, uint32_t a_len, uint32_t b_len )
int mbedtls_test_hexcmp( uint8_t * a, uint8_t * b, uint32_t a_len, uint32_t b_len )
{
int ret = 0;
uint32_t i = 0;
......@@ -750,3 +786,202 @@ int hexcmp( uint8_t * a, uint8_t * b, uint32_t a_len, uint32_t b_len )
}
return ret;
}
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
/** Mutex usage verification framework.
*
* The mutex usage verification code below aims to detect bad usage of
* Mbed TLS's mutex abstraction layer at runtime. Note that this is solely
* about the use of the mutex itself, not about checking whether the mutex
* correctly protects whatever it is supposed to protect.
*
* The normal usage of a mutex is:
* ```
* digraph mutex_states {
* "UNINITIALIZED"; // the initial state
* "IDLE";
* "FREED";
* "LOCKED";
* "UNINITIALIZED" -> "IDLE" [label="init"];
* "FREED" -> "IDLE" [label="init"];
* "IDLE" -> "LOCKED" [label="lock"];
* "LOCKED" -> "IDLE" [label="unlock"];
* "IDLE" -> "FREED" [label="free"];
* }
* ```
*
* All bad transitions that can be unambiguously detected are reported.
* An attempt to use an uninitialized mutex cannot be detected in general
* since the memory content may happen to denote a valid state. For the same
* reason, a double init cannot be detected.
* All-bits-zero is the state of a freed mutex, which is distinct from an
* initialized mutex, so attempting to use zero-initialized memory as a mutex
* without calling the init function is detected.
*
* The framework attempts to detect missing calls to init and free by counting
* calls to init and free. If there are more calls to init than free, this
* means that a mutex is not being freed somewhere, which is a memory leak
* on platforms where a mutex consumes resources other than the
* mbedtls_threading_mutex_t object itself. If there are more calls to free
* than init, this indicates a missing init, which is likely to be detected
* by an attempt to lock the mutex as well. A limitation of this framework is
* that it cannot detect scenarios where there is exactly the same number of
* calls to init and free but the calls don't match. A bug like this is
* unlikely to happen uniformly throughout the whole test suite though.
*
* If an error is detected, this framework will report what happened and the
* test case will be marked as failed. Unfortunately, the error report cannot
* indicate the exact location of the problematic call. To locate the error,
* use a debugger and set a breakpoint on mbedtls_test_mutex_usage_error().
*/
enum value_of_mutex_is_valid_field
{
/* Potential values for the is_valid field of mbedtls_threading_mutex_t.
* Note that MUTEX_FREED must be 0 and MUTEX_IDLE must be 1 for
* compatibility with threading_mutex_init_pthread() and
* threading_mutex_free_pthread(). MUTEX_LOCKED could be any nonzero
* value. */
MUTEX_FREED = 0, //!< Set by threading_mutex_free_pthread
MUTEX_IDLE = 1, //!< Set by threading_mutex_init_pthread and by our unlock
MUTEX_LOCKED = 2, //!< Set by our lock
};
typedef struct
{
void (*init)( mbedtls_threading_mutex_t * );
void (*free)( mbedtls_threading_mutex_t * );
int (*lock)( mbedtls_threading_mutex_t * );
int (*unlock)( mbedtls_threading_mutex_t * );
} mutex_functions_t;
static mutex_functions_t mutex_functions;
/** The total number of calls to mbedtls_mutex_init(), minus the total number
* of calls to mbedtls_mutex_free().
*
* Reset to 0 after each test case.
*/
static int live_mutexes;
static void mbedtls_test_mutex_usage_error( mbedtls_threading_mutex_t *mutex,
const char *msg )
{
(void) mutex;
if( test_info.mutex_usage_error == NULL )
test_info.mutex_usage_error = msg;
mbedtls_fprintf( stdout, "[mutex: %s] ", msg );
/* Don't mark the test as failed yet. This way, if the test fails later
* for a functional reason, the test framework will report the message
* and location for this functional reason. If the test passes,
* mbedtls_test_mutex_usage_check() will mark it as failed. */
}
static void mbedtls_test_wrap_mutex_init( mbedtls_threading_mutex_t *mutex )
{
mutex_functions.init( mutex );
if( mutex->is_valid )
++live_mutexes;
}
static void mbedtls_test_wrap_mutex_free( mbedtls_threading_mutex_t *mutex )
{
switch( mutex->is_valid )
{
case MUTEX_FREED:
mbedtls_test_mutex_usage_error( mutex, "free without init or double free" );
break;
case MUTEX_IDLE:
/* Do nothing. The underlying free function will reset is_valid
* to 0. */
break;
case MUTEX_LOCKED:
mbedtls_test_mutex_usage_error( mutex, "free without unlock" );
break;
default:
mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
break;
}
if( mutex->is_valid )
--live_mutexes;
mutex_functions.free( mutex );
}
static int mbedtls_test_wrap_mutex_lock( mbedtls_threading_mutex_t *mutex )
{
int ret = mutex_functions.lock( mutex );
switch( mutex->is_valid )
{
case MUTEX_FREED:
mbedtls_test_mutex_usage_error( mutex, "lock without init" );
break;
case MUTEX_IDLE:
if( ret == 0 )
mutex->is_valid = 2;
break;
case MUTEX_LOCKED:
mbedtls_test_mutex_usage_error( mutex, "double lock" );
break;
default:
mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
break;
}
return( ret );
}
static int mbedtls_test_wrap_mutex_unlock( mbedtls_threading_mutex_t *mutex )
{
int ret = mutex_functions.unlock( mutex );
switch( mutex->is_valid )
{
case MUTEX_FREED:
mbedtls_test_mutex_usage_error( mutex, "unlock without init" );
break;
case MUTEX_IDLE:
mbedtls_test_mutex_usage_error( mutex, "unlock without lock" );
break;
case MUTEX_LOCKED:
if( ret == 0 )
mutex->is_valid = MUTEX_IDLE;
break;
default:
mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
break;
}
return( ret );
}
static void mbedtls_test_mutex_usage_init( void )
{
mutex_functions.init = mbedtls_mutex_init;
mutex_functions.free = mbedtls_mutex_free;
mutex_functions.lock = mbedtls_mutex_lock;
mutex_functions.unlock = mbedtls_mutex_unlock;
mbedtls_mutex_init = &mbedtls_test_wrap_mutex_init;
mbedtls_mutex_free = &mbedtls_test_wrap_mutex_free;
mbedtls_mutex_lock = &mbedtls_test_wrap_mutex_lock;
mbedtls_mutex_unlock = &mbedtls_test_wrap_mutex_unlock;
}
static void mbedtls_test_mutex_usage_check( void )
{
if( live_mutexes != 0 )
{
/* A positive number (more init than free) means that a mutex resource
* is leaking (on platforms where a mutex consumes more than the
* mbedtls_threading_mutex_t object itself). The rare case of a
* negative number means a missing init somewhere. */
mbedtls_fprintf( stdout, "[mutex: %d leaked] ", live_mutexes );
live_mutexes = 0;
if( test_info.mutex_usage_error == NULL )
test_info.mutex_usage_error = "missing free";
}
if( test_info.mutex_usage_error != NULL &&
test_info.result != TEST_RESULT_FAILED )
{
/* Functionally, the test passed. But there was a mutex usage error,
* so mark the test as failed after all. */
test_fail( "Mutex usage error", __LINE__, __FILE__ );
}
test_info.mutex_usage_error = NULL;
}
#endif /* MBEDTLS_TEST_MUTEX_USAGE */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -756,7 +756,7 @@ void ecp_write_binary( int id, char * x, char * y, char * z, int format,
if( ret == 0 )
{
TEST_ASSERT( hexcmp( buf, out->x, olen, out->len ) == 0 );
TEST_ASSERT( mbedtls_test_hexcmp( buf, out->x, olen, out->len ) == 0 );
}
exit:
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册