Commit graph

10399 commits

Author SHA1 Message Date
Janos Follath c8256e7020 mbedtls_mpi_lt_mpi_ct: simplify condition
In the case of *ret we might need to preserve a 0 value throughout the
loop and therefore we need an extra condition to protect it from being
overwritten.

The value of done is always 1 after *ret has been set and does not need
to be protected from overwriting. Therefore in this case the extra
condition can be removed.
2020-03-13 15:25:40 +00:00
Janos Follath ec4c42a95f Rename variable for better readability 2020-03-13 15:25:40 +00:00
Janos Follath cf7eeef2cc mbedtls_mpi_lt_mpi_ct: Improve documentation 2020-03-13 15:25:40 +00:00
Janos Follath aa9e7a4717 Make mbedtls_mpi_lt_mpi_ct more portable
The code relied on the assumptions that CHAR_BIT is 8 and that unsigned
does not have padding bits.

In the Bignum module we already assume that the sign of an MPI is either
-1 or 1. Using this, we eliminate the above mentioned dependency.
2020-03-13 15:25:40 +00:00
Janos Follath f8dbfd4f05 Bignum: Document assumptions about the sign field 2020-03-13 15:25:40 +00:00
Janos Follath eb8fcf8181 Add more tests for mbedtls_mpi_lt_mpi_ct 2020-03-13 15:25:40 +00:00
Janos Follath 3be2fa44e1 mpi_lt_mpi_ct test: hardcode base 16 2020-03-13 15:25:40 +00:00
Janos Follath 3480947667 Document ct_lt_mpi_uint 2020-03-13 15:25:40 +00:00
Janos Follath afa5342452 mpi_lt_mpi_ct: make use of unsigned consistent 2020-03-13 15:25:40 +00:00
Janos Follath a830377142 ct_lt_mpi_uint: make use of biL 2020-03-13 15:25:40 +00:00
Janos Follath 8faf1d627b Change mbedtls_mpi_cmp_mpi_ct to check less than
The signature of mbedtls_mpi_cmp_mpi_ct() meant to support using it in
place of mbedtls_mpi_cmp_mpi(). This meant full comparison functionality
and a signed result.

To make the function more universal and friendly to constant time
coding, we change the result type to unsigned. Theoretically, we could
encode the comparison result in an unsigned value, but it would be less
intuitive.

Therefore we won't be able to represent the result as unsigned anymore
and the functionality will be constrained to checking if the first
operand is less than the second. This is sufficient to support the
current use case and to check any relationship between MPIs.

The only drawback is that we need to call the function twice when
checking for equality, but this can be optimised later if an when it is
needed.
2020-03-13 15:25:40 +00:00
Janos Follath 81c9fe5f2c mbedtls_mpi_cmp_mpi_ct: remove multiplications
Multiplication is known to have measurable timing variations based on
the operands. For example it typically is much faster if one of the
operands is zero. Remove them from constant time code.
2020-03-13 15:25:40 +00:00
Janos Follath fd9797b595 Remove excess vertical space 2020-03-13 15:25:40 +00:00
Janos Follath 78ed22b404 Remove declaration after statement
Visual Studio 2013 does not like it for some reason.
2020-03-13 15:25:40 +00:00
Janos Follath fc2a826ab4 Fix side channel vulnerability in ECDSA 2020-03-13 15:25:39 +00:00
Janos Follath 7ce3a25316 Add tests to constant time mpi comparison 2020-03-13 15:25:39 +00:00
Janos Follath c514ce474a Add new, constant time mpi comparison 2020-03-13 15:25:39 +00:00
Gilles Peskine a5e2d86c3f Note that mbedtls_ctr_drbg_seed() must not be called twice
You can't reuse a CTR_DRBG context without free()ing it and
re-init()ing it. This generally happened to work, but was never
guaranteed. It could have failed with alternative implementations of
the AES module because mbedtls_ctr_drbg_seed() calls
mbedtls_aes_init() on a context which is already initialized if
mbedtls_ctr_drbg_seed() hasn't been called before, plausibly causing a
memory leak.

