Commit Graph

1195 Commits

Author SHA1 Message Date
Manuel Pégourié-Gonnard
889bbc70b6 Fix unreachable code warnings with armc5
Some TLS-only code paths were not protected by an #ifdef and while some
compiler are happy to just silently remove them, armc5 complains:

Warning:  #111-D: statement is unreachable

Let's make armc5 happy.
2019-06-18 10:56:09 +02:00
Manuel Pégourié-Gonnard
cc71c77b5d Fix typos, grammar and wording in documentation 2019-06-18 10:09:27 +02:00
Manuel Pégourié-Gonnard
d87601e3ef Declare and document ssl_context_save()/load()
Also introduce stub definitions so that things compile and link.
2019-06-18 10:09:27 +02:00
Simon Butcher
c725e4b34e Merge remote-tracking branch 'origin/pr/590' into baremetal 2019-06-17 17:57:26 +01:00
Simon Butcher
01a8eb21d3 Merge remote-tracking branch 'origin/pr/585' into baremetal 2019-06-17 17:53:41 +01:00
Manuel Pégourié-Gonnard
ec1c222947 Fix a few style issues 2019-06-12 10:18:26 +02:00
Manuel Pégourié-Gonnard
8794a4290d Clarify a few more comments and documentation 2019-06-11 10:04:57 +02:00
Jarno Lamsa
18b9a491e1 Disable the enforce flag by default 2019-06-10 15:23:29 +03:00
Jarno Lamsa
842be16800 Check for the enforcing and fail handshake if the peer doesn't support 2019-06-10 15:05:33 +03:00
Jarno Lamsa
d9382f85e7 Add definitions for enforce flag values 2019-06-10 10:27:14 +03:00
Jarno Lamsa
7a5e2bec75 Create a new flag for enforcing the extended master secret
If the flag is enabled, drop the connection if peer doesn't support
extended master secret extension.
2019-06-10 10:13:03 +03:00
Manuel Pégourié-Gonnard
64c1681fbc Use new macros for all TLS/DTLS tests
sed -i -e 's/\([^ ]*transport\) == MBEDTLS_SSL_TRANSPORT_DATAGRAM/MBEDTLS_SSL_TRANSPORT_IS_DTLS( \1 )/' -e 's/\([^ ]*transport\) \(!= MBEDTLS_SSL_TRANSPORT_DATAGRAM\|== MBEDTLS_SSL_TRANSPORT_STREAM\)/MBEDTLS_SSL_TRANSPORT_IS_TLS( \1 )/' library/ssl_*.c

New sizes (see 2nd-previous commit for measuring script):

```

both
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  17156       0       0   17156    4304 ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  17649       0       0   17649    44f1 ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  39286      60       0   39346    99b2 ssl_tls.o (ex library/libmbedtls.a)
  88874      60     600   89534   15dbe (TOTALS)

DTLS-only
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  16948       0       0   16948    4234 ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  17437       0       0   17437    441d ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  38147      60       0   38207    953f ssl_tls.o (ex library/libmbedtls.a)
  87315      60     600   87975   157a7 (TOTALS)

TLS-only
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  14912       0       0   14912    3a40 ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  15868       0       0   15868    3dfc ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  27619      60       0   27679    6c1f ssl_tls.o (ex library/libmbedtls.a)
  73182      60     600   73842   12072 (TOTALS)
```
2019-06-06 13:19:59 +02:00
Manuel Pégourié-Gonnard
ff4bd9f405 Use new tools for all cases with TLS-specific code
This commit handles occurrences of case 2 and 3 in the following list:

1. Some DTLS-specific code with no TLS-specific code (most frequent)
2. Some specific code for each protocol
3. Some TLS-specific code with no DTLS-specific code (least frequent)

Case 3 previously had a weird structure in that the TLS-specific code was
always present, but the if structure was conditional on DTLS being enabled.
This is changed by this commit to a more logical structure where both the code
and the test are conditional on TLS being enabled.

Case 2 doesn't require any change in the code structure in general. However,
there is one occurrence where the if/else structure is simplified to assigning
the result of a boolean operation, and one occurrence where I also noticed a
useless use of `ssl_ep_len()` in a TLS-specific branch, that I turned to the
constant 0 as it makes more sense.

Case 1 will be handled in the next commit, as it can easily be handled in an
automated way - only cases 2 and 3 (sometimes) required manual intervention.

The list of occurrences for cases 2 and 3 was established manually by looking
for occurrences of '= MBEDTLS_SSL_TRANSPORT_' in the code and manually
checking if there was a TLS-specific branch.

New sizes (see previous commit for the measuring script):

```

both
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  17156       0       0   17156    4304 ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  17649       0       0   17649    44f1 ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  39286      60       0   39346    99b2 ssl_tls.o (ex library/libmbedtls.a)
  88874      60     600   89534   15dbe (TOTALS)

DTLS-only
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  17068       0       0   17068    42ac ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  17553       0       0   17553    4491 ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  38499      60       0   38559    969f ssl_tls.o (ex library/libmbedtls.a)
  87903      60     600   88563   159f3 (TOTALS)

TLS-only
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  14912       0       0   14912    3a40 ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  15868       0       0   15868    3dfc ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  27619      60       0   27679    6c1f ssl_tls.o (ex library/libmbedtls.a)
  73182      60     600   73842   12072 (TOTALS)
```
2019-06-06 13:18:19 +02:00
Manuel Pégourié-Gonnard
25838b795f Introduce tools for transport-specific code
And use those tools in a few places. For now the purpose is just to validate
those tools before using them in all occurrences of transport-specific code.

The effect of these changes was measured with the following script:

```
set -eu

build() {
    printf "\n$1\n"
    CC=arm-none-eabi-gcc CFLAGS='-Werror -Os -march=armv6-m -mthumb' \
        AR=arm-none-eabi-ar LD=arm-none-eabi-ld make clean lib >/dev/null
    arm-none-eabi-size -t library/libmbedtls.a
}

git checkout -- include/mbedtls/config.h
scripts/config.pl unset MBEDTLS_NET_C
scripts/config.pl unset MBEDTLS_TIMING_C
scripts/config.pl unset MBEDTLS_FS_IO
scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
build "both"

scripts/config.pl unset MBEDTLS_SSL_PROTO_TLS
build "DTLS-only"

scripts/config.pl set MBEDTLS_SSL_PROTO_TLS
scripts/config.pl unset MBEDTLS_SSL_PROTO_DTLS
scripts/config.pl unset MBEDTLS_SSL_DTLS_HELLO_VERIFY
scripts/config.pl unset MBEDTLS_SSL_DTLS_ANTI_REPLAY
scripts/config.pl unset MBEDTLS_SSL_DTLS_BADMAC_LIMIT
scripts/config.pl unset MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
build "TLS-only"

git checkout -- include/mbedtls/config.h
```

The output of the script is as follows:

```
both
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  17160       0       0   17160    4308 ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  17637       0       0   17637    44e5 ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  39322      60       0   39382    99d6 ssl_tls.o (ex library/libmbedtls.a)
  88902      60     600   89562   15dda (TOTALS)

DTLS-only
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  17072       0       0   17072    42b0 ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  17565       0       0   17565    449d ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  38953      60       0   39013    9865 ssl_tls.o (ex library/libmbedtls.a)
  88373      60     600   89033   15bc9 (TOTALS)

TLS-only
   text    data     bss     dec     hex filename
   1820       0       4    1824     720 debug.o (ex library/libmbedtls.a)
      0       0       0       0       0 net_sockets.o (ex library/libmbedtls.a)
    548       0       0     548     224 ssl_cache.o (ex library/libmbedtls.a)
  11155       0     596   11751    2de7 ssl_ciphersuites.o (ex library/libmbedtls.a)
  14916       0       0   14916    3a44 ssl_cli.o (ex library/libmbedtls.a)
    460       0       0     460     1cc ssl_cookie.o (ex library/libmbedtls.a)
  15852       0       0   15852    3dec ssl_srv.o (ex library/libmbedtls.a)
    800       0       0     800     320 ssl_ticket.o (ex library/libmbedtls.a)
  27623      60       0   27683    6c23 ssl_tls.o (ex library/libmbedtls.a)
  73174      60     600   73834   1206a (TOTALS)
```

It can be seen that a DTLS-only build is now starting to be a bit smaller than
a dual-mode build, which is the purpose of the new build option.
2019-06-06 13:02:14 +02:00
Manuel Pégourié-Gonnard
e744eab3b1 Adapt defaults and programs documentation 2019-06-06 13:02:14 +02:00
Hanno Becker
68b856d0ac Fix style issue and wording 2019-06-05 14:25:28 +01:00
Hanno Becker
fe87027512 Fix memory leak 2019-06-05 14:25:28 +01:00
Hanno Becker
fd39919aa3 Improve formatting of ssl_parse_certificate_chain() 2019-06-05 14:25:28 +01:00
Hanno Becker
285ff0c362 Add compile-time guards around helper routine 2019-06-05 14:25:28 +01:00
Hanno Becker
33c3dc8591 Don't store the peer CRT chain twice during renegotiation
Context: During a handshake, the SSL/TLS handshake logic constructs
an instance of ::mbedtls_ssl_session representing the SSL session
being established. This structure contains information such as the
session's master secret, the peer certificate, or the session ticket
issues by the server (if applicable).
During a renegotiation, the new session is constructed aside the existing
one and destroys and replaces the latter only when the renegotiation is
complete. While conceptually clear, this means that during the renegotiation,
large pieces of information such as the peer's CRT or the session ticket
exist twice in memory, even though the original versions are removed
eventually.

This commit removes the simultaneous presence of two peer CRT chains
in memory during renegotiation, in the following way:
- Unlike in the case of SessionTickets handled in the previous commit,
  we cannot simply free the peer's CRT chain from the previous handshake
  before parsing the new one, as we need to verify that the peer's end-CRT
  hasn't changed to mitigate the 'Triple Handshake Attack'.
- Instead, we perform a binary comparison of the original peer end-CRT
  with the one presented during renegotiation, and if it succeeds, we
  avoid re-parsing CRT by moving the corresponding CRT pointer from the
  old to the new session structure.
- The remaining CRTs in the peer's chain are not affected by the triple
  handshake attack protection, and for them we may employ the canonical
  approach of freeing them before parsing the remainder of the new chain.

Note that this commit intends to not change any observable behavior
of the stack. In particular:
- The peer's CRT chain is still verified during renegotiation.
- The tail of the peer's CRT chain may change during renegotiation.
2019-06-05 14:25:28 +01:00
Jaeden Amero
2eaf2c7969 ssl: Don't access non-existent encrypt_then_mac field
When MBEDTLS_SSL_ENCRYPT_THEN_MAC is enabled, but not
MBEDTLS_SSL_SOME_MODES_USE_MAC, mbedtls_ssl_derive_keys() and
build_transforms() will attempt to use a non-existent `encrypt_then_mac`
field in the ssl_transform.

    Compile [ 93.7%]: ssl_tls.c
    [Error] ssl_tls.c@865,14: 'mbedtls_ssl_transform {aka struct mbedtls_ssl_transform}' ha
