Commit graph

1179 commits

Author SHA1 Message Date
Simon Butcher 6617a24056 Merge remote-tracking branch 'origin/pr/633' into baremetal 2019-08-21 13:46:18 +01:00
Simon Butcher f0f01e1f0a Merge remote-tracking branch 'origin/pr/630' into baremetal 2019-08-14 16:53:38 +01:00
Simon Butcher 434ab19164 Merge remote-tracking branch 'origin/pr/629' into baremetal 2019-08-14 16:53:13 +01:00
Simon Butcher 0863b2a259 Merge remote-tracking branch 'origin/pr/612' into baremetal 2019-08-14 16:50:13 +01:00
Hanno Becker a9d5c452f3 Remove mbedtls_ssl_transform::minlen 2019-08-13 15:04:39 +01:00
Hanno Becker 7a19633c99 tinyCrypt: Avoid unused var warning by marking vars as unused 2019-08-12 18:01:47 +01:00
Hanno Becker 29d165565c Add MBEDTLS_ECDH_C guards to ECDH code-paths using legacy ECDH
Previously, MBEDTLS_KEY_EXCHANGE_ECDH[E]_XXX_ENABLED would imply
that MBEDTLS_ECDH_C is set, but with the introduction of tinyCrypt
as an alternative ECDH implementation, this is no longer the case.
2019-08-12 18:01:40 +01:00
Hanno Becker a3c2c1712c tinyCrypt: Share ECDH secret calculation code-path 2019-08-12 17:05:38 +01:00
Hanno Becker 75f12d1eb9 tinyCrypt: Add ServerKeyExchange parsing code 2019-08-12 17:05:38 +01:00
Hanno Becker d089fad925 tinyCrypt: Adapt RNG wrapper to return 0 on failure 2019-08-12 17:05:38 +01:00
Hanno Becker ef982d57bf tinyCrypt: Bind RNG wrapper to tinyCrypt in mbedtls_ssl_setup() 2019-08-12 17:05:38 +01:00
Jarno Lamsa e12aafbdc7 tinyCrypt: Initial commit towards ECDHE support
This commit is a first step towards using uECC for ECDH
during TLS handshakes.
2019-08-12 17:05:38 +01:00
Manuel Pégourié-Gonnard fb02e96cf5 Fix indentation to a multiple of 4 spaces 2019-08-12 17:05:03 +01:00
Manuel Pégourié-Gonnard 8793fab635 Fix two typos in comments 2019-08-12 17:05:03 +01:00
Hanno Becker 572d448ab2 Enforce NULL context for hardcoded RNG 2019-08-12 17:05:03 +01:00
Hanno Becker 9a12243b01 Introduce getter function for RNG context 2019-08-12 17:05:03 +01:00
Hanno Becker 09d236419e Share code between In-CliKeyExch and Out-CliKeyExch
The postprocessing code for the server-side incoming client key
exchange and the client-side outgoing client key exchange both
contain the same code-paths for building the premaster secret
depending on the chosen ciphersuite (e.g., for ECDHE-PSK,
concatenating the ECDHE secret with the chosen PSK).

This commit moves this common code to ssl_tls.c, allowing
client- and server-side to share it.
2019-08-12 17:05:03 +01:00
Manuel Pégourié-Gonnard f3a15b3de0 Fix possibly-lossy conversion warning from MSVC
ssl_tls.c(4876): warning C4267: '=': conversion from 'size_t' to 'uint8_t', possible loss of data
2019-08-02 10:17:15 +02:00
Hanno Becker 8844055b0e Remove compression field from SSL session if compression disabled 2019-08-01 10:11:20 +02:00
Hanno Becker ec01408389 Reintroduce length 0 check for records 2019-08-01 09:51:54 +02:00
Hanno Becker 8061c6e894 Don't use memcpy() for 2-byte copy operation
Manual copying is slightly shorter here.
2019-08-01 09:51:54 +02:00
Hanno Becker 7b5ba84624 Remove integer parsing macro
If this is introduced, it should be defined in a prominent place
and put to use throughout the library, but this is left for another
time.
2019-08-01 09:51:54 +02:00
Hanno Becker 618176126c Fix alignment in record header parsing routine 2019-08-01 09:51:54 +02:00
Hanno Becker c1c173cadf Make sure 'record from another epoch' is displayed for next epoch
The test 'DTLS proxy: delay ChangeCipherSpec' from ssl-opt.sh
relies on this.
2019-08-01 09:51:53 +02:00
Hanno Becker 03e2db6f35 Implement record checking API
This commit implements the record checking API

   mbedtls_ssl_check_record()

on top of the restructured incoming record stack.

Specifically, it makes use of the fact that the core processing routines

  ssl_parse_record_header()
  mbedtls_ssl_decrypt_buf()