Calling free() and seed() with no intervening init fails when
MBEDTLS_THREADING_C is enabled and all-bits-zero is not a valid mutex
representation.
2020-03-13 15:25:39 +00:00
Gilles Peskine 216040d46f Fix CTR_DRBG benchmark
You can't reuse a CTR_DRBG context without free()ing it and
re-init()ing. This generally happened to work, but was never
guaranteed. It could have failed with alternative implementations of
the AES module because mbedtls_ctr_drbg_seed() calls
mbedtls_aes_init() on a context which is already initialized if
mbedtls_ctr_drbg_seed() hasn't been called before, plausibly causing a
memory leak. Calling free() and seed() with no intervening init fails
when MBEDTLS_THREADING_C is enabled and all-bits-zero is not a valid
mutex representation. So add the missing free() and init().
2020-03-13 15:25:39 +00:00
Janos Follath d69ae8c21d Add ChangeLog entry 2020-03-13 15:25:39 +00:00
Janos Follath 6bd8c0ae2a ECDSA: Fix side channel vulnerability
The blinding applied to the scalar before modular inversion is
inadequate. Bignum is not constant time/constant trace, side channel
attacks can retrieve the blinded value, factor it (it is smaller than
RSA keys and not guaranteed to have only large prime factors). Then the
key can be recovered by brute force.

Reducing the blinded value makes factoring useless because the adversary
can only recover pk*t+z*N instead of pk*t.
2020-03-13 15:25:39 +00:00
Gilles Peskine bb3d55665e Changelog entry for xxx_drbg_set_entropy_len before xxx_drbg_seed 2020-03-13 15:25:39 +00:00
Gilles Peskine 20dbfb9938 CTR_DRBG: support set_entropy_len() before seed()
mbedtls_ctr_drbg_seed() always set the entropy length to the default,
so a call to mbedtls_ctr_drbg_set_entropy_len() before seed() had no
effect. Change this to the more intuitive behavior that
set_entropy_len() sets the entropy length and seed() respects that and
only uses the default entropy length if there was no call to
set_entropy_len().

The former test-only function mbedtls_ctr_drbg_seed_entropy_len() is
no longer used, but keep it for strict ABI compatibility.
2020-03-13 15:25:39 +00:00
Gilles Peskine f0bf757f9c CTR_DRBG: Don't use functions before they're defined
Move the definitions of mbedtls_ctr_drbg_seed_entropy_len() and
mbedtls_ctr_drbg_seed() to after they are used. This makes the code
easier to read and to maintain.
2020-03-13 15:25:39 +00:00
Gilles Peskine 1d2a9e88c3 HMAC_DRBG: support set_entropy_len() before seed()
mbedtls_hmac_drbg_seed() always set the entropy length to the default,
so a call to mbedtls_hmac_drbg_set_entropy_len() before seed() had no
effect. Change this to the more intuitive behavior that
set_entropy_len() sets the entropy length and seed() respects that and
only uses the default entropy length if there was no call to
set_entropy_len().
2020-03-13 15:24:20 +00:00
Gilles Peskine 6e2cb64a97 'make test' must fail if Asan fails
When running 'make test' with GNU make, if a test suite program
displays "PASSED", this was automatically counted as a pass. This
would in particular count as passing:
* A test suite with the substring "PASSED" in a test description.
* A test suite where all the test cases succeeded, but the final
  cleanup failed, in particular if a sanitizer reported a memory leak.

Use the test executable's return status instead to determine whether
the test suite passed. It's always 0 on PASSED unless the executable's
cleanup code fails, and it's never 0 on any failure.