s no member named 'encrypt_then_mac'
    [ERROR] ./mbed-os/features/mbedtls/src/ssl_tls.c: In function 'mbedtls_ssl_derive_keys'
:
    ./mbed-os/features/mbedtls/src/ssl_tls.c:865:14: error: 'mbedtls_ssl_transform {aka str
uct mbedtls_ssl_transform}' has no member named 'encrypt_then_mac'
         transform->encrypt_then_mac = session->encrypt_then_mac;
                  ^~

Change mbedtls_ssl_derive_keys() and build_transforms() to only access
`encrypt_then_mac` if `encrypt_then_mac` is actually present. Fix any
unused variable warnings along the way, by additionally wrapping
function parameters with MBEDTLS_SSL_SOME_MODES_USE_MAC.

Add a regression test to detect when we have regressions with
configurations that do not include any MAC ciphersuites.

Fixes 92231325a7 ("Reduce size of `ssl_transform` if no MAC ciphersuite is enabled")
2019-06-05 14:22:11 +01:00
Hanno Becker
7bf7710f40 Remove reference to outdated compile-time option 2019-06-04 09:44:25 +01:00
Hanno Becker
5dbcc9f441 Introduce specific error for ver/cfg mismatch on deserialization
This commit introduces a new SSL error code

  `MBEDTLS_ERR_SSL_VERSION_MISMATCH`

which can be used to indicate operation failure due to a
mismatch of version or configuration.

It is put to use in the implementation of `mbedtls_ssl_session_load()`
to signal the attempt to de-serialize a session which has been serialized
in a build of Mbed TLS using a different version or configuration.
2019-06-03 13:01:21 +01:00
Hanno Becker
baf968cf69 Use def'n consts for bits in config-identifier of serialized data 2019-06-03 12:49:09 +01:00
Hanno Becker
b36db4f368 Note that ver+fmt bytes in serialized data must not be removed 2019-06-03 12:49:09 +01:00
Hanno Becker
26829e99b2 Improve doc'n of config-identifying bitfield in serialized session 2019-06-03 12:48:50 +01:00
Hanno Becker
1d8b6d7b12 Session serialization: Fail with BAD_INPUT_DATA if buffer too small 2019-06-03 12:48:31 +01:00
Hanno Becker
41527624f6 Encode relevant parts of the config in serialized session header
This commit makes use of the added space in the session header to
encode the state of those parts of the compile-time configuration
which influence the structure of the serialized session in the
present version of Mbed TLS. Specifically, these are
- the options which influence the presence/omission of fields
  from mbedtls_ssl_session (which is currently shallow-copied
  into the serialized session)
- the setting of MBEDTLS_X509_CRT_PARSE_C, which determines whether
  the serialized session contains a CRT-length + CRT-value pair after
  the shallow-copied mbedtls_ssl_session instance.
- the setting of MBEDTLS_SSL_SESSION_TICKETS, which determines whether
  the serialized session contains a session ticket.
2019-06-03 12:48:16 +01:00
Hanno Becker
557fe9ffde Add configuration identifier to serialized SSL sessions
This commit adds space for two bytes in the header of serizlied
SSL sessions which can be used to determine the structure of the
remaining serialized session in the respective version of Mbed TLS.

Specifically, if parts of the session depend on whether specific
compile-time options are set or not, the setting of these options
can be encoded in the added space.

This commit doesn't yet make use of the fields.
2019-06-03 12:46:39 +01:00
Hanno Becker
b5352f0489 Add Mbed TLS version to SSL sessions
The format of serialized SSL sessions depends on the version and the
configuration of Mbed TLS; attempts to restore sessions established
in different versions and/or configurations lead to undefined behaviour.

This commit adds an 3-byte version header to the serialized session
generated and cleanly fails ticket parsing in case a session from a
non-matching version of Mbed TLS is presented.
2019-06-03 12:46:23 +01:00
Manuel Pégourié-Gonnard
60a4299bbf Add new ABI-independent format for serialization 2019-06-03 10:15:07 +02:00
Manuel Pégourié-Gonnard
35ccdbb636 Normalize spelling to serialiZation
We have explicit recommendations to use US spelling for technical writing, so
let's apply this to code as well for uniformity. (My fingers tend to prefer UK
spelling, so this needs to be fixed in many places.)

sed -i 's/\([Ss]eriali\)s/\1z/g' **/*.[ch] **/*.function **/*.data ChangeLog
2019-06-03 09:55:16 +02:00
Manuel Pégourié-Gonnard
5709811dd2 Add test for session_load() from small buffers
This uncovered a bug that led to a double-free (in practice, in general could
be free() on any invalid value): initially the session structure is loaded
with `memcpy()` which copies the previous values of pointers peer_cert and
ticket to heap-allocated buffers (or any other value if the input is
attacker-controlled). Now if we exit before we got a chance to replace those
invalid values with valid ones (for example because the input buffer is too
small, or because the second malloc() failed), then the next call to
session_free() is going to call free() on invalid pointers.

This bug is fixed in this commit by always setting the pointers to NULL right
after they've been read from the serialised state, so that the invalid values
can never be used.

(An alternative would be to NULL-ify them when writing, which was rejected
mostly because we need to do it when reading anyway (as the consequences of
free(invalid) are too severe to take any risk), so doing it when writing as
well is redundant and a waste of code size.)

Also, while thinking about what happens in case of errors, it became apparent
to me that it was bad practice to leave the session structure in an
half-initialised state and rely on the caller to call session_free(), so this
commit also ensures we always clear the structure when loading failed.
2019-06-03 09:51:08 +02:00
Manuel Pégourié-Gonnard
32ce596c35 Improve save API by always updating olen
This allows callers to discover what an appropriate size is. Otherwise they'd
have to either try repeatedly, or allocate an overly large buffer (or some
combination of those).

Adapt documentation an example usage in ssl_client2.
2019-06-03 09:51:08 +02:00
Manuel Pégourié-Gonnard
37a5324c74 Add mbedtls_ssl_get_session_pointer()
Avoid useless copy with mbedtls_ssl_get_session() before serialising.

Used in ssl_client2 for testing and demonstrating usage, but unfortunately
that means mbedtls_ssl_get_session() is no longer tested, which will be fixed
in the next commit.
2019-06-03 09:51:08 +02:00
Manuel Pégourié-Gonnard
ef4ae611e4 Add support for serialisation session with ticket
On client side, this is required for the main use case where of serialising a
session for later resumption, in case tickets are used.

On server side, this doesn't change much as ticket_len will always be 0.

This unblocks testing the functions by using them in ssl_client2, which will
be done in the next commit.
2019-06-03 09:51:08 +02:00
Manuel Pégourié-Gonnard
91f4ca2ed1 Move session save/load function to ssl_tls.c
This finishes making these functions public. Next step is to get them tested,
but there's currently a blocker for that, see next commit (and the commit
after it for tests).
2019-06-03 09:51:08 +02:00
Simon Butcher
0d1d76f987 Merge remote-tracking branch 'origin/pr/561' into baremetal 2019-05-29 15:09:24 +01:00
Simon Butcher
5a790f9214 Merge remote-tracking branch 'origin/pr/563' into baremetal 2019-05-24 15:06:16 +01:00
Hanno Becker
675c4d6d35 Add debug line witnessing receipt of unexpected CID 2019-05-24 10:11:06 +01:00
Hanno Becker
d8f7c4aa59 Fix indentation in debug message in ssl_tls.c 2019-05-23 17:03:44 +01:00
Hanno Becker
3b2bf5b214 Improve comment in ssl_parse_record_header() 2019-05-23 17:03:19 +01:00
Hanno Becker
633d604837 Allow passing NULL pointers to mbedtls_ssl_get_peer_cid()
This commit modifies mbedtls_ssl_get_peer_cid() to also allow passing
NULL pointers in the arguments for the peer's CID value and length, in
case this information is needed.

For example, some users might only be interested in whether the use of
the CID was negotiated, in which case both CID value and length pointers
can be set to NULL. Other users might only be interested in confirming
that the use of CID was negotiated and the peer chose the empty CID,
in which case the CID value pointer only would be set to NULL.
It doesn't make sense to pass a NULL pointer for the CID length but a
non-NULL pointer for the CID value, as the caller has no way of telling
the length of the returned CID - and this case is therefore forbidden.
2019-05-22 16:50:35 +01:00
Hanno Becker
a5a2b08a05 Rename MBEDTLS_SSL_CID to MBEDTLS_SSL_DTLS_CONNECTION_ID
Files modified via

sed -i 's/MBEDTLS_SSL_CID\([^_]\|$\)/MBEDTLS_SSL_DTLS_CONNECTION_ID\1/g' **/*.c **/*.h **/*.sh **/*.function
2019-05-20 15:35:36 +01:00
Hanno Becker
e582d12264 Slightly reorder CID debug messages during creation of transforms 2019-05-20 15:32:36 +01:00
Hanno Becker
791ec6bff2 Fix mbedtls_ssl_conf_cid() to not depend on macro constant values
The previous implementation of mbedtls_ssl_conf_cid() relied on
MBEDTLS_SSL_UNEXPECTED_CID_IGNORE being defined as 1.
2019-05-20 15:32:36 +01:00
Hanno Becker
b86c2a8c5d Remove warnings about unfinished CID implementation
The implementation is complete now.
2019-05-20 15:32:36 +01:00
Hanno Becker
e8eff9a517 Allow to configure the stack's behaviour on unexpected CIDs
This commit modifies the CID configuration API mbedtls_ssl_conf_cid_len()
to allow the configuration of the stack's behaviour when receiving an
encrypted DTLS record with unexpected CID.
2019-05-20 15:32:36 +01:00
Hanno Becker
7842609e3b Remove restriction on value of MBEDTLS_SSL_CID_PADDING_GRANULARITY 2019-05-20 15:32:36 +01:00
Hanno Becker
7ba3568318 Make signed to unsigned integer truncation cast explicit 2019-05-20 15:32:36 +01:00
Hanno Becker
550e1662c7 Allow the configuration of padding when using CID extension 2019-05-20 15:32:36 +01:00
Hanno Becker
9bf10ea25d Set CID pointer to default value even for TLS
There are two options:
1. Don't set it, and don't use it during record protection,
   guarding the respective paths by a check whether TLS or
   DTLS is used.
2. Set it to the default value even for TLS, and avoid the
   protocol-dependent branch during record protection.

This commit picks option 2.
2019-05-20 15:32:36 +01:00
Hanno Becker
f65ad82eba Fix typo in comment 2019-05-20 15:32:36 +01:00
Hanno Becker
043a2a4869 Remove indicators and warnings about unfinished CID implementation 2019-05-20 15:32:36 +01:00
Hanno Becker
4932f9f229 Re-enable passing CIDs to record transforms 2019-05-20 15:32:36 +01:00
Hanno Becker
687e0fb568 Don't fail on record with unexpected CID
This commit changes the stack's behaviour when facing a record
with a non-matching CID. Previously, the stack failed in this
case, while now we silently skip over the current record.
2019-05-20 15:32:36 +01:00
Hanno Becker
abd7c89923 Re-enable CID comparison when decrypting CID-based records 2019-05-20 15:32:36 +01:00
Hanno Becker
8b09b73cb1 Implement parsing of CID-based records
Previously, ssl_get_next_record() would fetch 13 Bytes for the
record header and hand over to ssl_parse_record_header() to parse
and validate these. With the introduction of CID-based records, the
record length is not known in advance, and parsing and validating
must happen at the same time. ssl_parse_record_header() is therefore
rewritten in the following way:
1. Fetch and validate record content type and version.
2. If the record content type indicates a record including a CID,
   adjust the record header pointers accordingly; here, we use the
   statically configured length of incoming CIDs, avoiding any
   elaborate CID parsing mechanism or dependency on the record
   epoch, as explained in the previous commit.
3. Fetch the rest of the record header (note: this doesn't actually
   fetch anything, but makes sure that the datagram fetched in the
   earlier call to ssl_fetch_input() contains enough data).
4. Parse and validate the rest of the record header as before.
2019-05-20 15:32:36 +01:00
Hanno Becker
ff3e9c2d0d Adapt record encryption/decryption routines to change of record type
This commit modifies the code surrounding the invocations of
ssl_decrypt_buf() and ssl_encrypt_buf() to deal with a change
of record content type during CID-based record encryption/decryption.
2019-05-20 15:32:36 +01:00
Hanno Becker
70e7928d76 Add pointers to in/out CID fields to mbedtls_ssl_context
mbedtls_ssl_context contains pointers in_buf, in_hdr, in_len, ...
which point to various parts of the header of an incoming TLS or
DTLS record; similarly, there are pointers out_buf, ... for
outgoing records.

This commit adds fields in_cid and out_cid which point to where
the CID of incoming/outgoing records should reside, if present,
namely prior to where the record length resides.

Quoting https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-04:

   The DTLSInnerPlaintext value is then encrypted and the CID added to
   produce the final DTLSCiphertext.

        struct {
            ContentType special_type = tls12_cid; /* 25 */
            ProtocolVersion version;
            uint16 epoch;
            uint48 sequence_number;
            opaque cid[cid_length];               // New field
            uint16 length;
            opaque enc_content[DTLSCiphertext.length];
        } DTLSCiphertext;

