Commit Graph

7509 Commits

Author SHA1 Message Date
Gilles Peskine
b2be1fca2c Catch AES failure in mbedtls_ctr_drbg_random
The functions mbedtls_ctr_drbg_random() and
mbedtls_ctr_drbg_random_with_add() could return 0 if an AES function
failed. This could only happen with alternative AES
implementations (the built-in implementation of the AES functions
involved never fail), typically due to a failure in a hardware
accelerator.

Bug reported and fix proposed by Johan Uppman Bruce and Christoffer
Lauri, Sectra.
2019-11-28 09:55:25 +01:00
Jaeden Amero
df1b3e54c7
Merge pull request #2937 from gilles-peskine-arm/memory_buffer_alloc-fatal-pass-2.7
Backport 2.7: Clarify test descriptions in test_suite_memory_buffer_alloc
2019-11-27 10:37:33 +00:00
Gilles Peskine
02fbc08d2e Enable more test cases without MBEDTLS_MEMORY_DEBUG
None of the test cases in tests_suite_memory_buffer_alloc actually
need MBEDTLS_MEMORY_DEBUG. Some have additional checks when
MBEDTLS_MEMORY_DEBUG but all are useful even without it. So enable
them all and #ifdef out the parts that require DEBUG.
2019-11-26 18:48:08 +01:00
Gilles Peskine
786f068ec0 More accurate test case description 2019-11-26 18:47:14 +01:00
Gilles Peskine
04d45c98e8 Clarify that the "FATAL" message is expected
The test case "Memory buffer small buffer" emits a message
"FATAL: verification of first header failed". In this test case, it's
actually expected, but it looks weird to see this message from a
passing test. Add a comment that states this explicitly, and modify
the test description to indicate that the failure is expected, and
change the test function name to be more accurate.

Fix #309
2019-11-26 18:47:14 +01:00
Gilles Peskine
99258ff315 Parse HelloVerifyRequest buffer overread: add changelog entry 2019-11-21 14:18:56 +01:00
Gilles Peskine
2414ce1a5e Parse HelloVerifyRequest: avoid buffer overread at the start
In ssl_parse_hello_verify_request, we read 3 bytes (version and cookie
length) without checking that there are that many bytes left in
ssl->in_msg. This could potentially read from memory outside of the
ssl->receive buffer (which would be a remotely exploitable
crash).
2019-11-21 14:18:27 +01:00
Gilles Peskine
99b6777b72 Parse HelloVerifyRequest: avoid buffer overread on the cookie
In ssl_parse_hello_verify_request, we print cookie_len bytes without
checking that there are that many bytes left in ssl->in_msg. This
could potentially log data outside the received message (not a big
deal) and could potentially read from memory outside of the receive
buffer (which would be a remotely exploitable crash).
2019-11-21 14:18:26 +01:00
Jaeden Amero
c5a016dde1 Merge remote-tracking branch 'restricted/pr/666' into mbedtls-2.7-restricted
* restricted/pr/666: (24 commits)
  Add ChangeLog entry
  mpi_lt_mpi_ct: fix condition handling
  mpi_lt_mpi_ct: Add further tests
  mpi_lt_mpi_ct: Fix test numbering
  mpi_lt_mpi_ct perform tests for both limb size
  ct_lt_mpi_uint: cast the return value explicitely
  mbedtls_mpi_lt_mpi_ct: add tests for 32 bit limbs
  mbedtls_mpi_lt_mpi_ct: simplify condition
  Rename variable for better readability
  mbedtls_mpi_lt_mpi_ct: Improve documentation
  Make mbedtls_mpi_lt_mpi_ct more portable
  Bignum: Document assumptions about the sign field
  Add more tests for mbedtls_mpi_lt_mpi_ct
  mpi_lt_mpi_ct test: hardcode base 16
  Document ct_lt_mpi_uint
  mpi_lt_mpi_ct: make use of unsigned consistent
  ct_lt_mpi_uint: make use of biL
  Change mbedtls_mpi_cmp_mpi_ct to check less than
  mbedtls_mpi_cmp_mpi_ct: remove multiplications
  Remove excess vertical space
  ...
2019-11-12 10:47:55 +00:00
Jaeden Amero
e70059df85 Merge remote-tracking branch 'restricted/pr/668' into mbedtls-2.7-restricted
* restricted/pr/668:
  Zeroize local AES variables before exiting the function
2019-11-12 10:42:45 +00:00
Jaeden Amero
10fcdd25d4
Merge pull request #664 from ARMmbed/dev/yanesca/iotcrypt-958-ecdsa-side-channel-fix-2.7
Backport 2.7: ECDSA side channel fix
2019-11-12 10:37:27 +00:00
Andrzej Kurek
07597365cd Zeroize local AES variables before exiting the function
This issue has been reported by Tuba Yavuz, Farhaan Fowze, Ken (Yihang) Bai,
Grant Hernandez, and Kevin Butler (University of Florida) and
Dave Tian (Purdue University).