Fix ARMmbed/mbed-crypto#303
2020-03-13 15:24:20 +00:00
Gilles Peskine 6eec4ab323 Asan make builds: avoid sanitizer recovery
Some sanitizers default to displaying an error message and recovering.
This could result in a test being recorded as passing despite a
complaint from the sanitizer. Turn off sanitizer recovery to avoid
this risk.
2020-03-13 15:24:20 +00:00
Gilles Peskine b3e54396fa Use UBsan in addition to Asan with 'make test'
When building with make with the address sanitizer enabled, also
enable the undefined behavior sanitizer.
2020-03-13 15:24:19 +00:00
Gilles Peskine 3ccb7f18e0 Unify ASan options in make builds
Use a common set of options when building with Asan without CMake.
2020-03-13 15:24:19 +00:00
Gilles Peskine 6b5e60c26c config.pl full: exclude MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
This is a variant toggle, not an extra feature, so it should be tested
separately.
2020-03-13 15:22:14 +00:00
Gilles Peskine d41a95e223 mbedtls_hmac_drbg_set_entropy_len() only matters when reseeding
The documentation of HMAC_DRBG erroneously claimed that
mbedtls_hmac_drbg_set_entropy_len() had an impact on the initial
seeding. This is in fact not the case: mbedtls_hmac_drbg_seed() forces
the entropy length to its chosen value. Fix the documentation.
2020-03-13 15:22:14 +00:00
Gilles Peskine 5fc111fe69 mbedtls_ctr_drbg_set_entropy_len() only matters when reseeding
The documentation of CTR_DRBG erroneously claimed that
mbedtls_ctr_drbg_set_entropy_len() had an impact on the initial
seeding. This is in fact not the case: mbedtls_ctr_drbg_seed() forces
the initial seeding to grab MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of
entropy. Fix the documentation and rewrite the discussion of the
entropy length and the security strength accordingly.
2020-03-13 15:22:14 +00:00
Gilles Peskine 4c57b20247 mbedtls_ctr_drbg_seed: correct maximum for len 2020-03-13 15:22:14 +00:00
Gilles Peskine 5953660a6a Add a note about CTR_DRBG security strength to config.h 2020-03-13 15:22:14 +00:00
Gilles Peskine e1dc2de900 Move MBEDTLS_CTR_DRBG_USE_128_BIT_KEY to the correct section
It's an on/off feature, so it should be listed in version_features.
2020-03-13 15:22:14 +00:00
Gilles Peskine 6e36d0b33c CTR_DRBG: more consistent formatting and wording
In particular, don't use #MBEDTLS_xxx on macros that are undefined in
some configurations, since this would be typeset with a literal '#'.
2020-03-13 15:22:14 +00:00
Gilles Peskine 9640403fa0 CTR_DRBG documentation: further wording improvements 2020-03-13 15:22:14 +00:00
Gilles Peskine 7b674eac64 CTR_DRBG: Improve the explanation of security strength
Separate the cases that achieve a 128-bit strength and the cases that
achieve a 256-bit strength.
2020-03-13 15:22:14 +00:00
Gilles Peskine 7df4b7b3b6 CTR_DRBG: make it easier to understand the security strength
Explain how MBEDTLS_CTR_DRBG_ENTROPY_LEN is set next to the security
strength statement, rather than giving a partial explanation (current
setting only) in the documentation of MBEDTLS_CTR_DRBG_ENTROPY_LEN.
2020-03-13 15:22:14 +00:00
Gilles Peskine 56f628ca26 HMAC_DRBG: note that the initial seeding grabs entropy for the nonce 2020-03-13 15:22:14 +00:00
Gilles Peskine beddfdcd7f Use standard terminology to describe the personalization string
NIST and many other sources call it a "personalization string", and
certainly not "device-specific identifiers" which is actually somewhat
misleading since this is just one of many things that might go into a
personalization string.
2020-03-13 15:22:13 +00:00
Gilles Peskine 57553fa2f0 Do note that xxx_drbg_random functions reseed with PR enabled 2020-03-13 15:22:13 +00:00
Gilles Peskine 20a3846725 Consistently use \c NULL and \c 0 2020-03-13 15:22:13 +00:00
Gilles Peskine 9e2543bd4f Also mention HMAC_DRBG in the changelog entry
There were no tricky compliance issues for HMAC_DBRG, unlike CTR_DRBG,
but mention it anyway. For CTR_DRBG, summarize the salient issue.
2020-03-13 15:22:13 +00:00
Gilles Peskine ccb38381e8 HMAC_DRBG: improve the documentation of the entropy length 2020-03-13 15:21:09 +00:00
Gilles Peskine 4bfe4540f3 HMAC_DRBG documentation improvements clarifications
Improve the formatting and writing of the documentation based on what
had been done for CTR_DRBG.

Document the maximum size and nullability of some buffer parameters.
2020-03-13 15:21:08 +00:00
Gilles Peskine f17079d960 More CTR_DRBG documentation improvements and clarifications 2020-03-13 12:03:12 +00:00
Gilles Peskine 34693b5dd6 Add a test component with malloc(0) returning NULL
Exercise the library functions with calloc returning NULL for a size
of 0. Make this a separate job with UBSan (and ASan) to detect
places where we try to dereference the result of calloc(0) or to do
things like

    buf = calloc(size, 1);
    if (buf == NULL && size != 0) return INSUFFICIENT_MEMORY;
    memcpy(buf, source, size);

which has undefined behavior when buf is NULL at the memcpy call even
if size is 0.

This is needed because other test components jobs either use the system
malloc which returns non-NULL on Linux and FreeBSD, or the
memory_buffer_alloc malloc which returns NULL but does not give as
useful feedback with ASan (because the whole heap is a single C
object).
2020-03-13 12:03:12 +00:00
Gilles Peskine 99d76f8805 Add a calloc self-test
Add a very basic test of calloc to the selftest program. The selftest
program acts in its capacity as a platform compatibility checker rather
than in its capacity as a test of the library.

The main objective is to report whether calloc returns NULL for a size
of 0. Also observe whether a free/alloc sequence returns the address
that was just freed and whether a size overflow is properly detected.
2020-03-13 12:03:12 +00:00
Gilles Peskine c32f74cf8e Fix wording 2020-03-13 12:03:12 +00:00