For outgoing records, out_cid is set in ssl_update_out_pointers()
based on the settings in the current outgoing transform.

For incoming records, ssl_update_in_pointers() sets in_cid as if no
CID was present, and it is the responsibility of ssl_parse_record_header()
to update the field (as well as in_len, in_msg and in_iv) when parsing
records that do contain a CID. This will be done in a subsequent commit.

Finally, the code around the invocations of ssl_decrypt_buf()
and ssl_encrypt_buf() is adapted to transfer the CID from the
input/output buffer to the CID field in the internal record
structure (which is what ssl_{encrypt/decrypt}_buf() uses).

Note that mbedtls_ssl_in_hdr_len() doesn't need change because
it infers the header length as in_iv - in_hdr, which will account
for the CID for records using such.
2019-05-20 15:32:36 +01:00
Hanno Becker
add0190059 Account for additional record expansion when using CIDs
Using the Connection ID extension increases the maximum record expansion
because
- the real record content type is added to the plaintext
- the plaintext may be padded with an arbitrary number of
  zero bytes, in order to prevent leakage of information
  through package length analysis. Currently, we always
  pad the plaintext in a minimal way so that its length
  is a multiple of 16 Bytes.

This commit adapts the various parts of the library to account
for that additional source of record expansion.
2019-05-20 15:32:36 +01:00
Hanno Becker
eec2be9c9f Add CID configuration API
Context:
The CID draft does not require that the length of CIDs used for incoming
records must not change in the course of a connection. Since the record
header does not contain a length field for the CID, this means that if
CIDs of varying lengths are used, the CID length must be inferred from
other aspects of the record header (such as the epoch) and/or by means
outside of the protocol, e.g. by coding its length in the CID itself.

Inferring the CID length from the record's epoch is theoretically possible
in DTLS 1.2, but it requires the information about the epoch to be present
even if the epoch is no longer used: That's because one should silently drop
records from old epochs, but not the entire datagrams to which they belong
(there might be entire flights in a single datagram, including a change of
epoch); however, in order to do so, one needs to parse the record's content
length, the position of which is only known once the CID length for the epoch
is known. In conclusion, it puts a significant burden on the implementation
to infer the CID length from the record epoch, which moreover mangles record
processing with the high-level logic of the protocol (determining which epochs
are in use in which flights, when they are changed, etc. -- this would normally
determine when we drop epochs).

Moreover, with DTLS 1.3, CIDs are no longer uniquely associated to epochs,
but every epoch may use a set of CIDs of varying lengths -- in that case,
it's even theoretically impossible to do record header parsing based on
the epoch configuration only.

We must therefore seek a way for standalone record header parsing, which
means that we must either (a) fix the CID lengths for incoming records,
or (b) allow the application-code to configure a callback to implement
an application-specific CID parsing which would somehow infer the length
of the CID from the CID itself.

Supporting multiple lengths for incoming CIDs significantly increases
complexity while, on the other hand, the restriction to a fixed CID length
for incoming CIDs (which the application controls - in contrast to the
lengths of the CIDs used when writing messages to the peer) doesn't
appear to severely limit the usefulness of the CID extension.

Therefore, the initial implementation of the CID feature will require
a fixed length for incoming CIDs, which is what this commit enforces,
in the following way:

In order to avoid a change of API in case support for variable lengths
CIDs shall be added at some point, we keep mbedtls_ssl_set_cid(), which
includes a CID length parameter, but add a new API mbedtls_ssl_conf_cid_len()
which applies to an SSL configuration, and which fixes the CID length that
any call to mbetls_ssl_set_cid() which applies to an SSL context that is bound
to the given SSL configuration must use.

While this creates a slight redundancy of parameters, it allows to
potentially add an API like mbedtls_ssl_conf_cid_len_cb() later which
could allow users to register a callback which dynamically infers the
length of a CID at record header parsing time, without changing the
rest of the API.
2019-05-20 15:32:36 +01:00
Hanno Becker
4339576208 Split mbedtls_ssl_hdr_len() in separate functions for in/out records
The function mbedtls_ssl_hdr_len() returns the length of the record
header (so far: always 13 Bytes for DTLS, and always 5 Bytes for TLS).

With the introduction of the CID extension, the lengths of record
headers depends on whether the records are incoming or outgoing,
and also on the current transform.

Preparing for this, this commit splits mbedtls_ssl_hdr_len() in two
-- so far unmodified -- functions mbedtls_ssl_in_hdr_len() and
mbedtls_ssl_out_hdr_len() and replaces the uses of mbedtls_ssl_hdr_len()
according to whether they are about incoming or outgoing records.

There is no need to change the signature of mbedtls_ssl_{in/out}_hdr_len()
in preparation for its dependency on the currently active transform,
since the SSL context is passed as an argument, and the currently
active transform is referenced from that.
2019-05-20 15:32:36 +01:00
Hanno Becker
46483f11bf Add helper function to check validity of record content type
With the introduction of the CID feature, the stack needs to be able
to handle a change of record content type during record protection,
which in particular means that the record content type check will
need to move or be duplicated.

This commit introduces a tiny static helper function which checks
the validity of record content types, which hopefully makes it
easier to subsequently move or duplicate this check.
2019-05-20 15:32:36 +01:00
Hanno Becker
74dd3a70d8 Move dropping of unexpected AD records to after record decryption
With the introduction of the CID extension, the record content type
may change during decryption; we must therefore re-consider every
record content type check that happens before decryption, and either
move or duplicate it to ensure it also applies to records whose
real content type is only revealed during decryption.

This commit does this for the silent dropping of unexpected
ApplicationData records in DTLS. Previously, this was caught
in ssl_parse_record_header(), returning
MBEDTLS_ERR_SSL_UNEXPECTED_RECORD which in ssl_get_next_record()
would lead to silent skipping of the record.

When using CID, this check wouldn't trigger e.g. when delayed
encrypted ApplicationData records come on a CID-based connection
during a renegotiation.

This commit moves the check to mbedtls_ssl_handle_message_type()
and returns MBEDTLS_ERR_SSL_NON_FATAL if it triggers, which leads
so silent skipover in the caller mbedtls_ssl_read_record().
2019-05-20 15:32:36 +01:00
Hanno Becker
f5970a0945 Set pointer to start of plaintext at record decryption time
The SSL context structure mbedtls_ssl_context contains several pointers
ssl->in_hdr, ssl->in_len, ssl->in_iv, ssl->in_msg pointing to various
parts of the record header in an incoming record, and they are setup
in the static function ssl_update_in_pointers() based on the _expected_
transform for the next incoming record.
In particular, the pointer ssl->in_msg is set to where the record plaintext
should reside after record decryption, and an assertion double-checks this
after each call to ssl_decrypt_buf().

This commit removes the dependency of ssl_update_in_pointers() on the
expected incoming transform by setting ssl->in_msg to ssl->in_iv --
the beginning of the record content (potentially including the IV) --
and adjusting ssl->in_msg after calling ssl_decrypt_buf() on a protected
record.

Care has to be taken to not load ssl->in_msg before calling
mbedtls_ssl_read_record(), then, which was previously the
case in ssl_parse_server_hello(); the commit fixes that.
2019-05-20 15:32:36 +01:00
Hanno Becker
16e9ae2f95 Treat an invalid record after decryption as fatal
If a record exhibits an invalid feature only after successful
authenticated decryption, this is a protocol violation by the
peer and should hence lead to connection failure. The previous
code, however, would silently ignore such records. This commit
fixes this.

So far, the only case to which this applies is the non-acceptance
of empty non-AD records in TLS 1.2. With the present commit, such
records lead to connection failure, while previously, they were
silently ignored.