In AES encrypt and decrypt some variables were left on the stack. The value
of these variables can be used to recover the last round key. To follow best
practice and to limit the impact of buffer overread vulnerabilities (like
Heartbleed) we need to zeroize them before exiting the function.
2019-11-12 03:23:51 -05:00
Janos Follath
dfa4d71873 Add ChangeLog entry 2019-11-11 14:18:18 +00:00
Janos Follath
b4edac5616 mpi_lt_mpi_ct: fix condition handling
The code previously only set the done flag if the return value was one.
This led to overriding the correct return value later on.
2019-11-11 12:27:36 +00:00
Janos Follath
f4482aaccc mpi_lt_mpi_ct: Add further tests
The existing tests did not catch a failure that came up at integration
testing. Adding the missing test cases to trigger the bug.
2019-11-11 12:27:36 +00:00
Janos Follath
a776aea91a mpi_lt_mpi_ct: Fix test numbering 2019-11-11 12:27:36 +00:00
Janos Follath
1b86eeb06b mpi_lt_mpi_ct perform tests for both limb size
The corner case tests were designed for 32 and 64 bit limbs
independently and performed only on the target platform. On the other
platform they are not corner cases anymore, but we can still exercise
them.
2019-11-11 12:27:36 +00:00
Janos Follath
5823961558 ct_lt_mpi_uint: cast the return value explicitely
The return value is always either one or zero and therefore there is no
risk of losing precision. Some compilers can't deduce this and complain.
2019-11-11 12:27:36 +00:00
Janos Follath
6adff06e50 mbedtls_mpi_lt_mpi_ct: add tests for 32 bit limbs
The corner case tests were designed for 64 bit limbs and failed on 32
bit platforms because the numbers in the test ended up being stored in a
different number of limbs and the function (correctly) returnd an error
upon receiving them.
2019-11-11 12:27:36 +00:00
Janos Follath
cff9e6e03d 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.
2019-11-11 12:27:36 +00:00
Janos Follath
8ec2a953af Rename variable for better readability 2019-11-11 12:27:36 +00:00
Janos Follath
a2b9a96fb8 mbedtls_mpi_lt_mpi_ct: Improve documentation 2019-11-11 12:27:36 +00:00
Janos Follath
51ed14e20f 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.
2019-11-11 12:27:36 +00:00
Janos Follath
9741fa6e2b Bignum: Document assumptions about the sign field 2019-11-11 12:27:36 +00:00
Janos Follath
9332ecefc8 Add more tests for mbedtls_mpi_lt_mpi_ct 2019-11-11 12:27:36 +00:00
Janos Follath
aaa3f22b76 mpi_lt_mpi_ct test: hardcode base 16 2019-11-11 12:27:36 +00:00
Janos Follath
3173a53fe9 Document ct_lt_mpi_uint 2019-11-11 12:27:36 +00:00
Janos Follath
782cbe592d mpi_lt_mpi_ct: make use of unsigned consistent 2019-11-11 12:27:36 +00:00
Janos Follath
db9f449409 ct_lt_mpi_uint: make use of biL 2019-11-11 12:27:36 +00:00
Janos Follath
c3b376e2f2 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.
2019-11-11 12:27:36 +00:00
Janos Follath
8461c0e2a8 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.
2019-11-11 12:27:36 +00:00
Janos Follath
8de2d45cd7 Remove excess vertical space 2019-11-11 12:27:36 +00:00
Janos Follath
c587a32a9c Remove declaration after statement
Visual Studio 2013 does not like it for some reason.
2019-11-11 12:27:36 +00:00
Janos Follath
5f3019b298 Fix side channel vulnerability in ECDSA 2019-11-11 12:27:36 +00:00
Janos Follath
883801d3ec Add tests to constant time mpi comparison 2019-11-11 12:27:36 +00:00
Janos Follath
e0187b95f0 Add new, constant time mpi comparison 2019-11-11 12:27:27 +00:00
Gilles Peskine
4c575c0270 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.
2019-10-28 21:15:21 +01:00
Gilles Peskine
eab4d701ca Fix CTR_DRBG benchmark
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. So add the missing free() and init().
2019-10-28 21:07:08 +01:00
Janos Follath
5cf41f80a4 Add ChangeLog entry 2019-10-25 11:26:13 +01:00
Janos Follath
82debf8332 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.
2019-10-25 09:01:34 +01:00
Gilles Peskine
093aa517c4 Changelog entry for xxx_drbg_set_entropy_len before xxx_drbg_seed 2019-10-23 18:01:25 +02:00
Gilles Peskine
b729e1b9ba 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.
2019-10-23 18:01:25 +02:00
Gilles Peskine
845ac103a9 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.
2019-10-23 18:01:25 +02:00
Gilles Peskine
9c742249cf 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().
2019-10-23 18:01:25 +02:00
Jaeden Amero
c87a54683b
Merge pull request #2900 from gilles-peskine-arm/asan-test-fail-2.7
Backport 2.7: Make sure Asan failures are detected in 'make test'
2019-10-22 16:30:37 +01:00
Jaeden Amero
cc656ac96b
Merge pull request #2872 from gilles-peskine-arm/test_malloc_0_null-2.7
Backport 2.7: Test the library when malloc(0) returns NULL
2019-10-22 13:41:37 +01:00
Gilles Peskine
5ee14d70d2 '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
2019-10-21 20:48:51 +02:00
Gilles Peskine
4c2697f43f 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.
2019-10-21 20:48:51 +02:00
Gilles Peskine
260921d3f2 Use UBsan in addition to Asan with 'make test'
When building with make with the address sanitizer enabled, also
enable the undefined behavior sanitizer.
2019-10-21 20:48:51 +02:00
Gilles Peskine
c20a4053c3 Unify ASan options in make builds
Use a common set of options when building with Asan without CMake.
2019-10-21 20:48:51 +02:00