now operate on instances of the SSL record structure mbedtls_record
instead of the previous mbedtls_ssl_context::in_xxx fields.
2019-08-01 09:51:53 +02:00
Hanno Becker 21fc61c7a7 Mark ssl_parse_record_header() as const in SSL context 2019-08-01 09:51:53 +02:00
Hanno Becker c360dcc679 [API break] Remove mbedtls_ssl_context::in_iv field
After the rewrite of incoming record processing to use the internal
SSL record structure mbedtls_record (which contains the data_offset
field to indicate where the IV resides), this field is no longer
necessary.

Note: This is an API break.
2019-08-01 09:51:53 +02:00
Hanno Becker 05413d9041 Remove duplicate setting of ssl->in_msgtype and ssl->in_msglen 2019-08-01 09:51:53 +02:00
Hanno Becker bd70c8e771 Move update of in_xxx fields in ssl_get_next_record()
ssl_get_next_record() updates the legacy in_xxx fields in two places,
once before record decryption and once after. Now that record decryption
doesn't use or affect the in_xxx fields anymore, setting up the these
legacy fields can entirely be moved to the end of ssl_get_next_record(),
which is what this comit does.

This commit solely moves existing code, but doesn't yet simplify the
now partially redundant settings of the in_xxx fields. This will be
done in a separate commit.
2019-08-01 09:51:53 +02:00
Hanno Becker bf256cdb0b Move update of in_xxx fields outside of ssl_prepare_record_content()
Multiple record attributes such as content type and payload length
may change during record decryption, and the legacy in_xxx fields
in the SSL context therefore need to be updated after the record
decryption routine ssl_decrypt_buf() has been called.

After the previous commit has made ssl_prepare_record_content()
independent of the in_xxx fields, setting them can be moved
outside of ssl_prepare_record_content(), which is what this
commit does.
2019-08-01 09:51:53 +02:00
Hanno Becker 106f3dab57 Reduce dependency of ssl_prepare_record_content() on in_xxx fields 2019-08-01 09:51:53 +02:00
Hanno Becker 68379720b6 Move ssl_update_in_pointers() to after record hdr parsing
Previously, ssl_update_in_pointers() ensured that the in_xxx pointers
in the SSL context are set to their default state so that the record
header parsing function ssl_parse_record_header() could make use of them.
By now, the latter is independent of these pointers, so they don't need
to be setup before calling ssl_parse_record_header() anymore.
However, other parts of the messaging stack might still depend on it
(to be studied), and hence this commit does not yet reomve
ssl_update_in_pointers() entirely.
2019-08-01 09:51:53 +02:00
Hanno Becker fc55172c41 Mark DTLS replay check as const on the SSL context 2019-08-01 09:51:53 +02:00
Hanno Becker 6941245852 Move updating the internal rec ptrs to outside of rec hdr parsing
The stack maintains pointers mbedtls_ssl_context::in_xxx pointing to
various parts of the [D]TLS record header. Originally, these fields
were determined and set in ssl_parse_record_header(). By now,
ssl_parse_record_header() has been modularized to setup an instance
of the internal SSL record structure mbedtls_record, and to derive
the old in_xxx fields from that.

This commit takes a further step towards removing the in_xxx fields
by deriving them from the established record structure _outside_ of
ssl_parse_record_header() after the latter has succeeded.