With the introduction of the Connection ID extension (or TLS 1.3),
this will also apply to records whose real content type -- which
is only revealed during authenticated decryption -- is invalid.
2019-05-20 15:32:36 +01:00
Hanno Becker
70463dbb2d Expain rationale for handling of consecutive empty AD records 2019-05-20 15:32:36 +01:00
Hanno Becker
78c430269b Don't allow calling CID API outside of DTLS 2019-05-20 15:32:36 +01:00
Hanno Becker
1f02f05f2e Fix additional data calculation if CID is disabled
In contrast to other aspects of the Connection ID extension,
the CID-based additional data for MAC computations differs from
the non-CID case even if the CID length is 0, because it
includes the CID length.
2019-05-20 15:17:05 +01:00
Hanno Becker
3b1a88506b Remove unnecessary empty line in ssl_tls.c 2019-05-20 15:10:50 +01:00
Hanno Becker
7dc2577f01 Don't quote DTLSInnerPlaintext structure multiple times 2019-05-20 15:08:01 +01:00
Hanno Becker
8969369a83 Improve wording in ssl_build_inner_plaintext() 2019-05-20 15:06:12 +01:00
Hanno Becker
24ce1eba66 Remove unnecessary whitespace in ssl_extract_add_data_from_record() 2019-05-20 15:01:46 +01:00
Hanno Becker
28a0c4e149 Reduce stack usage for additional data buffers in record dec/enc 2019-05-20 14:56:03 +01:00
Hanno Becker
acadb0a8c9 Add length of CID to additional data used for record protection
Quoting the CID draft 04:

   -  Block Ciphers:

       MAC(MAC_write_key, seq_num +
           tls12_cid +                     // New input
           DTLSPlaintext.version +
           cid +                           // New input
           cid_length +                    // New input
           length_of_DTLSInnerPlaintext +  // New input
           DTLSInnerPlaintext.content +    // New input
           DTLSInnerPlaintext.real_type +  // New input
           DTLSInnerPlaintext.zeros        // New input
       )

And similar for AEAD and Encrypt-then-MAC.
2019-05-20 14:55:59 +01:00
Hanno Becker
99abf51056 Improve documentation of ssl_extract_add_data_from_record() 2019-05-20 14:55:30 +01:00
Manuel Pégourié-Gonnard
9c5bcc9220 Use more specific name in debug message for testing
While 'session hash' is currently unique, so suitable to prove that the
intended code path has been taken, it's a generic enough phrase that in the
future we might add other debug messages containing it in completely unrelated
code paths. In order to future-proof the accuracy of the test, let's use a
more specific string.
2019-05-20 12:09:50 +02:00
Manuel Pégourié-Gonnard
762d011ece Fix alignment issues 2019-05-20 10:27:20 +02:00
Manuel Pégourié-Gonnard
42c814fdc1 Clarify comment about TLS versions
The previous comment used "TLS" as a shortcut for "TLS 1.0/1.1" which was
confusing. This partially reflected the names of the calc_verify/finished that
go ssl, tls (for 1.0/1.1) tls_shaxxx (for 1.2), but still it's clearer to be
explicit in the comment - and perhaps in the long term the function names
could be clarified instead.
2019-05-20 10:12:43 +02:00
Manuel Pégourié-Gonnard
5478e1e5ed Remove redundant debug message.
Two consecutive messages (ie no branch between them) at the same level are not
needed, so only keep the one that has the most information.
2019-05-20 10:07:29 +02:00
Hanno Becker
505089d944 Fix missing compile-time guards around CID-only constants 2019-05-17 10:23:47 +01:00
Hanno Becker
4c6fe12db8 Remove TODO 2019-05-17 10:23:47 +01:00
Hanno Becker
2e7cd5aa4c Use MBEDTLS_ namespace for internal CID length constant 2019-05-17 10:23:47 +01:00
Hanno Becker
d91dc3767f Skip copying CIDs to SSL transforms until CID feature is complete
This commit temporarily comments the copying of the negotiated CIDs
into the established ::mbedtls_ssl_transform in mbedtls_ssl_derive_keys()
until the CID feature has been fully implemented.

While mbedtls_ssl_decrypt_buf() and mbedtls_ssl_encrypt_buf() do
support CID-based record protection by now and can be unit tested,
the following two changes in the rest of the stack are still missing
before CID-based record protection can be integrated:
- Parsing of CIDs in incoming records.
- Allowing the new CID record content type for incoming records.
- Dealing with a change of record content type during record
  decryption.

Further, since mbedtls_ssl_get_peer_cid() judges the use of CIDs by
the CID fields in the currently transforms, this change also requires
temporarily disabling some grepping for ssl_client2 / ssl_server2
debug output in ssl-opt.sh.
2019-05-17 10:23:47 +01:00
Hanno Becker
92c930f7c4 Implement inner plaintext parsing/writing for CID-based connections 2019-05-17 10:23:47 +01:00
Hanno Becker
e83efe6d79 Incorporate CID into MAC computations during record protection
This commit modifies ssl_decrypt_buf() and ssl_encrypt_buf()
to include the CID into authentication data during record
protection.

It does not yet implement the new DTLSInnerPlaintext format
from https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-04
2019-05-17 10:23:47 +01:00
Hanno Becker
8013b27481 Replace 'ingoing' -> 'incoming' in CID debug messages 2019-05-17 10:20:41 +01:00
Hanno Becker
cb063f5a5b Document behaviour of mbedtls_ssl_get_peer_cid() for empty CIDs 2019-05-17 10:20:41 +01:00
Hanno Becker
b4a5606e2d Make integer truncation explicit in mbedtls_ssl_set_cid() 2019-05-17 10:20:41 +01:00
Hanno Becker
2de89fae8f Implement mbedtls_ssl_get_peer_cid() 2019-05-17 10:20:41 +01:00
Hanno Becker
dd0afca3f6 Copy CIDs into SSL transform if use of CID has been negotiated 2019-05-17 10:20:41 +01:00
Hanno Becker
0748986178 Allow configuring own CID fields through mbedtls_ssl_get_peer_cid() 2019-05-17 10:20:41 +01:00
Manuel Pégourié-Gonnard
84ef8bde68 Remove 'session' input from populate_tranform()
When using this function to deserialize, it's not a problem to have a session
structure as input as we'll have one around anyway (most probably freshly
deserialised).

However for tests it's convenient to be able to build a transform without
having a session structure around.

Also, removing this structure from parameters makes the function signature
more uniform, the only exception left being the ssl param at the end that's
hard to avoid for now.
2019-05-10 10:50:04 +02:00
Manuel Pégourié-Gonnard
cf31216ace Fix typo in comment 2019-05-10 10:25:00 +02:00
Simon Butcher
724a695534 Merge remote-tracking branch 'origin/pr/562' into baremetal 2019-05-09 17:11:38 +01:00
Manuel Pégourié-Gonnard
86e48c213c Enforce promise to not use whole ssl context
Configs with no DEBUG_C are use for example in test-ref-configs.pl, which also
runs parts of compat.sh or ssl-opt.sh on them, so the added 'ssl = NULL'
statements will be exercised in those tests at least.
2019-05-07 10:32:19 +02:00
Manuel Pégourié-Gonnard
1d10a98f56 Partially rm 'ssl' input from populate_transform() 2019-05-07 10:31:53 +02:00
Manuel Pégourié-Gonnard
0bcfbc3e04 Remove "handshake" input from populate_transform() 2019-05-07 09:59:41 +02:00
Manuel Pégourié-Gonnard
12a3f445b6 Start refining parameters of populate_transform()
Parameters 'handshake' and 'ssl' will be replaced with more fine-grained
inputs in follow-up commits.
2019-05-07 09:59:41 +02:00
Manuel Pégourié-Gonnard
a1abb26094 Move compress_buf allocation to derive_keys 2019-05-07 09:59:41 +02:00
Manuel Pégourié-Gonnard
707728dfca Move handling of randbytes to derive_keys() 2019-05-07 09:59:41 +02:00
Manuel Pégourié-Gonnard
bcf258e077 Remove duplicated branch in ssl_compute_master() 2019-05-07 09:59:40 +02:00
Manuel Pégourié-Gonnard
a575975280 Make calc_verify() return the length as well
Simplifies ssl_compute_hash(), but unfortunately not so much the other uses.
2019-05-07 09:59:32 +02:00
Manuel Pégourié-Gonnard
ed3b7a9492 Constify ssl_context param of calc_verify() 2019-05-03 10:00:45 +02:00
Manuel Pégourié-Gonnard
c28c8895e5 Improve signature of ssl_compute_master()
Make it more explicit what's used. Unfortunately, we still need ssl as a
parameter for debugging, and because calc_verify wants it as a parameter (for
all TLS versions except SSL3 it would actually only need handshake, but SSL3
also accesses session_negotiate).

It's also because of calc_verify that we can't make it const yet, but see next
commit.
2019-05-03 10:00:45 +02:00
Manuel Pégourié-Gonnard
dafe5227d4 Reduce indentation in ssl_compute_master()
Exit earlier when there's noting to do.

For a small diff, review with 'git show -w'.
2019-05-03 10:00:44 +02:00
Manuel Pégourié-Gonnard
7edd5876ce Start extracting ssl_compute_master()
For now just moving code around, not changing indentation. Calling convention
and signature are going to be adjusted in upcoming commits.
2019-05-03 10:00:44 +02:00
Manuel Pégourié-Gonnard
aa3c701193 Fix signature of ssl_set_transform_prfs() 2019-05-03 10:00:44 +02:00
Manuel Pégourié-Gonnard
52aa520c96 Start extraction ssl_set_handshake_prfs()
For now just moving code around, will improve signature in the next commit.
2019-04-30 11:54:22 +02:00
Manuel Pégourié-Gonnard
5ed5e90ec4 Start splitting populate_transform() out of derive_keys()
This is currently a dummy, just introducing the new name.
2019-04-30 11:41:40 +02:00
Hanno Becker
08885813c3 Fix uninitialized variable access in debug output of record enc/dec 2019-04-29 12:21:31 +02:00
Hanno Becker
c5aee96855 Adapt record length value after encryption 2019-04-29 12:19:07 +02:00
Hanno Becker
30d02cdeb0 Rename ssl_decrypt_buf() to mbedtls_ssl_decrypt_buf() in comment 2019-04-29 12:18:38 +02:00
Hanno Becker
93012fe8e8 Double check that record expansion is as expected during decryption 2019-04-29 12:17:58 +02:00
Hanno Becker
a795323cd5 Move debugging output after record decryption
The debugging call printing the decrypted record payload happened
before updating ssl->in_msglen.
2019-04-29 12:17:51 +02:00
Hanno Becker
611a83b571 Add tests for record encryption/decryption
This commit adds tests exercising mutually inverse pairs of
record encryption and decryption transformations for the various
transformation types allowed in TLS: Stream, CBC, and AEAD.
2019-04-29 12:15:21 +02:00
Hanno Becker
92231325a7 Reduce size of ssl_transform if no MAC ciphersuite is enabled
The hash contexts `ssl_transform->md_ctx_{enc/dec}` are not used if
only AEAD ciphersuites are enabled. This commit removes them from the
`ssl_transform` struct in this case, saving a few bytes.
2019-04-29 12:15:05 +02:00
Hanno Becker
f122944b7d Remove code from ssl_derive_keys if relevant modes are not enabled
This commit guards code specific to AEAD, CBC and stream cipher modes
in `ssl_derive_keys` by the respective configuration flags, analogous
to the guards that are already in place in the record decryption and
encryption functions `ssl_decrypt_buf` resp. `ssl_decrypt_buf`.
2019-04-29 12:14:51 +02:00
Hanno Becker
4c6876b134 Provide standalone version of ssl_decrypt_buf
Analogous to the previous commit, but concerning the record decryption
routine `ssl_decrypt_buf`.

An important change regards the checking of CBC padding:
Prior to this commit, the CBC padding check always read 256 bytes at
the end of the internal record buffer, almost always going past the
boundaries of the record under consideration. In order to stay within
the bounds of the given record, this commit changes this behavior by
always reading the last min(256, plaintext_len) bytes of the record
plaintext buffer and taking into consideration the last `padlen` of
these for the padding check. With this change, the memory access
pattern and runtime of the padding check is entirely determined by
the size of the encrypted record, in particular not giving away
any information on the validity of the padding.

The following depicts the different behaviors:

1) Previous CBC padding check

1.a) Claimed padding length <= plaintext length

  +----------------------------------------+----+
  |   Record plaintext buffer   |          | PL |
  +----------------------------------------+----+
                                 \__ PL __/

                                +------------------------------------...
                                |  read for padding check            ...
                                +------------------------------------...
                                                |
                                                 contents discarded
                                                 from here

1.b) Claimed padding length > plaintext length

  +----------------------------------------+----+
  |   Record plaintext buffer              | PL |
  +----------------------------------------+----+
                                           +-------------------------...
                                           |  read for padding check ...
                                           +-------------------------...
                                                |
                                                 contents discarded
                                                 from here

2) New CBC padding check

  +----------------------------------------+----+
  |   Record plaintext buffer   |          | PL |
  +----------------------------------------+----+
                                 \__ PL __/

        +---------------------------------------+
        |        read for padding check         |
        +---------------------------------------+
                                |
                                 contents discarded
                                 until here
2019-04-29 12:13:25 +02:00
Hanno Becker
3307b53413 Provide standalone version of ssl_encrypt_buf
The previous version of the record encryption function
`ssl_encrypt_buf` takes the entire SSL context as an argument,
while intuitively, it should only depend on the current security
parameters and the record buffer.

Analyzing the exact dependencies, it turned out that in addition
to the currently active `ssl_transform` instance and the record
information, the encryption function needs access to
- the negotiated protocol version, and
- the status of the encrypt-then-MAC extension.

This commit moves these two fields into `ssl_transform` and
changes the signature of `ssl_encrypt_buf` to only use an instance
of `ssl_transform` and an instance of the new `ssl_record` type.
The `ssl_context` instance is *solely* kept for the debugging macros
which need an SSL context instance.

The benefit of the change is twofold:
1) It avoids the need of the MPS to deal with instances of
   `ssl_context`. The MPS should only work with records and
   opaque security parameters, which is what the change in
   this commit makes progress towards.
2) It significantly eases testing of the encryption function:
   independent of any SSL context, the encryption function can
   be passed some record buffer to encrypt alongside some arbitrary
   choice of parameters, and e.g. be checked to not overflow the
   provided memory.
2019-04-29 10:58:15 +02:00
Hanno Becker
5cc04d5ae7 Correct space needed for MAC in case of NULL cipher
The macro constant `MBEDTLS_SSL_MAC_ADD` defined in `ssl_internal.h`
defines an upper bound for the amount of space needed for the record
authentication tag. Its definition distinguishes between the
presence of an ARC4 or CBC ciphersuite suite, in which case the maximum
size of an enabled SHA digest is used; otherwise, `MBEDTLS_SSL_MAC_ADD`
is set to 16 to accomodate AEAD authentication tags.

This assignment has a flaw in the situation where confidentiality is
not needed and the NULL cipher is in use. In this case, the
authentication tag also uses a SHA digest, but the definition of
`MBEDTLS_SSL_MAC_ADD` doesn't guarantee enough space.

The present commit fixes this by distinguishing between the presence
of *some* ciphersuite using a MAC, including those using a NULL cipher.
For that, the previously internal macro `SSL_SOME_MODES_USE_MAC` from
`ssl_tls.c` is renamed and moved to the public macro
`MBEDTLS_SOME_MODES_USE_MAC` defined in `ssl_internal.h`.
2019-04-29 10:36:09 +02:00
Hanno Becker
8759e16242 Remove ciphersuite_info from ssl_transform
Prior to this commit, the security parameter struct `ssl_transform`
contained a `ciphersuite_info` field pointing to the information
structure for the negotiated ciphersuite. However, the only
information extracted from that structure that was used in the core
encryption and decryption functions `ssl_encrypt_buf`/`ssl_decrypt_buf`
was the authentication tag length in case of an AEAD cipher.

The present commit removes the `ciphersuite_info` field from the
`ssl_transform` structure and adds an explicit `taglen` field
for AEAD authentication tag length.

This is in accordance with the principle that the `ssl_transform`
structure should contain the raw parameters needed for the record
encryption and decryption functions to work, but not the higher-level
information that gave rise to them. For example, the `ssl_transform`
structure implicitly contains the encryption/decryption keys within
their cipher contexts, but it doesn't contain the SSL master or
premaster secrets. Likewise, it contains an explicit `maclen`, while
the status of the 'Truncated HMAC' extension -- which  determines the
value of `maclen` when the `ssl_transform` structure is created in
`ssl_derive_keys` -- is not contained in `ssl_transform`.

The `ciphersuite_info` pointer was used in other places outside
the encryption/decryption functions during the handshake, and for
these functions to work, this commit adds a `ciphersuite_info` pointer
field to the handshake-local `ssl_handshake_params` structure.
2019-04-29 10:36:01 +02:00
Hanno Becker
e7f2df03a3 Remove key length field from ssl_transform
The `ssl_transform` security parameter structure contains opaque
cipher contexts for use by the record encryption/decryption functions
`ssl_decrypt_buf`/`ssl_encrypt_buf`, while the underlying key material
is configured once in `ssl_derive_keys` and is not explicitly dealt with
anymore afterwards. In particular, the key length is not needed
explicitly by the encryption/decryption functions but is nonetheless
stored in an explicit yet superfluous `keylen` field in `ssl_transform`.
This commit removes this field.
2019-04-29 09:32:08 +02:00
Hanno Becker
ba8cd67467 Guard CID implementations by MBEDTLS_SSL_CID 2019-04-23 12:31:42 +01:00
Hanno Becker
8d0893d0b0 Add warnings about status of implementation of CID API 2019-04-23 12:01:20 +01:00
Hanno Becker
b9e7dea082 Add dummy implementations for CID API 2019-04-09 18:26:59 +01:00
Antonin Décimo
d5f4759594 Fix #2370, minor typos and spelling mistakes 2019-02-18 14:50:57 +00:00
Jaeden Amero
e1b1a2c979 Merge remote-tracking branch 'upstream-public/pr/2181' into development 2018-12-06 16:11:49 +00:00
Janos Follath
3fbdadad7b SSL: Make use of the new ECDH interface
The SSL module accesses ECDH context members directly. This can't work
with the new context, where we can't make any assumption about the
implementation of the context.

This commit makes use of the new functions to avoid accessing ECDH
members directly. The only members that are still accessed directly are
the group ID and the point format and they are independent from the
implementation.
2018-12-06 12:22:46 +00:00
Hanno Becker
f6d6e30820 Fix incomplete assertion in ssl_write_handshake_msg()
ssl_write_handshake_msg() includes the assertion that
`ssl->handshake != NULL` when handling a record which is
(a) a handshake message, and NOT
(b) a HelloRequest.
However, it later calls `ssl_append_flight()` for any
record different from a HelloRequest handshake record,
that is, records satisfying !(a) || !(b), instead of
(a) && !(b) as covered by the assertion (specifically,
CCS or Alert records).

Since `ssl_append_flight()` assumes that `ssl->handshake != NULL`,
this rightfully triggers static analyzer warnings.

This commit expands the scope of the assertion to check
that `ssl->handshake != NULL` for any record which is not
a HelloRequest.
2018-11-07 11:57:51 +00:00
Simon Butcher
2705beaeef Merge remote-tracking branch 'public/pr/2095' into development-proposed 2018-11-04 18:48:04 +00:00
Simon Butcher
17a0fab345 Merge remote-tracking branch 'public/pr/2111' into development-proposed 2018-10-28 16:22:18 +00:00
Simon Butcher
169712e15a Merge remote-tracking branch 'restricted/pr/390' into development 2018-10-24 18:34:30 +01:00
Hanno Becker
dd3ab13da3 Fail when encountering invalid CBC padding in EtM records
This commit changes the behavior of the record decryption routine
`ssl_decrypt_buf()` in the following situation:
1. A CBC ciphersuite with Encrypt-then-MAC is used.
2. A record with valid MAC but invalid CBC padding is received.
In this situation, the previous code would not raise and error but
instead forward the decrypted packet, including the wrong padding,
to the user.

This commit changes this behavior to return the error
MBEDTLS_ERR_SSL_INVALID_MAC instead.

While erroneous, the previous behavior does not constitute a
security flaw since it can only happen for properly authenticated
records, that is, if the peer makes a mistake while preparing the
padded plaintext.
2018-10-17 14:43:14 +01:00
Hanno Becker
805f2e11bd Add missing zeroization of buffered handshake messages
This commit ensures that buffers holding fragmented or
future handshake messages get zeroized before they are
freed when the respective handshake message is no longer
needed. Previously, the handshake message content would
leak on the heap.
2018-10-12 16:50:37 +01:00
Andrzej Kurek
748face36f ssl_tls: fix maximum output length
set maximum output length to MBEDTLS_SSL_OUT_CONTENT_LEN instead of
MBEDTLS_SSL_MAX_CONTENT_LEN.
2018-10-11 07:20:19 -04:00
Andrzej Kurek
ef43ce6e25 Dtls: change the way unlimited mtu is set for client hello messages 2018-10-09 08:24:12 -04:00
Andrzej Kurek
6290dae909 Disable dtls fragmentation for ClientHello messages
Set the handshake mtu to unlimited when encountering a ClienHello message and
reset it to its previous value after writing the record.
2018-10-05 08:06:01 -04:00
Manuel Pégourié-Gonnard
125af948c3 Merge branch 'development-restricted' into iotssl-1260-non-blocking-ecc-restricted
* development-restricted: (578 commits)
  Update library version number to 2.13.1
  Don't define _POSIX_C_SOURCE in header file
  Don't declare and define gmtime()-mutex on Windows platforms
  Correct preprocessor guards determining use of gmtime()
  Correct documentation of mbedtls_platform_gmtime_r()
  Correct typo in documentation of mbedtls_platform_gmtime_r()
  Correct POSIX version check to determine presence of gmtime_r()
  Improve documentation of mbedtls_platform_gmtime_r()
  platform_utils.{c/h} -> platform_util.{c/h}
  Don't include platform_time.h if !MBEDTLS_HAVE_TIME
  Improve wording of documentation of MBEDTLS_PLATFORM_GMTIME_R_ALT
  Fix typo in documentation of MBEDTLS_PLATFORM_GMTIME_R_ALT
  Replace 'thread safe' by 'thread-safe' in the documentation
  Improve documentation of MBEDTLS_HAVE_TIME_DATE
  ChangeLog: Add missing renamings gmtime -> gmtime_r
  Improve documentation of MBEDTLS_HAVE_TIME_DATE
  Minor documentation improvements
  Style: Add missing period in documentation in threading.h
  Rename mbedtls_platform_gmtime() to mbedtls_platform_gmtime_r()
  Guard decl and use of gmtime mutex by HAVE_TIME_DATE and !GMTIME_ALT
  ...