One exception is the handling of possible client reconnects,
which happens in the case then ssl_parse_record_header() returns
MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; since ssl_check_client_reconnect()
so far uses the in_xxx fields, they need to be derived from the
record structure beforehand.
2019-08-01 09:51:53 +02:00
Hanno Becker 40478be987 Mark ssl_decrypt_buf() as `const in the input SSL context
In fact, the SSL context is only used to access the debug callback.
2019-08-01 09:51:52 +02:00
Hanno Becker a89610aaf2 Adapt ssl_prepare_record_content() to use SSL record structure 2019-08-01 09:51:52 +02:00
Hanno Becker 9babbf7e75 Use record length from record structure when fetching content in TLS 2019-08-01 09:51:52 +02:00
Hanno Becker 2720f4c33c Use record structure when remembering offset of next record in dgram 2019-08-01 09:51:52 +02:00
Hanno Becker 2528ee09ac Use SSL record structure when skipping over unexpected record 2019-08-01 09:51:52 +02:00
Hanno Becker af5bcfc765 Adapt ssl_buffer_future_record() to work with SSL record structure 2019-08-01 09:51:52 +02:00
Hanno Becker c6e7c573d9 Setup SSL record structure in ssl_parse_record_header()
This commit makes a first step towards modularizing the incoming record
processing by having it operate on instances of the structure mbedtls_record
representing SSL records.

So far, only record encryption/decryption operate in terms of record
instances, but the rest of the parsing doesn't. In particular,
ssl_parse_record_header() operates directly on the fixed input buffer,
setting the various ssl->in_xxx pointers and fields, and only directly
before/after calling ssl_decrypt_buf() these fields a converted to/from
mbedtls_record instances.

This commit does not yet remove the ssl->in_xxx fields, but makes a step
towards extending the lifetime of mbedtls_record structure representing
incoming records, by modifying ssl_parse_record_header() to setup an
instance of mbedtls_record, and setting the ssl->in_xxx fields from that
instance. The instance so-constructed isn't used further so far, and in
particular it is not yet consolidated with the instance set up for use
in ssl_decrypt_record(). That's for a later commit.
2019-08-01 09:51:52 +02:00
Hanno Becker 6c0e53ce6f Minor documentation improvements in ssl_parse_record_header() 2019-08-01 09:51:51 +02:00
Hanno Becker e04527755b Check for sufficient datagram size in ssl_parse_record_header()
Previously, ssl_parse_record_header() did not check whether the current
datagram is large enough to hold a record of the advertised size. This
could lead to records being silently skipped over or backed up on the
basis of an invalid record length. Concretely, the following would happen:

1) In the case of a record from an old epoch, the record would be
   'skipped over' by setting next_record_offset according to the advertised
   but non-validated length, and only in the subsequent mbedtls_ssl_fetch_input()
   it would be noticed in an assertion failure if the record length is too
   large for the current incoming datagram.
   While not critical, this is fragile, and also contrary to the intend
   that MBEDTLS_ERR_SSL_INTERNAL_ERROR should never be trigger-able by
   external input.
2) In the case of a future record being buffered, it might be that we
   backup a record before we have validated its length, hence copying
   parts of the input buffer that don't belong to the current record.
   This is a bug, and it's by luck that it doesn't seem to have critical
   consequences.

This commit fixes this by modifying ssl_parse_record_header() to check that
the current incoming datagram is large enough to hold a record of the
advertised length, returning MBEDTLS_ERR_SSL_INVALID_RECORD otherwise.
2019-08-01 09:51:51 +02:00
Hanno Becker a61925fa51 Don't send an alert when receiving a record of unknown ContentType
We don't send alerts on other instances of ill-formed records,
so why should we do it here? If we want to keep it, the alerts
should rather be sent ssl_get_next_record().
2019-08-01 09:51:49 +02:00
Hanno Becker dc4d62748c Don't call ssl_fetch_input for record content fetch in DTLS
As explained in the previous commit, if mbedtls_ssl_fetch_input()
is called multiple times, all but the first call are equivalent to
bounds checks in the incoming datagram.
2019-08-01 09:50:27 +02:00
Hanno Becker 29823466a1 Don't call ssl_fetch_input for record hdr size check in DTLS
In DTLS, if mbedtls_ssl_fetch_input() is called multiple times without
resetting the input buffer in between, the non-initial calls are functionally
equivalent to mere bounds checks ensuring that the incoming datagram is
large enough to hold the requested data. In the interest of code-size
and modularity (removing a call to a non-const function which is logically
const in this instance), this commit replaces such a call to
mbedtls_ssl_fetch_input() by an explicit bounds check in
ssl_parse_record_header().
2019-08-01 09:50:27 +02:00
Hanno Becker de7d6d33e5 Move size-check for DTLS record header with CID to DTLS-only branch 2019-08-01 09:50:27 +02:00
Hanno Becker 87b5626d73 Check same-port-reconnect from client outside of record hdr parsing
Previously, `ssl_handle_possible_reconnect()` was part of
`ssl_parse_record_header()`, which was required to return a non-zero error
code to indicate a record which should not be further processed because it
was invalid, unexpected, duplicate, .... In this case, some error codes
would lead to some actions to be taken, e.g. `MBEDTLS_ERR_SSL_EARLY_MESSAGE`
to potential buffering of the record, but eventually, the record would be
dropped regardless of the precise value of the error code. The error code
`MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED` returned from
`ssl_handle_possible_reconnect()` did not receive any special treatment and
lead to silent dopping of the record - in particular, it was never returned
to the user.

In the new logic this commit introduces, `ssl_handle_possible_reconnect()` is
part of `ssl_check_client_reconnect()` which is triggered _after_
`ssl_parse_record_header()` found an unexpected record, which is already in
the code-path eventually dropping the record; we want to leave this code-path
only if a valid cookie has been found and we want to reset, but do nothing
otherwise. That's why `ssl_handle_possible_reconnect()` now returns `0` unless
a valid cookie has been found or a fatal error occurred.
2019-08-01 09:50:27 +02:00
Hanno Becker 07d420d6ad Remove unnecessary backup of explicit IV in AEAD record decryption
There is no need to hold back the explicit IV for AEAD ciphers.
2019-08-01 09:50:27 +02:00
Hanno Becker 8244cfa8bc Remove redundant minimum length check
Availability of sufficient incoming data should be checked when
it is needed, which is in mbedtls_ssl_fetch_input(), and this
function has the necessary bounds checks in place.
2019-08-01 09:50:27 +02:00