2018-09-11 12:39:14 +02:00
Simon Butcher
0bbb4fc132 Merge branch 'development' into development 2018-08-30 01:11:35 +01:00
Simon Butcher
552754a6ee Merge remote-tracking branch 'public/pr/1988' into development 2018-08-30 00:57:28 +01:00
Simon Butcher
68dbc94720 Merge remote-tracking branch 'public/pr/1951' into development 2018-08-30 00:56:56 +01:00
Hanno Becker
a591c48302 Correct typo in debug message 2018-08-28 17:52:53 +01:00
Hanno Becker
83ab41c665 Correct typo in comment 2018-08-28 17:52:53 +01:00
Hanno Becker
cd9dcda0a0 Add const qualifier to handshake header reading functions 2018-08-28 17:52:53 +01:00
Hanno Becker
39b8bc9aef Change wording of debug message 2018-08-28 17:52:49 +01:00
Hanno Becker
ef7afdfa5a Rename another_record_in_datagram to next_record_is_in_datagram 2018-08-28 17:16:31 +01:00
Hanno Becker
c573ac33dd Fix typos in debug message and comment in ssl-tls.c 2018-08-28 17:15:25 +01:00
Simon Butcher
3af567d4a7 Merge remote-tracking branch 'restricted/pr/437' into development-restricted 2018-08-28 15:33:59 +01:00
Simon Butcher
7f85563f9b Merge remote-tracking branch 'restricted/pr/491' into development-restricted 2018-08-28 15:22:40 +01:00
Simon Butcher
14dac0953e Merge remote-tracking branch 'public/pr/1918' into development 2018-08-28 12:21:41 +01:00
Simon Butcher
1846e406c8 Merge remote-tracking branch 'public/pr/1939' into development 2018-08-28 12:19:56 +01:00
Simon Butcher
4613772dea Merge remote-tracking branch 'public/pr/1915' into development 2018-08-28 11:45:44 +01:00
Hanno Becker
0207e533b2 Style: Correct typo in ssl-tls.c 2018-08-28 10:28:28 +01:00
Hanno Becker
d58477769d Style: Group buffering-related forward declarations in ssl_tls.c 2018-08-28 10:09:23 +01:00
Hanno Becker
360bef3fe3 Reordering: Document that only HS and CCS msgs are buffered 2018-08-28 10:04:33 +01:00
Hanno Becker
4f432ad44d Style: Don't use abbreviations in comments 2018-08-28 10:02:32 +01:00
Hanno Becker
b8f50147ee Add explicit MBEDTLS_DEBUG_C-guard around debugging code 2018-08-28 10:01:34 +01:00
Hanno Becker
f0da6670dc Style: Add braces around if-branch where else-branch has them 2018-08-28 09:55:10 +01:00
Hanno Becker
ecbdf1c048 Style: Correct indentation of debug msgs in mbedtls_ssl_write_record 2018-08-28 09:54:44 +01:00
Hanno Becker
3f7b973e32 Correct typo in mbedtls_ssl_flight_transmit() 2018-08-28 09:53:25 +01:00
Hanno Becker
6e12c1ea7d Enhance debugging output 2018-08-24 14:48:08 +01:00
Hanno Becker
0e96585bdd Merge branch 'datagram_packing' into message_reordering 2018-08-24 12:16:41 +01:00
Hanno Becker
1841b0a11c Rename ssl_conf_datagram_packing() to ssl_set_datagram_packing()
The naming convention is that functions of the form mbedtls_ssl_conf_xxx()
apply to the SSL configuration.
2018-08-24 11:13:57 +01:00
Hanno Becker
f4b010efc4 Limit MTU by maximum fragment length setting
By the standard (RFC 6066, Sect. 4), the Maximum Fragment Length (MFL)
extension limits the maximum record payload size, but not the maximum
datagram size. However, not inferring any limitations on the MTU when
setting the MFL means that a party has no means to dynamically inform
the peer about MTU limitations.

This commit changes the function ssl_get_remaining_payload_in_datagram()
to never return more than

MFL - { Total size of all records within the current datagram }

thereby limiting the MTU to MFL + { Maximum Record Expansion }.
2018-08-24 10:47:29 +01:00
Hanno Becker
283f5efe7d Buffering: Free future record epoch after each flight
The function ssl_free_buffered_record() frees a future epoch record, if
such is present. Previously, it was called in mbedtls_handshake_free(),
i.e. an unused buffered record would be cleared at the end of the handshake.
This commit moves the call to the function ssl_buffering_free() responsible
for freeing all buffering-related data, and which is called not only at
the end of the handshake, but at the end of every flight. In particular,
future record epochs won't be buffered across flight boundaries anymore,
and they shouldn't.
2018-08-24 09:34:47 +01:00
Hanno Becker
081bd81865 ssl_write_handshake_msg(): Always append CCS messages to flights
The previous code appended messages to flights only if their handshake type,
as derived from the first byte in the message, was different from
MBEDTLS_SSL_HS_HELLO_REQUEST. This check should only be performed
for handshake records, while CCS records should immediately be appended.
2018-08-23 19:22:26 +02:00
Hanno Becker
c83d2b3e09 ssl_write_handshake_msg(): Allow alert on client-side SSLv3
In SSLv3, the client sends a NoCertificate alert in response to
a CertificateRequest if it doesn't have a CRT. This previously
lead to failure in ssl_write_handshake_msg() which only accepted
handshake or CCS records.
2018-08-23 19:22:05 +02:00
Hanno Becker
b309b92ee8 ssl_buffering_free_slot(): Double-check validity of slot index 2018-08-23 13:18:05 +01:00
Hanno Becker
65dc885a3b Use size_t for msg_len argument in ssl_get_reassembly_buffer_size() 2018-08-23 09:40:49 +01:00
Hanno Becker
1b20e8e46e Merge branch 'datagram_packing' into message_reordering 2018-08-22 20:36:50 +01:00
Hanno Becker
554b0af195 Fix assertion in mbedtls_ssl_write_record() 2018-08-22 20:33:41 +01:00
Hanno Becker
7428d4fe87 Merge branch 'datagram_packing' into message_reordering 2018-08-22 16:16:59 +01:00
Hanno Becker
551835d5e7 ssl_write_handshake_msg(): Always append CCS messages to flights
The previous code appended messages to flights only if their handshake type,
as derived from the first byte in the message, was different from
MBEDTLS_SSL_HS_HELLO_REQUEST. This check should only be performed
for handshake records, while CCS records should immediately be appended.
2018-08-22 16:16:25 +01:00
Hanno Becker
2c98db2478 ssl_write_handshake_msg(): Allow alert on client-side SSLv3
In SSLv3, the client sends a NoCertificate alert in response to
a CertificateRequest if it doesn't have a CRT. This previously
lead to failure in ssl_write_handshake_msg() which only accepted
handshake or CCS records.
2018-08-22 16:05:47 +01:00
Hanno Becker
635313459f Merge branch 'datagram_packing' into message_reordering 2018-08-22 16:00:57 +01:00
Hanno Becker
11682ccc78 Uniformly treat MTU as size_t 2018-08-22 14:41:02 +01:00
Hanno Becker
3546201dbc Merge branch 'datagram_packing' into message_reordering 2018-08-22 10:25:40 +01:00
Hanno Becker
a67dee256d Merge branch 'iotssl-2402-basic-pmtu-adaptation' into datagram_packing 2018-08-22 10:06:38 +01:00
Manuel Pégourié-Gonnard
b8eec192f6 Implement PMTU auto-reduction in handshake 2018-08-22 10:50:30 +02:00
Hanno Becker
170e2d89da Merge branch 'iotssl-165-dtls-hs-fragmentation-new' into datagram_packing 2018-08-22 09:44:54 +01:00
Hanno Becker
903ee3d363 Merge branch 'datagram_packing' into message_reordering 2018-08-21 17:24:17 +01:00
Hanno Becker
01315ea03a Account for future epoch records in the total buffering size
Previous commits introduced the field `total_bytes_buffered`
which is supposed to keep track of the cumulative size of
all heap allocated buffers used for the purpose of reassembly
and/or buffering of future messages.

However, the buffering of future epoch records were not reflected
in this field so far. This commit changes this, adding the length
of a future epoch record to `total_bytes_buffered` when it's buffered,
and subtracting it when it's freed.
2018-08-21 17:22:17 +01:00
Hanno Becker
a02b0b462d Add function making space for current message reassembly
This commit adds a static function ssl_buffer_make_space() which
takes a buffer size as an argument and attempts to free as many
future message bufffers as necessary to ensure that the desired
amount of buffering space is available without violating the
total buffering limit set by MBEDTLS_SSL_DTLS_MAX_BUFFERING.
2018-08-21 17:20:27 +01:00
Hanno Becker
e1801399a9 Add another debug message to ssl_buffer_message()
Report if there's not enough buffering space available to reassemble
the next expected incoming message.
2018-08-21 16:51:05 +01:00
Hanno Becker
55e9e2aa6b Free future buffers if next handshake messages can't be reassembled
If the next expected handshake message can't be reassembled because
buffered future messages have already used up too much of the available
space for buffering, free those future message buffers in order to
make space for the reassembly, starting with the handshake message
that's farthest in the future.
2018-08-21 16:24:30 +01:00
Hanno Becker
e605b19631 Add function to free a particular buffering slot
This commit adds a static function ssl_buffering_free_slot()
which allows to free a particular structure used to buffer
and/or reassembly some handshake message.
2018-08-21 16:24:27 +01:00
Hanno Becker
96a6c69d0c Correct bounds check in ssl_buffer_message()
The previous bounds check omitted the DTLS handshake header.
2018-08-21 16:11:09 +01:00
Hanno Becker
e0b150f96b Allow limiting the total amount of heap allocations for buffering
This commit introduces a compile time constant MBEDTLS_SSL_DTLS_MAX_BUFFERING
to mbedtls/config.h which allows the user to control the cumulative size of
all heap buffer allocated for the purpose of reassembling and buffering
handshake messages.

It is put to use by introducing a new field `total_bytes_buffered` to
the buffering substructure of `mbedtls_ssl_handshake_params` that keeps
track of the total size of heap allocated buffers for the purpose of
reassembly and buffering at any time. It is increased whenever a handshake
message is buffered or prepared for reassembly, and decreased when a
buffered or fully reassembled message is copied into the input buffer
and passed to the handshake logic layer.

This commit does not yet include future epoch record buffering into
account; this will be done in a subsequent commit.

Also, it is now conceivable that the reassembly of the next expected
handshake message fails because too much buffering space has already
been used up for future messages. This case currently leads to an
error, but instead, the stack should get rid of buffered messages
to be able to buffer the next one. This will need to be implemented
in one of the next commits.
2018-08-21 16:11:04 +01:00
Hanno Becker
2a97b0e7a3 Introduce function to return size of buffer needed for reassembly
A previous commit introduced the function ssl_prepare_reassembly_buffer()
which took a message length and a boolean flag indicating if a reassembly
bit map was needed, and attempted to heap-allocate a buffer of sufficient
size to hold both the message, its header, and potentially the reassembly
bitmap.

A subsequent commit is going to introduce a limit on the amount of heap
allocations allowed for the purpose of buffering, and this change will
need to know the reassembly buffer size before attempting the allocation.

To this end, this commit changes ssl_prepare_reassembly_buffer() into
ssl_get_reassembly_buffer_size() which solely computes the reassembly
buffer size, and performing the heap allocation manually in
ssl_buffer_message().
2018-08-21 15:47:49 +01:00
Hanno Becker
e678eaa93e Reject invalid CCS records early
This commit moves the length and content check for CCS messages to
the function mbedtls_ssl_handle_message_type() which is called after
a record has been deprotected.

Previously, these checks were performed in the function
mbedtls_ssl_parse_change_cipher_spec(); however, now that
the arrival of out-of-order CCS messages is remembered
as a boolean flag, the check also has to happen when this
flag is set. Moving the length and content check to
mbedtls_ssl_handle_message_type() allows to treat both
checks uniformly.
2018-08-21 14:57:46 +01:00
Hanno Becker
47db877039 ssl_write_record: Consider setting flush variable only if unset 2018-08-21 13:32:13 +01:00
Hanno Becker
1f5a15d86d Check retval of remaining_payload_in_datagram in ssl_write_record() 2018-08-21 13:31:31 +01:00
Hanno Becker
ecff205548 Remove stray bracket if MBEDTLS_ZLIB_SUPPORT is defined 2018-08-21 13:20:00 +01:00
Manuel Pégourié-Gonnard
000281e07d Fix "unused parameter" warning in small configs 2018-08-21 11:20:58 +02:00
Hanno Becker
6aeaa05a95 Merge branch 'iotssl-165-dtls-hs-fragmentation-new' into datagram_packing 2018-08-20 12:53:37 +01:00
Hanno Becker
513815a38d Fix typo in debugging output 2018-08-20 11:56:09 +01:00
Hanno Becker
4cb782d2f6 Return from ssl_load_buffered_record early if no record is buffered 2018-08-20 11:19:05 +01:00
Manuel Pégourié-Gonnard
a1071a58a3 Compute record expansion at the right time
Depends on the current transform, which might change when retransmitting a
flight containing a Finished message, so compute it only after the transform
is swapped.
2018-08-20 11:56:14 +02:00
Manuel Pégourié-Gonnard
065a2a3472 Fix some typos and links in comments and doc 2018-08-20 11:09:26 +02:00
Hanno Becker
3a0aad1c9d Rename update_digest to update_hs_digest 2018-08-20 09:44:02 +01:00
Hanno Becker
4422bbb096 Whitespace fixes 2018-08-20 09:40:19 +01:00
Hanno Becker
e00ae375d3 Omit debug output in ssl_load_buffered_message outside a handshake 2018-08-20 09:39:42 +01:00
Manuel Pégourié-Gonnard
6e7aaca146 Move MTU setting to SSL context, not config
This setting belongs to the individual connection, not to a configuration
shared by many connections. (If a default value is desired, that can be handled
by the application code that calls mbedtls_ssl_set_mtu().)

There are at least two ways in which this matters:
- per-connection settings can be adjusted if MTU estimates become available
  during the lifetime of the connection
- it is at least conceivable that a server might recognize restricted clients
  based on range of IPs and immediately set a lower MTU for them. This is much
easier to do with a per-connection setting than by maintaining multiple
near-duplicated ssl_config objects that differ only by the MTU setting.
2018-08-20 10:37:23 +02:00
Hanno Becker
0d4b376ddf Return through cleanup section in ssl_load_buffered_message() 2018-08-20 09:36:59 +01:00
Hanno Becker
56d5eaa96c Mark SSL ctx unused in ssl_prepare_reassembly_buffer() if !DEBUG
The SSL context is passed to the reassembly preparation function
ssl_prepare_reassembly_buffer() solely for the purpose of allowing
debugging output. This commit marks the context as unused if
debugging is disabled (through !MBEDTLS_DEBUG_C).
2018-08-17 16:52:08 +01:00
Hanno Becker
5f066e7aac Implement future record buffering
This commit implements the buffering of a record from the next epoch.

- The buffering substructure of mbedtls_ssl_handshake_params
  gets another field to hold a raw record (incl. header) from
  a future epoch.
- If ssl_parse_record_header() sees a record from the next epoch,
  it signals that it might be suitable for buffering by returning
  MBEDTLS_ERR_SSL_EARLY_MESSAGE.
- If ssl_get_next_record() finds this error code, it passes control
  to ssl_buffer_future_record() which may or may not decide to buffer
  the record; it does so if
  - a handshake is in progress,
  - the record is a handshake record
  - no record has already been buffered.
  If these conditions are met, the record is backed up in the
  aforementioned buffering substructure.
- If the current datagram is fully processed, ssl_load_buffered_record()
  is called to check if a record has been buffered, and if yes,
  if by now the its epoch is the current one; if yes, it copies
  the record into the (empty! otherwise, ssl_load_buffered_record()
  wouldn't have been called) input buffer.
2018-08-17 16:52:08 +01:00
Hanno Becker
37f9532081 Implement future message buffering and loading
This commit implements future handshake message buffering
and loading by implementing ssl_load_buffered_message()
and ssl_buffer_message().

Whenever a handshake message is received which is
- a future handshake message (i.e., the sequence number
  is larger than the next expected one), or which is
- a proper fragment of the next expected handshake message,
ssl_buffer_message() is called, which does the following:
- Ignore message if its sequence number is too far ahead
  of the next expected sequence number, as controlled by
  the macro constant MBEDTLS_SSL_MAX_BUFFERED_HS.
- Otherwise, check if buffering for the message with the
  respective sequence number has already commenced.
  - If not, allocate space to back up the message within
    the buffering substructure of mbedtls_ssl_handshake_params.
    If the message is a proper fragment, allocate additional
    space for a reassembly bitmap; if it is a full message,
    omit the bitmap. In any case, fall throuh to the next case.
  - If the message has already been buffered, check that
    the header is the same, and add the current fragment
    if the message is not yet complete (this excludes the
    case where a future message has been received in a single
    fragment, hence omitting the bitmap, and is afterwards
    also received as a series of proper fragments; in this
    case, the proper fragments will be ignored).

For loading buffered messages in ssl_load_buffered_message(),
the approach is the following:
- Check the first entry in the buffering window (the window
  is always based at the next expected handshake message).
  If buffering hasn't started or if reassembly is still
  in progress, ignore. If the next expected message has been
  fully received, copy it to the input buffer (which is empty,
  as ssl_load_buffered_message() is only called in this case).
2018-08-17 16:52:08 +01:00
Hanno Becker
6d97ef5a03 Use uniform treatment for future messages and proper HS fragments
This commit returns the error code MBEDTLS_ERR_SSL_EARLY_MESSAGE
for proper handshake fragments, forwarding their treatment to
the buffering function ssl_buffer_message(); currently, though,
this function does not yet buffer or reassembly HS messages, so:

! This commit temporarily disables support for handshake reassembly !
2018-08-17 16:52:08 +01:00
Hanno Becker
44650b7a74 Introduce function checking sanity of the DTLS HS header
This commit introduces helper functions
- ssl_get_hs_frag_len()
- ssl_get_hs_frag_off()
to parse the fragment length resp. fragment offset fields
in the handshake header.

Moreover, building on these helper functions, it adds a
function ssl_check_hs_header() checking the validity of
a DTLS handshake header with respect to the specification,
i.e. the indicated fragment must be a subrange of the total
handshake message, and the total handshake fragment length
(including header) must not exceed the record content size.

These checks were previously performed at a later stage during
ssl_reassemble_dtls_handshake().
2018-08-17 16:52:08 +01:00
Hanno Becker
12555c61d3 Introduce function to parse total handshake length
This commit introduces a static helper function ssl_get_hs_total_len()
parsing the total message length field in the handshake header, and
puts it to use in mbedtls_ssl_prepare_handshake_record().
2018-08-17 16:52:08 +01:00
Hanno Becker
0271f967d6 Introduce buffering structure for handshake messages
This commit introduces, but does not yet put to use, a sub-structure
of mbedtls_ssl_handshake_params::buffering that will be used for the
buffering and/or reassembly of handshake messages with handshake
sequence numbers that are greater or equal to the next expected
sequence number.
2018-08-17 16:52:08 +01:00
Hanno Becker
d7f8ae2508 Introduce sub-structure of ssl_handshake_params for buffering
This commit introduces a sub-structure `buffering` within
mbedtls_ssl_handshake_params that shall contain all data
related to the reassembly and/or buffering of handshake
messages.

Currently, only buffering of CCS messages is implemented,
so the only member of this struct is the previously introduced
`seen_ccs` field.
2018-08-17 16:52:08 +01:00
Hanno Becker
e25e3b7d96 Add function to check is HS msg is a proper fragment
This commit introduces a static function ssl_hs_is_proper_fragment()
to check if the current incoming handshake message is a proper fragment.
It is used within mbedtls_ssl_prepare_handshake_record() to decide whether
handshake reassembly through ssl_reassemble_dtls_handshake() is needed.

The commit changes the behavior of the library in the (unnatural)
situation where proper fragments for a handshake message are followed
by a non-fragmented version of the same message. In this case,
the previous code invoked the handshake reassembly routine
ssl_reassemble_dtls_handshake(), while with this commit, the full
handshake message is directly forwarded to the user, no altering
the handshake reassembly state -- in particular, not freeing it.
As a remedy, freeing of a potential handshake reassembly structure
is now done as part of the handshake update function
mbedtls_ssl_update_handshake_status().
2018-08-17 16:52:08 +01:00
Hanno Becker
d07df86871 Make allocation of reassembly bitmap optional
This commit adds a parameter to ssl_prepare_reassembly_buffer()
allowing to disable the allocation of space for a reassembly bitmap.
This will allow this function to be used for the allocation of buffers
for future handshake messages in case these need no fragmentation.
2018-08-17 16:52:08 +01:00
Hanno Becker
56e205e2c9 Prepare handshake reassembly in separate function
This commit moves the code-path preparing the handshake
reassembly buffer, consisting of header, message content,
and reassembly bitmap, to a separate function
ssl_prepare_reassembly_buffer().
2018-08-17 16:52:08 +01:00
Hanno Becker
9e1ec22c36 Return MBEDTLS_ERR_SSL_EARLY_MESSAGE for future HS messages
This leads future HS messages to traverse the buffering
function ssl_buffer_message(), which however doesn't do
anything at the moment for HS messages. Since the error
code MBEDTLS_ERR_SSL_EARLY_MESSAGE is afterwards remapped
to MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -- which is what
was returned prior to this commit when receiving a future
handshake message -- this commit therefore does not yet
introduce any change in observable behavior.
2018-08-17 16:52:08 +01:00
Hanno Becker
2ed6bcc793 Implement support for remembering CCS messages
This commit implements support for remembering out-of-order
CCS messages. Specifically, a flag is set whenever a CCS message
is read which remains until the end of a flight, and when a
CCS message is expected and a CCS message has been seen in the
current flight, a synthesized CCS record is created.
2018-08-17 16:52:08 +01:00
Hanno Becker
40f50848fa Add frame for loading and storing buffered messages
This commit introduces the frame for saving and loading
buffered messages within message reading function
mbedtls_ssl_read_record().
2018-08-17 16:52:08 +01:00
Hanno Becker
e74d556b43 Introduce function to indicate if record is fully processed
This commit introduces a function ssl_record_is_in_progress()
to indicate if there is there is more data within the current
record to be processed. Further, it moves the corresponding
call from ssl_read_record_layer() to the parent function
mbedtls_ssl_read_record(). With this change, ssl_read_record_layer()
has the sole purpose of fetching and decoding a new record,
and hence this commit also renames it to ssl_get_next_record().
2018-08-17 16:52:08 +01:00
Hanno Becker
2699459529 Move call to ssl_consume_current_message()
Subsequent commits will potentially inject buffered
messages after the last incoming message has been
consumed, but before a new one is fetched. As a
preparatory step to this, this commit moves the call
to ssl_consume_current_message() from ssl_read_record_layer()
to the calling function mbedtls_ssl_read_record().
2018-08-17 16:52:08 +01:00
Hanno Becker
1097b34022 Extract message-consuming code-path to separate function
The first part of the function ssl_read_record_layer() was
to mark the previous message as consumed. This commit moves
the corresponding code-path to a separate static function
ssl_consume_current_message().
2018-08-17 16:52:08 +01:00
Hanno Becker
4162b11eb4 Make mbedtls_ssl_read_record_layer() static
This function was previously global because it was
used directly within ssl_parse_certificate_verify()
in library/ssl_srv.c. The previous commit removed
this dependency, replacing the call by a call to
the global parent function mbedtls_ssl_read_record().
This renders mbedtls_ssl_read_record_layer() internal
and therefore allows to make it static, and accordingly
rename it as ssl_read_record_layer().
2018-08-17 16:52:08 +01:00
Hanno Becker
a4b143a57c Remove nested loop in mbedtls_ssl_read_record() 2018-08-17 16:52:08 +01:00
Hanno Becker
02f5907499 Correct misleading debugging output
Usually, debug messages beginning with "=> and "<="
match up and indicate entering of and returning from
functions, respectively. This commit fixes one exception
to this rule in mbedtls_ssl_read_record(), which sometimes
printed two messages of the form "<= XXX".
2018-08-17 16:52:08 +01:00
Hanno Becker
327c93b182 Add parameter to ssl_read_record() controlling checksum update
Previously, mbedtls_ssl_read_record() always updated the handshake
checksum in case a handshake record was received. While desirable
most of the time, for the CertificateVerify message the checksum
update must only happen after the message has been fully processed,
because the validation requires the handshake digest up to but
excluding the CertificateVerify itself. As a remedy, the bulk
of mbedtls_ssl_read_record() was previously duplicated within
ssl_parse_certificate_verify(), hardening maintenance in case
mbedtls_ssl_read_record() is subject to changes.

This commit adds a boolean parameter to mbedtls_ssl_read_record()
indicating whether the checksum should be updated in case of a
handshake message or not. This allows using it also for
ssl_parse_certificate_verify(), manually updating the checksum
after the message has been processed.
2018-08-17 16:52:08 +01:00
Hanno Becker
e1dcb03557 Don't send empty fragments of nonempty handshake messages
This for example lead to the following corner case bug:
The code attempted to piggy-back a Finished message at
the end of a datagram where precisely 12 bytes of payload
were still available. This lead to an empty Finished fragment
being sent, and when  mbedtls_ssl_flight_transmit() was called
again, it believed that it was just starting to send the
Finished message, thereby calling ssl_swap_epochs() which
had already happened in the call sending the empty fragment.
Therefore, the second call would send the 'rest' of the
Finished message with wrong epoch.
2018-08-17 16:47:58 +01:00
Hanno Becker
04da189225 Make datagram packing dynamically configurable
This commit adds a public function

   `mbedtls_ssl_conf_datagram_packing()`

that allows to allow / forbid the packing of multiple
records within a single datagram.
2018-08-17 15:45:25 +01:00
Hanno Becker
7e7721350b Fix unused variable warning in ssl_session_reset_int()
The `partial` argument is only used when DTLS and same port
client reconnect are enabled. This commit marks the variable
as unused if that's not the case.
2018-08-17 15:45:10 +01:00
Hanno Becker
0defedb488 Fix unused variable warning in mbedtls_ssl_get_max_record_payload
If neither the maximum fragment length extension nor DTLS
are used, the SSL context argument is unnecessary as the
maximum payload length is hardcoded as MBEDTLS_SSL_MAX_CONTENT_LEN.
2018-08-17 15:45:05 +01:00
Hanno Becker
f29d4702f7 Reset in/out pointers on SSL session reset
If a previous session was interrupted during flushing, the out
pointers might point arbitrarily into the output buffer.
2018-08-17 15:44:57 +01:00
Hanno Becker
4ccbf064ed Minor improvements in ssl_session_reset_int() 2018-08-17 15:44:53 +01:00
Hanno Becker
2a43f6f539 Introduce function to reset in/out pointers 2018-08-17 15:44:43 +01:00
Hanno Becker
b50a253a87 Move size check for records 2018-08-17 15:44:26 +01:00
Hanno Becker
67bc7c3a38 Don't immediately flush datagram after preparing a record
This commit finally enables datagram packing by modifying the
record preparation function ssl_write_record() to not always
calling mbedtls_ssl_flush_output().
2018-08-17 15:44:09 +01:00
Hanno Becker
2b1e354754 Increase record buffer pointer after preparing a record
The packing of multiple records within a single datagram works
by increasing the pointer `out_hdr` (pointing to the beginning
of the next outgoing record) within the datagram buffer, as
long as space is available and no flush was mandatory.

This commit does not yet change the code's behavior of always
flushing after preparing a record, but it introduces the logic
of increasing `out_hdr` after preparing the record, and resetting
it after the flush has been completed.
2018-08-17 15:41:02 +01:00
Hanno Becker
3b235902b8 Log calls to ssl_flight_append() in debugging output 2018-08-17 15:40:55 +01:00
Hanno Becker
04484621d0 Increment record sequence number in ssl_write_record()
Previously, the record sequence number was incremented at the
end of each successful call to mbedtls_ssl_flush_output(),
which works as long as there is precisely one such call for
each outgoing record.

When packing multiple records into a single datagram, this
property is no longer true, and instead the increment of the
record sequence number must happen after the record has been
prepared, and not after it has been dispatched.

This commit moves the code for incrementing the record sequence
number from mbedtls_ssl_flush_output() to ssl_write_record().
2018-08-17 15:40:52 +01:00
Hanno Becker
198594709b Store outgoing record sequence number outside record buffer
This commit is another step towards supporting the packing of
multiple records within a single datagram.

Previously, the incremental outgoing record sequence number was
statically stored within the record buffer, at its final place
within the record header. This slightly increased efficiency
as it was not necessary to copy the sequence number when writing
outgoing records.

When allowing multiple records within a single datagram, it is
necessary to allow the position of the current record within the
datagram buffer to be flexible; in particular, there is no static
address for the record sequence number field within the record header.

This commit introduces an additional field `cur_out_ctr` within
the main SSL context structure `mbedtls_ssl_context` to keep track
of the outgoing record sequence number independent of the buffer used
for the current record / datagram. Whenever a new record is written,
this sequence number is copied to the the address `out_ctr` of the
sequence number header field within the current outgoing record.
2018-08-17 15:40:35 +01:00
Hanno Becker
5aa4e2cedd Move deduction of internal record buffer pointers to function
The SSL/TLS module maintains a number of internally used pointers
`out_hdr`, `out_len`, `out_iv`, ..., indicating where to write the
various parts of the record header.

These pointers have to be kept in sync and sometimes need update:
Most notably, the `out_msg` pointer should always point to the
beginning of the record payload, and its offset from the pointer
`out_iv` pointing to the end of the record header is determined
by the length of the explicit IV used in the current record
protection mechanism.

This commit introduces functions deducing these pointers from
the pointers `out_hdr` / `in_hdr` to the beginning of the header
of the current outgoing / incoming record.

The flexibility gained by these functions will subsequently
be used to allow shifting of `out_hdr` for the purpose of
packing multiple records into a single datagram.
2018-08-17 15:40:24 +01:00
Hanno Becker
3136ede0e8 Compute record expansion in steps to ease readability 2018-08-17 15:28:19 +01:00
Manuel Pégourié-Gonnard
19c62f90e4 Add test for session resumption 2018-08-16 10:50:39 +02:00
Manuel Pégourié-Gonnard
7e89c17788 Fix two typos in comments 2018-08-16 10:01:47 +02:00
Manuel Pégourié-Gonnard
b747c6cf9b Add basic first tests for MTU setting
For now, just check that it causes us to fragment. More tests are coming in
follow-up commits to ensure we respect the exact value set, including when
renegotiating.
2018-08-16 10:01:47 +02:00
Manuel Pégourié-Gonnard
637e234d9f Merge remote-tracking branch 'public/pr/1915' into iotssl-165-dtls-hs-fragmentation-new
* public/pr/1915:
  Adapt ChangeLog
  Fix mbedtls_ssl_get_record_expansion() for ChaChaPoly and CBC
2018-08-16 10:01:21 +02:00
Manuel Pégourié-Gonnard
9468ff1966 Implement support for MTU setting 2018-08-16 10:01:10 +02:00
Manuel Pégourié-Gonnard
0b1d9b2c75 Declare ssl_conf_mtu() 2018-08-16 10:01:10 +02:00
Manuel Pégourié-Gonnard
2cb17e201b Make handshake fragmentation follow max_frag_len
Note: no interop tests in ssl-opt.sh for now, as some of them make us run into
bugs in (the CI's default versions of) OpenSSL and GnuTLS, so interop tests
will be added later once the situation is clarified. <- TODO
2018-08-16 10:01:10 +02:00
Manuel Pégourié-Gonnard
28f4beab1c Start implementing fragmentation 2018-08-16 10:01:10 +02:00