xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_msg.c (revision 11fa71b9ddb429088f325cfda430183003ccd1db)
1*11fa71b9SJerome Forissier /*
2*11fa71b9SJerome Forissier  *  Generic SSL/TLS messaging layer functions
3*11fa71b9SJerome Forissier  *  (record layer + retransmission state machine)
4*11fa71b9SJerome Forissier  *
5*11fa71b9SJerome Forissier  *  Copyright (C) 2006-2020, ARM Limited, All Rights Reserved
6*11fa71b9SJerome Forissier  *  SPDX-License-Identifier: Apache-2.0
7*11fa71b9SJerome Forissier  *
8*11fa71b9SJerome Forissier  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
9*11fa71b9SJerome Forissier  *  not use this file except in compliance with the License.
10*11fa71b9SJerome Forissier  *  You may obtain a copy of the License at
11*11fa71b9SJerome Forissier  *
12*11fa71b9SJerome Forissier  *  http://www.apache.org/licenses/LICENSE-2.0
13*11fa71b9SJerome Forissier  *
14*11fa71b9SJerome Forissier  *  Unless required by applicable law or agreed to in writing, software
15*11fa71b9SJerome Forissier  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16*11fa71b9SJerome Forissier  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17*11fa71b9SJerome Forissier  *  See the License for the specific language governing permissions and
18*11fa71b9SJerome Forissier  *  limitations under the License.
19*11fa71b9SJerome Forissier  *
20*11fa71b9SJerome Forissier  *  This file is part of mbed TLS (https://tls.mbed.org)
21*11fa71b9SJerome Forissier  */
22*11fa71b9SJerome Forissier /*
23*11fa71b9SJerome Forissier  *  The SSL 3.0 specification was drafted by Netscape in 1996,
24*11fa71b9SJerome Forissier  *  and became an IETF standard in 1999.
25*11fa71b9SJerome Forissier  *
26*11fa71b9SJerome Forissier  *  http://wp.netscape.com/eng/ssl3/
27*11fa71b9SJerome Forissier  *  http://www.ietf.org/rfc/rfc2246.txt
28*11fa71b9SJerome Forissier  *  http://www.ietf.org/rfc/rfc4346.txt
29*11fa71b9SJerome Forissier  */
30*11fa71b9SJerome Forissier 
31*11fa71b9SJerome Forissier #if !defined(MBEDTLS_CONFIG_FILE)
32*11fa71b9SJerome Forissier #include "mbedtls/config.h"
33*11fa71b9SJerome Forissier #else
34*11fa71b9SJerome Forissier #include MBEDTLS_CONFIG_FILE
35*11fa71b9SJerome Forissier #endif
36*11fa71b9SJerome Forissier 
37*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_TLS_C)
38*11fa71b9SJerome Forissier 
39*11fa71b9SJerome Forissier #if defined(MBEDTLS_PLATFORM_C)
40*11fa71b9SJerome Forissier #include "mbedtls/platform.h"
41*11fa71b9SJerome Forissier #else
42*11fa71b9SJerome Forissier #include <stdlib.h>
43*11fa71b9SJerome Forissier #define mbedtls_calloc    calloc
44*11fa71b9SJerome Forissier #define mbedtls_free      free
45*11fa71b9SJerome Forissier #endif
46*11fa71b9SJerome Forissier 
47*11fa71b9SJerome Forissier #include "mbedtls/ssl.h"
48*11fa71b9SJerome Forissier #include "mbedtls/ssl_internal.h"
49*11fa71b9SJerome Forissier #include "mbedtls/debug.h"
50*11fa71b9SJerome Forissier #include "mbedtls/error.h"
51*11fa71b9SJerome Forissier #include "mbedtls/platform_util.h"
52*11fa71b9SJerome Forissier #include "mbedtls/version.h"
53*11fa71b9SJerome Forissier 
54*11fa71b9SJerome Forissier #include <string.h>
55*11fa71b9SJerome Forissier 
56*11fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO)
57*11fa71b9SJerome Forissier #include "mbedtls/psa_util.h"
58*11fa71b9SJerome Forissier #include "psa/crypto.h"
59*11fa71b9SJerome Forissier #endif
60*11fa71b9SJerome Forissier 
61*11fa71b9SJerome Forissier #if defined(MBEDTLS_X509_CRT_PARSE_C)
62*11fa71b9SJerome Forissier #include "mbedtls/oid.h"
63*11fa71b9SJerome Forissier #endif
64*11fa71b9SJerome Forissier 
65*11fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
66*11fa71b9SJerome Forissier 
67*11fa71b9SJerome Forissier /*
68*11fa71b9SJerome Forissier  * Start a timer.
69*11fa71b9SJerome Forissier  * Passing millisecs = 0 cancels a running timer.
70*11fa71b9SJerome Forissier  */
71*11fa71b9SJerome Forissier void mbedtls_ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
72*11fa71b9SJerome Forissier {
73*11fa71b9SJerome Forissier     if( ssl->f_set_timer == NULL )
74*11fa71b9SJerome Forissier         return;
75*11fa71b9SJerome Forissier 
76*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
77*11fa71b9SJerome Forissier     ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
78*11fa71b9SJerome Forissier }
79*11fa71b9SJerome Forissier 
80*11fa71b9SJerome Forissier /*
81*11fa71b9SJerome Forissier  * Return -1 is timer is expired, 0 if it isn't.
82*11fa71b9SJerome Forissier  */
83*11fa71b9SJerome Forissier int mbedtls_ssl_check_timer( mbedtls_ssl_context *ssl )
84*11fa71b9SJerome Forissier {
85*11fa71b9SJerome Forissier     if( ssl->f_get_timer == NULL )
86*11fa71b9SJerome Forissier         return( 0 );
87*11fa71b9SJerome Forissier 
88*11fa71b9SJerome Forissier     if( ssl->f_get_timer( ssl->p_timer ) == 2 )
89*11fa71b9SJerome Forissier     {
90*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
91*11fa71b9SJerome Forissier         return( -1 );
92*11fa71b9SJerome Forissier     }
93*11fa71b9SJerome Forissier 
94*11fa71b9SJerome Forissier     return( 0 );
95*11fa71b9SJerome Forissier }
96*11fa71b9SJerome Forissier 
97*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RECORD_CHECKING)
98*11fa71b9SJerome Forissier static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
99*11fa71b9SJerome Forissier                                     unsigned char *buf,
100*11fa71b9SJerome Forissier                                     size_t len,
101*11fa71b9SJerome Forissier                                     mbedtls_record *rec );
102*11fa71b9SJerome Forissier 
103*11fa71b9SJerome Forissier int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl,
104*11fa71b9SJerome Forissier                               unsigned char *buf,
105*11fa71b9SJerome Forissier                               size_t buflen )
106*11fa71b9SJerome Forissier {
107*11fa71b9SJerome Forissier     int ret = 0;
108*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) );
109*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen );
110*11fa71b9SJerome Forissier 
111*11fa71b9SJerome Forissier     /* We don't support record checking in TLS because
112*11fa71b9SJerome Forissier      * (a) there doesn't seem to be a usecase for it, and
113*11fa71b9SJerome Forissier      * (b) In SSLv3 and TLS 1.0, CBC record decryption has state
114*11fa71b9SJerome Forissier      *     and we'd need to backup the transform here.
115*11fa71b9SJerome Forissier      */
116*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
117*11fa71b9SJerome Forissier     {
118*11fa71b9SJerome Forissier         ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
119*11fa71b9SJerome Forissier         goto exit;
120*11fa71b9SJerome Forissier     }
121*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
122*11fa71b9SJerome Forissier     else
123*11fa71b9SJerome Forissier     {
124*11fa71b9SJerome Forissier         mbedtls_record rec;
125*11fa71b9SJerome Forissier 
126*11fa71b9SJerome Forissier         ret = ssl_parse_record_header( ssl, buf, buflen, &rec );
127*11fa71b9SJerome Forissier         if( ret != 0 )
128*11fa71b9SJerome Forissier         {
129*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 3, "ssl_parse_record_header", ret );
130*11fa71b9SJerome Forissier             goto exit;
131*11fa71b9SJerome Forissier         }
132*11fa71b9SJerome Forissier 
133*11fa71b9SJerome Forissier         if( ssl->transform_in != NULL )
134*11fa71b9SJerome Forissier         {
135*11fa71b9SJerome Forissier             ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, &rec );
136*11fa71b9SJerome Forissier             if( ret != 0 )
137*11fa71b9SJerome Forissier             {
138*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET( 3, "mbedtls_ssl_decrypt_buf", ret );
139*11fa71b9SJerome Forissier                 goto exit;
140*11fa71b9SJerome Forissier             }
141*11fa71b9SJerome Forissier         }
142*11fa71b9SJerome Forissier     }
143*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
144*11fa71b9SJerome Forissier 
145*11fa71b9SJerome Forissier exit:
146*11fa71b9SJerome Forissier     /* On success, we have decrypted the buffer in-place, so make
147*11fa71b9SJerome Forissier      * sure we don't leak any plaintext data. */
148*11fa71b9SJerome Forissier     mbedtls_platform_zeroize( buf, buflen );
149*11fa71b9SJerome Forissier 
150*11fa71b9SJerome Forissier     /* For the purpose of this API, treat messages with unexpected CID
151*11fa71b9SJerome Forissier      * as well as such from future epochs as unexpected. */
152*11fa71b9SJerome Forissier     if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
153*11fa71b9SJerome Forissier         ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
154*11fa71b9SJerome Forissier     {
155*11fa71b9SJerome Forissier         ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
156*11fa71b9SJerome Forissier     }
157*11fa71b9SJerome Forissier 
158*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) );
159*11fa71b9SJerome Forissier     return( ret );
160*11fa71b9SJerome Forissier }
161*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RECORD_CHECKING */
162*11fa71b9SJerome Forissier 
163*11fa71b9SJerome Forissier #define SSL_DONT_FORCE_FLUSH 0
164*11fa71b9SJerome Forissier #define SSL_FORCE_FLUSH      1
165*11fa71b9SJerome Forissier 
166*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
167*11fa71b9SJerome Forissier 
168*11fa71b9SJerome Forissier /* Forward declarations for functions related to message buffering. */
169*11fa71b9SJerome Forissier static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
170*11fa71b9SJerome Forissier                                      uint8_t slot );
171*11fa71b9SJerome Forissier static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
172*11fa71b9SJerome Forissier static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
173*11fa71b9SJerome Forissier static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
174*11fa71b9SJerome Forissier static int ssl_buffer_message( mbedtls_ssl_context *ssl );
175*11fa71b9SJerome Forissier static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
176*11fa71b9SJerome Forissier                                      mbedtls_record const *rec );
177*11fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
178*11fa71b9SJerome Forissier 
179*11fa71b9SJerome Forissier static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
180*11fa71b9SJerome Forissier {
181*11fa71b9SJerome Forissier     size_t mtu = mbedtls_ssl_get_current_mtu( ssl );
182*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
183*11fa71b9SJerome Forissier     size_t out_buf_len = ssl->out_buf_len;
184*11fa71b9SJerome Forissier #else
185*11fa71b9SJerome Forissier     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
186*11fa71b9SJerome Forissier #endif
187*11fa71b9SJerome Forissier 
188*11fa71b9SJerome Forissier     if( mtu != 0 && mtu < out_buf_len )
189*11fa71b9SJerome Forissier         return( mtu );
190*11fa71b9SJerome Forissier 
191*11fa71b9SJerome Forissier     return( out_buf_len );
192*11fa71b9SJerome Forissier }
193*11fa71b9SJerome Forissier 
194*11fa71b9SJerome Forissier static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
195*11fa71b9SJerome Forissier {
196*11fa71b9SJerome Forissier     size_t const bytes_written = ssl->out_left;
197*11fa71b9SJerome Forissier     size_t const mtu           = ssl_get_maximum_datagram_size( ssl );
198*11fa71b9SJerome Forissier 
199*11fa71b9SJerome Forissier     /* Double-check that the write-index hasn't gone
200*11fa71b9SJerome Forissier      * past what we can transmit in a single datagram. */
201*11fa71b9SJerome Forissier     if( bytes_written > mtu )
202*11fa71b9SJerome Forissier     {
203*11fa71b9SJerome Forissier         /* Should never happen... */
204*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
205*11fa71b9SJerome Forissier     }
206*11fa71b9SJerome Forissier 
207*11fa71b9SJerome Forissier     return( (int) ( mtu - bytes_written ) );
208*11fa71b9SJerome Forissier }
209*11fa71b9SJerome Forissier 
210*11fa71b9SJerome Forissier static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
211*11fa71b9SJerome Forissier {
212*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
213*11fa71b9SJerome Forissier     size_t remaining, expansion;
214*11fa71b9SJerome Forissier     size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
215*11fa71b9SJerome Forissier 
216*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
217*11fa71b9SJerome Forissier     const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );
218*11fa71b9SJerome Forissier 
219*11fa71b9SJerome Forissier     if( max_len > mfl )
220*11fa71b9SJerome Forissier         max_len = mfl;
221*11fa71b9SJerome Forissier 
222*11fa71b9SJerome Forissier     /* By the standard (RFC 6066 Sect. 4), the MFL extension
223*11fa71b9SJerome Forissier      * only limits the maximum record payload size, so in theory
224*11fa71b9SJerome Forissier      * we would be allowed to pack multiple records of payload size
225*11fa71b9SJerome Forissier      * MFL into a single datagram. However, this would mean that there's
226*11fa71b9SJerome Forissier      * no way to explicitly communicate MTU restrictions to the peer.
227*11fa71b9SJerome Forissier      *
228*11fa71b9SJerome Forissier      * The following reduction of max_len makes sure that we never
229*11fa71b9SJerome Forissier      * write datagrams larger than MFL + Record Expansion Overhead.
230*11fa71b9SJerome Forissier      */
231*11fa71b9SJerome Forissier     if( max_len <= ssl->out_left )
232*11fa71b9SJerome Forissier         return( 0 );
233*11fa71b9SJerome Forissier 
234*11fa71b9SJerome Forissier     max_len -= ssl->out_left;
235*11fa71b9SJerome Forissier #endif
236*11fa71b9SJerome Forissier 
237*11fa71b9SJerome Forissier     ret = ssl_get_remaining_space_in_datagram( ssl );
238*11fa71b9SJerome Forissier     if( ret < 0 )
239*11fa71b9SJerome Forissier         return( ret );
240*11fa71b9SJerome Forissier     remaining = (size_t) ret;
241*11fa71b9SJerome Forissier 
242*11fa71b9SJerome Forissier     ret = mbedtls_ssl_get_record_expansion( ssl );
243*11fa71b9SJerome Forissier     if( ret < 0 )
244*11fa71b9SJerome Forissier         return( ret );
245*11fa71b9SJerome Forissier     expansion = (size_t) ret;
246*11fa71b9SJerome Forissier 
247*11fa71b9SJerome Forissier     if( remaining <= expansion )
248*11fa71b9SJerome Forissier         return( 0 );
249*11fa71b9SJerome Forissier 
250*11fa71b9SJerome Forissier     remaining -= expansion;
251*11fa71b9SJerome Forissier     if( remaining >= max_len )
252*11fa71b9SJerome Forissier         remaining = max_len;
253*11fa71b9SJerome Forissier 
254*11fa71b9SJerome Forissier     return( (int) remaining );
255*11fa71b9SJerome Forissier }
256*11fa71b9SJerome Forissier 
257*11fa71b9SJerome Forissier /*
258*11fa71b9SJerome Forissier  * Double the retransmit timeout value, within the allowed range,
259*11fa71b9SJerome Forissier  * returning -1 if the maximum value has already been reached.
260*11fa71b9SJerome Forissier  */
261*11fa71b9SJerome Forissier static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
262*11fa71b9SJerome Forissier {
263*11fa71b9SJerome Forissier     uint32_t new_timeout;
264*11fa71b9SJerome Forissier 
265*11fa71b9SJerome Forissier     if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
266*11fa71b9SJerome Forissier         return( -1 );
267*11fa71b9SJerome Forissier 
268*11fa71b9SJerome Forissier     /* Implement the final paragraph of RFC 6347 section 4.1.1.1
269*11fa71b9SJerome Forissier      * in the following way: after the initial transmission and a first
270*11fa71b9SJerome Forissier      * retransmission, back off to a temporary estimated MTU of 508 bytes.
271*11fa71b9SJerome Forissier      * This value is guaranteed to be deliverable (if not guaranteed to be
272*11fa71b9SJerome Forissier      * delivered) of any compliant IPv4 (and IPv6) network, and should work
273*11fa71b9SJerome Forissier      * on most non-IP stacks too. */
274*11fa71b9SJerome Forissier     if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
275*11fa71b9SJerome Forissier     {
276*11fa71b9SJerome Forissier         ssl->handshake->mtu = 508;
277*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) );
278*11fa71b9SJerome Forissier     }
279*11fa71b9SJerome Forissier 
280*11fa71b9SJerome Forissier     new_timeout = 2 * ssl->handshake->retransmit_timeout;
281*11fa71b9SJerome Forissier 
282*11fa71b9SJerome Forissier     /* Avoid arithmetic overflow and range overflow */
283*11fa71b9SJerome Forissier     if( new_timeout < ssl->handshake->retransmit_timeout ||
284*11fa71b9SJerome Forissier         new_timeout > ssl->conf->hs_timeout_max )
285*11fa71b9SJerome Forissier     {
286*11fa71b9SJerome Forissier         new_timeout = ssl->conf->hs_timeout_max;
287*11fa71b9SJerome Forissier     }
288*11fa71b9SJerome Forissier 
289*11fa71b9SJerome Forissier     ssl->handshake->retransmit_timeout = new_timeout;
290*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
291*11fa71b9SJerome Forissier                         ssl->handshake->retransmit_timeout ) );
292*11fa71b9SJerome Forissier 
293*11fa71b9SJerome Forissier     return( 0 );
294*11fa71b9SJerome Forissier }
295*11fa71b9SJerome Forissier 
296*11fa71b9SJerome Forissier static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
297*11fa71b9SJerome Forissier {
298*11fa71b9SJerome Forissier     ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
299*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
300*11fa71b9SJerome Forissier                         ssl->handshake->retransmit_timeout ) );
301*11fa71b9SJerome Forissier }
302*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
303*11fa71b9SJerome Forissier 
304*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
305*11fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
306*11fa71b9SJerome Forissier                      const unsigned char *key_enc, const unsigned char *key_dec,
307*11fa71b9SJerome Forissier                      size_t keylen,
308*11fa71b9SJerome Forissier                      const unsigned char *iv_enc,  const unsigned char *iv_dec,
309*11fa71b9SJerome Forissier                      size_t ivlen,
310*11fa71b9SJerome Forissier                      const unsigned char *mac_enc, const unsigned char *mac_dec,
311*11fa71b9SJerome Forissier                      size_t maclen ) = NULL;
312*11fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
313*11fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
314*11fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
315*11fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
316*11fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
317*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
318*11fa71b9SJerome Forissier 
319*11fa71b9SJerome Forissier /* The function below is only used in the Lucky 13 counter-measure in
320*11fa71b9SJerome Forissier  * mbedtls_ssl_decrypt_buf(). These are the defines that guard the call site. */
321*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) && \
322*11fa71b9SJerome Forissier     ( defined(MBEDTLS_SSL_PROTO_TLS1) || \
323*11fa71b9SJerome Forissier       defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
324*11fa71b9SJerome Forissier       defined(MBEDTLS_SSL_PROTO_TLS1_2) )
325*11fa71b9SJerome Forissier /* This function makes sure every byte in the memory region is accessed
326*11fa71b9SJerome Forissier  * (in ascending addresses order) */
327*11fa71b9SJerome Forissier static void ssl_read_memory( unsigned char *p, size_t len )
328*11fa71b9SJerome Forissier {
329*11fa71b9SJerome Forissier     unsigned char acc = 0;
330*11fa71b9SJerome Forissier     volatile unsigned char force;
331*11fa71b9SJerome Forissier 
332*11fa71b9SJerome Forissier     for( ; len != 0; p++, len-- )
333*11fa71b9SJerome Forissier         acc ^= *p;
334*11fa71b9SJerome Forissier 
335*11fa71b9SJerome Forissier     force = acc;
336*11fa71b9SJerome Forissier     (void) force;
337*11fa71b9SJerome Forissier }
338*11fa71b9SJerome Forissier #endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */
339*11fa71b9SJerome Forissier 
340*11fa71b9SJerome Forissier /*
341*11fa71b9SJerome Forissier  * Encryption/decryption functions
342*11fa71b9SJerome Forissier  */
343*11fa71b9SJerome Forissier 
344*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
345*11fa71b9SJerome Forissier /* This functions transforms a DTLS plaintext fragment and a record content
346*11fa71b9SJerome Forissier  * type into an instance of the DTLSInnerPlaintext structure:
347*11fa71b9SJerome Forissier  *
348*11fa71b9SJerome Forissier  *        struct {
349*11fa71b9SJerome Forissier  *            opaque content[DTLSPlaintext.length];
350*11fa71b9SJerome Forissier  *            ContentType real_type;
351*11fa71b9SJerome Forissier  *            uint8 zeros[length_of_padding];
352*11fa71b9SJerome Forissier  *        } DTLSInnerPlaintext;
353*11fa71b9SJerome Forissier  *
354*11fa71b9SJerome Forissier  *  Input:
355*11fa71b9SJerome Forissier  *  - `content`: The beginning of the buffer holding the
356*11fa71b9SJerome Forissier  *               plaintext to be wrapped.
357*11fa71b9SJerome Forissier  *  - `*content_size`: The length of the plaintext in Bytes.
358*11fa71b9SJerome Forissier  *  - `max_len`: The number of Bytes available starting from
359*11fa71b9SJerome Forissier  *               `content`. This must be `>= *content_size`.
360*11fa71b9SJerome Forissier  *  - `rec_type`: The desired record content type.
361*11fa71b9SJerome Forissier  *
362*11fa71b9SJerome Forissier  *  Output:
363*11fa71b9SJerome Forissier  *  - `content`: The beginning of the resulting DTLSInnerPlaintext structure.
364*11fa71b9SJerome Forissier  *  - `*content_size`: The length of the resulting DTLSInnerPlaintext structure.
365*11fa71b9SJerome Forissier  *
366*11fa71b9SJerome Forissier  *  Returns:
367*11fa71b9SJerome Forissier  *  - `0` on success.
368*11fa71b9SJerome Forissier  *  - A negative error code if `max_len` didn't offer enough space
369*11fa71b9SJerome Forissier  *    for the expansion.
370*11fa71b9SJerome Forissier  */
371*11fa71b9SJerome Forissier static int ssl_cid_build_inner_plaintext( unsigned char *content,
372*11fa71b9SJerome Forissier                                           size_t *content_size,
373*11fa71b9SJerome Forissier                                           size_t remaining,
374*11fa71b9SJerome Forissier                                           uint8_t rec_type )
375*11fa71b9SJerome Forissier {
376*11fa71b9SJerome Forissier     size_t len = *content_size;
377*11fa71b9SJerome Forissier     size_t pad = ( MBEDTLS_SSL_CID_PADDING_GRANULARITY -
378*11fa71b9SJerome Forissier                    ( len + 1 ) % MBEDTLS_SSL_CID_PADDING_GRANULARITY ) %
379*11fa71b9SJerome Forissier         MBEDTLS_SSL_CID_PADDING_GRANULARITY;
380*11fa71b9SJerome Forissier 
381*11fa71b9SJerome Forissier     /* Write real content type */
382*11fa71b9SJerome Forissier     if( remaining == 0 )
383*11fa71b9SJerome Forissier         return( -1 );
384*11fa71b9SJerome Forissier     content[ len ] = rec_type;
385*11fa71b9SJerome Forissier     len++;
386*11fa71b9SJerome Forissier     remaining--;
387*11fa71b9SJerome Forissier 
388*11fa71b9SJerome Forissier     if( remaining < pad )
389*11fa71b9SJerome Forissier         return( -1 );
390*11fa71b9SJerome Forissier     memset( content + len, 0, pad );
391*11fa71b9SJerome Forissier     len += pad;
392*11fa71b9SJerome Forissier     remaining -= pad;
393*11fa71b9SJerome Forissier 
394*11fa71b9SJerome Forissier     *content_size = len;
395*11fa71b9SJerome Forissier     return( 0 );
396*11fa71b9SJerome Forissier }
397*11fa71b9SJerome Forissier 
398*11fa71b9SJerome Forissier /* This function parses a DTLSInnerPlaintext structure.
399*11fa71b9SJerome Forissier  * See ssl_cid_build_inner_plaintext() for details. */
400*11fa71b9SJerome Forissier static int ssl_cid_parse_inner_plaintext( unsigned char const *content,
401*11fa71b9SJerome Forissier                                           size_t *content_size,
402*11fa71b9SJerome Forissier                                           uint8_t *rec_type )
403*11fa71b9SJerome Forissier {
404*11fa71b9SJerome Forissier     size_t remaining = *content_size;
405*11fa71b9SJerome Forissier 
406*11fa71b9SJerome Forissier     /* Determine length of padding by skipping zeroes from the back. */
407*11fa71b9SJerome Forissier     do
408*11fa71b9SJerome Forissier     {
409*11fa71b9SJerome Forissier         if( remaining == 0 )
410*11fa71b9SJerome Forissier             return( -1 );
411*11fa71b9SJerome Forissier         remaining--;
412*11fa71b9SJerome Forissier     } while( content[ remaining ] == 0 );
413*11fa71b9SJerome Forissier 
414*11fa71b9SJerome Forissier     *content_size = remaining;
415*11fa71b9SJerome Forissier     *rec_type = content[ remaining ];
416*11fa71b9SJerome Forissier 
417*11fa71b9SJerome Forissier     return( 0 );
418*11fa71b9SJerome Forissier }
419*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
420*11fa71b9SJerome Forissier 
421*11fa71b9SJerome Forissier /* `add_data` must have size 13 Bytes if the CID extension is disabled,
422*11fa71b9SJerome Forissier  * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */
423*11fa71b9SJerome Forissier static void ssl_extract_add_data_from_record( unsigned char* add_data,
424*11fa71b9SJerome Forissier                                               size_t *add_data_len,
425*11fa71b9SJerome Forissier                                               mbedtls_record *rec )
426*11fa71b9SJerome Forissier {
427*11fa71b9SJerome Forissier     /* Quoting RFC 5246 (TLS 1.2):
428*11fa71b9SJerome Forissier      *
429*11fa71b9SJerome Forissier      *    additional_data = seq_num + TLSCompressed.type +
430*11fa71b9SJerome Forissier      *                      TLSCompressed.version + TLSCompressed.length;
431*11fa71b9SJerome Forissier      *
432*11fa71b9SJerome Forissier      * For the CID extension, this is extended as follows
433*11fa71b9SJerome Forissier      * (quoting draft-ietf-tls-dtls-connection-id-05,
434*11fa71b9SJerome Forissier      *  https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05):
435*11fa71b9SJerome Forissier      *
436*11fa71b9SJerome Forissier      *       additional_data = seq_num + DTLSPlaintext.type +
437*11fa71b9SJerome Forissier      *                         DTLSPlaintext.version +
438*11fa71b9SJerome Forissier      *                         cid +
439*11fa71b9SJerome Forissier      *                         cid_length +
440*11fa71b9SJerome Forissier      *                         length_of_DTLSInnerPlaintext;
441*11fa71b9SJerome Forissier      */
442*11fa71b9SJerome Forissier 
443*11fa71b9SJerome Forissier     memcpy( add_data, rec->ctr, sizeof( rec->ctr ) );
444*11fa71b9SJerome Forissier     add_data[8] = rec->type;
445*11fa71b9SJerome Forissier     memcpy( add_data + 9, rec->ver, sizeof( rec->ver ) );
446*11fa71b9SJerome Forissier 
447*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
448*11fa71b9SJerome Forissier     if( rec->cid_len != 0 )
449*11fa71b9SJerome Forissier     {
450*11fa71b9SJerome Forissier         memcpy( add_data + 11, rec->cid, rec->cid_len );
451*11fa71b9SJerome Forissier         add_data[11 + rec->cid_len + 0] = rec->cid_len;
452*11fa71b9SJerome Forissier         add_data[11 + rec->cid_len + 1] = ( rec->data_len >> 8 ) & 0xFF;
453*11fa71b9SJerome Forissier         add_data[11 + rec->cid_len + 2] = ( rec->data_len >> 0 ) & 0xFF;
454*11fa71b9SJerome Forissier         *add_data_len = 13 + 1 + rec->cid_len;
455*11fa71b9SJerome Forissier     }
456*11fa71b9SJerome Forissier     else
457*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
458*11fa71b9SJerome Forissier     {
459*11fa71b9SJerome Forissier         add_data[11 + 0] = ( rec->data_len >> 8 ) & 0xFF;
460*11fa71b9SJerome Forissier         add_data[11 + 1] = ( rec->data_len >> 0 ) & 0xFF;
461*11fa71b9SJerome Forissier         *add_data_len = 13;
462*11fa71b9SJerome Forissier     }
463*11fa71b9SJerome Forissier }
464*11fa71b9SJerome Forissier 
465*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3)
466*11fa71b9SJerome Forissier 
467*11fa71b9SJerome Forissier #define SSL3_MAC_MAX_BYTES   20  /* MD-5 or SHA-1 */
468*11fa71b9SJerome Forissier 
469*11fa71b9SJerome Forissier /*
470*11fa71b9SJerome Forissier  * SSLv3.0 MAC functions
471*11fa71b9SJerome Forissier  */
472*11fa71b9SJerome Forissier static void ssl_mac( mbedtls_md_context_t *md_ctx,
473*11fa71b9SJerome Forissier                      const unsigned char *secret,
474*11fa71b9SJerome Forissier                      const unsigned char *buf, size_t len,
475*11fa71b9SJerome Forissier                      const unsigned char *ctr, int type,
476*11fa71b9SJerome Forissier                      unsigned char out[SSL3_MAC_MAX_BYTES] )
477*11fa71b9SJerome Forissier {
478*11fa71b9SJerome Forissier     unsigned char header[11];
479*11fa71b9SJerome Forissier     unsigned char padding[48];
480*11fa71b9SJerome Forissier     int padlen;
481*11fa71b9SJerome Forissier     int md_size = mbedtls_md_get_size( md_ctx->md_info );
482*11fa71b9SJerome Forissier     int md_type = mbedtls_md_get_type( md_ctx->md_info );
483*11fa71b9SJerome Forissier 
484*11fa71b9SJerome Forissier     /* Only MD5 and SHA-1 supported */
485*11fa71b9SJerome Forissier     if( md_type == MBEDTLS_MD_MD5 )
486*11fa71b9SJerome Forissier         padlen = 48;
487*11fa71b9SJerome Forissier     else
488*11fa71b9SJerome Forissier         padlen = 40;
489*11fa71b9SJerome Forissier 
490*11fa71b9SJerome Forissier     memcpy( header, ctr, 8 );
491*11fa71b9SJerome Forissier     header[ 8] = (unsigned char)  type;
492*11fa71b9SJerome Forissier     header[ 9] = (unsigned char)( len >> 8 );
493*11fa71b9SJerome Forissier     header[10] = (unsigned char)( len      );
494*11fa71b9SJerome Forissier 
495*11fa71b9SJerome Forissier     memset( padding, 0x36, padlen );
496*11fa71b9SJerome Forissier     mbedtls_md_starts( md_ctx );
497*11fa71b9SJerome Forissier     mbedtls_md_update( md_ctx, secret,  md_size );
498*11fa71b9SJerome Forissier     mbedtls_md_update( md_ctx, padding, padlen  );
499*11fa71b9SJerome Forissier     mbedtls_md_update( md_ctx, header,  11      );
500*11fa71b9SJerome Forissier     mbedtls_md_update( md_ctx, buf,     len     );
501*11fa71b9SJerome Forissier     mbedtls_md_finish( md_ctx, out              );
502*11fa71b9SJerome Forissier 
503*11fa71b9SJerome Forissier     memset( padding, 0x5C, padlen );
504*11fa71b9SJerome Forissier     mbedtls_md_starts( md_ctx );
505*11fa71b9SJerome Forissier     mbedtls_md_update( md_ctx, secret,    md_size );
506*11fa71b9SJerome Forissier     mbedtls_md_update( md_ctx, padding,   padlen  );
507*11fa71b9SJerome Forissier     mbedtls_md_update( md_ctx, out,       md_size );
508*11fa71b9SJerome Forissier     mbedtls_md_finish( md_ctx, out                );
509*11fa71b9SJerome Forissier }
510*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */
511*11fa71b9SJerome Forissier 
512*11fa71b9SJerome Forissier int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
513*11fa71b9SJerome Forissier                              mbedtls_ssl_transform *transform,
514*11fa71b9SJerome Forissier                              mbedtls_record *rec,
515*11fa71b9SJerome Forissier                              int (*f_rng)(void *, unsigned char *, size_t),
516*11fa71b9SJerome Forissier                              void *p_rng )
517*11fa71b9SJerome Forissier {
518*11fa71b9SJerome Forissier     mbedtls_cipher_mode_t mode;
519*11fa71b9SJerome Forissier     int auth_done = 0;
520*11fa71b9SJerome Forissier     unsigned char * data;
521*11fa71b9SJerome Forissier     unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ];
522*11fa71b9SJerome Forissier     size_t add_data_len;
523*11fa71b9SJerome Forissier     size_t post_avail;
524*11fa71b9SJerome Forissier 
525*11fa71b9SJerome Forissier     /* The SSL context is only used for debugging purposes! */
526*11fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C)
527*11fa71b9SJerome Forissier     ssl = NULL; /* make sure we don't use it except for debug */
528*11fa71b9SJerome Forissier     ((void) ssl);
529*11fa71b9SJerome Forissier #endif
530*11fa71b9SJerome Forissier 
531*11fa71b9SJerome Forissier     /* The PRNG is used for dynamic IV generation that's used
532*11fa71b9SJerome Forissier      * for CBC transformations in TLS 1.1 and TLS 1.2. */
533*11fa71b9SJerome Forissier #if !( defined(MBEDTLS_CIPHER_MODE_CBC) &&                              \
534*11fa71b9SJerome Forissier        ( defined(MBEDTLS_AES_C)  ||                                     \
535*11fa71b9SJerome Forissier          defined(MBEDTLS_ARIA_C) ||                                     \
536*11fa71b9SJerome Forissier          defined(MBEDTLS_CAMELLIA_C) ) &&                               \
537*11fa71b9SJerome Forissier        ( defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) ) )
538*11fa71b9SJerome Forissier     ((void) f_rng);
539*11fa71b9SJerome Forissier     ((void) p_rng);
540*11fa71b9SJerome Forissier #endif
541*11fa71b9SJerome Forissier 
542*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
543*11fa71b9SJerome Forissier 
544*11fa71b9SJerome Forissier     if( transform == NULL )
545*11fa71b9SJerome Forissier     {
546*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) );
547*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
548*11fa71b9SJerome Forissier     }
549*11fa71b9SJerome Forissier     if( rec == NULL
550*11fa71b9SJerome Forissier         || rec->buf == NULL
551*11fa71b9SJerome Forissier         || rec->buf_len < rec->data_offset
552*11fa71b9SJerome Forissier         || rec->buf_len - rec->data_offset < rec->data_len
553*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
554*11fa71b9SJerome Forissier         || rec->cid_len != 0
555*11fa71b9SJerome Forissier #endif
556*11fa71b9SJerome Forissier         )
557*11fa71b9SJerome Forissier     {
558*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) );
559*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
560*11fa71b9SJerome Forissier     }
561*11fa71b9SJerome Forissier 
562*11fa71b9SJerome Forissier     data = rec->buf + rec->data_offset;
563*11fa71b9SJerome Forissier     post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
564*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
565*11fa71b9SJerome Forissier                            data, rec->data_len );
566*11fa71b9SJerome Forissier 
567*11fa71b9SJerome Forissier     mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc );
568*11fa71b9SJerome Forissier 
569*11fa71b9SJerome Forissier     if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
570*11fa71b9SJerome Forissier     {
571*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %u too large, maximum %d",
572*11fa71b9SJerome Forissier                                     (unsigned) rec->data_len,
573*11fa71b9SJerome Forissier                                     MBEDTLS_SSL_OUT_CONTENT_LEN ) );
574*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
575*11fa71b9SJerome Forissier     }
576*11fa71b9SJerome Forissier 
577*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
578*11fa71b9SJerome Forissier     /*
579*11fa71b9SJerome Forissier      * Add CID information
580*11fa71b9SJerome Forissier      */
581*11fa71b9SJerome Forissier     rec->cid_len = transform->out_cid_len;
582*11fa71b9SJerome Forissier     memcpy( rec->cid, transform->out_cid, transform->out_cid_len );
583*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len );
584*11fa71b9SJerome Forissier 
585*11fa71b9SJerome Forissier     if( rec->cid_len != 0 )
586*11fa71b9SJerome Forissier     {
587*11fa71b9SJerome Forissier         /*
588*11fa71b9SJerome Forissier          * Wrap plaintext into DTLSInnerPlaintext structure.
589*11fa71b9SJerome Forissier          * See ssl_cid_build_inner_plaintext() for more information.
590*11fa71b9SJerome Forissier          *
591*11fa71b9SJerome Forissier          * Note that this changes `rec->data_len`, and hence
592*11fa71b9SJerome Forissier          * `post_avail` needs to be recalculated afterwards.
593*11fa71b9SJerome Forissier          */
594*11fa71b9SJerome Forissier         if( ssl_cid_build_inner_plaintext( data,
595*11fa71b9SJerome Forissier                         &rec->data_len,
596*11fa71b9SJerome Forissier                         post_avail,
597*11fa71b9SJerome Forissier                         rec->type ) != 0 )
598*11fa71b9SJerome Forissier         {
599*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
600*11fa71b9SJerome Forissier         }
601*11fa71b9SJerome Forissier 
602*11fa71b9SJerome Forissier         rec->type = MBEDTLS_SSL_MSG_CID;
603*11fa71b9SJerome Forissier     }
604*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
605*11fa71b9SJerome Forissier 
606*11fa71b9SJerome Forissier     post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
607*11fa71b9SJerome Forissier 
608*11fa71b9SJerome Forissier     /*
609*11fa71b9SJerome Forissier      * Add MAC before if needed
610*11fa71b9SJerome Forissier      */
611*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
612*11fa71b9SJerome Forissier     if( mode == MBEDTLS_MODE_STREAM ||
613*11fa71b9SJerome Forissier         ( mode == MBEDTLS_MODE_CBC
614*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
615*11fa71b9SJerome Forissier           && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
616*11fa71b9SJerome Forissier #endif
617*11fa71b9SJerome Forissier         ) )
618*11fa71b9SJerome Forissier     {
619*11fa71b9SJerome Forissier         if( post_avail < transform->maclen )
620*11fa71b9SJerome Forissier         {
621*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
622*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
623*11fa71b9SJerome Forissier         }
624*11fa71b9SJerome Forissier 
625*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3)
626*11fa71b9SJerome Forissier         if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
627*11fa71b9SJerome Forissier         {
628*11fa71b9SJerome Forissier             unsigned char mac[SSL3_MAC_MAX_BYTES];
629*11fa71b9SJerome Forissier             ssl_mac( &transform->md_ctx_enc, transform->mac_enc,
630*11fa71b9SJerome Forissier                      data, rec->data_len, rec->ctr, rec->type, mac );
631*11fa71b9SJerome Forissier             memcpy( data + rec->data_len, mac, transform->maclen );
632*11fa71b9SJerome Forissier         }
633*11fa71b9SJerome Forissier         else
634*11fa71b9SJerome Forissier #endif
635*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
636*11fa71b9SJerome Forissier         defined(MBEDTLS_SSL_PROTO_TLS1_2)
637*11fa71b9SJerome Forissier         if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
638*11fa71b9SJerome Forissier         {
639*11fa71b9SJerome Forissier             unsigned char mac[MBEDTLS_SSL_MAC_ADD];
640*11fa71b9SJerome Forissier 
641*11fa71b9SJerome Forissier             ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
642*11fa71b9SJerome Forissier 
643*11fa71b9SJerome Forissier             mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
644*11fa71b9SJerome Forissier                                     add_data_len );
645*11fa71b9SJerome Forissier             mbedtls_md_hmac_update( &transform->md_ctx_enc,
646*11fa71b9SJerome Forissier                                     data, rec->data_len );
647*11fa71b9SJerome Forissier             mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
648*11fa71b9SJerome Forissier             mbedtls_md_hmac_reset( &transform->md_ctx_enc );
649*11fa71b9SJerome Forissier 
650*11fa71b9SJerome Forissier             memcpy( data + rec->data_len, mac, transform->maclen );
651*11fa71b9SJerome Forissier         }
652*11fa71b9SJerome Forissier         else
653*11fa71b9SJerome Forissier #endif
654*11fa71b9SJerome Forissier         {
655*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
656*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
657*11fa71b9SJerome Forissier         }
658*11fa71b9SJerome Forissier 
659*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len,
660*11fa71b9SJerome Forissier                                transform->maclen );
661*11fa71b9SJerome Forissier 
662*11fa71b9SJerome Forissier         rec->data_len += transform->maclen;
663*11fa71b9SJerome Forissier         post_avail -= transform->maclen;
664*11fa71b9SJerome Forissier         auth_done++;
665*11fa71b9SJerome Forissier     }
666*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
667*11fa71b9SJerome Forissier 
668*11fa71b9SJerome Forissier     /*
669*11fa71b9SJerome Forissier      * Encrypt
670*11fa71b9SJerome Forissier      */
671*11fa71b9SJerome Forissier #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
672*11fa71b9SJerome Forissier     if( mode == MBEDTLS_MODE_STREAM )
673*11fa71b9SJerome Forissier     {
674*11fa71b9SJerome Forissier         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
675*11fa71b9SJerome Forissier         size_t olen;
676*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
677*11fa71b9SJerome Forissier                                     "including %d bytes of padding",
678*11fa71b9SJerome Forissier                                     rec->data_len, 0 ) );
679*11fa71b9SJerome Forissier 
680*11fa71b9SJerome Forissier         if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
681*11fa71b9SJerome Forissier                                    transform->iv_enc, transform->ivlen,
682*11fa71b9SJerome Forissier                                    data, rec->data_len,
683*11fa71b9SJerome Forissier                                    data, &olen ) ) != 0 )
684*11fa71b9SJerome Forissier         {
685*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
686*11fa71b9SJerome Forissier             return( ret );
687*11fa71b9SJerome Forissier         }
688*11fa71b9SJerome Forissier 
689*11fa71b9SJerome Forissier         if( rec->data_len != olen )
690*11fa71b9SJerome Forissier         {
691*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
692*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
693*11fa71b9SJerome Forissier         }
694*11fa71b9SJerome Forissier     }
695*11fa71b9SJerome Forissier     else
696*11fa71b9SJerome Forissier #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
697*11fa71b9SJerome Forissier 
698*11fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || \
699*11fa71b9SJerome Forissier     defined(MBEDTLS_CCM_C) || \
700*11fa71b9SJerome Forissier     defined(MBEDTLS_CHACHAPOLY_C)
701*11fa71b9SJerome Forissier     if( mode == MBEDTLS_MODE_GCM ||
702*11fa71b9SJerome Forissier         mode == MBEDTLS_MODE_CCM ||
703*11fa71b9SJerome Forissier         mode == MBEDTLS_MODE_CHACHAPOLY )
704*11fa71b9SJerome Forissier     {
705*11fa71b9SJerome Forissier         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
706*11fa71b9SJerome Forissier         unsigned char iv[12];
707*11fa71b9SJerome Forissier         size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen;
708*11fa71b9SJerome Forissier 
709*11fa71b9SJerome Forissier         /* Check that there's space for both the authentication tag
710*11fa71b9SJerome Forissier          * and the explicit IV before and after the record content. */
711*11fa71b9SJerome Forissier         if( post_avail < transform->taglen ||
712*11fa71b9SJerome Forissier             rec->data_offset < explicit_iv_len )
713*11fa71b9SJerome Forissier         {
714*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
715*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
716*11fa71b9SJerome Forissier         }
717*11fa71b9SJerome Forissier 
718*11fa71b9SJerome Forissier         /*
719*11fa71b9SJerome Forissier          * Generate IV
720*11fa71b9SJerome Forissier          */
721*11fa71b9SJerome Forissier         if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
722*11fa71b9SJerome Forissier         {
723*11fa71b9SJerome Forissier             /* GCM and CCM: fixed || explicit (=seqnum) */
724*11fa71b9SJerome Forissier             memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
725*11fa71b9SJerome Forissier             memcpy( iv + transform->fixed_ivlen, rec->ctr,
726*11fa71b9SJerome Forissier                     explicit_iv_len );
727*11fa71b9SJerome Forissier             /* Prefix record content with explicit IV. */
728*11fa71b9SJerome Forissier             memcpy( data - explicit_iv_len, rec->ctr, explicit_iv_len );
729*11fa71b9SJerome Forissier         }
730*11fa71b9SJerome Forissier         else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
731*11fa71b9SJerome Forissier         {
732*11fa71b9SJerome Forissier             /* ChachaPoly: fixed XOR sequence number */
733*11fa71b9SJerome Forissier             unsigned char i;
734*11fa71b9SJerome Forissier 
735*11fa71b9SJerome Forissier             memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
736*11fa71b9SJerome Forissier 
737*11fa71b9SJerome Forissier             for( i = 0; i < 8; i++ )
738*11fa71b9SJerome Forissier                 iv[i+4] ^= rec->ctr[i];
739*11fa71b9SJerome Forissier         }
740*11fa71b9SJerome Forissier         else
741*11fa71b9SJerome Forissier         {
742*11fa71b9SJerome Forissier             /* Reminder if we ever add an AEAD mode with a different size */
743*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
744*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
745*11fa71b9SJerome Forissier         }
746*11fa71b9SJerome Forissier 
747*11fa71b9SJerome Forissier         ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
748*11fa71b9SJerome Forissier 
749*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
750*11fa71b9SJerome Forissier                                   iv, transform->ivlen );
751*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)",
752*11fa71b9SJerome Forissier                                   data - explicit_iv_len, explicit_iv_len );
753*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
754*11fa71b9SJerome Forissier                                add_data, add_data_len );
755*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
756*11fa71b9SJerome Forissier                                     "including 0 bytes of padding",
757*11fa71b9SJerome Forissier                                     rec->data_len ) );
758*11fa71b9SJerome Forissier 
759*11fa71b9SJerome Forissier         /*
760*11fa71b9SJerome Forissier          * Encrypt and authenticate
761*11fa71b9SJerome Forissier          */
762*11fa71b9SJerome Forissier 
763*11fa71b9SJerome Forissier         if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc,
764*11fa71b9SJerome Forissier                    iv, transform->ivlen,
765*11fa71b9SJerome Forissier                    add_data, add_data_len,       /* add data     */
766*11fa71b9SJerome Forissier                    data, rec->data_len,          /* source       */
767*11fa71b9SJerome Forissier                    data, &rec->data_len,         /* destination  */
768*11fa71b9SJerome Forissier                    data + rec->data_len, transform->taglen ) ) != 0 )
769*11fa71b9SJerome Forissier         {
770*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
771*11fa71b9SJerome Forissier             return( ret );
772*11fa71b9SJerome Forissier         }
773*11fa71b9SJerome Forissier 
774*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag",
775*11fa71b9SJerome Forissier                                data + rec->data_len, transform->taglen );
776*11fa71b9SJerome Forissier 
777*11fa71b9SJerome Forissier         rec->data_len    += transform->taglen + explicit_iv_len;
778*11fa71b9SJerome Forissier         rec->data_offset -= explicit_iv_len;
779*11fa71b9SJerome Forissier         post_avail -= transform->taglen;
780*11fa71b9SJerome Forissier         auth_done++;
781*11fa71b9SJerome Forissier     }
782*11fa71b9SJerome Forissier     else
783*11fa71b9SJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
784*11fa71b9SJerome Forissier #if defined(MBEDTLS_CIPHER_MODE_CBC) &&                                    \
785*11fa71b9SJerome Forissier     ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
786*11fa71b9SJerome Forissier     if( mode == MBEDTLS_MODE_CBC )
787*11fa71b9SJerome Forissier     {
788*11fa71b9SJerome Forissier         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
789*11fa71b9SJerome Forissier         size_t padlen, i;
790*11fa71b9SJerome Forissier         size_t olen;
791*11fa71b9SJerome Forissier 
792*11fa71b9SJerome Forissier         /* Currently we're always using minimal padding
793*11fa71b9SJerome Forissier          * (up to 255 bytes would be allowed). */
794*11fa71b9SJerome Forissier         padlen = transform->ivlen - ( rec->data_len + 1 ) % transform->ivlen;
795*11fa71b9SJerome Forissier         if( padlen == transform->ivlen )
796*11fa71b9SJerome Forissier             padlen = 0;
797*11fa71b9SJerome Forissier 
798*11fa71b9SJerome Forissier         /* Check there's enough space in the buffer for the padding. */
799*11fa71b9SJerome Forissier         if( post_avail < padlen + 1 )
800*11fa71b9SJerome Forissier         {
801*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
802*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
803*11fa71b9SJerome Forissier         }
804*11fa71b9SJerome Forissier 
805*11fa71b9SJerome Forissier         for( i = 0; i <= padlen; i++ )
806*11fa71b9SJerome Forissier             data[rec->data_len + i] = (unsigned char) padlen;
807*11fa71b9SJerome Forissier 
808*11fa71b9SJerome Forissier         rec->data_len += padlen + 1;
809*11fa71b9SJerome Forissier         post_avail -= padlen + 1;
810*11fa71b9SJerome Forissier 
811*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
812*11fa71b9SJerome Forissier         /*
813*11fa71b9SJerome Forissier          * Prepend per-record IV for block cipher in TLS v1.1 and up as per
814*11fa71b9SJerome Forissier          * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
815*11fa71b9SJerome Forissier          */
816*11fa71b9SJerome Forissier         if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
817*11fa71b9SJerome Forissier         {
818*11fa71b9SJerome Forissier             if( f_rng == NULL )
819*11fa71b9SJerome Forissier             {
820*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) );
821*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
822*11fa71b9SJerome Forissier             }
823*11fa71b9SJerome Forissier 
824*11fa71b9SJerome Forissier             if( rec->data_offset < transform->ivlen )
825*11fa71b9SJerome Forissier             {
826*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
827*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
828*11fa71b9SJerome Forissier             }
829*11fa71b9SJerome Forissier 
830*11fa71b9SJerome Forissier             /*
831*11fa71b9SJerome Forissier              * Generate IV
832*11fa71b9SJerome Forissier              */
833*11fa71b9SJerome Forissier             ret = f_rng( p_rng, transform->iv_enc, transform->ivlen );
834*11fa71b9SJerome Forissier             if( ret != 0 )
835*11fa71b9SJerome Forissier                 return( ret );
836*11fa71b9SJerome Forissier 
837*11fa71b9SJerome Forissier             memcpy( data - transform->ivlen, transform->iv_enc,
838*11fa71b9SJerome Forissier                     transform->ivlen );
839*11fa71b9SJerome Forissier 
840*11fa71b9SJerome Forissier         }
841*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
842*11fa71b9SJerome Forissier 
843*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
844*11fa71b9SJerome Forissier                             "including %d bytes of IV and %d bytes of padding",
845*11fa71b9SJerome Forissier                             rec->data_len, transform->ivlen,
846*11fa71b9SJerome Forissier                             padlen + 1 ) );
847*11fa71b9SJerome Forissier 
848*11fa71b9SJerome Forissier         if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
849*11fa71b9SJerome Forissier                                    transform->iv_enc,
850*11fa71b9SJerome Forissier                                    transform->ivlen,
851*11fa71b9SJerome Forissier                                    data, rec->data_len,
852*11fa71b9SJerome Forissier                                    data, &olen ) ) != 0 )
853*11fa71b9SJerome Forissier         {
854*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
855*11fa71b9SJerome Forissier             return( ret );
856*11fa71b9SJerome Forissier         }
857*11fa71b9SJerome Forissier 
858*11fa71b9SJerome Forissier         if( rec->data_len != olen )
859*11fa71b9SJerome Forissier         {
860*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
861*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
862*11fa71b9SJerome Forissier         }
863*11fa71b9SJerome Forissier 
864*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
865*11fa71b9SJerome Forissier         if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
866*11fa71b9SJerome Forissier         {
867*11fa71b9SJerome Forissier             /*
868*11fa71b9SJerome Forissier              * Save IV in SSL3 and TLS1
869*11fa71b9SJerome Forissier              */
870*11fa71b9SJerome Forissier             memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv,
871*11fa71b9SJerome Forissier                     transform->ivlen );
872*11fa71b9SJerome Forissier         }
873*11fa71b9SJerome Forissier         else
874*11fa71b9SJerome Forissier #endif
875*11fa71b9SJerome Forissier         {
876*11fa71b9SJerome Forissier             data             -= transform->ivlen;
877*11fa71b9SJerome Forissier             rec->data_offset -= transform->ivlen;
878*11fa71b9SJerome Forissier             rec->data_len    += transform->ivlen;
879*11fa71b9SJerome Forissier         }
880*11fa71b9SJerome Forissier 
881*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
882*11fa71b9SJerome Forissier         if( auth_done == 0 )
883*11fa71b9SJerome Forissier         {
884*11fa71b9SJerome Forissier             unsigned char mac[MBEDTLS_SSL_MAC_ADD];
885*11fa71b9SJerome Forissier 
886*11fa71b9SJerome Forissier             /*
887*11fa71b9SJerome Forissier              * MAC(MAC_write_key, seq_num +
888*11fa71b9SJerome Forissier              *     TLSCipherText.type +
889*11fa71b9SJerome Forissier              *     TLSCipherText.version +
890*11fa71b9SJerome Forissier              *     length_of( (IV +) ENC(...) ) +
891*11fa71b9SJerome Forissier              *     IV + // except for TLS 1.0
892*11fa71b9SJerome Forissier              *     ENC(content + padding + padding_length));
893*11fa71b9SJerome Forissier              */
894*11fa71b9SJerome Forissier 
895*11fa71b9SJerome Forissier             if( post_avail < transform->maclen)
896*11fa71b9SJerome Forissier             {
897*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
898*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
899*11fa71b9SJerome Forissier             }
900*11fa71b9SJerome Forissier 
901*11fa71b9SJerome Forissier             ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
902*11fa71b9SJerome Forissier 
903*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
904*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
905*11fa71b9SJerome Forissier                                    add_data_len );
906*11fa71b9SJerome Forissier 
907*11fa71b9SJerome Forissier             mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
908*11fa71b9SJerome Forissier                                     add_data_len );
909*11fa71b9SJerome Forissier             mbedtls_md_hmac_update( &transform->md_ctx_enc,
910*11fa71b9SJerome Forissier                                     data, rec->data_len );
911*11fa71b9SJerome Forissier             mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
912*11fa71b9SJerome Forissier             mbedtls_md_hmac_reset( &transform->md_ctx_enc );
913*11fa71b9SJerome Forissier 
914*11fa71b9SJerome Forissier             memcpy( data + rec->data_len, mac, transform->maclen );
915*11fa71b9SJerome Forissier 
916*11fa71b9SJerome Forissier             rec->data_len += transform->maclen;
917*11fa71b9SJerome Forissier             post_avail -= transform->maclen;
918*11fa71b9SJerome Forissier             auth_done++;
919*11fa71b9SJerome Forissier         }
920*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
921*11fa71b9SJerome Forissier     }
922*11fa71b9SJerome Forissier     else
923*11fa71b9SJerome Forissier #endif /* MBEDTLS_CIPHER_MODE_CBC &&
924*11fa71b9SJerome Forissier           ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
925*11fa71b9SJerome Forissier     {
926*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
927*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
928*11fa71b9SJerome Forissier     }
929*11fa71b9SJerome Forissier 
930*11fa71b9SJerome Forissier     /* Make extra sure authentication was performed, exactly once */
931*11fa71b9SJerome Forissier     if( auth_done != 1 )
932*11fa71b9SJerome Forissier     {
933*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
934*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
935*11fa71b9SJerome Forissier     }
936*11fa71b9SJerome Forissier 
937*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
938*11fa71b9SJerome Forissier 
939*11fa71b9SJerome Forissier     return( 0 );
940*11fa71b9SJerome Forissier }
941*11fa71b9SJerome Forissier 
942*11fa71b9SJerome Forissier int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
943*11fa71b9SJerome Forissier                              mbedtls_ssl_transform *transform,
944*11fa71b9SJerome Forissier                              mbedtls_record *rec )
945*11fa71b9SJerome Forissier {
946*11fa71b9SJerome Forissier     size_t olen;
947*11fa71b9SJerome Forissier     mbedtls_cipher_mode_t mode;
948*11fa71b9SJerome Forissier     int ret, auth_done = 0;
949*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
950*11fa71b9SJerome Forissier     size_t padlen = 0, correct = 1;
951*11fa71b9SJerome Forissier #endif
952*11fa71b9SJerome Forissier     unsigned char* data;
953*11fa71b9SJerome Forissier     unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ];
954*11fa71b9SJerome Forissier     size_t add_data_len;
955*11fa71b9SJerome Forissier 
956*11fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C)
957*11fa71b9SJerome Forissier     ssl = NULL; /* make sure we don't use it except for debug */
958*11fa71b9SJerome Forissier     ((void) ssl);
959*11fa71b9SJerome Forissier #endif
960*11fa71b9SJerome Forissier 
961*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
962*11fa71b9SJerome Forissier     if( rec == NULL                     ||
963*11fa71b9SJerome Forissier         rec->buf == NULL                ||
964*11fa71b9SJerome Forissier         rec->buf_len < rec->data_offset ||
965*11fa71b9SJerome Forissier         rec->buf_len - rec->data_offset < rec->data_len )
966*11fa71b9SJerome Forissier     {
967*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to decrypt_buf" ) );
968*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
969*11fa71b9SJerome Forissier     }
970*11fa71b9SJerome Forissier 
971*11fa71b9SJerome Forissier     data = rec->buf + rec->data_offset;
972*11fa71b9SJerome Forissier     mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec );
973*11fa71b9SJerome Forissier 
974*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
975*11fa71b9SJerome Forissier     /*
976*11fa71b9SJerome Forissier      * Match record's CID with incoming CID.
977*11fa71b9SJerome Forissier      */
978*11fa71b9SJerome Forissier     if( rec->cid_len != transform->in_cid_len ||
979*11fa71b9SJerome Forissier         memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 )
980*11fa71b9SJerome Forissier     {
981*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_UNEXPECTED_CID );
982*11fa71b9SJerome Forissier     }
983*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
984*11fa71b9SJerome Forissier 
985*11fa71b9SJerome Forissier #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
986*11fa71b9SJerome Forissier     if( mode == MBEDTLS_MODE_STREAM )
987*11fa71b9SJerome Forissier     {
988*11fa71b9SJerome Forissier         padlen = 0;
989*11fa71b9SJerome Forissier         if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
990*11fa71b9SJerome Forissier                                    transform->iv_dec,
991*11fa71b9SJerome Forissier                                    transform->ivlen,
992*11fa71b9SJerome Forissier                                    data, rec->data_len,
993*11fa71b9SJerome Forissier                                    data, &olen ) ) != 0 )
994*11fa71b9SJerome Forissier         {
995*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
996*11fa71b9SJerome Forissier             return( ret );
997*11fa71b9SJerome Forissier         }
998*11fa71b9SJerome Forissier 
999*11fa71b9SJerome Forissier         if( rec->data_len != olen )
1000*11fa71b9SJerome Forissier         {
1001*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1002*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1003*11fa71b9SJerome Forissier         }
1004*11fa71b9SJerome Forissier     }
1005*11fa71b9SJerome Forissier     else
1006*11fa71b9SJerome Forissier #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
1007*11fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || \
1008*11fa71b9SJerome Forissier     defined(MBEDTLS_CCM_C) || \
1009*11fa71b9SJerome Forissier     defined(MBEDTLS_CHACHAPOLY_C)
1010*11fa71b9SJerome Forissier     if( mode == MBEDTLS_MODE_GCM ||
1011*11fa71b9SJerome Forissier         mode == MBEDTLS_MODE_CCM ||
1012*11fa71b9SJerome Forissier         mode == MBEDTLS_MODE_CHACHAPOLY )
1013*11fa71b9SJerome Forissier     {
1014*11fa71b9SJerome Forissier         unsigned char iv[12];
1015*11fa71b9SJerome Forissier         size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen;
1016*11fa71b9SJerome Forissier 
1017*11fa71b9SJerome Forissier         /*
1018*11fa71b9SJerome Forissier          * Prepare IV from explicit and implicit data.
1019*11fa71b9SJerome Forissier          */
1020*11fa71b9SJerome Forissier 
1021*11fa71b9SJerome Forissier         /* Check that there's enough space for the explicit IV
1022*11fa71b9SJerome Forissier          * (at the beginning of the record) and the MAC (at the
1023*11fa71b9SJerome Forissier          * end of the record). */
1024*11fa71b9SJerome Forissier         if( rec->data_len < explicit_iv_len + transform->taglen )
1025*11fa71b9SJerome Forissier         {
1026*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) "
1027*11fa71b9SJerome Forissier                                         "+ taglen (%d)", rec->data_len,
1028*11fa71b9SJerome Forissier                                         explicit_iv_len, transform->taglen ) );
1029*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_MAC );
1030*11fa71b9SJerome Forissier         }
1031*11fa71b9SJerome Forissier 
1032*11fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
1033*11fa71b9SJerome Forissier         if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
1034*11fa71b9SJerome Forissier         {
1035*11fa71b9SJerome Forissier             /* GCM and CCM: fixed || explicit */
1036*11fa71b9SJerome Forissier 
1037*11fa71b9SJerome Forissier             /* Fixed */
1038*11fa71b9SJerome Forissier             memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
1039*11fa71b9SJerome Forissier             /* Explicit */
1040*11fa71b9SJerome Forissier             memcpy( iv + transform->fixed_ivlen, data, 8 );
1041*11fa71b9SJerome Forissier         }
1042*11fa71b9SJerome Forissier         else
1043*11fa71b9SJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
1044*11fa71b9SJerome Forissier #if defined(MBEDTLS_CHACHAPOLY_C)
1045*11fa71b9SJerome Forissier         if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
1046*11fa71b9SJerome Forissier         {
1047*11fa71b9SJerome Forissier             /* ChachaPoly: fixed XOR sequence number */
1048*11fa71b9SJerome Forissier             unsigned char i;
1049*11fa71b9SJerome Forissier 
1050*11fa71b9SJerome Forissier             memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
1051*11fa71b9SJerome Forissier 
1052*11fa71b9SJerome Forissier             for( i = 0; i < 8; i++ )
1053*11fa71b9SJerome Forissier                 iv[i+4] ^= rec->ctr[i];
1054*11fa71b9SJerome Forissier         }
1055*11fa71b9SJerome Forissier         else
1056*11fa71b9SJerome Forissier #endif /* MBEDTLS_CHACHAPOLY_C */
1057*11fa71b9SJerome Forissier         {
1058*11fa71b9SJerome Forissier             /* Reminder if we ever add an AEAD mode with a different size */
1059*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1060*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1061*11fa71b9SJerome Forissier         }
1062*11fa71b9SJerome Forissier 
1063*11fa71b9SJerome Forissier         /* Group changes to data, data_len, and add_data, because
1064*11fa71b9SJerome Forissier          * add_data depends on data_len. */
1065*11fa71b9SJerome Forissier         data += explicit_iv_len;
1066*11fa71b9SJerome Forissier         rec->data_offset += explicit_iv_len;
1067*11fa71b9SJerome Forissier         rec->data_len -= explicit_iv_len + transform->taglen;
1068*11fa71b9SJerome Forissier 
1069*11fa71b9SJerome Forissier         ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
1070*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
1071*11fa71b9SJerome Forissier                                add_data, add_data_len );
1072*11fa71b9SJerome Forissier 
1073*11fa71b9SJerome Forissier         /* Because of the check above, we know that there are
1074*11fa71b9SJerome Forissier          * explicit_iv_len Bytes preceeding data, and taglen
1075*11fa71b9SJerome Forissier          * bytes following data + data_len. This justifies
1076*11fa71b9SJerome Forissier          * the debug message and the invocation of
1077*11fa71b9SJerome Forissier          * mbedtls_cipher_auth_decrypt() below. */
1078*11fa71b9SJerome Forissier 
1079*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
1080*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", data + rec->data_len,
1081*11fa71b9SJerome Forissier                                transform->taglen );
1082*11fa71b9SJerome Forissier 
1083*11fa71b9SJerome Forissier         /*
1084*11fa71b9SJerome Forissier          * Decrypt and authenticate
1085*11fa71b9SJerome Forissier          */
1086*11fa71b9SJerome Forissier         if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx_dec,
1087*11fa71b9SJerome Forissier                   iv, transform->ivlen,
1088*11fa71b9SJerome Forissier                   add_data, add_data_len,
1089*11fa71b9SJerome Forissier                   data, rec->data_len,
1090*11fa71b9SJerome Forissier                   data, &olen,
1091*11fa71b9SJerome Forissier                   data + rec->data_len,
1092*11fa71b9SJerome Forissier                   transform->taglen ) ) != 0 )
1093*11fa71b9SJerome Forissier         {
1094*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
1095*11fa71b9SJerome Forissier 
1096*11fa71b9SJerome Forissier             if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
1097*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INVALID_MAC );
1098*11fa71b9SJerome Forissier 
1099*11fa71b9SJerome Forissier             return( ret );
1100*11fa71b9SJerome Forissier         }
1101*11fa71b9SJerome Forissier         auth_done++;
1102*11fa71b9SJerome Forissier 
1103*11fa71b9SJerome Forissier         /* Double-check that AEAD decryption doesn't change content length. */
1104*11fa71b9SJerome Forissier         if( olen != rec->data_len )
1105*11fa71b9SJerome Forissier         {
1106*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1107*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1108*11fa71b9SJerome Forissier         }
1109*11fa71b9SJerome Forissier     }
1110*11fa71b9SJerome Forissier     else
1111*11fa71b9SJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
1112*11fa71b9SJerome Forissier #if defined(MBEDTLS_CIPHER_MODE_CBC) &&                                    \
1113*11fa71b9SJerome Forissier     ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
1114*11fa71b9SJerome Forissier     if( mode == MBEDTLS_MODE_CBC )
1115*11fa71b9SJerome Forissier     {
1116*11fa71b9SJerome Forissier         size_t minlen = 0;
1117*11fa71b9SJerome Forissier 
1118*11fa71b9SJerome Forissier         /*
1119*11fa71b9SJerome Forissier          * Check immediate ciphertext sanity
1120*11fa71b9SJerome Forissier          */
1121*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
1122*11fa71b9SJerome Forissier         if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
1123*11fa71b9SJerome Forissier         {
1124*11fa71b9SJerome Forissier             /* The ciphertext is prefixed with the CBC IV. */
1125*11fa71b9SJerome Forissier             minlen += transform->ivlen;
1126*11fa71b9SJerome Forissier         }
1127*11fa71b9SJerome Forissier #endif
1128*11fa71b9SJerome Forissier 
1129*11fa71b9SJerome Forissier         /* Size considerations:
1130*11fa71b9SJerome Forissier          *
1131*11fa71b9SJerome Forissier          * - The CBC cipher text must not be empty and hence
1132*11fa71b9SJerome Forissier          *   at least of size transform->ivlen.
1133*11fa71b9SJerome Forissier          *
1134*11fa71b9SJerome Forissier          * Together with the potential IV-prefix, this explains
1135*11fa71b9SJerome Forissier          * the first of the two checks below.
1136*11fa71b9SJerome Forissier          *
1137*11fa71b9SJerome Forissier          * - The record must contain a MAC, either in plain or
1138*11fa71b9SJerome Forissier          *   encrypted, depending on whether Encrypt-then-MAC
1139*11fa71b9SJerome Forissier          *   is used or not.
1140*11fa71b9SJerome Forissier          *   - If it is, the message contains the IV-prefix,
1141*11fa71b9SJerome Forissier          *     the CBC ciphertext, and the MAC.
1142*11fa71b9SJerome Forissier          *   - If it is not, the padded plaintext, and hence
1143*11fa71b9SJerome Forissier          *     the CBC ciphertext, has at least length maclen + 1
1144*11fa71b9SJerome Forissier          *     because there is at least the padding length byte.
1145*11fa71b9SJerome Forissier          *
1146*11fa71b9SJerome Forissier          * As the CBC ciphertext is not empty, both cases give the
1147*11fa71b9SJerome Forissier          * lower bound minlen + maclen + 1 on the record size, which
1148*11fa71b9SJerome Forissier          * we test for in the second check below.
1149*11fa71b9SJerome Forissier          */
1150*11fa71b9SJerome Forissier         if( rec->data_len < minlen + transform->ivlen ||
1151*11fa71b9SJerome Forissier             rec->data_len < minlen + transform->maclen + 1 )
1152*11fa71b9SJerome Forissier         {
1153*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) "
1154*11fa71b9SJerome Forissier                                 "+ 1 ) ( + expl IV )", rec->data_len,
1155*11fa71b9SJerome Forissier                                 transform->ivlen,
1156*11fa71b9SJerome Forissier                                 transform->maclen ) );
1157*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_MAC );
1158*11fa71b9SJerome Forissier         }
1159*11fa71b9SJerome Forissier 
1160*11fa71b9SJerome Forissier         /*
1161*11fa71b9SJerome Forissier          * Authenticate before decrypt if enabled
1162*11fa71b9SJerome Forissier          */
1163*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1164*11fa71b9SJerome Forissier         if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
1165*11fa71b9SJerome Forissier         {
1166*11fa71b9SJerome Forissier             unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
1167*11fa71b9SJerome Forissier 
1168*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
1169*11fa71b9SJerome Forissier 
1170*11fa71b9SJerome Forissier             /* Update data_len in tandem with add_data.
1171*11fa71b9SJerome Forissier              *
1172*11fa71b9SJerome Forissier              * The subtraction is safe because of the previous check
1173*11fa71b9SJerome Forissier              * data_len >= minlen + maclen + 1.
1174*11fa71b9SJerome Forissier              *
1175*11fa71b9SJerome Forissier              * Afterwards, we know that data + data_len is followed by at
1176*11fa71b9SJerome Forissier              * least maclen Bytes, which justifies the call to
1177*11fa71b9SJerome Forissier              * mbedtls_ssl_safer_memcmp() below.
1178*11fa71b9SJerome Forissier              *
1179*11fa71b9SJerome Forissier              * Further, we still know that data_len > minlen */
1180*11fa71b9SJerome Forissier             rec->data_len -= transform->maclen;
1181*11fa71b9SJerome Forissier             ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
1182*11fa71b9SJerome Forissier 
1183*11fa71b9SJerome Forissier             /* Calculate expected MAC. */
1184*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
1185*11fa71b9SJerome Forissier                                    add_data_len );
1186*11fa71b9SJerome Forissier             mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
1187*11fa71b9SJerome Forissier                                     add_data_len );
1188*11fa71b9SJerome Forissier             mbedtls_md_hmac_update( &transform->md_ctx_dec,
1189*11fa71b9SJerome Forissier                                     data, rec->data_len );
1190*11fa71b9SJerome Forissier             mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
1191*11fa71b9SJerome Forissier             mbedtls_md_hmac_reset( &transform->md_ctx_dec );
1192*11fa71b9SJerome Forissier 
1193*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", data + rec->data_len,
1194*11fa71b9SJerome Forissier                                    transform->maclen );
1195*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
1196*11fa71b9SJerome Forissier                                    transform->maclen );
1197*11fa71b9SJerome Forissier 
1198*11fa71b9SJerome Forissier             /* Compare expected MAC with MAC at the end of the record. */
1199*11fa71b9SJerome Forissier             if( mbedtls_ssl_safer_memcmp( data + rec->data_len, mac_expect,
1200*11fa71b9SJerome Forissier                                           transform->maclen ) != 0 )
1201*11fa71b9SJerome Forissier             {
1202*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
1203*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INVALID_MAC );
1204*11fa71b9SJerome Forissier             }
1205*11fa71b9SJerome Forissier             auth_done++;
1206*11fa71b9SJerome Forissier         }
1207*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
1208*11fa71b9SJerome Forissier 
1209*11fa71b9SJerome Forissier         /*
1210*11fa71b9SJerome Forissier          * Check length sanity
1211*11fa71b9SJerome Forissier          */
1212*11fa71b9SJerome Forissier 
1213*11fa71b9SJerome Forissier         /* We know from above that data_len > minlen >= 0,
1214*11fa71b9SJerome Forissier          * so the following check in particular implies that
1215*11fa71b9SJerome Forissier          * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */
1216*11fa71b9SJerome Forissier         if( rec->data_len % transform->ivlen != 0 )
1217*11fa71b9SJerome Forissier         {
1218*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
1219*11fa71b9SJerome Forissier                                         rec->data_len, transform->ivlen ) );
1220*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_MAC );
1221*11fa71b9SJerome Forissier         }
1222*11fa71b9SJerome Forissier 
1223*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
1224*11fa71b9SJerome Forissier         /*
1225*11fa71b9SJerome Forissier          * Initialize for prepended IV for block cipher in TLS v1.1 and up
1226*11fa71b9SJerome Forissier          */
1227*11fa71b9SJerome Forissier         if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
1228*11fa71b9SJerome Forissier         {
1229*11fa71b9SJerome Forissier             /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
1230*11fa71b9SJerome Forissier             memcpy( transform->iv_dec, data, transform->ivlen );
1231*11fa71b9SJerome Forissier 
1232*11fa71b9SJerome Forissier             data += transform->ivlen;
1233*11fa71b9SJerome Forissier             rec->data_offset += transform->ivlen;
1234*11fa71b9SJerome Forissier             rec->data_len -= transform->ivlen;
1235*11fa71b9SJerome Forissier         }
1236*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
1237*11fa71b9SJerome Forissier 
1238*11fa71b9SJerome Forissier         /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
1239*11fa71b9SJerome Forissier 
1240*11fa71b9SJerome Forissier         if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
1241*11fa71b9SJerome Forissier                                    transform->iv_dec, transform->ivlen,
1242*11fa71b9SJerome Forissier                                    data, rec->data_len, data, &olen ) ) != 0 )
1243*11fa71b9SJerome Forissier         {
1244*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
1245*11fa71b9SJerome Forissier             return( ret );
1246*11fa71b9SJerome Forissier         }
1247*11fa71b9SJerome Forissier 
1248*11fa71b9SJerome Forissier         /* Double-check that length hasn't changed during decryption. */
1249*11fa71b9SJerome Forissier         if( rec->data_len != olen )
1250*11fa71b9SJerome Forissier         {
1251*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1252*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1253*11fa71b9SJerome Forissier         }
1254*11fa71b9SJerome Forissier 
1255*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
1256*11fa71b9SJerome Forissier         if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
1257*11fa71b9SJerome Forissier         {
1258*11fa71b9SJerome Forissier             /*
1259*11fa71b9SJerome Forissier              * Save IV in SSL3 and TLS1, where CBC decryption of consecutive
1260*11fa71b9SJerome Forissier              * records is equivalent to CBC decryption of the concatenation
1261*11fa71b9SJerome Forissier              * of the records; in other words, IVs are maintained across
1262*11fa71b9SJerome Forissier              * record decryptions.
1263*11fa71b9SJerome Forissier              */
1264*11fa71b9SJerome Forissier             memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv,
1265*11fa71b9SJerome Forissier                     transform->ivlen );
1266*11fa71b9SJerome Forissier         }
1267*11fa71b9SJerome Forissier #endif
1268*11fa71b9SJerome Forissier 
1269*11fa71b9SJerome Forissier         /* Safe since data_len >= minlen + maclen + 1, so after having
1270*11fa71b9SJerome Forissier          * subtracted at most minlen and maclen up to this point,
1271*11fa71b9SJerome Forissier          * data_len > 0 (because of data_len % ivlen == 0, it's actually
1272*11fa71b9SJerome Forissier          * >= ivlen ). */
1273*11fa71b9SJerome Forissier         padlen = data[rec->data_len - 1];
1274*11fa71b9SJerome Forissier 
1275*11fa71b9SJerome Forissier         if( auth_done == 1 )
1276*11fa71b9SJerome Forissier         {
1277*11fa71b9SJerome Forissier             correct *= ( rec->data_len >= padlen + 1 );
1278*11fa71b9SJerome Forissier             padlen  *= ( rec->data_len >= padlen + 1 );
1279*11fa71b9SJerome Forissier         }
1280*11fa71b9SJerome Forissier         else
1281*11fa71b9SJerome Forissier         {
1282*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
1283*11fa71b9SJerome Forissier             if( rec->data_len < transform->maclen + padlen + 1 )
1284*11fa71b9SJerome Forissier             {
1285*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
1286*11fa71b9SJerome Forissier                                             rec->data_len,
1287*11fa71b9SJerome Forissier                                             transform->maclen,
1288*11fa71b9SJerome Forissier                                             padlen + 1 ) );
1289*11fa71b9SJerome Forissier             }
1290*11fa71b9SJerome Forissier #endif
1291*11fa71b9SJerome Forissier 
1292*11fa71b9SJerome Forissier             correct *= ( rec->data_len >= transform->maclen + padlen + 1 );
1293*11fa71b9SJerome Forissier             padlen  *= ( rec->data_len >= transform->maclen + padlen + 1 );
1294*11fa71b9SJerome Forissier         }
1295*11fa71b9SJerome Forissier 
1296*11fa71b9SJerome Forissier         padlen++;
1297*11fa71b9SJerome Forissier 
1298*11fa71b9SJerome Forissier         /* Regardless of the validity of the padding,
1299*11fa71b9SJerome Forissier          * we have data_len >= padlen here. */
1300*11fa71b9SJerome Forissier 
1301*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3)
1302*11fa71b9SJerome Forissier         if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
1303*11fa71b9SJerome Forissier         {
1304*11fa71b9SJerome Forissier             if( padlen > transform->ivlen )
1305*11fa71b9SJerome Forissier             {
1306*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
1307*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
1308*11fa71b9SJerome Forissier                                             "should be no more than %d",
1309*11fa71b9SJerome Forissier                                             padlen, transform->ivlen ) );
1310*11fa71b9SJerome Forissier #endif
1311*11fa71b9SJerome Forissier                 correct = 0;
1312*11fa71b9SJerome Forissier             }
1313*11fa71b9SJerome Forissier         }
1314*11fa71b9SJerome Forissier         else
1315*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */
1316*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
1317*11fa71b9SJerome Forissier     defined(MBEDTLS_SSL_PROTO_TLS1_2)
1318*11fa71b9SJerome Forissier         if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
1319*11fa71b9SJerome Forissier         {
1320*11fa71b9SJerome Forissier             /* The padding check involves a series of up to 256
1321*11fa71b9SJerome Forissier              * consecutive memory reads at the end of the record
1322*11fa71b9SJerome Forissier              * plaintext buffer. In order to hide the length and
1323*11fa71b9SJerome Forissier              * validity of the padding, always perform exactly
1324*11fa71b9SJerome Forissier              * `min(256,plaintext_len)` reads (but take into account
1325*11fa71b9SJerome Forissier              * only the last `padlen` bytes for the padding check). */
1326*11fa71b9SJerome Forissier             size_t pad_count = 0;
1327*11fa71b9SJerome Forissier             size_t real_count = 0;
1328*11fa71b9SJerome Forissier             volatile unsigned char* const check = data;
1329*11fa71b9SJerome Forissier 
1330*11fa71b9SJerome Forissier             /* Index of first padding byte; it has been ensured above
1331*11fa71b9SJerome Forissier              * that the subtraction is safe. */
1332*11fa71b9SJerome Forissier             size_t const padding_idx = rec->data_len - padlen;
1333*11fa71b9SJerome Forissier             size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
1334*11fa71b9SJerome Forissier             size_t const start_idx = rec->data_len - num_checks;
1335*11fa71b9SJerome Forissier             size_t idx;
1336*11fa71b9SJerome Forissier 
1337*11fa71b9SJerome Forissier             for( idx = start_idx; idx < rec->data_len; idx++ )
1338*11fa71b9SJerome Forissier             {
1339*11fa71b9SJerome Forissier                 real_count |= ( idx >= padding_idx );
1340*11fa71b9SJerome Forissier                 pad_count += real_count * ( check[idx] == padlen - 1 );
1341*11fa71b9SJerome Forissier             }
1342*11fa71b9SJerome Forissier             correct &= ( pad_count == padlen );
1343*11fa71b9SJerome Forissier 
1344*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
1345*11fa71b9SJerome Forissier             if( padlen > 0 && correct == 0 )
1346*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
1347*11fa71b9SJerome Forissier #endif
1348*11fa71b9SJerome Forissier             padlen &= correct * 0x1FF;
1349*11fa71b9SJerome Forissier         }
1350*11fa71b9SJerome Forissier         else
1351*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
1352*11fa71b9SJerome Forissier           MBEDTLS_SSL_PROTO_TLS1_2 */
1353*11fa71b9SJerome Forissier         {
1354*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1355*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1356*11fa71b9SJerome Forissier         }
1357*11fa71b9SJerome Forissier 
1358*11fa71b9SJerome Forissier         /* If the padding was found to be invalid, padlen == 0
1359*11fa71b9SJerome Forissier          * and the subtraction is safe. If the padding was found valid,
1360*11fa71b9SJerome Forissier          * padlen hasn't been changed and the previous assertion
1361*11fa71b9SJerome Forissier          * data_len >= padlen still holds. */
1362*11fa71b9SJerome Forissier         rec->data_len -= padlen;
1363*11fa71b9SJerome Forissier     }
1364*11fa71b9SJerome Forissier     else
1365*11fa71b9SJerome Forissier #endif /* MBEDTLS_CIPHER_MODE_CBC &&
1366*11fa71b9SJerome Forissier           ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
1367*11fa71b9SJerome Forissier     {
1368*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1369*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1370*11fa71b9SJerome Forissier     }
1371*11fa71b9SJerome Forissier 
1372*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
1373*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
1374*11fa71b9SJerome Forissier                            data, rec->data_len );
1375*11fa71b9SJerome Forissier #endif
1376*11fa71b9SJerome Forissier 
1377*11fa71b9SJerome Forissier     /*
1378*11fa71b9SJerome Forissier      * Authenticate if not done yet.
1379*11fa71b9SJerome Forissier      * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
1380*11fa71b9SJerome Forissier      */
1381*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
1382*11fa71b9SJerome Forissier     if( auth_done == 0 )
1383*11fa71b9SJerome Forissier     {
1384*11fa71b9SJerome Forissier         unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
1385*11fa71b9SJerome Forissier 
1386*11fa71b9SJerome Forissier         /* If the initial value of padlen was such that
1387*11fa71b9SJerome Forissier          * data_len < maclen + padlen + 1, then padlen
1388*11fa71b9SJerome Forissier          * got reset to 1, and the initial check
1389*11fa71b9SJerome Forissier          * data_len >= minlen + maclen + 1
1390*11fa71b9SJerome Forissier          * guarantees that at this point we still
1391*11fa71b9SJerome Forissier          * have at least data_len >= maclen.
1392*11fa71b9SJerome Forissier          *
1393*11fa71b9SJerome Forissier          * If the initial value of padlen was such that
1394*11fa71b9SJerome Forissier          * data_len >= maclen + padlen + 1, then we have
1395*11fa71b9SJerome Forissier          * subtracted either padlen + 1 (if the padding was correct)
1396*11fa71b9SJerome Forissier          * or 0 (if the padding was incorrect) since then,
1397*11fa71b9SJerome Forissier          * hence data_len >= maclen in any case.
1398*11fa71b9SJerome Forissier          */
1399*11fa71b9SJerome Forissier         rec->data_len -= transform->maclen;
1400*11fa71b9SJerome Forissier         ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
1401*11fa71b9SJerome Forissier 
1402*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3)
1403*11fa71b9SJerome Forissier         if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
1404*11fa71b9SJerome Forissier         {
1405*11fa71b9SJerome Forissier             ssl_mac( &transform->md_ctx_dec,
1406*11fa71b9SJerome Forissier                      transform->mac_dec,
1407*11fa71b9SJerome Forissier                      data, rec->data_len,
1408*11fa71b9SJerome Forissier                      rec->ctr, rec->type,
1409*11fa71b9SJerome Forissier                      mac_expect );
1410*11fa71b9SJerome Forissier         }
1411*11fa71b9SJerome Forissier         else
1412*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */
1413*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
1414*11fa71b9SJerome Forissier         defined(MBEDTLS_SSL_PROTO_TLS1_2)
1415*11fa71b9SJerome Forissier         if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
1416*11fa71b9SJerome Forissier         {
1417*11fa71b9SJerome Forissier             /*
1418*11fa71b9SJerome Forissier              * Process MAC and always update for padlen afterwards to make
1419*11fa71b9SJerome Forissier              * total time independent of padlen.
1420*11fa71b9SJerome Forissier              *
1421*11fa71b9SJerome Forissier              * Known timing attacks:
1422*11fa71b9SJerome Forissier              *  - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
1423*11fa71b9SJerome Forissier              *
1424*11fa71b9SJerome Forissier              * To compensate for different timings for the MAC calculation
1425*11fa71b9SJerome Forissier              * depending on how much padding was removed (which is determined
1426*11fa71b9SJerome Forissier              * by padlen), process extra_run more blocks through the hash
1427*11fa71b9SJerome Forissier              * function.
1428*11fa71b9SJerome Forissier              *
1429*11fa71b9SJerome Forissier              * The formula in the paper is
1430*11fa71b9SJerome Forissier              *   extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 )
1431*11fa71b9SJerome Forissier              * where L1 is the size of the header plus the decrypted message
1432*11fa71b9SJerome Forissier              * plus CBC padding and L2 is the size of the header plus the
1433*11fa71b9SJerome Forissier              * decrypted message. This is for an underlying hash function
1434*11fa71b9SJerome Forissier              * with 64-byte blocks.
1435*11fa71b9SJerome Forissier              * We use ( (Lx+8) / 64 ) to handle 'negative Lx' values
1436*11fa71b9SJerome Forissier              * correctly. We round down instead of up, so -56 is the correct
1437*11fa71b9SJerome Forissier              * value for our calculations instead of -55.
1438*11fa71b9SJerome Forissier              *
1439*11fa71b9SJerome Forissier              * Repeat the formula rather than defining a block_size variable.
1440*11fa71b9SJerome Forissier              * This avoids requiring division by a variable at runtime
1441*11fa71b9SJerome Forissier              * (which would be marginally less efficient and would require
1442*11fa71b9SJerome Forissier              * linking an extra division function in some builds).
1443*11fa71b9SJerome Forissier              */
1444*11fa71b9SJerome Forissier             size_t j, extra_run = 0;
1445*11fa71b9SJerome Forissier             unsigned char tmp[MBEDTLS_MD_MAX_BLOCK_SIZE];
1446*11fa71b9SJerome Forissier 
1447*11fa71b9SJerome Forissier             /*
1448*11fa71b9SJerome Forissier              * The next two sizes are the minimum and maximum values of
1449*11fa71b9SJerome Forissier              * in_msglen over all padlen values.
1450*11fa71b9SJerome Forissier              *
1451*11fa71b9SJerome Forissier              * They're independent of padlen, since we previously did
1452*11fa71b9SJerome Forissier              * data_len -= padlen.
1453*11fa71b9SJerome Forissier              *
1454*11fa71b9SJerome Forissier              * Note that max_len + maclen is never more than the buffer
1455*11fa71b9SJerome Forissier              * length, as we previously did in_msglen -= maclen too.
1456*11fa71b9SJerome Forissier              */
1457*11fa71b9SJerome Forissier             const size_t max_len = rec->data_len + padlen;
1458*11fa71b9SJerome Forissier             const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
1459*11fa71b9SJerome Forissier 
1460*11fa71b9SJerome Forissier             memset( tmp, 0, sizeof( tmp ) );
1461*11fa71b9SJerome Forissier 
1462*11fa71b9SJerome Forissier             switch( mbedtls_md_get_type( transform->md_ctx_dec.md_info ) )
1463*11fa71b9SJerome Forissier             {
1464*11fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \
1465*11fa71b9SJerome Forissier     defined(MBEDTLS_SHA256_C)
1466*11fa71b9SJerome Forissier                 case MBEDTLS_MD_MD5:
1467*11fa71b9SJerome Forissier                 case MBEDTLS_MD_SHA1:
1468*11fa71b9SJerome Forissier                 case MBEDTLS_MD_SHA256:
1469*11fa71b9SJerome Forissier                     /* 8 bytes of message size, 64-byte compression blocks */
1470*11fa71b9SJerome Forissier                     extra_run =
1471*11fa71b9SJerome Forissier                         ( add_data_len + rec->data_len + padlen + 8 ) / 64 -
1472*11fa71b9SJerome Forissier                         ( add_data_len + rec->data_len          + 8 ) / 64;
1473*11fa71b9SJerome Forissier                     break;
1474*11fa71b9SJerome Forissier #endif
1475*11fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
1476*11fa71b9SJerome Forissier                 case MBEDTLS_MD_SHA384:
1477*11fa71b9SJerome Forissier                     /* 16 bytes of message size, 128-byte compression blocks */
1478*11fa71b9SJerome Forissier                     extra_run =
1479*11fa71b9SJerome Forissier                         ( add_data_len + rec->data_len + padlen + 16 ) / 128 -
1480*11fa71b9SJerome Forissier                         ( add_data_len + rec->data_len          + 16 ) / 128;
1481*11fa71b9SJerome Forissier                     break;
1482*11fa71b9SJerome Forissier #endif
1483*11fa71b9SJerome Forissier                 default:
1484*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1485*11fa71b9SJerome Forissier                     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1486*11fa71b9SJerome Forissier             }
1487*11fa71b9SJerome Forissier 
1488*11fa71b9SJerome Forissier             extra_run &= correct * 0xFF;
1489*11fa71b9SJerome Forissier 
1490*11fa71b9SJerome Forissier             mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
1491*11fa71b9SJerome Forissier                                     add_data_len );
1492*11fa71b9SJerome Forissier             mbedtls_md_hmac_update( &transform->md_ctx_dec, data,
1493*11fa71b9SJerome Forissier                                     rec->data_len );
1494*11fa71b9SJerome Forissier             /* Make sure we access everything even when padlen > 0. This
1495*11fa71b9SJerome Forissier              * makes the synchronisation requirements for just-in-time
1496*11fa71b9SJerome Forissier              * Prime+Probe attacks much tighter and hopefully impractical. */
1497*11fa71b9SJerome Forissier             ssl_read_memory( data + rec->data_len, padlen );
1498*11fa71b9SJerome Forissier             mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
1499*11fa71b9SJerome Forissier 
1500*11fa71b9SJerome Forissier             /* Call mbedtls_md_process at least once due to cache attacks
1501*11fa71b9SJerome Forissier              * that observe whether md_process() was called of not */
1502*11fa71b9SJerome Forissier             for( j = 0; j < extra_run + 1; j++ )
1503*11fa71b9SJerome Forissier                 mbedtls_md_process( &transform->md_ctx_dec, tmp );
1504*11fa71b9SJerome Forissier 
1505*11fa71b9SJerome Forissier             mbedtls_md_hmac_reset( &transform->md_ctx_dec );
1506*11fa71b9SJerome Forissier 
1507*11fa71b9SJerome Forissier             /* Make sure we access all the memory that could contain the MAC,
1508*11fa71b9SJerome Forissier              * before we check it in the next code block. This makes the
1509*11fa71b9SJerome Forissier              * synchronisation requirements for just-in-time Prime+Probe
1510*11fa71b9SJerome Forissier              * attacks much tighter and hopefully impractical. */
1511*11fa71b9SJerome Forissier             ssl_read_memory( data + min_len,
1512*11fa71b9SJerome Forissier                              max_len - min_len + transform->maclen );
1513*11fa71b9SJerome Forissier         }
1514*11fa71b9SJerome Forissier         else
1515*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
1516*11fa71b9SJerome Forissier               MBEDTLS_SSL_PROTO_TLS1_2 */
1517*11fa71b9SJerome Forissier         {
1518*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1519*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1520*11fa71b9SJerome Forissier         }
1521*11fa71b9SJerome Forissier 
1522*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
1523*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen );
1524*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", data + rec->data_len, transform->maclen );
1525*11fa71b9SJerome Forissier #endif
1526*11fa71b9SJerome Forissier 
1527*11fa71b9SJerome Forissier         if( mbedtls_ssl_safer_memcmp( data + rec->data_len, mac_expect,
1528*11fa71b9SJerome Forissier                                       transform->maclen ) != 0 )
1529*11fa71b9SJerome Forissier         {
1530*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
1531*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
1532*11fa71b9SJerome Forissier #endif
1533*11fa71b9SJerome Forissier             correct = 0;
1534*11fa71b9SJerome Forissier         }
1535*11fa71b9SJerome Forissier         auth_done++;
1536*11fa71b9SJerome Forissier     }
1537*11fa71b9SJerome Forissier 
1538*11fa71b9SJerome Forissier     /*
1539*11fa71b9SJerome Forissier      * Finally check the correct flag
1540*11fa71b9SJerome Forissier      */
1541*11fa71b9SJerome Forissier     if( correct == 0 )
1542*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INVALID_MAC );
1543*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
1544*11fa71b9SJerome Forissier 
1545*11fa71b9SJerome Forissier     /* Make extra sure authentication was performed, exactly once */
1546*11fa71b9SJerome Forissier     if( auth_done != 1 )
1547*11fa71b9SJerome Forissier     {
1548*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1549*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1550*11fa71b9SJerome Forissier     }
1551*11fa71b9SJerome Forissier 
1552*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1553*11fa71b9SJerome Forissier     if( rec->cid_len != 0 )
1554*11fa71b9SJerome Forissier     {
1555*11fa71b9SJerome Forissier         ret = ssl_cid_parse_inner_plaintext( data, &rec->data_len,
1556*11fa71b9SJerome Forissier                                              &rec->type );
1557*11fa71b9SJerome Forissier         if( ret != 0 )
1558*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
1559*11fa71b9SJerome Forissier     }
1560*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1561*11fa71b9SJerome Forissier 
1562*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
1563*11fa71b9SJerome Forissier 
1564*11fa71b9SJerome Forissier     return( 0 );
1565*11fa71b9SJerome Forissier }
1566*11fa71b9SJerome Forissier 
1567*11fa71b9SJerome Forissier #undef MAC_NONE
1568*11fa71b9SJerome Forissier #undef MAC_PLAINTEXT
1569*11fa71b9SJerome Forissier #undef MAC_CIPHERTEXT
1570*11fa71b9SJerome Forissier 
1571*11fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT)
1572*11fa71b9SJerome Forissier /*
1573*11fa71b9SJerome Forissier  * Compression/decompression functions
1574*11fa71b9SJerome Forissier  */
1575*11fa71b9SJerome Forissier static int ssl_compress_buf( mbedtls_ssl_context *ssl )
1576*11fa71b9SJerome Forissier {
1577*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1578*11fa71b9SJerome Forissier     unsigned char *msg_post = ssl->out_msg;
1579*11fa71b9SJerome Forissier     ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
1580*11fa71b9SJerome Forissier     size_t len_pre = ssl->out_msglen;
1581*11fa71b9SJerome Forissier     unsigned char *msg_pre = ssl->compress_buf;
1582*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
1583*11fa71b9SJerome Forissier     size_t out_buf_len = ssl->out_buf_len;
1584*11fa71b9SJerome Forissier #else
1585*11fa71b9SJerome Forissier     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
1586*11fa71b9SJerome Forissier #endif
1587*11fa71b9SJerome Forissier 
1588*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
1589*11fa71b9SJerome Forissier 
1590*11fa71b9SJerome Forissier     if( len_pre == 0 )
1591*11fa71b9SJerome Forissier         return( 0 );
1592*11fa71b9SJerome Forissier 
1593*11fa71b9SJerome Forissier     memcpy( msg_pre, ssl->out_msg, len_pre );
1594*11fa71b9SJerome Forissier 
1595*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ",
1596*11fa71b9SJerome Forissier                    ssl->out_msglen ) );
1597*11fa71b9SJerome Forissier 
1598*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
1599*11fa71b9SJerome Forissier                    ssl->out_msg, ssl->out_msglen );
1600*11fa71b9SJerome Forissier 
1601*11fa71b9SJerome Forissier     ssl->transform_out->ctx_deflate.next_in = msg_pre;
1602*11fa71b9SJerome Forissier     ssl->transform_out->ctx_deflate.avail_in = len_pre;
1603*11fa71b9SJerome Forissier     ssl->transform_out->ctx_deflate.next_out = msg_post;
1604*11fa71b9SJerome Forissier     ssl->transform_out->ctx_deflate.avail_out = out_buf_len - bytes_written;
1605*11fa71b9SJerome Forissier 
1606*11fa71b9SJerome Forissier     ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
1607*11fa71b9SJerome Forissier     if( ret != Z_OK )
1608*11fa71b9SJerome Forissier     {
1609*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
1610*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
1611*11fa71b9SJerome Forissier     }
1612*11fa71b9SJerome Forissier 
1613*11fa71b9SJerome Forissier     ssl->out_msglen = out_buf_len -
1614*11fa71b9SJerome Forissier                       ssl->transform_out->ctx_deflate.avail_out - bytes_written;
1615*11fa71b9SJerome Forissier 
1616*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
1617*11fa71b9SJerome Forissier                    ssl->out_msglen ) );
1618*11fa71b9SJerome Forissier 
1619*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
1620*11fa71b9SJerome Forissier                    ssl->out_msg, ssl->out_msglen );
1621*11fa71b9SJerome Forissier 
1622*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
1623*11fa71b9SJerome Forissier 
1624*11fa71b9SJerome Forissier     return( 0 );
1625*11fa71b9SJerome Forissier }
1626*11fa71b9SJerome Forissier 
1627*11fa71b9SJerome Forissier static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
1628*11fa71b9SJerome Forissier {
1629*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1630*11fa71b9SJerome Forissier     unsigned char *msg_post = ssl->in_msg;
1631*11fa71b9SJerome Forissier     ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
1632*11fa71b9SJerome Forissier     size_t len_pre = ssl->in_msglen;
1633*11fa71b9SJerome Forissier     unsigned char *msg_pre = ssl->compress_buf;
1634*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
1635*11fa71b9SJerome Forissier     size_t in_buf_len = ssl->in_buf_len;
1636*11fa71b9SJerome Forissier #else
1637*11fa71b9SJerome Forissier     size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
1638*11fa71b9SJerome Forissier #endif
1639*11fa71b9SJerome Forissier 
1640*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
1641*11fa71b9SJerome Forissier 
1642*11fa71b9SJerome Forissier     if( len_pre == 0 )
1643*11fa71b9SJerome Forissier         return( 0 );
1644*11fa71b9SJerome Forissier 
1645*11fa71b9SJerome Forissier     memcpy( msg_pre, ssl->in_msg, len_pre );
1646*11fa71b9SJerome Forissier 
1647*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ",
1648*11fa71b9SJerome Forissier                    ssl->in_msglen ) );
1649*11fa71b9SJerome Forissier 
1650*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
1651*11fa71b9SJerome Forissier                    ssl->in_msg, ssl->in_msglen );
1652*11fa71b9SJerome Forissier 
1653*11fa71b9SJerome Forissier     ssl->transform_in->ctx_inflate.next_in = msg_pre;
1654*11fa71b9SJerome Forissier     ssl->transform_in->ctx_inflate.avail_in = len_pre;
1655*11fa71b9SJerome Forissier     ssl->transform_in->ctx_inflate.next_out = msg_post;
1656*11fa71b9SJerome Forissier     ssl->transform_in->ctx_inflate.avail_out = in_buf_len - header_bytes;
1657*11fa71b9SJerome Forissier 
1658*11fa71b9SJerome Forissier     ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
1659*11fa71b9SJerome Forissier     if( ret != Z_OK )
1660*11fa71b9SJerome Forissier     {
1661*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
1662*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
1663*11fa71b9SJerome Forissier     }
1664*11fa71b9SJerome Forissier 
1665*11fa71b9SJerome Forissier     ssl->in_msglen = in_buf_len -
1666*11fa71b9SJerome Forissier                      ssl->transform_in->ctx_inflate.avail_out - header_bytes;
1667*11fa71b9SJerome Forissier 
1668*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
1669*11fa71b9SJerome Forissier                    ssl->in_msglen ) );
1670*11fa71b9SJerome Forissier 
1671*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
1672*11fa71b9SJerome Forissier                    ssl->in_msg, ssl->in_msglen );
1673*11fa71b9SJerome Forissier 
1674*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
1675*11fa71b9SJerome Forissier 
1676*11fa71b9SJerome Forissier     return( 0 );
1677*11fa71b9SJerome Forissier }
1678*11fa71b9SJerome Forissier #endif /* MBEDTLS_ZLIB_SUPPORT */
1679*11fa71b9SJerome Forissier 
1680*11fa71b9SJerome Forissier /*
1681*11fa71b9SJerome Forissier  * Fill the input message buffer by appending data to it.
1682*11fa71b9SJerome Forissier  * The amount of data already fetched is in ssl->in_left.
1683*11fa71b9SJerome Forissier  *
1684*11fa71b9SJerome Forissier  * If we return 0, is it guaranteed that (at least) nb_want bytes are
1685*11fa71b9SJerome Forissier  * available (from this read and/or a previous one). Otherwise, an error code
1686*11fa71b9SJerome Forissier  * is returned (possibly EOF or WANT_READ).
1687*11fa71b9SJerome Forissier  *
1688*11fa71b9SJerome Forissier  * With stream transport (TLS) on success ssl->in_left == nb_want, but
1689*11fa71b9SJerome Forissier  * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
1690*11fa71b9SJerome Forissier  * since we always read a whole datagram at once.
1691*11fa71b9SJerome Forissier  *
1692*11fa71b9SJerome Forissier  * For DTLS, it is up to the caller to set ssl->next_record_offset when
1693*11fa71b9SJerome Forissier  * they're done reading a record.
1694*11fa71b9SJerome Forissier  */
1695*11fa71b9SJerome Forissier int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
1696*11fa71b9SJerome Forissier {
1697*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1698*11fa71b9SJerome Forissier     size_t len;
1699*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
1700*11fa71b9SJerome Forissier     size_t in_buf_len = ssl->in_buf_len;
1701*11fa71b9SJerome Forissier #else
1702*11fa71b9SJerome Forissier     size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
1703*11fa71b9SJerome Forissier #endif
1704*11fa71b9SJerome Forissier 
1705*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
1706*11fa71b9SJerome Forissier 
1707*11fa71b9SJerome Forissier     if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
1708*11fa71b9SJerome Forissier     {
1709*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
1710*11fa71b9SJerome Forissier                             "or mbedtls_ssl_set_bio()" ) );
1711*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
1712*11fa71b9SJerome Forissier     }
1713*11fa71b9SJerome Forissier 
1714*11fa71b9SJerome Forissier     if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
1715*11fa71b9SJerome Forissier     {
1716*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
1717*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
1718*11fa71b9SJerome Forissier     }
1719*11fa71b9SJerome Forissier 
1720*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
1721*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
1722*11fa71b9SJerome Forissier     {
1723*11fa71b9SJerome Forissier         uint32_t timeout;
1724*11fa71b9SJerome Forissier 
1725*11fa71b9SJerome Forissier         /* Just to be sure */
1726*11fa71b9SJerome Forissier         if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
1727*11fa71b9SJerome Forissier         {
1728*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
1729*11fa71b9SJerome Forissier                         "mbedtls_ssl_set_timer_cb() for DTLS" ) );
1730*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
1731*11fa71b9SJerome Forissier         }
1732*11fa71b9SJerome Forissier 
1733*11fa71b9SJerome Forissier         /*
1734*11fa71b9SJerome Forissier          * The point is, we need to always read a full datagram at once, so we
1735*11fa71b9SJerome Forissier          * sometimes read more then requested, and handle the additional data.
1736*11fa71b9SJerome Forissier          * It could be the rest of the current record (while fetching the
1737*11fa71b9SJerome Forissier          * header) and/or some other records in the same datagram.
1738*11fa71b9SJerome Forissier          */
1739*11fa71b9SJerome Forissier 
1740*11fa71b9SJerome Forissier         /*
1741*11fa71b9SJerome Forissier          * Move to the next record in the already read datagram if applicable
1742*11fa71b9SJerome Forissier          */
1743*11fa71b9SJerome Forissier         if( ssl->next_record_offset != 0 )
1744*11fa71b9SJerome Forissier         {
1745*11fa71b9SJerome Forissier             if( ssl->in_left < ssl->next_record_offset )
1746*11fa71b9SJerome Forissier             {
1747*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1748*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1749*11fa71b9SJerome Forissier             }
1750*11fa71b9SJerome Forissier 
1751*11fa71b9SJerome Forissier             ssl->in_left -= ssl->next_record_offset;
1752*11fa71b9SJerome Forissier 
1753*11fa71b9SJerome Forissier             if( ssl->in_left != 0 )
1754*11fa71b9SJerome Forissier             {
1755*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d",
1756*11fa71b9SJerome Forissier                                     ssl->next_record_offset ) );
1757*11fa71b9SJerome Forissier                 memmove( ssl->in_hdr,
1758*11fa71b9SJerome Forissier                          ssl->in_hdr + ssl->next_record_offset,
1759*11fa71b9SJerome Forissier                          ssl->in_left );
1760*11fa71b9SJerome Forissier             }
1761*11fa71b9SJerome Forissier 
1762*11fa71b9SJerome Forissier             ssl->next_record_offset = 0;
1763*11fa71b9SJerome Forissier         }
1764*11fa71b9SJerome Forissier 
1765*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
1766*11fa71b9SJerome Forissier                        ssl->in_left, nb_want ) );
1767*11fa71b9SJerome Forissier 
1768*11fa71b9SJerome Forissier         /*
1769*11fa71b9SJerome Forissier          * Done if we already have enough data.
1770*11fa71b9SJerome Forissier          */
1771*11fa71b9SJerome Forissier         if( nb_want <= ssl->in_left)
1772*11fa71b9SJerome Forissier         {
1773*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
1774*11fa71b9SJerome Forissier             return( 0 );
1775*11fa71b9SJerome Forissier         }
1776*11fa71b9SJerome Forissier 
1777*11fa71b9SJerome Forissier         /*
1778*11fa71b9SJerome Forissier          * A record can't be split across datagrams. If we need to read but
1779*11fa71b9SJerome Forissier          * are not at the beginning of a new record, the caller did something
1780*11fa71b9SJerome Forissier          * wrong.
1781*11fa71b9SJerome Forissier          */
1782*11fa71b9SJerome Forissier         if( ssl->in_left != 0 )
1783*11fa71b9SJerome Forissier         {
1784*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1785*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1786*11fa71b9SJerome Forissier         }
1787*11fa71b9SJerome Forissier 
1788*11fa71b9SJerome Forissier         /*
1789*11fa71b9SJerome Forissier          * Don't even try to read if time's out already.
1790*11fa71b9SJerome Forissier          * This avoids by-passing the timer when repeatedly receiving messages
1791*11fa71b9SJerome Forissier          * that will end up being dropped.
1792*11fa71b9SJerome Forissier          */
1793*11fa71b9SJerome Forissier         if( mbedtls_ssl_check_timer( ssl ) != 0 )
1794*11fa71b9SJerome Forissier         {
1795*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) );
1796*11fa71b9SJerome Forissier             ret = MBEDTLS_ERR_SSL_TIMEOUT;
1797*11fa71b9SJerome Forissier         }
1798*11fa71b9SJerome Forissier         else
1799*11fa71b9SJerome Forissier         {
1800*11fa71b9SJerome Forissier             len = in_buf_len - ( ssl->in_hdr - ssl->in_buf );
1801*11fa71b9SJerome Forissier 
1802*11fa71b9SJerome Forissier             if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
1803*11fa71b9SJerome Forissier                 timeout = ssl->handshake->retransmit_timeout;
1804*11fa71b9SJerome Forissier             else
1805*11fa71b9SJerome Forissier                 timeout = ssl->conf->read_timeout;
1806*11fa71b9SJerome Forissier 
1807*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
1808*11fa71b9SJerome Forissier 
1809*11fa71b9SJerome Forissier             if( ssl->f_recv_timeout != NULL )
1810*11fa71b9SJerome Forissier                 ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
1811*11fa71b9SJerome Forissier                                                                     timeout );
1812*11fa71b9SJerome Forissier             else
1813*11fa71b9SJerome Forissier                 ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
1814*11fa71b9SJerome Forissier 
1815*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
1816*11fa71b9SJerome Forissier 
1817*11fa71b9SJerome Forissier             if( ret == 0 )
1818*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_CONN_EOF );
1819*11fa71b9SJerome Forissier         }
1820*11fa71b9SJerome Forissier 
1821*11fa71b9SJerome Forissier         if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
1822*11fa71b9SJerome Forissier         {
1823*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
1824*11fa71b9SJerome Forissier             mbedtls_ssl_set_timer( ssl, 0 );
1825*11fa71b9SJerome Forissier 
1826*11fa71b9SJerome Forissier             if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
1827*11fa71b9SJerome Forissier             {
1828*11fa71b9SJerome Forissier                 if( ssl_double_retransmit_timeout( ssl ) != 0 )
1829*11fa71b9SJerome Forissier                 {
1830*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
1831*11fa71b9SJerome Forissier                     return( MBEDTLS_ERR_SSL_TIMEOUT );
1832*11fa71b9SJerome Forissier                 }
1833*11fa71b9SJerome Forissier 
1834*11fa71b9SJerome Forissier                 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
1835*11fa71b9SJerome Forissier                 {
1836*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
1837*11fa71b9SJerome Forissier                     return( ret );
1838*11fa71b9SJerome Forissier                 }
1839*11fa71b9SJerome Forissier 
1840*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_WANT_READ );
1841*11fa71b9SJerome Forissier             }
1842*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
1843*11fa71b9SJerome Forissier             else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
1844*11fa71b9SJerome Forissier                      ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
1845*11fa71b9SJerome Forissier             {
1846*11fa71b9SJerome Forissier                 if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 )
1847*11fa71b9SJerome Forissier                 {
1848*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request",
1849*11fa71b9SJerome Forissier                                            ret );
1850*11fa71b9SJerome Forissier                     return( ret );
1851*11fa71b9SJerome Forissier                 }
1852*11fa71b9SJerome Forissier 
1853*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_WANT_READ );
1854*11fa71b9SJerome Forissier             }
1855*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
1856*11fa71b9SJerome Forissier         }
1857*11fa71b9SJerome Forissier 
1858*11fa71b9SJerome Forissier         if( ret < 0 )
1859*11fa71b9SJerome Forissier             return( ret );
1860*11fa71b9SJerome Forissier 
1861*11fa71b9SJerome Forissier         ssl->in_left = ret;
1862*11fa71b9SJerome Forissier     }
1863*11fa71b9SJerome Forissier     else
1864*11fa71b9SJerome Forissier #endif
1865*11fa71b9SJerome Forissier     {
1866*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
1867*11fa71b9SJerome Forissier                        ssl->in_left, nb_want ) );
1868*11fa71b9SJerome Forissier 
1869*11fa71b9SJerome Forissier         while( ssl->in_left < nb_want )
1870*11fa71b9SJerome Forissier         {
1871*11fa71b9SJerome Forissier             len = nb_want - ssl->in_left;
1872*11fa71b9SJerome Forissier 
1873*11fa71b9SJerome Forissier             if( mbedtls_ssl_check_timer( ssl ) != 0 )
1874*11fa71b9SJerome Forissier                 ret = MBEDTLS_ERR_SSL_TIMEOUT;
1875*11fa71b9SJerome Forissier             else
1876*11fa71b9SJerome Forissier             {
1877*11fa71b9SJerome Forissier                 if( ssl->f_recv_timeout != NULL )
1878*11fa71b9SJerome Forissier                 {
1879*11fa71b9SJerome Forissier                     ret = ssl->f_recv_timeout( ssl->p_bio,
1880*11fa71b9SJerome Forissier                                                ssl->in_hdr + ssl->in_left, len,
1881*11fa71b9SJerome Forissier                                                ssl->conf->read_timeout );
1882*11fa71b9SJerome Forissier                 }
1883*11fa71b9SJerome Forissier                 else
1884*11fa71b9SJerome Forissier                 {
1885*11fa71b9SJerome Forissier                     ret = ssl->f_recv( ssl->p_bio,
1886*11fa71b9SJerome Forissier                                        ssl->in_hdr + ssl->in_left, len );
1887*11fa71b9SJerome Forissier                 }
1888*11fa71b9SJerome Forissier             }
1889*11fa71b9SJerome Forissier 
1890*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
1891*11fa71b9SJerome Forissier                                         ssl->in_left, nb_want ) );
1892*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
1893*11fa71b9SJerome Forissier 
1894*11fa71b9SJerome Forissier             if( ret == 0 )
1895*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_CONN_EOF );
1896*11fa71b9SJerome Forissier 
1897*11fa71b9SJerome Forissier             if( ret < 0 )
1898*11fa71b9SJerome Forissier                 return( ret );
1899*11fa71b9SJerome Forissier 
1900*11fa71b9SJerome Forissier             if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
1901*11fa71b9SJerome Forissier             {
1902*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1,
1903*11fa71b9SJerome Forissier                     ( "f_recv returned %d bytes but only %lu were requested",
1904*11fa71b9SJerome Forissier                     ret, (unsigned long)len ) );
1905*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1906*11fa71b9SJerome Forissier             }
1907*11fa71b9SJerome Forissier 
1908*11fa71b9SJerome Forissier             ssl->in_left += ret;
1909*11fa71b9SJerome Forissier         }
1910*11fa71b9SJerome Forissier     }
1911*11fa71b9SJerome Forissier 
1912*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
1913*11fa71b9SJerome Forissier 
1914*11fa71b9SJerome Forissier     return( 0 );
1915*11fa71b9SJerome Forissier }
1916*11fa71b9SJerome Forissier 
1917*11fa71b9SJerome Forissier /*
1918*11fa71b9SJerome Forissier  * Flush any data not yet written
1919*11fa71b9SJerome Forissier  */
1920*11fa71b9SJerome Forissier int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
1921*11fa71b9SJerome Forissier {
1922*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1923*11fa71b9SJerome Forissier     unsigned char *buf;
1924*11fa71b9SJerome Forissier 
1925*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
1926*11fa71b9SJerome Forissier 
1927*11fa71b9SJerome Forissier     if( ssl->f_send == NULL )
1928*11fa71b9SJerome Forissier     {
1929*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
1930*11fa71b9SJerome Forissier                             "or mbedtls_ssl_set_bio()" ) );
1931*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
1932*11fa71b9SJerome Forissier     }
1933*11fa71b9SJerome Forissier 
1934*11fa71b9SJerome Forissier     /* Avoid incrementing counter if data is flushed */
1935*11fa71b9SJerome Forissier     if( ssl->out_left == 0 )
1936*11fa71b9SJerome Forissier     {
1937*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
1938*11fa71b9SJerome Forissier         return( 0 );
1939*11fa71b9SJerome Forissier     }
1940*11fa71b9SJerome Forissier 
1941*11fa71b9SJerome Forissier     while( ssl->out_left > 0 )
1942*11fa71b9SJerome Forissier     {
1943*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
1944*11fa71b9SJerome Forissier                        mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
1945*11fa71b9SJerome Forissier 
1946*11fa71b9SJerome Forissier         buf = ssl->out_hdr - ssl->out_left;
1947*11fa71b9SJerome Forissier         ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
1948*11fa71b9SJerome Forissier 
1949*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
1950*11fa71b9SJerome Forissier 
1951*11fa71b9SJerome Forissier         if( ret <= 0 )
1952*11fa71b9SJerome Forissier             return( ret );
1953*11fa71b9SJerome Forissier 
1954*11fa71b9SJerome Forissier         if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
1955*11fa71b9SJerome Forissier         {
1956*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1,
1957*11fa71b9SJerome Forissier                 ( "f_send returned %d bytes but only %lu bytes were sent",
1958*11fa71b9SJerome Forissier                 ret, (unsigned long)ssl->out_left ) );
1959*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
1960*11fa71b9SJerome Forissier         }
1961*11fa71b9SJerome Forissier 
1962*11fa71b9SJerome Forissier         ssl->out_left -= ret;
1963*11fa71b9SJerome Forissier     }
1964*11fa71b9SJerome Forissier 
1965*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
1966*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
1967*11fa71b9SJerome Forissier     {
1968*11fa71b9SJerome Forissier         ssl->out_hdr = ssl->out_buf;
1969*11fa71b9SJerome Forissier     }
1970*11fa71b9SJerome Forissier     else
1971*11fa71b9SJerome Forissier #endif
1972*11fa71b9SJerome Forissier     {
1973*11fa71b9SJerome Forissier         ssl->out_hdr = ssl->out_buf + 8;
1974*11fa71b9SJerome Forissier     }
1975*11fa71b9SJerome Forissier     mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
1976*11fa71b9SJerome Forissier 
1977*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
1978*11fa71b9SJerome Forissier 
1979*11fa71b9SJerome Forissier     return( 0 );
1980*11fa71b9SJerome Forissier }
1981*11fa71b9SJerome Forissier 
1982*11fa71b9SJerome Forissier /*
1983*11fa71b9SJerome Forissier  * Functions to handle the DTLS retransmission state machine
1984*11fa71b9SJerome Forissier  */
1985*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
1986*11fa71b9SJerome Forissier /*
1987*11fa71b9SJerome Forissier  * Append current handshake message to current outgoing flight
1988*11fa71b9SJerome Forissier  */
1989*11fa71b9SJerome Forissier static int ssl_flight_append( mbedtls_ssl_context *ssl )
1990*11fa71b9SJerome Forissier {
1991*11fa71b9SJerome Forissier     mbedtls_ssl_flight_item *msg;
1992*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
1993*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
1994*11fa71b9SJerome Forissier                            ssl->out_msg, ssl->out_msglen );
1995*11fa71b9SJerome Forissier 
1996*11fa71b9SJerome Forissier     /* Allocate space for current message */
1997*11fa71b9SJerome Forissier     if( ( msg = mbedtls_calloc( 1, sizeof(  mbedtls_ssl_flight_item ) ) ) == NULL )
1998*11fa71b9SJerome Forissier     {
1999*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed",
2000*11fa71b9SJerome Forissier                             sizeof( mbedtls_ssl_flight_item ) ) );
2001*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
2002*11fa71b9SJerome Forissier     }
2003*11fa71b9SJerome Forissier 
2004*11fa71b9SJerome Forissier     if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
2005*11fa71b9SJerome Forissier     {
2006*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) );
2007*11fa71b9SJerome Forissier         mbedtls_free( msg );
2008*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
2009*11fa71b9SJerome Forissier     }
2010*11fa71b9SJerome Forissier 
2011*11fa71b9SJerome Forissier     /* Copy current handshake message with headers */
2012*11fa71b9SJerome Forissier     memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
2013*11fa71b9SJerome Forissier     msg->len = ssl->out_msglen;
2014*11fa71b9SJerome Forissier     msg->type = ssl->out_msgtype;
2015*11fa71b9SJerome Forissier     msg->next = NULL;
2016*11fa71b9SJerome Forissier 
2017*11fa71b9SJerome Forissier     /* Append to the current flight */
2018*11fa71b9SJerome Forissier     if( ssl->handshake->flight == NULL )
2019*11fa71b9SJerome Forissier         ssl->handshake->flight = msg;
2020*11fa71b9SJerome Forissier     else
2021*11fa71b9SJerome Forissier     {
2022*11fa71b9SJerome Forissier         mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
2023*11fa71b9SJerome Forissier         while( cur->next != NULL )
2024*11fa71b9SJerome Forissier             cur = cur->next;
2025*11fa71b9SJerome Forissier         cur->next = msg;
2026*11fa71b9SJerome Forissier     }
2027*11fa71b9SJerome Forissier 
2028*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
2029*11fa71b9SJerome Forissier     return( 0 );
2030*11fa71b9SJerome Forissier }
2031*11fa71b9SJerome Forissier 
2032*11fa71b9SJerome Forissier /*
2033*11fa71b9SJerome Forissier  * Free the current flight of handshake messages
2034*11fa71b9SJerome Forissier  */
2035*11fa71b9SJerome Forissier void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight )
2036*11fa71b9SJerome Forissier {
2037*11fa71b9SJerome Forissier     mbedtls_ssl_flight_item *cur = flight;
2038*11fa71b9SJerome Forissier     mbedtls_ssl_flight_item *next;
2039*11fa71b9SJerome Forissier 
2040*11fa71b9SJerome Forissier     while( cur != NULL )
2041*11fa71b9SJerome Forissier     {
2042*11fa71b9SJerome Forissier         next = cur->next;
2043*11fa71b9SJerome Forissier 
2044*11fa71b9SJerome Forissier         mbedtls_free( cur->p );
2045*11fa71b9SJerome Forissier         mbedtls_free( cur );
2046*11fa71b9SJerome Forissier 
2047*11fa71b9SJerome Forissier         cur = next;
2048*11fa71b9SJerome Forissier     }
2049*11fa71b9SJerome Forissier }
2050*11fa71b9SJerome Forissier 
2051*11fa71b9SJerome Forissier /*
2052*11fa71b9SJerome Forissier  * Swap transform_out and out_ctr with the alternative ones
2053*11fa71b9SJerome Forissier  */
2054*11fa71b9SJerome Forissier static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
2055*11fa71b9SJerome Forissier {
2056*11fa71b9SJerome Forissier     mbedtls_ssl_transform *tmp_transform;
2057*11fa71b9SJerome Forissier     unsigned char tmp_out_ctr[8];
2058*11fa71b9SJerome Forissier 
2059*11fa71b9SJerome Forissier     if( ssl->transform_out == ssl->handshake->alt_transform_out )
2060*11fa71b9SJerome Forissier     {
2061*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
2062*11fa71b9SJerome Forissier         return( 0 );
2063*11fa71b9SJerome Forissier     }
2064*11fa71b9SJerome Forissier 
2065*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
2066*11fa71b9SJerome Forissier 
2067*11fa71b9SJerome Forissier     /* Swap transforms */
2068*11fa71b9SJerome Forissier     tmp_transform                     = ssl->transform_out;
2069*11fa71b9SJerome Forissier     ssl->transform_out                = ssl->handshake->alt_transform_out;
2070*11fa71b9SJerome Forissier     ssl->handshake->alt_transform_out = tmp_transform;
2071*11fa71b9SJerome Forissier 
2072*11fa71b9SJerome Forissier     /* Swap epoch + sequence_number */
2073*11fa71b9SJerome Forissier     memcpy( tmp_out_ctr,                 ssl->cur_out_ctr,            8 );
2074*11fa71b9SJerome Forissier     memcpy( ssl->cur_out_ctr,            ssl->handshake->alt_out_ctr, 8 );
2075*11fa71b9SJerome Forissier     memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr,                 8 );
2076*11fa71b9SJerome Forissier 
2077*11fa71b9SJerome Forissier     /* Adjust to the newly activated transform */
2078*11fa71b9SJerome Forissier     mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
2079*11fa71b9SJerome Forissier 
2080*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
2081*11fa71b9SJerome Forissier     if( mbedtls_ssl_hw_record_activate != NULL )
2082*11fa71b9SJerome Forissier     {
2083*11fa71b9SJerome Forissier         int ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND );
2084*11fa71b9SJerome Forissier         if( ret != 0 )
2085*11fa71b9SJerome Forissier         {
2086*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
2087*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
2088*11fa71b9SJerome Forissier         }
2089*11fa71b9SJerome Forissier     }
2090*11fa71b9SJerome Forissier #endif
2091*11fa71b9SJerome Forissier 
2092*11fa71b9SJerome Forissier     return( 0 );
2093*11fa71b9SJerome Forissier }
2094*11fa71b9SJerome Forissier 
2095*11fa71b9SJerome Forissier /*
2096*11fa71b9SJerome Forissier  * Retransmit the current flight of messages.
2097*11fa71b9SJerome Forissier  */
2098*11fa71b9SJerome Forissier int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
2099*11fa71b9SJerome Forissier {
2100*11fa71b9SJerome Forissier     int ret = 0;
2101*11fa71b9SJerome Forissier 
2102*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
2103*11fa71b9SJerome Forissier 
2104*11fa71b9SJerome Forissier     ret = mbedtls_ssl_flight_transmit( ssl );
2105*11fa71b9SJerome Forissier 
2106*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
2107*11fa71b9SJerome Forissier 
2108*11fa71b9SJerome Forissier     return( ret );
2109*11fa71b9SJerome Forissier }
2110*11fa71b9SJerome Forissier 
2111*11fa71b9SJerome Forissier /*
2112*11fa71b9SJerome Forissier  * Transmit or retransmit the current flight of messages.
2113*11fa71b9SJerome Forissier  *
2114*11fa71b9SJerome Forissier  * Need to remember the current message in case flush_output returns
2115*11fa71b9SJerome Forissier  * WANT_WRITE, causing us to exit this function and come back later.
2116*11fa71b9SJerome Forissier  * This function must be called until state is no longer SENDING.
2117*11fa71b9SJerome Forissier  */
2118*11fa71b9SJerome Forissier int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
2119*11fa71b9SJerome Forissier {
2120*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2121*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
2122*11fa71b9SJerome Forissier 
2123*11fa71b9SJerome Forissier     if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
2124*11fa71b9SJerome Forissier     {
2125*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) );
2126*11fa71b9SJerome Forissier 
2127*11fa71b9SJerome Forissier         ssl->handshake->cur_msg = ssl->handshake->flight;
2128*11fa71b9SJerome Forissier         ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
2129*11fa71b9SJerome Forissier         ret = ssl_swap_epochs( ssl );
2130*11fa71b9SJerome Forissier         if( ret != 0 )
2131*11fa71b9SJerome Forissier             return( ret );
2132*11fa71b9SJerome Forissier 
2133*11fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
2134*11fa71b9SJerome Forissier     }
2135*11fa71b9SJerome Forissier 
2136*11fa71b9SJerome Forissier     while( ssl->handshake->cur_msg != NULL )
2137*11fa71b9SJerome Forissier     {
2138*11fa71b9SJerome Forissier         size_t max_frag_len;
2139*11fa71b9SJerome Forissier         const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
2140*11fa71b9SJerome Forissier 
2141*11fa71b9SJerome Forissier         int const is_finished =
2142*11fa71b9SJerome Forissier             ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
2143*11fa71b9SJerome Forissier               cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
2144*11fa71b9SJerome Forissier 
2145*11fa71b9SJerome Forissier         uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
2146*11fa71b9SJerome Forissier             SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
2147*11fa71b9SJerome Forissier 
2148*11fa71b9SJerome Forissier         /* Swap epochs before sending Finished: we can't do it after
2149*11fa71b9SJerome Forissier          * sending ChangeCipherSpec, in case write returns WANT_READ.
2150*11fa71b9SJerome Forissier          * Must be done before copying, may change out_msg pointer */
2151*11fa71b9SJerome Forissier         if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
2152*11fa71b9SJerome Forissier         {
2153*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
2154*11fa71b9SJerome Forissier             ret = ssl_swap_epochs( ssl );
2155*11fa71b9SJerome Forissier             if( ret != 0 )
2156*11fa71b9SJerome Forissier                 return( ret );
2157*11fa71b9SJerome Forissier         }
2158*11fa71b9SJerome Forissier 
2159*11fa71b9SJerome Forissier         ret = ssl_get_remaining_payload_in_datagram( ssl );
2160*11fa71b9SJerome Forissier         if( ret < 0 )
2161*11fa71b9SJerome Forissier             return( ret );
2162*11fa71b9SJerome Forissier         max_frag_len = (size_t) ret;
2163*11fa71b9SJerome Forissier 
2164*11fa71b9SJerome Forissier         /* CCS is copied as is, while HS messages may need fragmentation */
2165*11fa71b9SJerome Forissier         if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
2166*11fa71b9SJerome Forissier         {
2167*11fa71b9SJerome Forissier             if( max_frag_len == 0 )
2168*11fa71b9SJerome Forissier             {
2169*11fa71b9SJerome Forissier                 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
2170*11fa71b9SJerome Forissier                     return( ret );
2171*11fa71b9SJerome Forissier 
2172*11fa71b9SJerome Forissier                 continue;
2173*11fa71b9SJerome Forissier             }
2174*11fa71b9SJerome Forissier 
2175*11fa71b9SJerome Forissier             memcpy( ssl->out_msg, cur->p, cur->len );
2176*11fa71b9SJerome Forissier             ssl->out_msglen  = cur->len;
2177*11fa71b9SJerome Forissier             ssl->out_msgtype = cur->type;
2178*11fa71b9SJerome Forissier 
2179*11fa71b9SJerome Forissier             /* Update position inside current message */
2180*11fa71b9SJerome Forissier             ssl->handshake->cur_msg_p += cur->len;
2181*11fa71b9SJerome Forissier         }
2182*11fa71b9SJerome Forissier         else
2183*11fa71b9SJerome Forissier         {
2184*11fa71b9SJerome Forissier             const unsigned char * const p = ssl->handshake->cur_msg_p;
2185*11fa71b9SJerome Forissier             const size_t hs_len = cur->len - 12;
2186*11fa71b9SJerome Forissier             const size_t frag_off = p - ( cur->p + 12 );
2187*11fa71b9SJerome Forissier             const size_t rem_len = hs_len - frag_off;
2188*11fa71b9SJerome Forissier             size_t cur_hs_frag_len, max_hs_frag_len;
2189*11fa71b9SJerome Forissier 
2190*11fa71b9SJerome Forissier             if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
2191*11fa71b9SJerome Forissier             {
2192*11fa71b9SJerome Forissier                 if( is_finished )
2193*11fa71b9SJerome Forissier                 {
2194*11fa71b9SJerome Forissier                     ret = ssl_swap_epochs( ssl );
2195*11fa71b9SJerome Forissier                     if( ret != 0 )
2196*11fa71b9SJerome Forissier                         return( ret );
2197*11fa71b9SJerome Forissier                 }
2198*11fa71b9SJerome Forissier 
2199*11fa71b9SJerome Forissier                 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
2200*11fa71b9SJerome Forissier                     return( ret );
2201*11fa71b9SJerome Forissier 
2202*11fa71b9SJerome Forissier                 continue;
2203*11fa71b9SJerome Forissier             }
2204*11fa71b9SJerome Forissier             max_hs_frag_len = max_frag_len - 12;
2205*11fa71b9SJerome Forissier 
2206*11fa71b9SJerome Forissier             cur_hs_frag_len = rem_len > max_hs_frag_len ?
2207*11fa71b9SJerome Forissier                 max_hs_frag_len : rem_len;
2208*11fa71b9SJerome Forissier 
2209*11fa71b9SJerome Forissier             if( frag_off == 0 && cur_hs_frag_len != hs_len )
2210*11fa71b9SJerome Forissier             {
2211*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
2212*11fa71b9SJerome Forissier                                             (unsigned) cur_hs_frag_len,
2213*11fa71b9SJerome Forissier                                             (unsigned) max_hs_frag_len ) );
2214*11fa71b9SJerome Forissier             }
2215*11fa71b9SJerome Forissier 
2216*11fa71b9SJerome Forissier             /* Messages are stored with handshake headers as if not fragmented,
2217*11fa71b9SJerome Forissier              * copy beginning of headers then fill fragmentation fields.
2218*11fa71b9SJerome Forissier              * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
2219*11fa71b9SJerome Forissier             memcpy( ssl->out_msg, cur->p, 6 );
2220*11fa71b9SJerome Forissier 
2221*11fa71b9SJerome Forissier             ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff );
2222*11fa71b9SJerome Forissier             ssl->out_msg[7] = ( ( frag_off >>  8 ) & 0xff );
2223*11fa71b9SJerome Forissier             ssl->out_msg[8] = ( ( frag_off       ) & 0xff );
2224*11fa71b9SJerome Forissier 
2225*11fa71b9SJerome Forissier             ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff );
2226*11fa71b9SJerome Forissier             ssl->out_msg[10] = ( ( cur_hs_frag_len >>  8 ) & 0xff );
2227*11fa71b9SJerome Forissier             ssl->out_msg[11] = ( ( cur_hs_frag_len       ) & 0xff );
2228*11fa71b9SJerome Forissier 
2229*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
2230*11fa71b9SJerome Forissier 
2231*11fa71b9SJerome Forissier             /* Copy the handshake message content and set records fields */
2232*11fa71b9SJerome Forissier             memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
2233*11fa71b9SJerome Forissier             ssl->out_msglen = cur_hs_frag_len + 12;
2234*11fa71b9SJerome Forissier             ssl->out_msgtype = cur->type;
2235*11fa71b9SJerome Forissier 
2236*11fa71b9SJerome Forissier             /* Update position inside current message */
2237*11fa71b9SJerome Forissier             ssl->handshake->cur_msg_p += cur_hs_frag_len;
2238*11fa71b9SJerome Forissier         }
2239*11fa71b9SJerome Forissier 
2240*11fa71b9SJerome Forissier         /* If done with the current message move to the next one if any */
2241*11fa71b9SJerome Forissier         if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
2242*11fa71b9SJerome Forissier         {
2243*11fa71b9SJerome Forissier             if( cur->next != NULL )
2244*11fa71b9SJerome Forissier             {
2245*11fa71b9SJerome Forissier                 ssl->handshake->cur_msg = cur->next;
2246*11fa71b9SJerome Forissier                 ssl->handshake->cur_msg_p = cur->next->p + 12;
2247*11fa71b9SJerome Forissier             }
2248*11fa71b9SJerome Forissier             else
2249*11fa71b9SJerome Forissier             {
2250*11fa71b9SJerome Forissier                 ssl->handshake->cur_msg = NULL;
2251*11fa71b9SJerome Forissier                 ssl->handshake->cur_msg_p = NULL;
2252*11fa71b9SJerome Forissier             }
2253*11fa71b9SJerome Forissier         }
2254*11fa71b9SJerome Forissier 
2255*11fa71b9SJerome Forissier         /* Actually send the message out */
2256*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
2257*11fa71b9SJerome Forissier         {
2258*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
2259*11fa71b9SJerome Forissier             return( ret );
2260*11fa71b9SJerome Forissier         }
2261*11fa71b9SJerome Forissier     }
2262*11fa71b9SJerome Forissier 
2263*11fa71b9SJerome Forissier     if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
2264*11fa71b9SJerome Forissier         return( ret );
2265*11fa71b9SJerome Forissier 
2266*11fa71b9SJerome Forissier     /* Update state and set timer */
2267*11fa71b9SJerome Forissier     if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
2268*11fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
2269*11fa71b9SJerome Forissier     else
2270*11fa71b9SJerome Forissier     {
2271*11fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
2272*11fa71b9SJerome Forissier         mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
2273*11fa71b9SJerome Forissier     }
2274*11fa71b9SJerome Forissier 
2275*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
2276*11fa71b9SJerome Forissier 
2277*11fa71b9SJerome Forissier     return( 0 );
2278*11fa71b9SJerome Forissier }
2279*11fa71b9SJerome Forissier 
2280*11fa71b9SJerome Forissier /*
2281*11fa71b9SJerome Forissier  * To be called when the last message of an incoming flight is received.
2282*11fa71b9SJerome Forissier  */
2283*11fa71b9SJerome Forissier void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
2284*11fa71b9SJerome Forissier {
2285*11fa71b9SJerome Forissier     /* We won't need to resend that one any more */
2286*11fa71b9SJerome Forissier     mbedtls_ssl_flight_free( ssl->handshake->flight );
2287*11fa71b9SJerome Forissier     ssl->handshake->flight = NULL;
2288*11fa71b9SJerome Forissier     ssl->handshake->cur_msg = NULL;
2289*11fa71b9SJerome Forissier 
2290*11fa71b9SJerome Forissier     /* The next incoming flight will start with this msg_seq */
2291*11fa71b9SJerome Forissier     ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
2292*11fa71b9SJerome Forissier 
2293*11fa71b9SJerome Forissier     /* We don't want to remember CCS's across flight boundaries. */
2294*11fa71b9SJerome Forissier     ssl->handshake->buffering.seen_ccs = 0;
2295*11fa71b9SJerome Forissier 
2296*11fa71b9SJerome Forissier     /* Clear future message buffering structure. */
2297*11fa71b9SJerome Forissier     mbedtls_ssl_buffering_free( ssl );
2298*11fa71b9SJerome Forissier 
2299*11fa71b9SJerome Forissier     /* Cancel timer */
2300*11fa71b9SJerome Forissier     mbedtls_ssl_set_timer( ssl, 0 );
2301*11fa71b9SJerome Forissier 
2302*11fa71b9SJerome Forissier     if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2303*11fa71b9SJerome Forissier         ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
2304*11fa71b9SJerome Forissier     {
2305*11fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
2306*11fa71b9SJerome Forissier     }
2307*11fa71b9SJerome Forissier     else
2308*11fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
2309*11fa71b9SJerome Forissier }
2310*11fa71b9SJerome Forissier 
2311*11fa71b9SJerome Forissier /*
2312*11fa71b9SJerome Forissier  * To be called when the last message of an outgoing flight is send.
2313*11fa71b9SJerome Forissier  */
2314*11fa71b9SJerome Forissier void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
2315*11fa71b9SJerome Forissier {
2316*11fa71b9SJerome Forissier     ssl_reset_retransmit_timeout( ssl );
2317*11fa71b9SJerome Forissier     mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
2318*11fa71b9SJerome Forissier 
2319*11fa71b9SJerome Forissier     if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2320*11fa71b9SJerome Forissier         ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
2321*11fa71b9SJerome Forissier     {
2322*11fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
2323*11fa71b9SJerome Forissier     }
2324*11fa71b9SJerome Forissier     else
2325*11fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
2326*11fa71b9SJerome Forissier }
2327*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
2328*11fa71b9SJerome Forissier 
2329*11fa71b9SJerome Forissier /*
2330*11fa71b9SJerome Forissier  * Handshake layer functions
2331*11fa71b9SJerome Forissier  */
2332*11fa71b9SJerome Forissier 
2333*11fa71b9SJerome Forissier /*
2334*11fa71b9SJerome Forissier  * Write (DTLS: or queue) current handshake (including CCS) message.
2335*11fa71b9SJerome Forissier  *
2336*11fa71b9SJerome Forissier  *  - fill in handshake headers
2337*11fa71b9SJerome Forissier  *  - update handshake checksum
2338*11fa71b9SJerome Forissier  *  - DTLS: save message for resending
2339*11fa71b9SJerome Forissier  *  - then pass to the record layer
2340*11fa71b9SJerome Forissier  *
2341*11fa71b9SJerome Forissier  * DTLS: except for HelloRequest, messages are only queued, and will only be
2342*11fa71b9SJerome Forissier  * actually sent when calling flight_transmit() or resend().
2343*11fa71b9SJerome Forissier  *
2344*11fa71b9SJerome Forissier  * Inputs:
2345*11fa71b9SJerome Forissier  *  - ssl->out_msglen: 4 + actual handshake message len
2346*11fa71b9SJerome Forissier  *      (4 is the size of handshake headers for TLS)
2347*11fa71b9SJerome Forissier  *  - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
2348*11fa71b9SJerome Forissier  *  - ssl->out_msg + 4: the handshake message body
2349*11fa71b9SJerome Forissier  *
2350*11fa71b9SJerome Forissier  * Outputs, ie state before passing to flight_append() or write_record():
2351*11fa71b9SJerome Forissier  *   - ssl->out_msglen: the length of the record contents
2352*11fa71b9SJerome Forissier  *      (including handshake headers but excluding record headers)
2353*11fa71b9SJerome Forissier  *   - ssl->out_msg: the record contents (handshake headers + content)
2354*11fa71b9SJerome Forissier  */
2355*11fa71b9SJerome Forissier int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
2356*11fa71b9SJerome Forissier {
2357*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2358*11fa71b9SJerome Forissier     const size_t hs_len = ssl->out_msglen - 4;
2359*11fa71b9SJerome Forissier     const unsigned char hs_type = ssl->out_msg[0];
2360*11fa71b9SJerome Forissier 
2361*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) );
2362*11fa71b9SJerome Forissier 
2363*11fa71b9SJerome Forissier     /*
2364*11fa71b9SJerome Forissier      * Sanity checks
2365*11fa71b9SJerome Forissier      */
2366*11fa71b9SJerome Forissier     if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE          &&
2367*11fa71b9SJerome Forissier         ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
2368*11fa71b9SJerome Forissier     {
2369*11fa71b9SJerome Forissier         /* In SSLv3, the client might send a NoCertificate alert. */
2370*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
2371*11fa71b9SJerome Forissier         if( ! ( ssl->minor_ver      == MBEDTLS_SSL_MINOR_VERSION_0 &&
2372*11fa71b9SJerome Forissier                 ssl->out_msgtype    == MBEDTLS_SSL_MSG_ALERT       &&
2373*11fa71b9SJerome Forissier                 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) )
2374*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
2375*11fa71b9SJerome Forissier         {
2376*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2377*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2378*11fa71b9SJerome Forissier         }
2379*11fa71b9SJerome Forissier     }
2380*11fa71b9SJerome Forissier 
2381*11fa71b9SJerome Forissier     /* Whenever we send anything different from a
2382*11fa71b9SJerome Forissier      * HelloRequest we should be in a handshake - double check. */
2383*11fa71b9SJerome Forissier     if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2384*11fa71b9SJerome Forissier             hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
2385*11fa71b9SJerome Forissier         ssl->handshake == NULL )
2386*11fa71b9SJerome Forissier     {
2387*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2388*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2389*11fa71b9SJerome Forissier     }
2390*11fa71b9SJerome Forissier 
2391*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
2392*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2393*11fa71b9SJerome Forissier         ssl->handshake != NULL &&
2394*11fa71b9SJerome Forissier         ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
2395*11fa71b9SJerome Forissier     {
2396*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2397*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2398*11fa71b9SJerome Forissier     }
2399*11fa71b9SJerome Forissier #endif
2400*11fa71b9SJerome Forissier 
2401*11fa71b9SJerome Forissier     /* Double-check that we did not exceed the bounds
2402*11fa71b9SJerome Forissier      * of the outgoing record buffer.
2403*11fa71b9SJerome Forissier      * This should never fail as the various message
2404*11fa71b9SJerome Forissier      * writing functions must obey the bounds of the
2405*11fa71b9SJerome Forissier      * outgoing record buffer, but better be safe.
2406*11fa71b9SJerome Forissier      *
2407*11fa71b9SJerome Forissier      * Note: We deliberately do not check for the MTU or MFL here.
2408*11fa71b9SJerome Forissier      */
2409*11fa71b9SJerome Forissier     if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
2410*11fa71b9SJerome Forissier     {
2411*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
2412*11fa71b9SJerome Forissier                                     "size %u, maximum %u",
2413*11fa71b9SJerome Forissier                                     (unsigned) ssl->out_msglen,
2414*11fa71b9SJerome Forissier                                     (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
2415*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2416*11fa71b9SJerome Forissier     }
2417*11fa71b9SJerome Forissier 
2418*11fa71b9SJerome Forissier     /*
2419*11fa71b9SJerome Forissier      * Fill handshake headers
2420*11fa71b9SJerome Forissier      */
2421*11fa71b9SJerome Forissier     if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
2422*11fa71b9SJerome Forissier     {
2423*11fa71b9SJerome Forissier         ssl->out_msg[1] = (unsigned char)( hs_len >> 16 );
2424*11fa71b9SJerome Forissier         ssl->out_msg[2] = (unsigned char)( hs_len >>  8 );
2425*11fa71b9SJerome Forissier         ssl->out_msg[3] = (unsigned char)( hs_len       );
2426*11fa71b9SJerome Forissier 
2427*11fa71b9SJerome Forissier         /*
2428*11fa71b9SJerome Forissier          * DTLS has additional fields in the Handshake layer,
2429*11fa71b9SJerome Forissier          * between the length field and the actual payload:
2430*11fa71b9SJerome Forissier          *      uint16 message_seq;
2431*11fa71b9SJerome Forissier          *      uint24 fragment_offset;
2432*11fa71b9SJerome Forissier          *      uint24 fragment_length;
2433*11fa71b9SJerome Forissier          */
2434*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
2435*11fa71b9SJerome Forissier         if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
2436*11fa71b9SJerome Forissier         {
2437*11fa71b9SJerome Forissier             /* Make room for the additional DTLS fields */
2438*11fa71b9SJerome Forissier             if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
2439*11fa71b9SJerome Forissier             {
2440*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
2441*11fa71b9SJerome Forissier                               "size %u, maximum %u",
2442*11fa71b9SJerome Forissier                                (unsigned) ( hs_len ),
2443*11fa71b9SJerome Forissier                                (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) );
2444*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
2445*11fa71b9SJerome Forissier             }
2446*11fa71b9SJerome Forissier 
2447*11fa71b9SJerome Forissier             memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len );
2448*11fa71b9SJerome Forissier             ssl->out_msglen += 8;
2449*11fa71b9SJerome Forissier 
2450*11fa71b9SJerome Forissier             /* Write message_seq and update it, except for HelloRequest */
2451*11fa71b9SJerome Forissier             if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
2452*11fa71b9SJerome Forissier             {
2453*11fa71b9SJerome Forissier                 ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
2454*11fa71b9SJerome Forissier                 ssl->out_msg[5] = ( ssl->handshake->out_msg_seq      ) & 0xFF;
2455*11fa71b9SJerome Forissier                 ++( ssl->handshake->out_msg_seq );
2456*11fa71b9SJerome Forissier             }
2457*11fa71b9SJerome Forissier             else
2458*11fa71b9SJerome Forissier             {
2459*11fa71b9SJerome Forissier                 ssl->out_msg[4] = 0;
2460*11fa71b9SJerome Forissier                 ssl->out_msg[5] = 0;
2461*11fa71b9SJerome Forissier             }
2462*11fa71b9SJerome Forissier 
2463*11fa71b9SJerome Forissier             /* Handshake hashes are computed without fragmentation,
2464*11fa71b9SJerome Forissier              * so set frag_offset = 0 and frag_len = hs_len for now */
2465*11fa71b9SJerome Forissier             memset( ssl->out_msg + 6, 0x00, 3 );
2466*11fa71b9SJerome Forissier             memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
2467*11fa71b9SJerome Forissier         }
2468*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
2469*11fa71b9SJerome Forissier 
2470*11fa71b9SJerome Forissier         /* Update running hashes of handshake messages seen */
2471*11fa71b9SJerome Forissier         if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
2472*11fa71b9SJerome Forissier             ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
2473*11fa71b9SJerome Forissier     }
2474*11fa71b9SJerome Forissier 
2475*11fa71b9SJerome Forissier     /* Either send now, or just save to be sent (and resent) later */
2476*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
2477*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2478*11fa71b9SJerome Forissier         ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2479*11fa71b9SJerome Forissier             hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
2480*11fa71b9SJerome Forissier     {
2481*11fa71b9SJerome Forissier         if( ( ret = ssl_flight_append( ssl ) ) != 0 )
2482*11fa71b9SJerome Forissier         {
2483*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
2484*11fa71b9SJerome Forissier             return( ret );
2485*11fa71b9SJerome Forissier         }
2486*11fa71b9SJerome Forissier     }
2487*11fa71b9SJerome Forissier     else
2488*11fa71b9SJerome Forissier #endif
2489*11fa71b9SJerome Forissier     {
2490*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
2491*11fa71b9SJerome Forissier         {
2492*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
2493*11fa71b9SJerome Forissier             return( ret );
2494*11fa71b9SJerome Forissier         }
2495*11fa71b9SJerome Forissier     }
2496*11fa71b9SJerome Forissier 
2497*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
2498*11fa71b9SJerome Forissier 
2499*11fa71b9SJerome Forissier     return( 0 );
2500*11fa71b9SJerome Forissier }
2501*11fa71b9SJerome Forissier 
2502*11fa71b9SJerome Forissier /*
2503*11fa71b9SJerome Forissier  * Record layer functions
2504*11fa71b9SJerome Forissier  */
2505*11fa71b9SJerome Forissier 
2506*11fa71b9SJerome Forissier /*
2507*11fa71b9SJerome Forissier  * Write current record.
2508*11fa71b9SJerome Forissier  *
2509*11fa71b9SJerome Forissier  * Uses:
2510*11fa71b9SJerome Forissier  *  - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
2511*11fa71b9SJerome Forissier  *  - ssl->out_msglen: length of the record content (excl headers)
2512*11fa71b9SJerome Forissier  *  - ssl->out_msg: record content
2513*11fa71b9SJerome Forissier  */
2514*11fa71b9SJerome Forissier int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
2515*11fa71b9SJerome Forissier {
2516*11fa71b9SJerome Forissier     int ret, done = 0;
2517*11fa71b9SJerome Forissier     size_t len = ssl->out_msglen;
2518*11fa71b9SJerome Forissier     uint8_t flush = force_flush;
2519*11fa71b9SJerome Forissier 
2520*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
2521*11fa71b9SJerome Forissier 
2522*11fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT)
2523*11fa71b9SJerome Forissier     if( ssl->transform_out != NULL &&
2524*11fa71b9SJerome Forissier         ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
2525*11fa71b9SJerome Forissier     {
2526*11fa71b9SJerome Forissier         if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
2527*11fa71b9SJerome Forissier         {
2528*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
2529*11fa71b9SJerome Forissier             return( ret );
2530*11fa71b9SJerome Forissier         }
2531*11fa71b9SJerome Forissier 
2532*11fa71b9SJerome Forissier         len = ssl->out_msglen;
2533*11fa71b9SJerome Forissier     }
2534*11fa71b9SJerome Forissier #endif /*MBEDTLS_ZLIB_SUPPORT */
2535*11fa71b9SJerome Forissier 
2536*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
2537*11fa71b9SJerome Forissier     if( mbedtls_ssl_hw_record_write != NULL )
2538*11fa71b9SJerome Forissier     {
2539*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
2540*11fa71b9SJerome Forissier 
2541*11fa71b9SJerome Forissier         ret = mbedtls_ssl_hw_record_write( ssl );
2542*11fa71b9SJerome Forissier         if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
2543*11fa71b9SJerome Forissier         {
2544*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
2545*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
2546*11fa71b9SJerome Forissier         }
2547*11fa71b9SJerome Forissier 
2548*11fa71b9SJerome Forissier         if( ret == 0 )
2549*11fa71b9SJerome Forissier             done = 1;
2550*11fa71b9SJerome Forissier     }
2551*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
2552*11fa71b9SJerome Forissier     if( !done )
2553*11fa71b9SJerome Forissier     {
2554*11fa71b9SJerome Forissier         unsigned i;
2555*11fa71b9SJerome Forissier         size_t protected_record_size;
2556*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
2557*11fa71b9SJerome Forissier         size_t out_buf_len = ssl->out_buf_len;
2558*11fa71b9SJerome Forissier #else
2559*11fa71b9SJerome Forissier         size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
2560*11fa71b9SJerome Forissier #endif
2561*11fa71b9SJerome Forissier         /* Skip writing the record content type to after the encryption,
2562*11fa71b9SJerome Forissier          * as it may change when using the CID extension. */
2563*11fa71b9SJerome Forissier 
2564*11fa71b9SJerome Forissier         mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
2565*11fa71b9SJerome Forissier                            ssl->conf->transport, ssl->out_hdr + 1 );
2566*11fa71b9SJerome Forissier 
2567*11fa71b9SJerome Forissier         memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
2568*11fa71b9SJerome Forissier         ssl->out_len[0] = (unsigned char)( len >> 8 );
2569*11fa71b9SJerome Forissier         ssl->out_len[1] = (unsigned char)( len      );
2570*11fa71b9SJerome Forissier 
2571*11fa71b9SJerome Forissier         if( ssl->transform_out != NULL )
2572*11fa71b9SJerome Forissier         {
2573*11fa71b9SJerome Forissier             mbedtls_record rec;
2574*11fa71b9SJerome Forissier 
2575*11fa71b9SJerome Forissier             rec.buf         = ssl->out_iv;
2576*11fa71b9SJerome Forissier             rec.buf_len     = out_buf_len - ( ssl->out_iv - ssl->out_buf );
2577*11fa71b9SJerome Forissier             rec.data_len    = ssl->out_msglen;
2578*11fa71b9SJerome Forissier             rec.data_offset = ssl->out_msg - rec.buf;
2579*11fa71b9SJerome Forissier 
2580*11fa71b9SJerome Forissier             memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
2581*11fa71b9SJerome Forissier             mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
2582*11fa71b9SJerome Forissier                                        ssl->conf->transport, rec.ver );
2583*11fa71b9SJerome Forissier             rec.type = ssl->out_msgtype;
2584*11fa71b9SJerome Forissier 
2585*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2586*11fa71b9SJerome Forissier             /* The CID is set by mbedtls_ssl_encrypt_buf(). */
2587*11fa71b9SJerome Forissier             rec.cid_len = 0;
2588*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2589*11fa71b9SJerome Forissier 
2590*11fa71b9SJerome Forissier             if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec,
2591*11fa71b9SJerome Forissier                                          ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
2592*11fa71b9SJerome Forissier             {
2593*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
2594*11fa71b9SJerome Forissier                 return( ret );
2595*11fa71b9SJerome Forissier             }
2596*11fa71b9SJerome Forissier 
2597*11fa71b9SJerome Forissier             if( rec.data_offset != 0 )
2598*11fa71b9SJerome Forissier             {
2599*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2600*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2601*11fa71b9SJerome Forissier             }
2602*11fa71b9SJerome Forissier 
2603*11fa71b9SJerome Forissier             /* Update the record content type and CID. */
2604*11fa71b9SJerome Forissier             ssl->out_msgtype = rec.type;
2605*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID )
2606*11fa71b9SJerome Forissier             memcpy( ssl->out_cid, rec.cid, rec.cid_len );
2607*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2608*11fa71b9SJerome Forissier             ssl->out_msglen = len = rec.data_len;
2609*11fa71b9SJerome Forissier             ssl->out_len[0] = (unsigned char)( rec.data_len >> 8 );
2610*11fa71b9SJerome Forissier             ssl->out_len[1] = (unsigned char)( rec.data_len      );
2611*11fa71b9SJerome Forissier         }
2612*11fa71b9SJerome Forissier 
2613*11fa71b9SJerome Forissier         protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl );
2614*11fa71b9SJerome Forissier 
2615*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
2616*11fa71b9SJerome Forissier         /* In case of DTLS, double-check that we don't exceed
2617*11fa71b9SJerome Forissier          * the remaining space in the datagram. */
2618*11fa71b9SJerome Forissier         if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
2619*11fa71b9SJerome Forissier         {
2620*11fa71b9SJerome Forissier             ret = ssl_get_remaining_space_in_datagram( ssl );
2621*11fa71b9SJerome Forissier             if( ret < 0 )
2622*11fa71b9SJerome Forissier                 return( ret );
2623*11fa71b9SJerome Forissier 
2624*11fa71b9SJerome Forissier             if( protected_record_size > (size_t) ret )
2625*11fa71b9SJerome Forissier             {
2626*11fa71b9SJerome Forissier                 /* Should never happen */
2627*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2628*11fa71b9SJerome Forissier             }
2629*11fa71b9SJerome Forissier         }
2630*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
2631*11fa71b9SJerome Forissier 
2632*11fa71b9SJerome Forissier         /* Now write the potentially updated record content type. */
2633*11fa71b9SJerome Forissier         ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
2634*11fa71b9SJerome Forissier 
2635*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
2636*11fa71b9SJerome Forissier                                     "version = [%d:%d], msglen = %d",
2637*11fa71b9SJerome Forissier                                     ssl->out_hdr[0], ssl->out_hdr[1],
2638*11fa71b9SJerome Forissier                                     ssl->out_hdr[2], len ) );
2639*11fa71b9SJerome Forissier 
2640*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
2641*11fa71b9SJerome Forissier                                ssl->out_hdr, protected_record_size );
2642*11fa71b9SJerome Forissier 
2643*11fa71b9SJerome Forissier         ssl->out_left += protected_record_size;
2644*11fa71b9SJerome Forissier         ssl->out_hdr  += protected_record_size;
2645*11fa71b9SJerome Forissier         mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
2646*11fa71b9SJerome Forissier 
2647*11fa71b9SJerome Forissier         for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
2648*11fa71b9SJerome Forissier             if( ++ssl->cur_out_ctr[i - 1] != 0 )
2649*11fa71b9SJerome Forissier                 break;
2650*11fa71b9SJerome Forissier 
2651*11fa71b9SJerome Forissier         /* The loop goes to its end iff the counter is wrapping */
2652*11fa71b9SJerome Forissier         if( i == mbedtls_ssl_ep_len( ssl ) )
2653*11fa71b9SJerome Forissier         {
2654*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
2655*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
2656*11fa71b9SJerome Forissier         }
2657*11fa71b9SJerome Forissier     }
2658*11fa71b9SJerome Forissier 
2659*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
2660*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2661*11fa71b9SJerome Forissier         flush == SSL_DONT_FORCE_FLUSH )
2662*11fa71b9SJerome Forissier     {
2663*11fa71b9SJerome Forissier         size_t remaining;
2664*11fa71b9SJerome Forissier         ret = ssl_get_remaining_payload_in_datagram( ssl );
2665*11fa71b9SJerome Forissier         if( ret < 0 )
2666*11fa71b9SJerome Forissier         {
2667*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
2668*11fa71b9SJerome Forissier                                    ret );
2669*11fa71b9SJerome Forissier             return( ret );
2670*11fa71b9SJerome Forissier         }
2671*11fa71b9SJerome Forissier 
2672*11fa71b9SJerome Forissier         remaining = (size_t) ret;
2673*11fa71b9SJerome Forissier         if( remaining == 0 )
2674*11fa71b9SJerome Forissier         {
2675*11fa71b9SJerome Forissier             flush = SSL_FORCE_FLUSH;
2676*11fa71b9SJerome Forissier         }
2677*11fa71b9SJerome Forissier         else
2678*11fa71b9SJerome Forissier         {
2679*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
2680*11fa71b9SJerome Forissier         }
2681*11fa71b9SJerome Forissier     }
2682*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
2683*11fa71b9SJerome Forissier 
2684*11fa71b9SJerome Forissier     if( ( flush == SSL_FORCE_FLUSH ) &&
2685*11fa71b9SJerome Forissier         ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
2686*11fa71b9SJerome Forissier     {
2687*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
2688*11fa71b9SJerome Forissier         return( ret );
2689*11fa71b9SJerome Forissier     }
2690*11fa71b9SJerome Forissier 
2691*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
2692*11fa71b9SJerome Forissier 
2693*11fa71b9SJerome Forissier     return( 0 );
2694*11fa71b9SJerome Forissier }
2695*11fa71b9SJerome Forissier 
2696*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
2697*11fa71b9SJerome Forissier 
2698*11fa71b9SJerome Forissier static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
2699*11fa71b9SJerome Forissier {
2700*11fa71b9SJerome Forissier     if( ssl->in_msglen < ssl->in_hslen ||
2701*11fa71b9SJerome Forissier         memcmp( ssl->in_msg + 6, "\0\0\0",        3 ) != 0 ||
2702*11fa71b9SJerome Forissier         memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
2703*11fa71b9SJerome Forissier     {
2704*11fa71b9SJerome Forissier         return( 1 );
2705*11fa71b9SJerome Forissier     }
2706*11fa71b9SJerome Forissier     return( 0 );
2707*11fa71b9SJerome Forissier }
2708*11fa71b9SJerome Forissier 
2709*11fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl )
2710*11fa71b9SJerome Forissier {
2711*11fa71b9SJerome Forissier     return( ( ssl->in_msg[9] << 16  ) |
2712*11fa71b9SJerome Forissier             ( ssl->in_msg[10] << 8  ) |
2713*11fa71b9SJerome Forissier               ssl->in_msg[11] );
2714*11fa71b9SJerome Forissier }
2715*11fa71b9SJerome Forissier 
2716*11fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
2717*11fa71b9SJerome Forissier {
2718*11fa71b9SJerome Forissier     return( ( ssl->in_msg[6] << 16 ) |
2719*11fa71b9SJerome Forissier             ( ssl->in_msg[7] << 8  ) |
2720*11fa71b9SJerome Forissier               ssl->in_msg[8] );
2721*11fa71b9SJerome Forissier }
2722*11fa71b9SJerome Forissier 
2723*11fa71b9SJerome Forissier static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
2724*11fa71b9SJerome Forissier {
2725*11fa71b9SJerome Forissier     uint32_t msg_len, frag_off, frag_len;
2726*11fa71b9SJerome Forissier 
2727*11fa71b9SJerome Forissier     msg_len  = ssl_get_hs_total_len( ssl );
2728*11fa71b9SJerome Forissier     frag_off = ssl_get_hs_frag_off( ssl );
2729*11fa71b9SJerome Forissier     frag_len = ssl_get_hs_frag_len( ssl );
2730*11fa71b9SJerome Forissier 
2731*11fa71b9SJerome Forissier     if( frag_off > msg_len )
2732*11fa71b9SJerome Forissier         return( -1 );
2733*11fa71b9SJerome Forissier 
2734*11fa71b9SJerome Forissier     if( frag_len > msg_len - frag_off )
2735*11fa71b9SJerome Forissier         return( -1 );
2736*11fa71b9SJerome Forissier 
2737*11fa71b9SJerome Forissier     if( frag_len + 12 > ssl->in_msglen )
2738*11fa71b9SJerome Forissier         return( -1 );
2739*11fa71b9SJerome Forissier 
2740*11fa71b9SJerome Forissier     return( 0 );
2741*11fa71b9SJerome Forissier }
2742*11fa71b9SJerome Forissier 
2743*11fa71b9SJerome Forissier /*
2744*11fa71b9SJerome Forissier  * Mark bits in bitmask (used for DTLS HS reassembly)
2745*11fa71b9SJerome Forissier  */
2746*11fa71b9SJerome Forissier static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
2747*11fa71b9SJerome Forissier {
2748*11fa71b9SJerome Forissier     unsigned int start_bits, end_bits;
2749*11fa71b9SJerome Forissier 
2750*11fa71b9SJerome Forissier     start_bits = 8 - ( offset % 8 );
2751*11fa71b9SJerome Forissier     if( start_bits != 8 )
2752*11fa71b9SJerome Forissier     {
2753*11fa71b9SJerome Forissier         size_t first_byte_idx = offset / 8;
2754*11fa71b9SJerome Forissier 
2755*11fa71b9SJerome Forissier         /* Special case */
2756*11fa71b9SJerome Forissier         if( len <= start_bits )
2757*11fa71b9SJerome Forissier         {
2758*11fa71b9SJerome Forissier             for( ; len != 0; len-- )
2759*11fa71b9SJerome Forissier                 mask[first_byte_idx] |= 1 << ( start_bits - len );
2760*11fa71b9SJerome Forissier 
2761*11fa71b9SJerome Forissier             /* Avoid potential issues with offset or len becoming invalid */
2762*11fa71b9SJerome Forissier             return;
2763*11fa71b9SJerome Forissier         }
2764*11fa71b9SJerome Forissier 
2765*11fa71b9SJerome Forissier         offset += start_bits; /* Now offset % 8 == 0 */
2766*11fa71b9SJerome Forissier         len -= start_bits;
2767*11fa71b9SJerome Forissier 
2768*11fa71b9SJerome Forissier         for( ; start_bits != 0; start_bits-- )
2769*11fa71b9SJerome Forissier             mask[first_byte_idx] |= 1 << ( start_bits - 1 );
2770*11fa71b9SJerome Forissier     }
2771*11fa71b9SJerome Forissier 
2772*11fa71b9SJerome Forissier     end_bits = len % 8;
2773*11fa71b9SJerome Forissier     if( end_bits != 0 )
2774*11fa71b9SJerome Forissier     {
2775*11fa71b9SJerome Forissier         size_t last_byte_idx = ( offset + len ) / 8;
2776*11fa71b9SJerome Forissier 
2777*11fa71b9SJerome Forissier         len -= end_bits; /* Now len % 8 == 0 */
2778*11fa71b9SJerome Forissier 
2779*11fa71b9SJerome Forissier         for( ; end_bits != 0; end_bits-- )
2780*11fa71b9SJerome Forissier             mask[last_byte_idx] |= 1 << ( 8 - end_bits );
2781*11fa71b9SJerome Forissier     }
2782*11fa71b9SJerome Forissier 
2783*11fa71b9SJerome Forissier     memset( mask + offset / 8, 0xFF, len / 8 );
2784*11fa71b9SJerome Forissier }
2785*11fa71b9SJerome Forissier 
2786*11fa71b9SJerome Forissier /*
2787*11fa71b9SJerome Forissier  * Check that bitmask is full
2788*11fa71b9SJerome Forissier  */
2789*11fa71b9SJerome Forissier static int ssl_bitmask_check( unsigned char *mask, size_t len )
2790*11fa71b9SJerome Forissier {
2791*11fa71b9SJerome Forissier     size_t i;
2792*11fa71b9SJerome Forissier 
2793*11fa71b9SJerome Forissier     for( i = 0; i < len / 8; i++ )
2794*11fa71b9SJerome Forissier         if( mask[i] != 0xFF )
2795*11fa71b9SJerome Forissier             return( -1 );
2796*11fa71b9SJerome Forissier 
2797*11fa71b9SJerome Forissier     for( i = 0; i < len % 8; i++ )
2798*11fa71b9SJerome Forissier         if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
2799*11fa71b9SJerome Forissier             return( -1 );
2800*11fa71b9SJerome Forissier 
2801*11fa71b9SJerome Forissier     return( 0 );
2802*11fa71b9SJerome Forissier }
2803*11fa71b9SJerome Forissier 
2804*11fa71b9SJerome Forissier /* msg_len does not include the handshake header */
2805*11fa71b9SJerome Forissier static size_t ssl_get_reassembly_buffer_size( size_t msg_len,
2806*11fa71b9SJerome Forissier                                               unsigned add_bitmap )
2807*11fa71b9SJerome Forissier {
2808*11fa71b9SJerome Forissier     size_t alloc_len;
2809*11fa71b9SJerome Forissier 
2810*11fa71b9SJerome Forissier     alloc_len  = 12;                                 /* Handshake header */
2811*11fa71b9SJerome Forissier     alloc_len += msg_len;                            /* Content buffer   */
2812*11fa71b9SJerome Forissier 
2813*11fa71b9SJerome Forissier     if( add_bitmap )
2814*11fa71b9SJerome Forissier         alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap       */
2815*11fa71b9SJerome Forissier 
2816*11fa71b9SJerome Forissier     return( alloc_len );
2817*11fa71b9SJerome Forissier }
2818*11fa71b9SJerome Forissier 
2819*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
2820*11fa71b9SJerome Forissier 
2821*11fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl )
2822*11fa71b9SJerome Forissier {
2823*11fa71b9SJerome Forissier     return( ( ssl->in_msg[1] << 16 ) |
2824*11fa71b9SJerome Forissier             ( ssl->in_msg[2] << 8  ) |
2825*11fa71b9SJerome Forissier               ssl->in_msg[3] );
2826*11fa71b9SJerome Forissier }
2827*11fa71b9SJerome Forissier 
2828*11fa71b9SJerome Forissier int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
2829*11fa71b9SJerome Forissier {
2830*11fa71b9SJerome Forissier     if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
2831*11fa71b9SJerome Forissier     {
2832*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d",
2833*11fa71b9SJerome Forissier                             ssl->in_msglen ) );
2834*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
2835*11fa71b9SJerome Forissier     }
2836*11fa71b9SJerome Forissier 
2837*11fa71b9SJerome Forissier     ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl );
2838*11fa71b9SJerome Forissier 
2839*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
2840*11fa71b9SJerome Forissier                         " %d, type = %d, hslen = %d",
2841*11fa71b9SJerome Forissier                         ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
2842*11fa71b9SJerome Forissier 
2843*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
2844*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
2845*11fa71b9SJerome Forissier     {
2846*11fa71b9SJerome Forissier         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2847*11fa71b9SJerome Forissier         unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
2848*11fa71b9SJerome Forissier 
2849*11fa71b9SJerome Forissier         if( ssl_check_hs_header( ssl ) != 0 )
2850*11fa71b9SJerome Forissier         {
2851*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) );
2852*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
2853*11fa71b9SJerome Forissier         }
2854*11fa71b9SJerome Forissier 
2855*11fa71b9SJerome Forissier         if( ssl->handshake != NULL &&
2856*11fa71b9SJerome Forissier             ( ( ssl->state   != MBEDTLS_SSL_HANDSHAKE_OVER &&
2857*11fa71b9SJerome Forissier                 recv_msg_seq != ssl->handshake->in_msg_seq ) ||
2858*11fa71b9SJerome Forissier               ( ssl->state  == MBEDTLS_SSL_HANDSHAKE_OVER &&
2859*11fa71b9SJerome Forissier                 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) )
2860*11fa71b9SJerome Forissier         {
2861*11fa71b9SJerome Forissier             if( recv_msg_seq > ssl->handshake->in_msg_seq )
2862*11fa71b9SJerome Forissier             {
2863*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)",
2864*11fa71b9SJerome Forissier                                             recv_msg_seq,
2865*11fa71b9SJerome Forissier                                             ssl->handshake->in_msg_seq ) );
2866*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
2867*11fa71b9SJerome Forissier             }
2868*11fa71b9SJerome Forissier 
2869*11fa71b9SJerome Forissier             /* Retransmit only on last message from previous flight, to avoid
2870*11fa71b9SJerome Forissier              * too many retransmissions.
2871*11fa71b9SJerome Forissier              * Besides, No sane server ever retransmits HelloVerifyRequest */
2872*11fa71b9SJerome Forissier             if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
2873*11fa71b9SJerome Forissier                 ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
2874*11fa71b9SJerome Forissier             {
2875*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
2876*11fa71b9SJerome Forissier                                     "message_seq = %d, start_of_flight = %d",
2877*11fa71b9SJerome Forissier                                     recv_msg_seq,
2878*11fa71b9SJerome Forissier                                     ssl->handshake->in_flight_start_seq ) );
2879*11fa71b9SJerome Forissier 
2880*11fa71b9SJerome Forissier                 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
2881*11fa71b9SJerome Forissier                 {
2882*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
2883*11fa71b9SJerome Forissier                     return( ret );
2884*11fa71b9SJerome Forissier                 }
2885*11fa71b9SJerome Forissier             }
2886*11fa71b9SJerome Forissier             else
2887*11fa71b9SJerome Forissier             {
2888*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
2889*11fa71b9SJerome Forissier                                     "message_seq = %d, expected = %d",
2890*11fa71b9SJerome Forissier                                     recv_msg_seq,
2891*11fa71b9SJerome Forissier                                     ssl->handshake->in_msg_seq ) );
2892*11fa71b9SJerome Forissier             }
2893*11fa71b9SJerome Forissier 
2894*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
2895*11fa71b9SJerome Forissier         }
2896*11fa71b9SJerome Forissier         /* Wait until message completion to increment in_msg_seq */
2897*11fa71b9SJerome Forissier 
2898*11fa71b9SJerome Forissier         /* Message reassembly is handled alongside buffering of future
2899*11fa71b9SJerome Forissier          * messages; the commonality is that both handshake fragments and
2900*11fa71b9SJerome Forissier          * future messages cannot be forwarded immediately to the
2901*11fa71b9SJerome Forissier          * handshake logic layer. */
2902*11fa71b9SJerome Forissier         if( ssl_hs_is_proper_fragment( ssl ) == 1 )
2903*11fa71b9SJerome Forissier         {
2904*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
2905*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
2906*11fa71b9SJerome Forissier         }
2907*11fa71b9SJerome Forissier     }
2908*11fa71b9SJerome Forissier     else
2909*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
2910*11fa71b9SJerome Forissier     /* With TLS we don't handle fragmentation (for now) */
2911*11fa71b9SJerome Forissier     if( ssl->in_msglen < ssl->in_hslen )
2912*11fa71b9SJerome Forissier     {
2913*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
2914*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
2915*11fa71b9SJerome Forissier     }
2916*11fa71b9SJerome Forissier 
2917*11fa71b9SJerome Forissier     return( 0 );
2918*11fa71b9SJerome Forissier }
2919*11fa71b9SJerome Forissier 
2920*11fa71b9SJerome Forissier void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
2921*11fa71b9SJerome Forissier {
2922*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
2923*11fa71b9SJerome Forissier 
2924*11fa71b9SJerome Forissier     if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
2925*11fa71b9SJerome Forissier     {
2926*11fa71b9SJerome Forissier         ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
2927*11fa71b9SJerome Forissier     }
2928*11fa71b9SJerome Forissier 
2929*11fa71b9SJerome Forissier     /* Handshake message is complete, increment counter */
2930*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
2931*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2932*11fa71b9SJerome Forissier         ssl->handshake != NULL )
2933*11fa71b9SJerome Forissier     {
2934*11fa71b9SJerome Forissier         unsigned offset;
2935*11fa71b9SJerome Forissier         mbedtls_ssl_hs_buffer *hs_buf;
2936*11fa71b9SJerome Forissier 
2937*11fa71b9SJerome Forissier         /* Increment handshake sequence number */
2938*11fa71b9SJerome Forissier         hs->in_msg_seq++;
2939*11fa71b9SJerome Forissier 
2940*11fa71b9SJerome Forissier         /*
2941*11fa71b9SJerome Forissier          * Clear up handshake buffering and reassembly structure.
2942*11fa71b9SJerome Forissier          */
2943*11fa71b9SJerome Forissier 
2944*11fa71b9SJerome Forissier         /* Free first entry */
2945*11fa71b9SJerome Forissier         ssl_buffering_free_slot( ssl, 0 );
2946*11fa71b9SJerome Forissier 
2947*11fa71b9SJerome Forissier         /* Shift all other entries */
2948*11fa71b9SJerome Forissier         for( offset = 0, hs_buf = &hs->buffering.hs[0];
2949*11fa71b9SJerome Forissier              offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
2950*11fa71b9SJerome Forissier              offset++, hs_buf++ )
2951*11fa71b9SJerome Forissier         {
2952*11fa71b9SJerome Forissier             *hs_buf = *(hs_buf + 1);
2953*11fa71b9SJerome Forissier         }
2954*11fa71b9SJerome Forissier 
2955*11fa71b9SJerome Forissier         /* Create a fresh last entry */
2956*11fa71b9SJerome Forissier         memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
2957*11fa71b9SJerome Forissier     }
2958*11fa71b9SJerome Forissier #endif
2959*11fa71b9SJerome Forissier }
2960*11fa71b9SJerome Forissier 
2961*11fa71b9SJerome Forissier /*
2962*11fa71b9SJerome Forissier  * DTLS anti-replay: RFC 6347 4.1.2.6
2963*11fa71b9SJerome Forissier  *
2964*11fa71b9SJerome Forissier  * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
2965*11fa71b9SJerome Forissier  * Bit n is set iff record number in_window_top - n has been seen.
2966*11fa71b9SJerome Forissier  *
2967*11fa71b9SJerome Forissier  * Usually, in_window_top is the last record number seen and the lsb of
2968*11fa71b9SJerome Forissier  * in_window is set. The only exception is the initial state (record number 0
2969*11fa71b9SJerome Forissier  * not seen yet).
2970*11fa71b9SJerome Forissier  */
2971*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
2972*11fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
2973*11fa71b9SJerome Forissier {
2974*11fa71b9SJerome Forissier     ssl->in_window_top = 0;
2975*11fa71b9SJerome Forissier     ssl->in_window = 0;
2976*11fa71b9SJerome Forissier }
2977*11fa71b9SJerome Forissier 
2978*11fa71b9SJerome Forissier static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
2979*11fa71b9SJerome Forissier {
2980*11fa71b9SJerome Forissier     return( ( (uint64_t) buf[0] << 40 ) |
2981*11fa71b9SJerome Forissier             ( (uint64_t) buf[1] << 32 ) |
2982*11fa71b9SJerome Forissier             ( (uint64_t) buf[2] << 24 ) |
2983*11fa71b9SJerome Forissier             ( (uint64_t) buf[3] << 16 ) |
2984*11fa71b9SJerome Forissier             ( (uint64_t) buf[4] <<  8 ) |
2985*11fa71b9SJerome Forissier             ( (uint64_t) buf[5]       ) );
2986*11fa71b9SJerome Forissier }
2987*11fa71b9SJerome Forissier 
2988*11fa71b9SJerome Forissier static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr )
2989*11fa71b9SJerome Forissier {
2990*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2991*11fa71b9SJerome Forissier     unsigned char *original_in_ctr;
2992*11fa71b9SJerome Forissier 
2993*11fa71b9SJerome Forissier     // save original in_ctr
2994*11fa71b9SJerome Forissier     original_in_ctr = ssl->in_ctr;
2995*11fa71b9SJerome Forissier 
2996*11fa71b9SJerome Forissier     // use counter from record
2997*11fa71b9SJerome Forissier     ssl->in_ctr = record_in_ctr;
2998*11fa71b9SJerome Forissier 
2999*11fa71b9SJerome Forissier     ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl );
3000*11fa71b9SJerome Forissier 
3001*11fa71b9SJerome Forissier     // restore the counter
3002*11fa71b9SJerome Forissier     ssl->in_ctr = original_in_ctr;
3003*11fa71b9SJerome Forissier 
3004*11fa71b9SJerome Forissier     return ret;
3005*11fa71b9SJerome Forissier }
3006*11fa71b9SJerome Forissier 
3007*11fa71b9SJerome Forissier /*
3008*11fa71b9SJerome Forissier  * Return 0 if sequence number is acceptable, -1 otherwise
3009*11fa71b9SJerome Forissier  */
3010*11fa71b9SJerome Forissier int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl )
3011*11fa71b9SJerome Forissier {
3012*11fa71b9SJerome Forissier     uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
3013*11fa71b9SJerome Forissier     uint64_t bit;
3014*11fa71b9SJerome Forissier 
3015*11fa71b9SJerome Forissier     if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
3016*11fa71b9SJerome Forissier         return( 0 );
3017*11fa71b9SJerome Forissier 
3018*11fa71b9SJerome Forissier     if( rec_seqnum > ssl->in_window_top )
3019*11fa71b9SJerome Forissier         return( 0 );
3020*11fa71b9SJerome Forissier 
3021*11fa71b9SJerome Forissier     bit = ssl->in_window_top - rec_seqnum;
3022*11fa71b9SJerome Forissier 
3023*11fa71b9SJerome Forissier     if( bit >= 64 )
3024*11fa71b9SJerome Forissier         return( -1 );
3025*11fa71b9SJerome Forissier 
3026*11fa71b9SJerome Forissier     if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
3027*11fa71b9SJerome Forissier         return( -1 );
3028*11fa71b9SJerome Forissier 
3029*11fa71b9SJerome Forissier     return( 0 );
3030*11fa71b9SJerome Forissier }
3031*11fa71b9SJerome Forissier 
3032*11fa71b9SJerome Forissier /*
3033*11fa71b9SJerome Forissier  * Update replay window on new validated record
3034*11fa71b9SJerome Forissier  */
3035*11fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
3036*11fa71b9SJerome Forissier {
3037*11fa71b9SJerome Forissier     uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
3038*11fa71b9SJerome Forissier 
3039*11fa71b9SJerome Forissier     if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
3040*11fa71b9SJerome Forissier         return;
3041*11fa71b9SJerome Forissier 
3042*11fa71b9SJerome Forissier     if( rec_seqnum > ssl->in_window_top )
3043*11fa71b9SJerome Forissier     {
3044*11fa71b9SJerome Forissier         /* Update window_top and the contents of the window */
3045*11fa71b9SJerome Forissier         uint64_t shift = rec_seqnum - ssl->in_window_top;
3046*11fa71b9SJerome Forissier 
3047*11fa71b9SJerome Forissier         if( shift >= 64 )
3048*11fa71b9SJerome Forissier             ssl->in_window = 1;
3049*11fa71b9SJerome Forissier         else
3050*11fa71b9SJerome Forissier         {
3051*11fa71b9SJerome Forissier             ssl->in_window <<= shift;
3052*11fa71b9SJerome Forissier             ssl->in_window |= 1;
3053*11fa71b9SJerome Forissier         }
3054*11fa71b9SJerome Forissier 
3055*11fa71b9SJerome Forissier         ssl->in_window_top = rec_seqnum;
3056*11fa71b9SJerome Forissier     }
3057*11fa71b9SJerome Forissier     else
3058*11fa71b9SJerome Forissier     {
3059*11fa71b9SJerome Forissier         /* Mark that number as seen in the current window */
3060*11fa71b9SJerome Forissier         uint64_t bit = ssl->in_window_top - rec_seqnum;
3061*11fa71b9SJerome Forissier 
3062*11fa71b9SJerome Forissier         if( bit < 64 ) /* Always true, but be extra sure */
3063*11fa71b9SJerome Forissier             ssl->in_window |= (uint64_t) 1 << bit;
3064*11fa71b9SJerome Forissier     }
3065*11fa71b9SJerome Forissier }
3066*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
3067*11fa71b9SJerome Forissier 
3068*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
3069*11fa71b9SJerome Forissier /*
3070*11fa71b9SJerome Forissier  * Without any SSL context, check if a datagram looks like a ClientHello with
3071*11fa71b9SJerome Forissier  * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
3072*11fa71b9SJerome Forissier  * Both input and output include full DTLS headers.
3073*11fa71b9SJerome Forissier  *
3074*11fa71b9SJerome Forissier  * - if cookie is valid, return 0
3075*11fa71b9SJerome Forissier  * - if ClientHello looks superficially valid but cookie is not,
3076*11fa71b9SJerome Forissier  *   fill obuf and set olen, then
3077*11fa71b9SJerome Forissier  *   return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
3078*11fa71b9SJerome Forissier  * - otherwise return a specific error code
3079*11fa71b9SJerome Forissier  */
3080*11fa71b9SJerome Forissier static int ssl_check_dtls_clihlo_cookie(
3081*11fa71b9SJerome Forissier                            mbedtls_ssl_cookie_write_t *f_cookie_write,
3082*11fa71b9SJerome Forissier                            mbedtls_ssl_cookie_check_t *f_cookie_check,
3083*11fa71b9SJerome Forissier                            void *p_cookie,
3084*11fa71b9SJerome Forissier                            const unsigned char *cli_id, size_t cli_id_len,
3085*11fa71b9SJerome Forissier                            const unsigned char *in, size_t in_len,
3086*11fa71b9SJerome Forissier                            unsigned char *obuf, size_t buf_len, size_t *olen )
3087*11fa71b9SJerome Forissier {
3088*11fa71b9SJerome Forissier     size_t sid_len, cookie_len;
3089*11fa71b9SJerome Forissier     unsigned char *p;
3090*11fa71b9SJerome Forissier 
3091*11fa71b9SJerome Forissier     /*
3092*11fa71b9SJerome Forissier      * Structure of ClientHello with record and handshake headers,
3093*11fa71b9SJerome Forissier      * and expected values. We don't need to check a lot, more checks will be
3094*11fa71b9SJerome Forissier      * done when actually parsing the ClientHello - skipping those checks
3095*11fa71b9SJerome Forissier      * avoids code duplication and does not make cookie forging any easier.
3096*11fa71b9SJerome Forissier      *
3097*11fa71b9SJerome Forissier      *  0-0  ContentType type;                  copied, must be handshake
3098*11fa71b9SJerome Forissier      *  1-2  ProtocolVersion version;           copied
3099*11fa71b9SJerome Forissier      *  3-4  uint16 epoch;                      copied, must be 0
3100*11fa71b9SJerome Forissier      *  5-10 uint48 sequence_number;            copied
3101*11fa71b9SJerome Forissier      * 11-12 uint16 length;                     (ignored)
3102*11fa71b9SJerome Forissier      *
3103*11fa71b9SJerome Forissier      * 13-13 HandshakeType msg_type;            (ignored)
3104*11fa71b9SJerome Forissier      * 14-16 uint24 length;                     (ignored)
3105*11fa71b9SJerome Forissier      * 17-18 uint16 message_seq;                copied
3106*11fa71b9SJerome Forissier      * 19-21 uint24 fragment_offset;            copied, must be 0
3107*11fa71b9SJerome Forissier      * 22-24 uint24 fragment_length;            (ignored)
3108*11fa71b9SJerome Forissier      *
3109*11fa71b9SJerome Forissier      * 25-26 ProtocolVersion client_version;    (ignored)
3110*11fa71b9SJerome Forissier      * 27-58 Random random;                     (ignored)
3111*11fa71b9SJerome Forissier      * 59-xx SessionID session_id;              1 byte len + sid_len content
3112*11fa71b9SJerome Forissier      * 60+   opaque cookie<0..2^8-1>;           1 byte len + content
3113*11fa71b9SJerome Forissier      *       ...
3114*11fa71b9SJerome Forissier      *
3115*11fa71b9SJerome Forissier      * Minimum length is 61 bytes.
3116*11fa71b9SJerome Forissier      */
3117*11fa71b9SJerome Forissier     if( in_len < 61 ||
3118*11fa71b9SJerome Forissier         in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
3119*11fa71b9SJerome Forissier         in[3] != 0 || in[4] != 0 ||
3120*11fa71b9SJerome Forissier         in[19] != 0 || in[20] != 0 || in[21] != 0 )
3121*11fa71b9SJerome Forissier     {
3122*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
3123*11fa71b9SJerome Forissier     }
3124*11fa71b9SJerome Forissier 
3125*11fa71b9SJerome Forissier     sid_len = in[59];
3126*11fa71b9SJerome Forissier     if( sid_len > in_len - 61 )
3127*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
3128*11fa71b9SJerome Forissier 
3129*11fa71b9SJerome Forissier     cookie_len = in[60 + sid_len];
3130*11fa71b9SJerome Forissier     if( cookie_len > in_len - 60 )
3131*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
3132*11fa71b9SJerome Forissier 
3133*11fa71b9SJerome Forissier     if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
3134*11fa71b9SJerome Forissier                         cli_id, cli_id_len ) == 0 )
3135*11fa71b9SJerome Forissier     {
3136*11fa71b9SJerome Forissier         /* Valid cookie */
3137*11fa71b9SJerome Forissier         return( 0 );
3138*11fa71b9SJerome Forissier     }
3139*11fa71b9SJerome Forissier 
3140*11fa71b9SJerome Forissier     /*
3141*11fa71b9SJerome Forissier      * If we get here, we've got an invalid cookie, let's prepare HVR.
3142*11fa71b9SJerome Forissier      *
3143*11fa71b9SJerome Forissier      *  0-0  ContentType type;                  copied
3144*11fa71b9SJerome Forissier      *  1-2  ProtocolVersion version;           copied
3145*11fa71b9SJerome Forissier      *  3-4  uint16 epoch;                      copied
3146*11fa71b9SJerome Forissier      *  5-10 uint48 sequence_number;            copied
3147*11fa71b9SJerome Forissier      * 11-12 uint16 length;                     olen - 13
3148*11fa71b9SJerome Forissier      *
3149*11fa71b9SJerome Forissier      * 13-13 HandshakeType msg_type;            hello_verify_request
3150*11fa71b9SJerome Forissier      * 14-16 uint24 length;                     olen - 25
3151*11fa71b9SJerome Forissier      * 17-18 uint16 message_seq;                copied
3152*11fa71b9SJerome Forissier      * 19-21 uint24 fragment_offset;            copied
3153*11fa71b9SJerome Forissier      * 22-24 uint24 fragment_length;            olen - 25
3154*11fa71b9SJerome Forissier      *
3155*11fa71b9SJerome Forissier      * 25-26 ProtocolVersion server_version;    0xfe 0xff
3156*11fa71b9SJerome Forissier      * 27-27 opaque cookie<0..2^8-1>;           cookie_len = olen - 27, cookie
3157*11fa71b9SJerome Forissier      *
3158*11fa71b9SJerome Forissier      * Minimum length is 28.
3159*11fa71b9SJerome Forissier      */
3160*11fa71b9SJerome Forissier     if( buf_len < 28 )
3161*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
3162*11fa71b9SJerome Forissier 
3163*11fa71b9SJerome Forissier     /* Copy most fields and adapt others */
3164*11fa71b9SJerome Forissier     memcpy( obuf, in, 25 );
3165*11fa71b9SJerome Forissier     obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
3166*11fa71b9SJerome Forissier     obuf[25] = 0xfe;
3167*11fa71b9SJerome Forissier     obuf[26] = 0xff;
3168*11fa71b9SJerome Forissier 
3169*11fa71b9SJerome Forissier     /* Generate and write actual cookie */
3170*11fa71b9SJerome Forissier     p = obuf + 28;
3171*11fa71b9SJerome Forissier     if( f_cookie_write( p_cookie,
3172*11fa71b9SJerome Forissier                         &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
3173*11fa71b9SJerome Forissier     {
3174*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
3175*11fa71b9SJerome Forissier     }
3176*11fa71b9SJerome Forissier 
3177*11fa71b9SJerome Forissier     *olen = p - obuf;
3178*11fa71b9SJerome Forissier 
3179*11fa71b9SJerome Forissier     /* Go back and fill length fields */
3180*11fa71b9SJerome Forissier     obuf[27] = (unsigned char)( *olen - 28 );
3181*11fa71b9SJerome Forissier 
3182*11fa71b9SJerome Forissier     obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 );
3183*11fa71b9SJerome Forissier     obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >>  8 );
3184*11fa71b9SJerome Forissier     obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 )       );
3185*11fa71b9SJerome Forissier 
3186*11fa71b9SJerome Forissier     obuf[11] = (unsigned char)( ( *olen - 13 ) >>  8 );
3187*11fa71b9SJerome Forissier     obuf[12] = (unsigned char)( ( *olen - 13 )       );
3188*11fa71b9SJerome Forissier 
3189*11fa71b9SJerome Forissier     return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
3190*11fa71b9SJerome Forissier }
3191*11fa71b9SJerome Forissier 
3192*11fa71b9SJerome Forissier /*
3193*11fa71b9SJerome Forissier  * Handle possible client reconnect with the same UDP quadruplet
3194*11fa71b9SJerome Forissier  * (RFC 6347 Section 4.2.8).
3195*11fa71b9SJerome Forissier  *
3196*11fa71b9SJerome Forissier  * Called by ssl_parse_record_header() in case we receive an epoch 0 record
3197*11fa71b9SJerome Forissier  * that looks like a ClientHello.
3198*11fa71b9SJerome Forissier  *
3199*11fa71b9SJerome Forissier  * - if the input looks like a ClientHello without cookies,
3200*11fa71b9SJerome Forissier  *   send back HelloVerifyRequest, then return 0
3201*11fa71b9SJerome Forissier  * - if the input looks like a ClientHello with a valid cookie,
3202*11fa71b9SJerome Forissier  *   reset the session of the current context, and
3203*11fa71b9SJerome Forissier  *   return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
3204*11fa71b9SJerome Forissier  * - if anything goes wrong, return a specific error code
3205*11fa71b9SJerome Forissier  *
3206*11fa71b9SJerome Forissier  * This function is called (through ssl_check_client_reconnect()) when an
3207*11fa71b9SJerome Forissier  * unexpected record is found in ssl_get_next_record(), which will discard the
3208*11fa71b9SJerome Forissier  * record if we return 0, and bubble up the return value otherwise (this
3209*11fa71b9SJerome Forissier  * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
3210*11fa71b9SJerome Forissier  * errors, and is the right thing to do in both cases).
3211*11fa71b9SJerome Forissier  */
3212*11fa71b9SJerome Forissier static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
3213*11fa71b9SJerome Forissier {
3214*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3215*11fa71b9SJerome Forissier     size_t len;
3216*11fa71b9SJerome Forissier 
3217*11fa71b9SJerome Forissier     if( ssl->conf->f_cookie_write == NULL ||
3218*11fa71b9SJerome Forissier         ssl->conf->f_cookie_check == NULL )
3219*11fa71b9SJerome Forissier     {
3220*11fa71b9SJerome Forissier         /* If we can't use cookies to verify reachability of the peer,
3221*11fa71b9SJerome Forissier          * drop the record. */
3222*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "no cookie callbacks, "
3223*11fa71b9SJerome Forissier                                     "can't check reconnect validity" ) );
3224*11fa71b9SJerome Forissier         return( 0 );
3225*11fa71b9SJerome Forissier     }
3226*11fa71b9SJerome Forissier 
3227*11fa71b9SJerome Forissier     ret = ssl_check_dtls_clihlo_cookie(
3228*11fa71b9SJerome Forissier             ssl->conf->f_cookie_write,
3229*11fa71b9SJerome Forissier             ssl->conf->f_cookie_check,
3230*11fa71b9SJerome Forissier             ssl->conf->p_cookie,
3231*11fa71b9SJerome Forissier             ssl->cli_id, ssl->cli_id_len,
3232*11fa71b9SJerome Forissier             ssl->in_buf, ssl->in_left,
3233*11fa71b9SJerome Forissier             ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
3234*11fa71b9SJerome Forissier 
3235*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
3236*11fa71b9SJerome Forissier 
3237*11fa71b9SJerome Forissier     if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
3238*11fa71b9SJerome Forissier     {
3239*11fa71b9SJerome Forissier         int send_ret;
3240*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
3241*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
3242*11fa71b9SJerome Forissier                                   ssl->out_buf, len );
3243*11fa71b9SJerome Forissier         /* Don't check write errors as we can't do anything here.
3244*11fa71b9SJerome Forissier          * If the error is permanent we'll catch it later,
3245*11fa71b9SJerome Forissier          * if it's not, then hopefully it'll work next time. */
3246*11fa71b9SJerome Forissier         send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
3247*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
3248*11fa71b9SJerome Forissier         (void) send_ret;
3249*11fa71b9SJerome Forissier 
3250*11fa71b9SJerome Forissier         return( 0 );
3251*11fa71b9SJerome Forissier     }
3252*11fa71b9SJerome Forissier 
3253*11fa71b9SJerome Forissier     if( ret == 0 )
3254*11fa71b9SJerome Forissier     {
3255*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
3256*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_session_reset_int( ssl, 1 ) ) != 0 )
3257*11fa71b9SJerome Forissier         {
3258*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
3259*11fa71b9SJerome Forissier             return( ret );
3260*11fa71b9SJerome Forissier         }
3261*11fa71b9SJerome Forissier 
3262*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
3263*11fa71b9SJerome Forissier     }
3264*11fa71b9SJerome Forissier 
3265*11fa71b9SJerome Forissier     return( ret );
3266*11fa71b9SJerome Forissier }
3267*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
3268*11fa71b9SJerome Forissier 
3269*11fa71b9SJerome Forissier static int ssl_check_record_type( uint8_t record_type )
3270*11fa71b9SJerome Forissier {
3271*11fa71b9SJerome Forissier     if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
3272*11fa71b9SJerome Forissier         record_type != MBEDTLS_SSL_MSG_ALERT &&
3273*11fa71b9SJerome Forissier         record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
3274*11fa71b9SJerome Forissier         record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
3275*11fa71b9SJerome Forissier     {
3276*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3277*11fa71b9SJerome Forissier     }
3278*11fa71b9SJerome Forissier 
3279*11fa71b9SJerome Forissier     return( 0 );
3280*11fa71b9SJerome Forissier }
3281*11fa71b9SJerome Forissier 
3282*11fa71b9SJerome Forissier /*
3283*11fa71b9SJerome Forissier  * ContentType type;
3284*11fa71b9SJerome Forissier  * ProtocolVersion version;
3285*11fa71b9SJerome Forissier  * uint16 epoch;            // DTLS only
3286*11fa71b9SJerome Forissier  * uint48 sequence_number;  // DTLS only
3287*11fa71b9SJerome Forissier  * uint16 length;
3288*11fa71b9SJerome Forissier  *
3289*11fa71b9SJerome Forissier  * Return 0 if header looks sane (and, for DTLS, the record is expected)
3290*11fa71b9SJerome Forissier  * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
3291*11fa71b9SJerome Forissier  * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
3292*11fa71b9SJerome Forissier  *
3293*11fa71b9SJerome Forissier  * With DTLS, mbedtls_ssl_read_record() will:
3294*11fa71b9SJerome Forissier  * 1. proceed with the record if this function returns 0
3295*11fa71b9SJerome Forissier  * 2. drop only the current record if this function returns UNEXPECTED_RECORD
3296*11fa71b9SJerome Forissier  * 3. return CLIENT_RECONNECT if this function return that value
3297*11fa71b9SJerome Forissier  * 4. drop the whole datagram if this function returns anything else.
3298*11fa71b9SJerome Forissier  * Point 2 is needed when the peer is resending, and we have already received
3299*11fa71b9SJerome Forissier  * the first record from a datagram but are still waiting for the others.
3300*11fa71b9SJerome Forissier  */
3301*11fa71b9SJerome Forissier static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
3302*11fa71b9SJerome Forissier                                     unsigned char *buf,
3303*11fa71b9SJerome Forissier                                     size_t len,
3304*11fa71b9SJerome Forissier                                     mbedtls_record *rec )
3305*11fa71b9SJerome Forissier {
3306*11fa71b9SJerome Forissier     int major_ver, minor_ver;
3307*11fa71b9SJerome Forissier 
3308*11fa71b9SJerome Forissier     size_t const rec_hdr_type_offset    = 0;
3309*11fa71b9SJerome Forissier     size_t const rec_hdr_type_len       = 1;
3310*11fa71b9SJerome Forissier 
3311*11fa71b9SJerome Forissier     size_t const rec_hdr_version_offset = rec_hdr_type_offset +
3312*11fa71b9SJerome Forissier                                           rec_hdr_type_len;
3313*11fa71b9SJerome Forissier     size_t const rec_hdr_version_len    = 2;
3314*11fa71b9SJerome Forissier 
3315*11fa71b9SJerome Forissier     size_t const rec_hdr_ctr_len        = 8;
3316*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
3317*11fa71b9SJerome Forissier     uint32_t     rec_epoch;
3318*11fa71b9SJerome Forissier     size_t const rec_hdr_ctr_offset     = rec_hdr_version_offset +
3319*11fa71b9SJerome Forissier                                           rec_hdr_version_len;
3320*11fa71b9SJerome Forissier 
3321*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3322*11fa71b9SJerome Forissier     size_t const rec_hdr_cid_offset     = rec_hdr_ctr_offset +
3323*11fa71b9SJerome Forissier                                           rec_hdr_ctr_len;
3324*11fa71b9SJerome Forissier     size_t       rec_hdr_cid_len        = 0;
3325*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3326*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
3327*11fa71b9SJerome Forissier 
3328*11fa71b9SJerome Forissier     size_t       rec_hdr_len_offset; /* To be determined */
3329*11fa71b9SJerome Forissier     size_t const rec_hdr_len_len    = 2;
3330*11fa71b9SJerome Forissier 
3331*11fa71b9SJerome Forissier     /*
3332*11fa71b9SJerome Forissier      * Check minimum lengths for record header.
3333*11fa71b9SJerome Forissier      */
3334*11fa71b9SJerome Forissier 
3335*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
3336*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
3337*11fa71b9SJerome Forissier     {
3338*11fa71b9SJerome Forissier         rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
3339*11fa71b9SJerome Forissier     }
3340*11fa71b9SJerome Forissier     else
3341*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
3342*11fa71b9SJerome Forissier     {
3343*11fa71b9SJerome Forissier         rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len;
3344*11fa71b9SJerome Forissier     }
3345*11fa71b9SJerome Forissier 
3346*11fa71b9SJerome Forissier     if( len < rec_hdr_len_offset + rec_hdr_len_len )
3347*11fa71b9SJerome Forissier     {
3348*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header of length %u",
3349*11fa71b9SJerome Forissier                  (unsigned) len,
3350*11fa71b9SJerome Forissier                  (unsigned)( rec_hdr_len_len + rec_hdr_len_len ) ) );
3351*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3352*11fa71b9SJerome Forissier     }
3353*11fa71b9SJerome Forissier 
3354*11fa71b9SJerome Forissier     /*
3355*11fa71b9SJerome Forissier      * Parse and validate record content type
3356*11fa71b9SJerome Forissier      */
3357*11fa71b9SJerome Forissier 
3358*11fa71b9SJerome Forissier     rec->type = buf[ rec_hdr_type_offset ];
3359*11fa71b9SJerome Forissier 
3360*11fa71b9SJerome Forissier     /* Check record content type */
3361*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3362*11fa71b9SJerome Forissier     rec->cid_len = 0;
3363*11fa71b9SJerome Forissier 
3364*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3365*11fa71b9SJerome Forissier         ssl->conf->cid_len != 0                                &&
3366*11fa71b9SJerome Forissier         rec->type == MBEDTLS_SSL_MSG_CID )
3367*11fa71b9SJerome Forissier     {
3368*11fa71b9SJerome Forissier         /* Shift pointers to account for record header including CID
3369*11fa71b9SJerome Forissier          * struct {
3370*11fa71b9SJerome Forissier          *   ContentType special_type = tls12_cid;
3371*11fa71b9SJerome Forissier          *   ProtocolVersion version;
3372*11fa71b9SJerome Forissier          *   uint16 epoch;
3373*11fa71b9SJerome Forissier          *   uint48 sequence_number;
3374*11fa71b9SJerome Forissier          *   opaque cid[cid_length]; // Additional field compared to
3375*11fa71b9SJerome Forissier          *                           // default DTLS record format
3376*11fa71b9SJerome Forissier          *   uint16 length;
3377*11fa71b9SJerome Forissier          *   opaque enc_content[DTLSCiphertext.length];
3378*11fa71b9SJerome Forissier          * } DTLSCiphertext;
3379*11fa71b9SJerome Forissier          */
3380*11fa71b9SJerome Forissier 
3381*11fa71b9SJerome Forissier         /* So far, we only support static CID lengths
3382*11fa71b9SJerome Forissier          * fixed in the configuration. */
3383*11fa71b9SJerome Forissier         rec_hdr_cid_len = ssl->conf->cid_len;
3384*11fa71b9SJerome Forissier         rec_hdr_len_offset += rec_hdr_cid_len;
3385*11fa71b9SJerome Forissier 
3386*11fa71b9SJerome Forissier         if( len < rec_hdr_len_offset + rec_hdr_len_len )
3387*11fa71b9SJerome Forissier         {
3388*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header including CID, length %u",
3389*11fa71b9SJerome Forissier                 (unsigned) len,
3390*11fa71b9SJerome Forissier                 (unsigned)( rec_hdr_len_offset + rec_hdr_len_len ) ) );
3391*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3392*11fa71b9SJerome Forissier         }
3393*11fa71b9SJerome Forissier 
3394*11fa71b9SJerome Forissier         /* configured CID len is guaranteed at most 255, see
3395*11fa71b9SJerome Forissier          * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */
3396*11fa71b9SJerome Forissier         rec->cid_len = (uint8_t) rec_hdr_cid_len;
3397*11fa71b9SJerome Forissier         memcpy( rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len );
3398*11fa71b9SJerome Forissier     }
3399*11fa71b9SJerome Forissier     else
3400*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3401*11fa71b9SJerome Forissier     {
3402*11fa71b9SJerome Forissier         if( ssl_check_record_type( rec->type ) )
3403*11fa71b9SJerome Forissier         {
3404*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type %u",
3405*11fa71b9SJerome Forissier                                         (unsigned) rec->type ) );
3406*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3407*11fa71b9SJerome Forissier         }
3408*11fa71b9SJerome Forissier     }
3409*11fa71b9SJerome Forissier 
3410*11fa71b9SJerome Forissier     /*
3411*11fa71b9SJerome Forissier      * Parse and validate record version
3412*11fa71b9SJerome Forissier      */
3413*11fa71b9SJerome Forissier 
3414*11fa71b9SJerome Forissier     rec->ver[0] = buf[ rec_hdr_version_offset + 0 ];
3415*11fa71b9SJerome Forissier     rec->ver[1] = buf[ rec_hdr_version_offset + 1 ];
3416*11fa71b9SJerome Forissier     mbedtls_ssl_read_version( &major_ver, &minor_ver,
3417*11fa71b9SJerome Forissier                               ssl->conf->transport,
3418*11fa71b9SJerome Forissier                               &rec->ver[0] );
3419*11fa71b9SJerome Forissier 
3420*11fa71b9SJerome Forissier     if( major_ver != ssl->major_ver )
3421*11fa71b9SJerome Forissier     {
3422*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
3423*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3424*11fa71b9SJerome Forissier     }
3425*11fa71b9SJerome Forissier 
3426*11fa71b9SJerome Forissier     if( minor_ver > ssl->conf->max_minor_ver )
3427*11fa71b9SJerome Forissier     {
3428*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
3429*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3430*11fa71b9SJerome Forissier     }
3431*11fa71b9SJerome Forissier 
3432*11fa71b9SJerome Forissier     /*
3433*11fa71b9SJerome Forissier      * Parse/Copy record sequence number.
3434*11fa71b9SJerome Forissier      */
3435*11fa71b9SJerome Forissier 
3436*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
3437*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
3438*11fa71b9SJerome Forissier     {
3439*11fa71b9SJerome Forissier         /* Copy explicit record sequence number from input buffer. */
3440*11fa71b9SJerome Forissier         memcpy( &rec->ctr[0], buf + rec_hdr_ctr_offset,
3441*11fa71b9SJerome Forissier                 rec_hdr_ctr_len );
3442*11fa71b9SJerome Forissier     }
3443*11fa71b9SJerome Forissier     else
3444*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
3445*11fa71b9SJerome Forissier     {
3446*11fa71b9SJerome Forissier         /* Copy implicit record sequence number from SSL context structure. */
3447*11fa71b9SJerome Forissier         memcpy( &rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len );
3448*11fa71b9SJerome Forissier     }
3449*11fa71b9SJerome Forissier 
3450*11fa71b9SJerome Forissier     /*
3451*11fa71b9SJerome Forissier      * Parse record length.
3452*11fa71b9SJerome Forissier      */
3453*11fa71b9SJerome Forissier 
3454*11fa71b9SJerome Forissier     rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
3455*11fa71b9SJerome Forissier     rec->data_len    = ( (size_t) buf[ rec_hdr_len_offset + 0 ] << 8 ) |
3456*11fa71b9SJerome Forissier                        ( (size_t) buf[ rec_hdr_len_offset + 1 ] << 0 );
3457*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", buf, rec->data_offset );
3458*11fa71b9SJerome Forissier 
3459*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
3460*11fa71b9SJerome Forissier                                 "version = [%d:%d], msglen = %d",
3461*11fa71b9SJerome Forissier                                 rec->type,
3462*11fa71b9SJerome Forissier                                 major_ver, minor_ver, rec->data_len ) );
3463*11fa71b9SJerome Forissier 
3464*11fa71b9SJerome Forissier     rec->buf     = buf;
3465*11fa71b9SJerome Forissier     rec->buf_len = rec->data_offset + rec->data_len;
3466*11fa71b9SJerome Forissier 
3467*11fa71b9SJerome Forissier     if( rec->data_len == 0 )
3468*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3469*11fa71b9SJerome Forissier 
3470*11fa71b9SJerome Forissier     /*
3471*11fa71b9SJerome Forissier      * DTLS-related tests.
3472*11fa71b9SJerome Forissier      * Check epoch before checking length constraint because
3473*11fa71b9SJerome Forissier      * the latter varies with the epoch. E.g., if a ChangeCipherSpec
3474*11fa71b9SJerome Forissier      * message gets duplicated before the corresponding Finished message,
3475*11fa71b9SJerome Forissier      * the second ChangeCipherSpec should be discarded because it belongs
3476*11fa71b9SJerome Forissier      * to an old epoch, but not because its length is shorter than
3477*11fa71b9SJerome Forissier      * the minimum record length for packets using the new record transform.
3478*11fa71b9SJerome Forissier      * Note that these two kinds of failures are handled differently,
3479*11fa71b9SJerome Forissier      * as an unexpected record is silently skipped but an invalid
3480*11fa71b9SJerome Forissier      * record leads to the entire datagram being dropped.
3481*11fa71b9SJerome Forissier      */
3482*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
3483*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
3484*11fa71b9SJerome Forissier     {
3485*11fa71b9SJerome Forissier         rec_epoch = ( rec->ctr[0] << 8 ) | rec->ctr[1];
3486*11fa71b9SJerome Forissier 
3487*11fa71b9SJerome Forissier         /* Check that the datagram is large enough to contain a record
3488*11fa71b9SJerome Forissier          * of the advertised length. */
3489*11fa71b9SJerome Forissier         if( len < rec->data_offset + rec->data_len )
3490*11fa71b9SJerome Forissier         {
3491*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "Datagram of length %u too small to contain record of advertised length %u.",
3492*11fa71b9SJerome Forissier                              (unsigned) len,
3493*11fa71b9SJerome Forissier                              (unsigned)( rec->data_offset + rec->data_len ) ) );
3494*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3495*11fa71b9SJerome Forissier         }
3496*11fa71b9SJerome Forissier 
3497*11fa71b9SJerome Forissier         /* Records from other, non-matching epochs are silently discarded.
3498*11fa71b9SJerome Forissier          * (The case of same-port Client reconnects must be considered in
3499*11fa71b9SJerome Forissier          *  the caller). */
3500*11fa71b9SJerome Forissier         if( rec_epoch != ssl->in_epoch )
3501*11fa71b9SJerome Forissier         {
3502*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
3503*11fa71b9SJerome Forissier                                         "expected %d, received %d",
3504*11fa71b9SJerome Forissier                                         ssl->in_epoch, rec_epoch ) );
3505*11fa71b9SJerome Forissier 
3506*11fa71b9SJerome Forissier             /* Records from the next epoch are considered for buffering
3507*11fa71b9SJerome Forissier              * (concretely: early Finished messages). */
3508*11fa71b9SJerome Forissier             if( rec_epoch == (unsigned) ssl->in_epoch + 1 )
3509*11fa71b9SJerome Forissier             {
3510*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) );
3511*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
3512*11fa71b9SJerome Forissier             }
3513*11fa71b9SJerome Forissier 
3514*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
3515*11fa71b9SJerome Forissier         }
3516*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
3517*11fa71b9SJerome Forissier         /* For records from the correct epoch, check whether their
3518*11fa71b9SJerome Forissier          * sequence number has been seen before. */
3519*11fa71b9SJerome Forissier         else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl,
3520*11fa71b9SJerome Forissier             &rec->ctr[0] ) != 0 )
3521*11fa71b9SJerome Forissier         {
3522*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
3523*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
3524*11fa71b9SJerome Forissier         }
3525*11fa71b9SJerome Forissier #endif
3526*11fa71b9SJerome Forissier     }
3527*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
3528*11fa71b9SJerome Forissier 
3529*11fa71b9SJerome Forissier     return( 0 );
3530*11fa71b9SJerome Forissier }
3531*11fa71b9SJerome Forissier 
3532*11fa71b9SJerome Forissier 
3533*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
3534*11fa71b9SJerome Forissier static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl )
3535*11fa71b9SJerome Forissier {
3536*11fa71b9SJerome Forissier     unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
3537*11fa71b9SJerome Forissier 
3538*11fa71b9SJerome Forissier     /*
3539*11fa71b9SJerome Forissier      * Check for an epoch 0 ClientHello. We can't use in_msg here to
3540*11fa71b9SJerome Forissier      * access the first byte of record content (handshake type), as we
3541*11fa71b9SJerome Forissier      * have an active transform (possibly iv_len != 0), so use the
3542*11fa71b9SJerome Forissier      * fact that the record header len is 13 instead.
3543*11fa71b9SJerome Forissier      */
3544*11fa71b9SJerome Forissier     if( rec_epoch == 0 &&
3545*11fa71b9SJerome Forissier         ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
3546*11fa71b9SJerome Forissier         ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
3547*11fa71b9SJerome Forissier         ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
3548*11fa71b9SJerome Forissier         ssl->in_left > 13 &&
3549*11fa71b9SJerome Forissier         ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
3550*11fa71b9SJerome Forissier     {
3551*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
3552*11fa71b9SJerome Forissier                                     "from the same port" ) );
3553*11fa71b9SJerome Forissier         return( ssl_handle_possible_reconnect( ssl ) );
3554*11fa71b9SJerome Forissier     }
3555*11fa71b9SJerome Forissier 
3556*11fa71b9SJerome Forissier     return( 0 );
3557*11fa71b9SJerome Forissier }
3558*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
3559*11fa71b9SJerome Forissier 
3560*11fa71b9SJerome Forissier /*
3561*11fa71b9SJerome Forissier  * If applicable, decrypt record content
3562*11fa71b9SJerome Forissier  */
3563*11fa71b9SJerome Forissier static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
3564*11fa71b9SJerome Forissier                                        mbedtls_record *rec )
3565*11fa71b9SJerome Forissier {
3566*11fa71b9SJerome Forissier     int ret, done = 0;
3567*11fa71b9SJerome Forissier 
3568*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
3569*11fa71b9SJerome Forissier                            rec->buf, rec->buf_len );
3570*11fa71b9SJerome Forissier 
3571*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
3572*11fa71b9SJerome Forissier     if( mbedtls_ssl_hw_record_read != NULL )
3573*11fa71b9SJerome Forissier     {
3574*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
3575*11fa71b9SJerome Forissier 
3576*11fa71b9SJerome Forissier         ret = mbedtls_ssl_hw_record_read( ssl );
3577*11fa71b9SJerome Forissier         if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
3578*11fa71b9SJerome Forissier         {
3579*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
3580*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
3581*11fa71b9SJerome Forissier         }
3582*11fa71b9SJerome Forissier 
3583*11fa71b9SJerome Forissier         if( ret == 0 )
3584*11fa71b9SJerome Forissier             done = 1;
3585*11fa71b9SJerome Forissier     }
3586*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
3587*11fa71b9SJerome Forissier     if( !done && ssl->transform_in != NULL )
3588*11fa71b9SJerome Forissier     {
3589*11fa71b9SJerome Forissier         unsigned char const old_msg_type = rec->type;
3590*11fa71b9SJerome Forissier 
3591*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in,
3592*11fa71b9SJerome Forissier                                              rec ) ) != 0 )
3593*11fa71b9SJerome Forissier         {
3594*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
3595*11fa71b9SJerome Forissier 
3596*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3597*11fa71b9SJerome Forissier             if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
3598*11fa71b9SJerome Forissier                 ssl->conf->ignore_unexpected_cid
3599*11fa71b9SJerome Forissier                     == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE )
3600*11fa71b9SJerome Forissier             {
3601*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) );
3602*11fa71b9SJerome Forissier                 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
3603*11fa71b9SJerome Forissier             }
3604*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3605*11fa71b9SJerome Forissier 
3606*11fa71b9SJerome Forissier             return( ret );
3607*11fa71b9SJerome Forissier         }
3608*11fa71b9SJerome Forissier 
3609*11fa71b9SJerome Forissier         if( old_msg_type != rec->type )
3610*11fa71b9SJerome Forissier         {
3611*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d",
3612*11fa71b9SJerome Forissier                                         old_msg_type, rec->type ) );
3613*11fa71b9SJerome Forissier         }
3614*11fa71b9SJerome Forissier 
3615*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
3616*11fa71b9SJerome Forissier                                rec->buf + rec->data_offset, rec->data_len );
3617*11fa71b9SJerome Forissier 
3618*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3619*11fa71b9SJerome Forissier         /* We have already checked the record content type
3620*11fa71b9SJerome Forissier          * in ssl_parse_record_header(), failing or silently
3621*11fa71b9SJerome Forissier          * dropping the record in the case of an unknown type.
3622*11fa71b9SJerome Forissier          *
3623*11fa71b9SJerome Forissier          * Since with the use of CIDs, the record content type
3624*11fa71b9SJerome Forissier          * might change during decryption, re-check the record
3625*11fa71b9SJerome Forissier          * content type, but treat a failure as fatal this time. */
3626*11fa71b9SJerome Forissier         if( ssl_check_record_type( rec->type ) )
3627*11fa71b9SJerome Forissier         {
3628*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
3629*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3630*11fa71b9SJerome Forissier         }
3631*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3632*11fa71b9SJerome Forissier 
3633*11fa71b9SJerome Forissier         if( rec->data_len == 0 )
3634*11fa71b9SJerome Forissier         {
3635*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3636*11fa71b9SJerome Forissier             if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
3637*11fa71b9SJerome Forissier                 && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
3638*11fa71b9SJerome Forissier             {
3639*11fa71b9SJerome Forissier                 /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
3640*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
3641*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3642*11fa71b9SJerome Forissier             }
3643*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
3644*11fa71b9SJerome Forissier 
3645*11fa71b9SJerome Forissier             ssl->nb_zero++;
3646*11fa71b9SJerome Forissier 
3647*11fa71b9SJerome Forissier             /*
3648*11fa71b9SJerome Forissier              * Three or more empty messages may be a DoS attack
3649*11fa71b9SJerome Forissier              * (excessive CPU consumption).
3650*11fa71b9SJerome Forissier              */
3651*11fa71b9SJerome Forissier             if( ssl->nb_zero > 3 )
3652*11fa71b9SJerome Forissier             {
3653*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
3654*11fa71b9SJerome Forissier                                             "messages, possible DoS attack" ) );
3655*11fa71b9SJerome Forissier                 /* Treat the records as if they were not properly authenticated,
3656*11fa71b9SJerome Forissier                  * thereby failing the connection if we see more than allowed
3657*11fa71b9SJerome Forissier                  * by the configured bad MAC threshold. */
3658*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INVALID_MAC );
3659*11fa71b9SJerome Forissier             }
3660*11fa71b9SJerome Forissier         }
3661*11fa71b9SJerome Forissier         else
3662*11fa71b9SJerome Forissier             ssl->nb_zero = 0;
3663*11fa71b9SJerome Forissier 
3664*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
3665*11fa71b9SJerome Forissier         if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
3666*11fa71b9SJerome Forissier         {
3667*11fa71b9SJerome Forissier             ; /* in_ctr read from peer, not maintained internally */
3668*11fa71b9SJerome Forissier         }
3669*11fa71b9SJerome Forissier         else
3670*11fa71b9SJerome Forissier #endif
3671*11fa71b9SJerome Forissier         {
3672*11fa71b9SJerome Forissier             unsigned i;
3673*11fa71b9SJerome Forissier             for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
3674*11fa71b9SJerome Forissier                 if( ++ssl->in_ctr[i - 1] != 0 )
3675*11fa71b9SJerome Forissier                     break;
3676*11fa71b9SJerome Forissier 
3677*11fa71b9SJerome Forissier             /* The loop goes to its end iff the counter is wrapping */
3678*11fa71b9SJerome Forissier             if( i == mbedtls_ssl_ep_len( ssl ) )
3679*11fa71b9SJerome Forissier             {
3680*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
3681*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
3682*11fa71b9SJerome Forissier             }
3683*11fa71b9SJerome Forissier         }
3684*11fa71b9SJerome Forissier 
3685*11fa71b9SJerome Forissier     }
3686*11fa71b9SJerome Forissier 
3687*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
3688*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
3689*11fa71b9SJerome Forissier     {
3690*11fa71b9SJerome Forissier         mbedtls_ssl_dtls_replay_update( ssl );
3691*11fa71b9SJerome Forissier     }
3692*11fa71b9SJerome Forissier #endif
3693*11fa71b9SJerome Forissier 
3694*11fa71b9SJerome Forissier     /* Check actual (decrypted) record content length against
3695*11fa71b9SJerome Forissier      * configured maximum. */
3696*11fa71b9SJerome Forissier     if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
3697*11fa71b9SJerome Forissier     {
3698*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3699*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3700*11fa71b9SJerome Forissier     }
3701*11fa71b9SJerome Forissier 
3702*11fa71b9SJerome Forissier     return( 0 );
3703*11fa71b9SJerome Forissier }
3704*11fa71b9SJerome Forissier 
3705*11fa71b9SJerome Forissier /*
3706*11fa71b9SJerome Forissier  * Read a record.
3707*11fa71b9SJerome Forissier  *
3708*11fa71b9SJerome Forissier  * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
3709*11fa71b9SJerome Forissier  * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
3710*11fa71b9SJerome Forissier  *
3711*11fa71b9SJerome Forissier  */
3712*11fa71b9SJerome Forissier 
3713*11fa71b9SJerome Forissier /* Helper functions for mbedtls_ssl_read_record(). */
3714*11fa71b9SJerome Forissier static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
3715*11fa71b9SJerome Forissier static int ssl_get_next_record( mbedtls_ssl_context *ssl );
3716*11fa71b9SJerome Forissier static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
3717*11fa71b9SJerome Forissier 
3718*11fa71b9SJerome Forissier int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
3719*11fa71b9SJerome Forissier                              unsigned update_hs_digest )
3720*11fa71b9SJerome Forissier {
3721*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3722*11fa71b9SJerome Forissier 
3723*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
3724*11fa71b9SJerome Forissier 
3725*11fa71b9SJerome Forissier     if( ssl->keep_current_message == 0 )
3726*11fa71b9SJerome Forissier     {
3727*11fa71b9SJerome Forissier         do {
3728*11fa71b9SJerome Forissier 
3729*11fa71b9SJerome Forissier             ret = ssl_consume_current_message( ssl );
3730*11fa71b9SJerome Forissier             if( ret != 0 )
3731*11fa71b9SJerome Forissier                 return( ret );
3732*11fa71b9SJerome Forissier 
3733*11fa71b9SJerome Forissier             if( ssl_record_is_in_progress( ssl ) == 0 )
3734*11fa71b9SJerome Forissier             {
3735*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
3736*11fa71b9SJerome Forissier                 int have_buffered = 0;
3737*11fa71b9SJerome Forissier 
3738*11fa71b9SJerome Forissier                 /* We only check for buffered messages if the
3739*11fa71b9SJerome Forissier                  * current datagram is fully consumed. */
3740*11fa71b9SJerome Forissier                 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3741*11fa71b9SJerome Forissier                     ssl_next_record_is_in_datagram( ssl ) == 0 )
3742*11fa71b9SJerome Forissier                 {
3743*11fa71b9SJerome Forissier                     if( ssl_load_buffered_message( ssl ) == 0 )
3744*11fa71b9SJerome Forissier                         have_buffered = 1;
3745*11fa71b9SJerome Forissier                 }
3746*11fa71b9SJerome Forissier 
3747*11fa71b9SJerome Forissier                 if( have_buffered == 0 )
3748*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
3749*11fa71b9SJerome Forissier                 {
3750*11fa71b9SJerome Forissier                     ret = ssl_get_next_record( ssl );
3751*11fa71b9SJerome Forissier                     if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
3752*11fa71b9SJerome Forissier                         continue;
3753*11fa71b9SJerome Forissier 
3754*11fa71b9SJerome Forissier                     if( ret != 0 )
3755*11fa71b9SJerome Forissier                     {
3756*11fa71b9SJerome Forissier                         MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
3757*11fa71b9SJerome Forissier                         return( ret );
3758*11fa71b9SJerome Forissier                     }
3759*11fa71b9SJerome Forissier                 }
3760*11fa71b9SJerome Forissier             }
3761*11fa71b9SJerome Forissier 
3762*11fa71b9SJerome Forissier             ret = mbedtls_ssl_handle_message_type( ssl );
3763*11fa71b9SJerome Forissier 
3764*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
3765*11fa71b9SJerome Forissier             if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
3766*11fa71b9SJerome Forissier             {
3767*11fa71b9SJerome Forissier                 /* Buffer future message */
3768*11fa71b9SJerome Forissier                 ret = ssl_buffer_message( ssl );
3769*11fa71b9SJerome Forissier                 if( ret != 0 )
3770*11fa71b9SJerome Forissier                     return( ret );
3771*11fa71b9SJerome Forissier 
3772*11fa71b9SJerome Forissier                 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
3773*11fa71b9SJerome Forissier             }
3774*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
3775*11fa71b9SJerome Forissier 
3776*11fa71b9SJerome Forissier         } while( MBEDTLS_ERR_SSL_NON_FATAL           == ret  ||
3777*11fa71b9SJerome Forissier                  MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret );
3778*11fa71b9SJerome Forissier 
3779*11fa71b9SJerome Forissier         if( 0 != ret )
3780*11fa71b9SJerome Forissier         {
3781*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
3782*11fa71b9SJerome Forissier             return( ret );
3783*11fa71b9SJerome Forissier         }
3784*11fa71b9SJerome Forissier 
3785*11fa71b9SJerome Forissier         if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
3786*11fa71b9SJerome Forissier             update_hs_digest == 1 )
3787*11fa71b9SJerome Forissier         {
3788*11fa71b9SJerome Forissier             mbedtls_ssl_update_handshake_status( ssl );
3789*11fa71b9SJerome Forissier         }
3790*11fa71b9SJerome Forissier     }
3791*11fa71b9SJerome Forissier     else
3792*11fa71b9SJerome Forissier     {
3793*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
3794*11fa71b9SJerome Forissier         ssl->keep_current_message = 0;
3795*11fa71b9SJerome Forissier     }
3796*11fa71b9SJerome Forissier 
3797*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
3798*11fa71b9SJerome Forissier 
3799*11fa71b9SJerome Forissier     return( 0 );
3800*11fa71b9SJerome Forissier }
3801*11fa71b9SJerome Forissier 
3802*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
3803*11fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
3804*11fa71b9SJerome Forissier {
3805*11fa71b9SJerome Forissier     if( ssl->in_left > ssl->next_record_offset )
3806*11fa71b9SJerome Forissier         return( 1 );
3807*11fa71b9SJerome Forissier 
3808*11fa71b9SJerome Forissier     return( 0 );
3809*11fa71b9SJerome Forissier }
3810*11fa71b9SJerome Forissier 
3811*11fa71b9SJerome Forissier static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
3812*11fa71b9SJerome Forissier {
3813*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
3814*11fa71b9SJerome Forissier     mbedtls_ssl_hs_buffer * hs_buf;
3815*11fa71b9SJerome Forissier     int ret = 0;
3816*11fa71b9SJerome Forissier 
3817*11fa71b9SJerome Forissier     if( hs == NULL )
3818*11fa71b9SJerome Forissier         return( -1 );
3819*11fa71b9SJerome Forissier 
3820*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) );
3821*11fa71b9SJerome Forissier 
3822*11fa71b9SJerome Forissier     if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
3823*11fa71b9SJerome Forissier         ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
3824*11fa71b9SJerome Forissier     {
3825*11fa71b9SJerome Forissier         /* Check if we have seen a ChangeCipherSpec before.
3826*11fa71b9SJerome Forissier          * If yes, synthesize a CCS record. */
3827*11fa71b9SJerome Forissier         if( !hs->buffering.seen_ccs )
3828*11fa71b9SJerome Forissier         {
3829*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) );
3830*11fa71b9SJerome Forissier             ret = -1;
3831*11fa71b9SJerome Forissier             goto exit;
3832*11fa71b9SJerome Forissier         }
3833*11fa71b9SJerome Forissier 
3834*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) );
3835*11fa71b9SJerome Forissier         ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
3836*11fa71b9SJerome Forissier         ssl->in_msglen = 1;
3837*11fa71b9SJerome Forissier         ssl->in_msg[0] = 1;
3838*11fa71b9SJerome Forissier 
3839*11fa71b9SJerome Forissier         /* As long as they are equal, the exact value doesn't matter. */
3840*11fa71b9SJerome Forissier         ssl->in_left            = 0;
3841*11fa71b9SJerome Forissier         ssl->next_record_offset = 0;
3842*11fa71b9SJerome Forissier 
3843*11fa71b9SJerome Forissier         hs->buffering.seen_ccs = 0;
3844*11fa71b9SJerome Forissier         goto exit;
3845*11fa71b9SJerome Forissier     }
3846*11fa71b9SJerome Forissier 
3847*11fa71b9SJerome Forissier #if defined(MBEDTLS_DEBUG_C)
3848*11fa71b9SJerome Forissier     /* Debug only */
3849*11fa71b9SJerome Forissier     {
3850*11fa71b9SJerome Forissier         unsigned offset;
3851*11fa71b9SJerome Forissier         for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
3852*11fa71b9SJerome Forissier         {
3853*11fa71b9SJerome Forissier             hs_buf = &hs->buffering.hs[offset];
3854*11fa71b9SJerome Forissier             if( hs_buf->is_valid == 1 )
3855*11fa71b9SJerome Forissier             {
3856*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.",
3857*11fa71b9SJerome Forissier                             hs->in_msg_seq + offset,
3858*11fa71b9SJerome Forissier                             hs_buf->is_complete ? "fully" : "partially" ) );
3859*11fa71b9SJerome Forissier             }
3860*11fa71b9SJerome Forissier         }
3861*11fa71b9SJerome Forissier     }
3862*11fa71b9SJerome Forissier #endif /* MBEDTLS_DEBUG_C */
3863*11fa71b9SJerome Forissier 
3864*11fa71b9SJerome Forissier     /* Check if we have buffered and/or fully reassembled the
3865*11fa71b9SJerome Forissier      * next handshake message. */
3866*11fa71b9SJerome Forissier     hs_buf = &hs->buffering.hs[0];
3867*11fa71b9SJerome Forissier     if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) )
3868*11fa71b9SJerome Forissier     {
3869*11fa71b9SJerome Forissier         /* Synthesize a record containing the buffered HS message. */
3870*11fa71b9SJerome Forissier         size_t msg_len = ( hs_buf->data[1] << 16 ) |
3871*11fa71b9SJerome Forissier                          ( hs_buf->data[2] << 8  ) |
3872*11fa71b9SJerome Forissier                            hs_buf->data[3];
3873*11fa71b9SJerome Forissier 
3874*11fa71b9SJerome Forissier         /* Double-check that we haven't accidentally buffered
3875*11fa71b9SJerome Forissier          * a message that doesn't fit into the input buffer. */
3876*11fa71b9SJerome Forissier         if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
3877*11fa71b9SJerome Forissier         {
3878*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
3879*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
3880*11fa71b9SJerome Forissier         }
3881*11fa71b9SJerome Forissier 
3882*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) );
3883*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)",
3884*11fa71b9SJerome Forissier                                hs_buf->data, msg_len + 12 );
3885*11fa71b9SJerome Forissier 
3886*11fa71b9SJerome Forissier         ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3887*11fa71b9SJerome Forissier         ssl->in_hslen   = msg_len + 12;
3888*11fa71b9SJerome Forissier         ssl->in_msglen  = msg_len + 12;
3889*11fa71b9SJerome Forissier         memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen );
3890*11fa71b9SJerome Forissier 
3891*11fa71b9SJerome Forissier         ret = 0;
3892*11fa71b9SJerome Forissier         goto exit;
3893*11fa71b9SJerome Forissier     }
3894*11fa71b9SJerome Forissier     else
3895*11fa71b9SJerome Forissier     {
3896*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered",
3897*11fa71b9SJerome Forissier                                     hs->in_msg_seq ) );
3898*11fa71b9SJerome Forissier     }
3899*11fa71b9SJerome Forissier 
3900*11fa71b9SJerome Forissier     ret = -1;
3901*11fa71b9SJerome Forissier 
3902*11fa71b9SJerome Forissier exit:
3903*11fa71b9SJerome Forissier 
3904*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) );
3905*11fa71b9SJerome Forissier     return( ret );
3906*11fa71b9SJerome Forissier }
3907*11fa71b9SJerome Forissier 
3908*11fa71b9SJerome Forissier static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
3909*11fa71b9SJerome Forissier                                   size_t desired )
3910*11fa71b9SJerome Forissier {
3911*11fa71b9SJerome Forissier     int offset;
3912*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
3913*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available",
3914*11fa71b9SJerome Forissier                                 (unsigned) desired ) );
3915*11fa71b9SJerome Forissier 
3916*11fa71b9SJerome Forissier     /* Get rid of future records epoch first, if such exist. */
3917*11fa71b9SJerome Forissier     ssl_free_buffered_record( ssl );
3918*11fa71b9SJerome Forissier 
3919*11fa71b9SJerome Forissier     /* Check if we have enough space available now. */
3920*11fa71b9SJerome Forissier     if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
3921*11fa71b9SJerome Forissier                      hs->buffering.total_bytes_buffered ) )
3922*11fa71b9SJerome Forissier     {
3923*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) );
3924*11fa71b9SJerome Forissier         return( 0 );
3925*11fa71b9SJerome Forissier     }
3926*11fa71b9SJerome Forissier 
3927*11fa71b9SJerome Forissier     /* We don't have enough space to buffer the next expected handshake
3928*11fa71b9SJerome Forissier      * message. Remove buffers used for future messages to gain space,
3929*11fa71b9SJerome Forissier      * starting with the most distant one. */
3930*11fa71b9SJerome Forissier     for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
3931*11fa71b9SJerome Forissier          offset >= 0; offset-- )
3932*11fa71b9SJerome Forissier     {
3933*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message",
3934*11fa71b9SJerome Forissier                                     offset ) );
3935*11fa71b9SJerome Forissier 
3936*11fa71b9SJerome Forissier         ssl_buffering_free_slot( ssl, (uint8_t) offset );
3937*11fa71b9SJerome Forissier 
3938*11fa71b9SJerome Forissier         /* Check if we have enough space available now. */
3939*11fa71b9SJerome Forissier         if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
3940*11fa71b9SJerome Forissier                          hs->buffering.total_bytes_buffered ) )
3941*11fa71b9SJerome Forissier         {
3942*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) );
3943*11fa71b9SJerome Forissier             return( 0 );
3944*11fa71b9SJerome Forissier         }
3945*11fa71b9SJerome Forissier     }
3946*11fa71b9SJerome Forissier 
3947*11fa71b9SJerome Forissier     return( -1 );
3948*11fa71b9SJerome Forissier }
3949*11fa71b9SJerome Forissier 
3950*11fa71b9SJerome Forissier static int ssl_buffer_message( mbedtls_ssl_context *ssl )
3951*11fa71b9SJerome Forissier {
3952*11fa71b9SJerome Forissier     int ret = 0;
3953*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
3954*11fa71b9SJerome Forissier 
3955*11fa71b9SJerome Forissier     if( hs == NULL )
3956*11fa71b9SJerome Forissier         return( 0 );
3957*11fa71b9SJerome Forissier 
3958*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) );
3959*11fa71b9SJerome Forissier 
3960*11fa71b9SJerome Forissier     switch( ssl->in_msgtype )
3961*11fa71b9SJerome Forissier     {
3962*11fa71b9SJerome Forissier         case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
3963*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) );
3964*11fa71b9SJerome Forissier 
3965*11fa71b9SJerome Forissier             hs->buffering.seen_ccs = 1;
3966*11fa71b9SJerome Forissier             break;
3967*11fa71b9SJerome Forissier 
3968*11fa71b9SJerome Forissier         case MBEDTLS_SSL_MSG_HANDSHAKE:
3969*11fa71b9SJerome Forissier         {
3970*11fa71b9SJerome Forissier             unsigned recv_msg_seq_offset;
3971*11fa71b9SJerome Forissier             unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
3972*11fa71b9SJerome Forissier             mbedtls_ssl_hs_buffer *hs_buf;
3973*11fa71b9SJerome Forissier             size_t msg_len = ssl->in_hslen - 12;
3974*11fa71b9SJerome Forissier 
3975*11fa71b9SJerome Forissier             /* We should never receive an old handshake
3976*11fa71b9SJerome Forissier              * message - double-check nonetheless. */
3977*11fa71b9SJerome Forissier             if( recv_msg_seq < ssl->handshake->in_msg_seq )
3978*11fa71b9SJerome Forissier             {
3979*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
3980*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
3981*11fa71b9SJerome Forissier             }
3982*11fa71b9SJerome Forissier 
3983*11fa71b9SJerome Forissier             recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
3984*11fa71b9SJerome Forissier             if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS )
3985*11fa71b9SJerome Forissier             {
3986*11fa71b9SJerome Forissier                 /* Silently ignore -- message too far in the future */
3987*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2,
3988*11fa71b9SJerome Forissier                  ( "Ignore future HS message with sequence number %u, "
3989*11fa71b9SJerome Forissier                    "buffering window %u - %u",
3990*11fa71b9SJerome Forissier                    recv_msg_seq, ssl->handshake->in_msg_seq,
3991*11fa71b9SJerome Forissier                    ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) );
3992*11fa71b9SJerome Forissier 
3993*11fa71b9SJerome Forissier                 goto exit;
3994*11fa71b9SJerome Forissier             }
3995*11fa71b9SJerome Forissier 
3996*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ",
3997*11fa71b9SJerome Forissier                                         recv_msg_seq, recv_msg_seq_offset ) );
3998*11fa71b9SJerome Forissier 
3999*11fa71b9SJerome Forissier             hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ];
4000*11fa71b9SJerome Forissier 
4001*11fa71b9SJerome Forissier             /* Check if the buffering for this seq nr has already commenced. */
4002*11fa71b9SJerome Forissier             if( !hs_buf->is_valid )
4003*11fa71b9SJerome Forissier             {
4004*11fa71b9SJerome Forissier                 size_t reassembly_buf_sz;
4005*11fa71b9SJerome Forissier 
4006*11fa71b9SJerome Forissier                 hs_buf->is_fragmented =
4007*11fa71b9SJerome Forissier                     ( ssl_hs_is_proper_fragment( ssl ) == 1 );
4008*11fa71b9SJerome Forissier 
4009*11fa71b9SJerome Forissier                 /* We copy the message back into the input buffer
4010*11fa71b9SJerome Forissier                  * after reassembly, so check that it's not too large.
4011*11fa71b9SJerome Forissier                  * This is an implementation-specific limitation
4012*11fa71b9SJerome Forissier                  * and not one from the standard, hence it is not
4013*11fa71b9SJerome Forissier                  * checked in ssl_check_hs_header(). */
4014*11fa71b9SJerome Forissier                 if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
4015*11fa71b9SJerome Forissier                 {
4016*11fa71b9SJerome Forissier                     /* Ignore message */
4017*11fa71b9SJerome Forissier                     goto exit;
4018*11fa71b9SJerome Forissier                 }
4019*11fa71b9SJerome Forissier 
4020*11fa71b9SJerome Forissier                 /* Check if we have enough space to buffer the message. */
4021*11fa71b9SJerome Forissier                 if( hs->buffering.total_bytes_buffered >
4022*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DTLS_MAX_BUFFERING )
4023*11fa71b9SJerome Forissier                 {
4024*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
4025*11fa71b9SJerome Forissier                     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
4026*11fa71b9SJerome Forissier                 }
4027*11fa71b9SJerome Forissier 
4028*11fa71b9SJerome Forissier                 reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
4029*11fa71b9SJerome Forissier                                                        hs_buf->is_fragmented );
4030*11fa71b9SJerome Forissier 
4031*11fa71b9SJerome Forissier                 if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4032*11fa71b9SJerome Forissier                                           hs->buffering.total_bytes_buffered ) )
4033*11fa71b9SJerome Forissier                 {
4034*11fa71b9SJerome Forissier                     if( recv_msg_seq_offset > 0 )
4035*11fa71b9SJerome Forissier                     {
4036*11fa71b9SJerome Forissier                         /* If we can't buffer a future message because
4037*11fa71b9SJerome Forissier                          * of space limitations -- ignore. */
4038*11fa71b9SJerome Forissier                         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
4039*11fa71b9SJerome Forissier                              (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4040*11fa71b9SJerome Forissier                              (unsigned) hs->buffering.total_bytes_buffered ) );
4041*11fa71b9SJerome Forissier                         goto exit;
4042*11fa71b9SJerome Forissier                     }
4043*11fa71b9SJerome Forissier                     else
4044*11fa71b9SJerome Forissier                     {
4045*11fa71b9SJerome Forissier                         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n",
4046*11fa71b9SJerome Forissier                              (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4047*11fa71b9SJerome Forissier                              (unsigned) hs->buffering.total_bytes_buffered ) );
4048*11fa71b9SJerome Forissier                     }
4049*11fa71b9SJerome Forissier 
4050*11fa71b9SJerome Forissier                     if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 )
4051*11fa71b9SJerome Forissier                     {
4052*11fa71b9SJerome Forissier                         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n",
4053*11fa71b9SJerome Forissier                              (unsigned) msg_len,
4054*11fa71b9SJerome Forissier                              (unsigned) reassembly_buf_sz,
4055*11fa71b9SJerome Forissier                              MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4056*11fa71b9SJerome Forissier                              (unsigned) hs->buffering.total_bytes_buffered ) );
4057*11fa71b9SJerome Forissier                         ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
4058*11fa71b9SJerome Forissier                         goto exit;
4059*11fa71b9SJerome Forissier                     }
4060*11fa71b9SJerome Forissier                 }
4061*11fa71b9SJerome Forissier 
4062*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d",
4063*11fa71b9SJerome Forissier                                             msg_len ) );
4064*11fa71b9SJerome Forissier 
4065*11fa71b9SJerome Forissier                 hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
4066*11fa71b9SJerome Forissier                 if( hs_buf->data == NULL )
4067*11fa71b9SJerome Forissier                 {
4068*11fa71b9SJerome Forissier                     ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
4069*11fa71b9SJerome Forissier                     goto exit;
4070*11fa71b9SJerome Forissier                 }
4071*11fa71b9SJerome Forissier                 hs_buf->data_len = reassembly_buf_sz;
4072*11fa71b9SJerome Forissier 
4073*11fa71b9SJerome Forissier                 /* Prepare final header: copy msg_type, length and message_seq,
4074*11fa71b9SJerome Forissier                  * then add standardised fragment_offset and fragment_length */
4075*11fa71b9SJerome Forissier                 memcpy( hs_buf->data, ssl->in_msg, 6 );
4076*11fa71b9SJerome Forissier                 memset( hs_buf->data + 6, 0, 3 );
4077*11fa71b9SJerome Forissier                 memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
4078*11fa71b9SJerome Forissier 
4079*11fa71b9SJerome Forissier                 hs_buf->is_valid = 1;
4080*11fa71b9SJerome Forissier 
4081*11fa71b9SJerome Forissier                 hs->buffering.total_bytes_buffered += reassembly_buf_sz;
4082*11fa71b9SJerome Forissier             }
4083*11fa71b9SJerome Forissier             else
4084*11fa71b9SJerome Forissier             {
4085*11fa71b9SJerome Forissier                 /* Make sure msg_type and length are consistent */
4086*11fa71b9SJerome Forissier                 if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 )
4087*11fa71b9SJerome Forissier                 {
4088*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) );
4089*11fa71b9SJerome Forissier                     /* Ignore */
4090*11fa71b9SJerome Forissier                     goto exit;
4091*11fa71b9SJerome Forissier                 }
4092*11fa71b9SJerome Forissier             }
4093*11fa71b9SJerome Forissier 
4094*11fa71b9SJerome Forissier             if( !hs_buf->is_complete )
4095*11fa71b9SJerome Forissier             {
4096*11fa71b9SJerome Forissier                 size_t frag_len, frag_off;
4097*11fa71b9SJerome Forissier                 unsigned char * const msg = hs_buf->data + 12;
4098*11fa71b9SJerome Forissier 
4099*11fa71b9SJerome Forissier                 /*
4100*11fa71b9SJerome Forissier                  * Check and copy current fragment
4101*11fa71b9SJerome Forissier                  */
4102*11fa71b9SJerome Forissier 
4103*11fa71b9SJerome Forissier                 /* Validation of header fields already done in
4104*11fa71b9SJerome Forissier                  * mbedtls_ssl_prepare_handshake_record(). */
4105*11fa71b9SJerome Forissier                 frag_off = ssl_get_hs_frag_off( ssl );
4106*11fa71b9SJerome Forissier                 frag_len = ssl_get_hs_frag_len( ssl );
4107*11fa71b9SJerome Forissier 
4108*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d",
4109*11fa71b9SJerome Forissier                                             frag_off, frag_len ) );
4110*11fa71b9SJerome Forissier                 memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
4111*11fa71b9SJerome Forissier 
4112*11fa71b9SJerome Forissier                 if( hs_buf->is_fragmented )
4113*11fa71b9SJerome Forissier                 {
4114*11fa71b9SJerome Forissier                     unsigned char * const bitmask = msg + msg_len;
4115*11fa71b9SJerome Forissier                     ssl_bitmask_set( bitmask, frag_off, frag_len );
4116*11fa71b9SJerome Forissier                     hs_buf->is_complete = ( ssl_bitmask_check( bitmask,
4117*11fa71b9SJerome Forissier                                                                msg_len ) == 0 );
4118*11fa71b9SJerome Forissier                 }
4119*11fa71b9SJerome Forissier                 else
4120*11fa71b9SJerome Forissier                 {
4121*11fa71b9SJerome Forissier                     hs_buf->is_complete = 1;
4122*11fa71b9SJerome Forissier                 }
4123*11fa71b9SJerome Forissier 
4124*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete",
4125*11fa71b9SJerome Forissier                                    hs_buf->is_complete ? "" : "not yet " ) );
4126*11fa71b9SJerome Forissier             }
4127*11fa71b9SJerome Forissier 
4128*11fa71b9SJerome Forissier             break;
4129*11fa71b9SJerome Forissier         }
4130*11fa71b9SJerome Forissier 
4131*11fa71b9SJerome Forissier         default:
4132*11fa71b9SJerome Forissier             /* We don't buffer other types of messages. */
4133*11fa71b9SJerome Forissier             break;
4134*11fa71b9SJerome Forissier     }
4135*11fa71b9SJerome Forissier 
4136*11fa71b9SJerome Forissier exit:
4137*11fa71b9SJerome Forissier 
4138*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) );
4139*11fa71b9SJerome Forissier     return( ret );
4140*11fa71b9SJerome Forissier }
4141*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
4142*11fa71b9SJerome Forissier 
4143*11fa71b9SJerome Forissier static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
4144*11fa71b9SJerome Forissier {
4145*11fa71b9SJerome Forissier     /*
4146*11fa71b9SJerome Forissier      * Consume last content-layer message and potentially
4147*11fa71b9SJerome Forissier      * update in_msglen which keeps track of the contents'
4148*11fa71b9SJerome Forissier      * consumption state.
4149*11fa71b9SJerome Forissier      *
4150*11fa71b9SJerome Forissier      * (1) Handshake messages:
4151*11fa71b9SJerome Forissier      *     Remove last handshake message, move content
4152*11fa71b9SJerome Forissier      *     and adapt in_msglen.
4153*11fa71b9SJerome Forissier      *
4154*11fa71b9SJerome Forissier      * (2) Alert messages:
4155*11fa71b9SJerome Forissier      *     Consume whole record content, in_msglen = 0.
4156*11fa71b9SJerome Forissier      *
4157*11fa71b9SJerome Forissier      * (3) Change cipher spec:
4158*11fa71b9SJerome Forissier      *     Consume whole record content, in_msglen = 0.
4159*11fa71b9SJerome Forissier      *
4160*11fa71b9SJerome Forissier      * (4) Application data:
4161*11fa71b9SJerome Forissier      *     Don't do anything - the record layer provides
4162*11fa71b9SJerome Forissier      *     the application data as a stream transport
4163*11fa71b9SJerome Forissier      *     and consumes through mbedtls_ssl_read only.
4164*11fa71b9SJerome Forissier      *
4165*11fa71b9SJerome Forissier      */
4166*11fa71b9SJerome Forissier 
4167*11fa71b9SJerome Forissier     /* Case (1): Handshake messages */
4168*11fa71b9SJerome Forissier     if( ssl->in_hslen != 0 )
4169*11fa71b9SJerome Forissier     {
4170*11fa71b9SJerome Forissier         /* Hard assertion to be sure that no application data
4171*11fa71b9SJerome Forissier          * is in flight, as corrupting ssl->in_msglen during
4172*11fa71b9SJerome Forissier          * ssl->in_offt != NULL is fatal. */
4173*11fa71b9SJerome Forissier         if( ssl->in_offt != NULL )
4174*11fa71b9SJerome Forissier         {
4175*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
4176*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
4177*11fa71b9SJerome Forissier         }
4178*11fa71b9SJerome Forissier 
4179*11fa71b9SJerome Forissier         /*
4180*11fa71b9SJerome Forissier          * Get next Handshake message in the current record
4181*11fa71b9SJerome Forissier          */
4182*11fa71b9SJerome Forissier 
4183*11fa71b9SJerome Forissier         /* Notes:
4184*11fa71b9SJerome Forissier          * (1) in_hslen is not necessarily the size of the
4185*11fa71b9SJerome Forissier          *     current handshake content: If DTLS handshake
4186*11fa71b9SJerome Forissier          *     fragmentation is used, that's the fragment
4187*11fa71b9SJerome Forissier          *     size instead. Using the total handshake message
4188*11fa71b9SJerome Forissier          *     size here is faulty and should be changed at
4189*11fa71b9SJerome Forissier          *     some point.
4190*11fa71b9SJerome Forissier          * (2) While it doesn't seem to cause problems, one
4191*11fa71b9SJerome Forissier          *     has to be very careful not to assume that in_hslen
4192*11fa71b9SJerome Forissier          *     is always <= in_msglen in a sensible communication.
4193*11fa71b9SJerome Forissier          *     Again, it's wrong for DTLS handshake fragmentation.
4194*11fa71b9SJerome Forissier          *     The following check is therefore mandatory, and
4195*11fa71b9SJerome Forissier          *     should not be treated as a silently corrected assertion.
4196*11fa71b9SJerome Forissier          *     Additionally, ssl->in_hslen might be arbitrarily out of
4197*11fa71b9SJerome Forissier          *     bounds after handling a DTLS message with an unexpected
4198*11fa71b9SJerome Forissier          *     sequence number, see mbedtls_ssl_prepare_handshake_record.
4199*11fa71b9SJerome Forissier          */
4200*11fa71b9SJerome Forissier         if( ssl->in_hslen < ssl->in_msglen )
4201*11fa71b9SJerome Forissier         {
4202*11fa71b9SJerome Forissier             ssl->in_msglen -= ssl->in_hslen;
4203*11fa71b9SJerome Forissier             memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
4204*11fa71b9SJerome Forissier                      ssl->in_msglen );
4205*11fa71b9SJerome Forissier 
4206*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
4207*11fa71b9SJerome Forissier                                    ssl->in_msg, ssl->in_msglen );
4208*11fa71b9SJerome Forissier         }
4209*11fa71b9SJerome Forissier         else
4210*11fa71b9SJerome Forissier         {
4211*11fa71b9SJerome Forissier             ssl->in_msglen = 0;
4212*11fa71b9SJerome Forissier         }
4213*11fa71b9SJerome Forissier 
4214*11fa71b9SJerome Forissier         ssl->in_hslen   = 0;
4215*11fa71b9SJerome Forissier     }
4216*11fa71b9SJerome Forissier     /* Case (4): Application data */
4217*11fa71b9SJerome Forissier     else if( ssl->in_offt != NULL )
4218*11fa71b9SJerome Forissier     {
4219*11fa71b9SJerome Forissier         return( 0 );
4220*11fa71b9SJerome Forissier     }
4221*11fa71b9SJerome Forissier     /* Everything else (CCS & Alerts) */
4222*11fa71b9SJerome Forissier     else
4223*11fa71b9SJerome Forissier     {
4224*11fa71b9SJerome Forissier         ssl->in_msglen = 0;
4225*11fa71b9SJerome Forissier     }
4226*11fa71b9SJerome Forissier 
4227*11fa71b9SJerome Forissier     return( 0 );
4228*11fa71b9SJerome Forissier }
4229*11fa71b9SJerome Forissier 
4230*11fa71b9SJerome Forissier static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
4231*11fa71b9SJerome Forissier {
4232*11fa71b9SJerome Forissier     if( ssl->in_msglen > 0 )
4233*11fa71b9SJerome Forissier         return( 1 );
4234*11fa71b9SJerome Forissier 
4235*11fa71b9SJerome Forissier     return( 0 );
4236*11fa71b9SJerome Forissier }
4237*11fa71b9SJerome Forissier 
4238*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4239*11fa71b9SJerome Forissier 
4240*11fa71b9SJerome Forissier static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
4241*11fa71b9SJerome Forissier {
4242*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4243*11fa71b9SJerome Forissier     if( hs == NULL )
4244*11fa71b9SJerome Forissier         return;
4245*11fa71b9SJerome Forissier 
4246*11fa71b9SJerome Forissier     if( hs->buffering.future_record.data != NULL )
4247*11fa71b9SJerome Forissier     {
4248*11fa71b9SJerome Forissier         hs->buffering.total_bytes_buffered -=
4249*11fa71b9SJerome Forissier             hs->buffering.future_record.len;
4250*11fa71b9SJerome Forissier 
4251*11fa71b9SJerome Forissier         mbedtls_free( hs->buffering.future_record.data );
4252*11fa71b9SJerome Forissier         hs->buffering.future_record.data = NULL;
4253*11fa71b9SJerome Forissier     }
4254*11fa71b9SJerome Forissier }
4255*11fa71b9SJerome Forissier 
4256*11fa71b9SJerome Forissier static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
4257*11fa71b9SJerome Forissier {
4258*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4259*11fa71b9SJerome Forissier     unsigned char * rec;
4260*11fa71b9SJerome Forissier     size_t rec_len;
4261*11fa71b9SJerome Forissier     unsigned rec_epoch;
4262*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
4263*11fa71b9SJerome Forissier     size_t in_buf_len = ssl->in_buf_len;
4264*11fa71b9SJerome Forissier #else
4265*11fa71b9SJerome Forissier     size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
4266*11fa71b9SJerome Forissier #endif
4267*11fa71b9SJerome Forissier     if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4268*11fa71b9SJerome Forissier         return( 0 );
4269*11fa71b9SJerome Forissier 
4270*11fa71b9SJerome Forissier     if( hs == NULL )
4271*11fa71b9SJerome Forissier         return( 0 );
4272*11fa71b9SJerome Forissier 
4273*11fa71b9SJerome Forissier     rec       = hs->buffering.future_record.data;
4274*11fa71b9SJerome Forissier     rec_len   = hs->buffering.future_record.len;
4275*11fa71b9SJerome Forissier     rec_epoch = hs->buffering.future_record.epoch;
4276*11fa71b9SJerome Forissier 
4277*11fa71b9SJerome Forissier     if( rec == NULL )
4278*11fa71b9SJerome Forissier         return( 0 );
4279*11fa71b9SJerome Forissier 
4280*11fa71b9SJerome Forissier     /* Only consider loading future records if the
4281*11fa71b9SJerome Forissier      * input buffer is empty. */
4282*11fa71b9SJerome Forissier     if( ssl_next_record_is_in_datagram( ssl ) == 1 )
4283*11fa71b9SJerome Forissier         return( 0 );
4284*11fa71b9SJerome Forissier 
4285*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) );
4286*11fa71b9SJerome Forissier 
4287*11fa71b9SJerome Forissier     if( rec_epoch != ssl->in_epoch )
4288*11fa71b9SJerome Forissier     {
4289*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) );
4290*11fa71b9SJerome Forissier         goto exit;
4291*11fa71b9SJerome Forissier     }
4292*11fa71b9SJerome Forissier 
4293*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
4294*11fa71b9SJerome Forissier 
4295*11fa71b9SJerome Forissier     /* Double-check that the record is not too large */
4296*11fa71b9SJerome Forissier     if( rec_len > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
4297*11fa71b9SJerome Forissier     {
4298*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
4299*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
4300*11fa71b9SJerome Forissier     }
4301*11fa71b9SJerome Forissier 
4302*11fa71b9SJerome Forissier     memcpy( ssl->in_hdr, rec, rec_len );
4303*11fa71b9SJerome Forissier     ssl->in_left = rec_len;
4304*11fa71b9SJerome Forissier     ssl->next_record_offset = 0;
4305*11fa71b9SJerome Forissier 
4306*11fa71b9SJerome Forissier     ssl_free_buffered_record( ssl );
4307*11fa71b9SJerome Forissier 
4308*11fa71b9SJerome Forissier exit:
4309*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) );
4310*11fa71b9SJerome Forissier     return( 0 );
4311*11fa71b9SJerome Forissier }
4312*11fa71b9SJerome Forissier 
4313*11fa71b9SJerome Forissier static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
4314*11fa71b9SJerome Forissier                                      mbedtls_record const *rec )
4315*11fa71b9SJerome Forissier {
4316*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4317*11fa71b9SJerome Forissier 
4318*11fa71b9SJerome Forissier     /* Don't buffer future records outside handshakes. */
4319*11fa71b9SJerome Forissier     if( hs == NULL )
4320*11fa71b9SJerome Forissier         return( 0 );
4321*11fa71b9SJerome Forissier 
4322*11fa71b9SJerome Forissier     /* Only buffer handshake records (we are only interested
4323*11fa71b9SJerome Forissier      * in Finished messages). */
4324*11fa71b9SJerome Forissier     if( rec->type != MBEDTLS_SSL_MSG_HANDSHAKE )
4325*11fa71b9SJerome Forissier         return( 0 );
4326*11fa71b9SJerome Forissier 
4327*11fa71b9SJerome Forissier     /* Don't buffer more than one future epoch record. */
4328*11fa71b9SJerome Forissier     if( hs->buffering.future_record.data != NULL )
4329*11fa71b9SJerome Forissier         return( 0 );
4330*11fa71b9SJerome Forissier 
4331*11fa71b9SJerome Forissier     /* Don't buffer record if there's not enough buffering space remaining. */
4332*11fa71b9SJerome Forissier     if( rec->buf_len > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4333*11fa71b9SJerome Forissier                          hs->buffering.total_bytes_buffered ) )
4334*11fa71b9SJerome Forissier     {
4335*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
4336*11fa71b9SJerome Forissier                         (unsigned) rec->buf_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4337*11fa71b9SJerome Forissier                         (unsigned) hs->buffering.total_bytes_buffered ) );
4338*11fa71b9SJerome Forissier         return( 0 );
4339*11fa71b9SJerome Forissier     }
4340*11fa71b9SJerome Forissier 
4341*11fa71b9SJerome Forissier     /* Buffer record */
4342*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u",
4343*11fa71b9SJerome Forissier                                 ssl->in_epoch + 1 ) );
4344*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", rec->buf, rec->buf_len );
4345*11fa71b9SJerome Forissier 
4346*11fa71b9SJerome Forissier     /* ssl_parse_record_header() only considers records
4347*11fa71b9SJerome Forissier      * of the next epoch as candidates for buffering. */
4348*11fa71b9SJerome Forissier     hs->buffering.future_record.epoch = ssl->in_epoch + 1;
4349*11fa71b9SJerome Forissier     hs->buffering.future_record.len   = rec->buf_len;
4350*11fa71b9SJerome Forissier 
4351*11fa71b9SJerome Forissier     hs->buffering.future_record.data =
4352*11fa71b9SJerome Forissier         mbedtls_calloc( 1, hs->buffering.future_record.len );
4353*11fa71b9SJerome Forissier     if( hs->buffering.future_record.data == NULL )
4354*11fa71b9SJerome Forissier     {
4355*11fa71b9SJerome Forissier         /* If we run out of RAM trying to buffer a
4356*11fa71b9SJerome Forissier          * record from the next epoch, just ignore. */
4357*11fa71b9SJerome Forissier         return( 0 );
4358*11fa71b9SJerome Forissier     }
4359*11fa71b9SJerome Forissier 
4360*11fa71b9SJerome Forissier     memcpy( hs->buffering.future_record.data, rec->buf, rec->buf_len );
4361*11fa71b9SJerome Forissier 
4362*11fa71b9SJerome Forissier     hs->buffering.total_bytes_buffered += rec->buf_len;
4363*11fa71b9SJerome Forissier     return( 0 );
4364*11fa71b9SJerome Forissier }
4365*11fa71b9SJerome Forissier 
4366*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
4367*11fa71b9SJerome Forissier 
4368*11fa71b9SJerome Forissier static int ssl_get_next_record( mbedtls_ssl_context *ssl )
4369*11fa71b9SJerome Forissier {
4370*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4371*11fa71b9SJerome Forissier     mbedtls_record rec;
4372*11fa71b9SJerome Forissier 
4373*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4374*11fa71b9SJerome Forissier     /* We might have buffered a future record; if so,
4375*11fa71b9SJerome Forissier      * and if the epoch matches now, load it.
4376*11fa71b9SJerome Forissier      * On success, this call will set ssl->in_left to
4377*11fa71b9SJerome Forissier      * the length of the buffered record, so that
4378*11fa71b9SJerome Forissier      * the calls to ssl_fetch_input() below will
4379*11fa71b9SJerome Forissier      * essentially be no-ops. */
4380*11fa71b9SJerome Forissier     ret = ssl_load_buffered_record( ssl );
4381*11fa71b9SJerome Forissier     if( ret != 0 )
4382*11fa71b9SJerome Forissier         return( ret );
4383*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
4384*11fa71b9SJerome Forissier 
4385*11fa71b9SJerome Forissier     /* Ensure that we have enough space available for the default form
4386*11fa71b9SJerome Forissier      * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
4387*11fa71b9SJerome Forissier      * with no space for CIDs counted in). */
4388*11fa71b9SJerome Forissier     ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) );
4389*11fa71b9SJerome Forissier     if( ret != 0 )
4390*11fa71b9SJerome Forissier     {
4391*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
4392*11fa71b9SJerome Forissier         return( ret );
4393*11fa71b9SJerome Forissier     }
4394*11fa71b9SJerome Forissier 
4395*11fa71b9SJerome Forissier     ret = ssl_parse_record_header( ssl, ssl->in_hdr, ssl->in_left, &rec );
4396*11fa71b9SJerome Forissier     if( ret != 0 )
4397*11fa71b9SJerome Forissier     {
4398*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4399*11fa71b9SJerome Forissier         if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4400*11fa71b9SJerome Forissier         {
4401*11fa71b9SJerome Forissier             if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
4402*11fa71b9SJerome Forissier             {
4403*11fa71b9SJerome Forissier                 ret = ssl_buffer_future_record( ssl, &rec );
4404*11fa71b9SJerome Forissier                 if( ret != 0 )
4405*11fa71b9SJerome Forissier                     return( ret );
4406*11fa71b9SJerome Forissier 
4407*11fa71b9SJerome Forissier                 /* Fall through to handling of unexpected records */
4408*11fa71b9SJerome Forissier                 ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
4409*11fa71b9SJerome Forissier             }
4410*11fa71b9SJerome Forissier 
4411*11fa71b9SJerome Forissier             if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
4412*11fa71b9SJerome Forissier             {
4413*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
4414*11fa71b9SJerome Forissier                 /* Reset in pointers to default state for TLS/DTLS records,
4415*11fa71b9SJerome Forissier                  * assuming no CID and no offset between record content and
4416*11fa71b9SJerome Forissier                  * record plaintext. */
4417*11fa71b9SJerome Forissier                 mbedtls_ssl_update_in_pointers( ssl );
4418*11fa71b9SJerome Forissier 
4419*11fa71b9SJerome Forissier                 /* Setup internal message pointers from record structure. */
4420*11fa71b9SJerome Forissier                 ssl->in_msgtype = rec.type;
4421*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4422*11fa71b9SJerome Forissier                 ssl->in_len = ssl->in_cid + rec.cid_len;
4423*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4424*11fa71b9SJerome Forissier                 ssl->in_iv  = ssl->in_msg = ssl->in_len + 2;
4425*11fa71b9SJerome Forissier                 ssl->in_msglen = rec.data_len;
4426*11fa71b9SJerome Forissier 
4427*11fa71b9SJerome Forissier                 ret = ssl_check_client_reconnect( ssl );
4428*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_client_reconnect", ret );
4429*11fa71b9SJerome Forissier                 if( ret != 0 )
4430*11fa71b9SJerome Forissier                     return( ret );
4431*11fa71b9SJerome Forissier #endif
4432*11fa71b9SJerome Forissier 
4433*11fa71b9SJerome Forissier                 /* Skip unexpected record (but not whole datagram) */
4434*11fa71b9SJerome Forissier                 ssl->next_record_offset = rec.buf_len;
4435*11fa71b9SJerome Forissier 
4436*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
4437*11fa71b9SJerome Forissier                                             "(header)" ) );
4438*11fa71b9SJerome Forissier             }
4439*11fa71b9SJerome Forissier             else
4440*11fa71b9SJerome Forissier             {
4441*11fa71b9SJerome Forissier                 /* Skip invalid record and the rest of the datagram */
4442*11fa71b9SJerome Forissier                 ssl->next_record_offset = 0;
4443*11fa71b9SJerome Forissier                 ssl->in_left = 0;
4444*11fa71b9SJerome Forissier 
4445*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
4446*11fa71b9SJerome Forissier                                             "(header)" ) );
4447*11fa71b9SJerome Forissier             }
4448*11fa71b9SJerome Forissier 
4449*11fa71b9SJerome Forissier             /* Get next record */
4450*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
4451*11fa71b9SJerome Forissier         }
4452*11fa71b9SJerome Forissier         else
4453*11fa71b9SJerome Forissier #endif
4454*11fa71b9SJerome Forissier         {
4455*11fa71b9SJerome Forissier             return( ret );
4456*11fa71b9SJerome Forissier         }
4457*11fa71b9SJerome Forissier     }
4458*11fa71b9SJerome Forissier 
4459*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4460*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4461*11fa71b9SJerome Forissier     {
4462*11fa71b9SJerome Forissier         /* Remember offset of next record within datagram. */
4463*11fa71b9SJerome Forissier         ssl->next_record_offset = rec.buf_len;
4464*11fa71b9SJerome Forissier         if( ssl->next_record_offset < ssl->in_left )
4465*11fa71b9SJerome Forissier         {
4466*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
4467*11fa71b9SJerome Forissier         }
4468*11fa71b9SJerome Forissier     }
4469*11fa71b9SJerome Forissier     else
4470*11fa71b9SJerome Forissier #endif
4471*11fa71b9SJerome Forissier     {
4472*11fa71b9SJerome Forissier         /*
4473*11fa71b9SJerome Forissier          * Fetch record contents from underlying transport.
4474*11fa71b9SJerome Forissier          */
4475*11fa71b9SJerome Forissier         ret = mbedtls_ssl_fetch_input( ssl, rec.buf_len );
4476*11fa71b9SJerome Forissier         if( ret != 0 )
4477*11fa71b9SJerome Forissier         {
4478*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
4479*11fa71b9SJerome Forissier             return( ret );
4480*11fa71b9SJerome Forissier         }
4481*11fa71b9SJerome Forissier 
4482*11fa71b9SJerome Forissier         ssl->in_left = 0;
4483*11fa71b9SJerome Forissier     }
4484*11fa71b9SJerome Forissier 
4485*11fa71b9SJerome Forissier     /*
4486*11fa71b9SJerome Forissier      * Decrypt record contents.
4487*11fa71b9SJerome Forissier      */
4488*11fa71b9SJerome Forissier 
4489*11fa71b9SJerome Forissier     if( ( ret = ssl_prepare_record_content( ssl, &rec ) ) != 0 )
4490*11fa71b9SJerome Forissier     {
4491*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4492*11fa71b9SJerome Forissier         if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4493*11fa71b9SJerome Forissier         {
4494*11fa71b9SJerome Forissier             /* Silently discard invalid records */
4495*11fa71b9SJerome Forissier             if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
4496*11fa71b9SJerome Forissier             {
4497*11fa71b9SJerome Forissier                 /* Except when waiting for Finished as a bad mac here
4498*11fa71b9SJerome Forissier                  * probably means something went wrong in the handshake
4499*11fa71b9SJerome Forissier                  * (eg wrong psk used, mitm downgrade attempt, etc.) */
4500*11fa71b9SJerome Forissier                 if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
4501*11fa71b9SJerome Forissier                     ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
4502*11fa71b9SJerome Forissier                 {
4503*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
4504*11fa71b9SJerome Forissier                     if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
4505*11fa71b9SJerome Forissier                     {
4506*11fa71b9SJerome Forissier                         mbedtls_ssl_send_alert_message( ssl,
4507*11fa71b9SJerome Forissier                                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4508*11fa71b9SJerome Forissier                                 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
4509*11fa71b9SJerome Forissier                     }
4510*11fa71b9SJerome Forissier #endif
4511*11fa71b9SJerome Forissier                     return( ret );
4512*11fa71b9SJerome Forissier                 }
4513*11fa71b9SJerome Forissier 
4514*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
4515*11fa71b9SJerome Forissier                 if( ssl->conf->badmac_limit != 0 &&
4516*11fa71b9SJerome Forissier                     ++ssl->badmac_seen >= ssl->conf->badmac_limit )
4517*11fa71b9SJerome Forissier                 {
4518*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
4519*11fa71b9SJerome Forissier                     return( MBEDTLS_ERR_SSL_INVALID_MAC );
4520*11fa71b9SJerome Forissier                 }
4521*11fa71b9SJerome Forissier #endif
4522*11fa71b9SJerome Forissier 
4523*11fa71b9SJerome Forissier                 /* As above, invalid records cause
4524*11fa71b9SJerome Forissier                  * dismissal of the whole datagram. */
4525*11fa71b9SJerome Forissier 
4526*11fa71b9SJerome Forissier                 ssl->next_record_offset = 0;
4527*11fa71b9SJerome Forissier                 ssl->in_left = 0;
4528*11fa71b9SJerome Forissier 
4529*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
4530*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
4531*11fa71b9SJerome Forissier             }
4532*11fa71b9SJerome Forissier 
4533*11fa71b9SJerome Forissier             return( ret );
4534*11fa71b9SJerome Forissier         }
4535*11fa71b9SJerome Forissier         else
4536*11fa71b9SJerome Forissier #endif
4537*11fa71b9SJerome Forissier         {
4538*11fa71b9SJerome Forissier             /* Error out (and send alert) on invalid records */
4539*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
4540*11fa71b9SJerome Forissier             if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
4541*11fa71b9SJerome Forissier             {
4542*11fa71b9SJerome Forissier                 mbedtls_ssl_send_alert_message( ssl,
4543*11fa71b9SJerome Forissier                         MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4544*11fa71b9SJerome Forissier                         MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
4545*11fa71b9SJerome Forissier             }
4546*11fa71b9SJerome Forissier #endif
4547*11fa71b9SJerome Forissier             return( ret );
4548*11fa71b9SJerome Forissier         }
4549*11fa71b9SJerome Forissier     }
4550*11fa71b9SJerome Forissier 
4551*11fa71b9SJerome Forissier 
4552*11fa71b9SJerome Forissier     /* Reset in pointers to default state for TLS/DTLS records,
4553*11fa71b9SJerome Forissier      * assuming no CID and no offset between record content and
4554*11fa71b9SJerome Forissier      * record plaintext. */
4555*11fa71b9SJerome Forissier     mbedtls_ssl_update_in_pointers( ssl );
4556*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4557*11fa71b9SJerome Forissier     ssl->in_len = ssl->in_cid + rec.cid_len;
4558*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4559*11fa71b9SJerome Forissier     ssl->in_iv  = ssl->in_len + 2;
4560*11fa71b9SJerome Forissier 
4561*11fa71b9SJerome Forissier     /* The record content type may change during decryption,
4562*11fa71b9SJerome Forissier      * so re-read it. */
4563*11fa71b9SJerome Forissier     ssl->in_msgtype = rec.type;
4564*11fa71b9SJerome Forissier     /* Also update the input buffer, because unfortunately
4565*11fa71b9SJerome Forissier      * the server-side ssl_parse_client_hello() reparses the
4566*11fa71b9SJerome Forissier      * record header when receiving a ClientHello initiating
4567*11fa71b9SJerome Forissier      * a renegotiation. */
4568*11fa71b9SJerome Forissier     ssl->in_hdr[0] = rec.type;
4569*11fa71b9SJerome Forissier     ssl->in_msg    = rec.buf + rec.data_offset;
4570*11fa71b9SJerome Forissier     ssl->in_msglen = rec.data_len;
4571*11fa71b9SJerome Forissier     ssl->in_len[0] = (unsigned char)( rec.data_len >> 8 );
4572*11fa71b9SJerome Forissier     ssl->in_len[1] = (unsigned char)( rec.data_len      );
4573*11fa71b9SJerome Forissier 
4574*11fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT)
4575*11fa71b9SJerome Forissier     if( ssl->transform_in != NULL &&
4576*11fa71b9SJerome Forissier         ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
4577*11fa71b9SJerome Forissier     {
4578*11fa71b9SJerome Forissier         if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
4579*11fa71b9SJerome Forissier         {
4580*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
4581*11fa71b9SJerome Forissier             return( ret );
4582*11fa71b9SJerome Forissier         }
4583*11fa71b9SJerome Forissier 
4584*11fa71b9SJerome Forissier         /* Check actual (decompress) record content length against
4585*11fa71b9SJerome Forissier          * configured maximum. */
4586*11fa71b9SJerome Forissier         if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
4587*11fa71b9SJerome Forissier         {
4588*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
4589*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
4590*11fa71b9SJerome Forissier         }
4591*11fa71b9SJerome Forissier     }
4592*11fa71b9SJerome Forissier #endif /* MBEDTLS_ZLIB_SUPPORT */
4593*11fa71b9SJerome Forissier 
4594*11fa71b9SJerome Forissier     return( 0 );
4595*11fa71b9SJerome Forissier }
4596*11fa71b9SJerome Forissier 
4597*11fa71b9SJerome Forissier int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
4598*11fa71b9SJerome Forissier {
4599*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4600*11fa71b9SJerome Forissier 
4601*11fa71b9SJerome Forissier     /*
4602*11fa71b9SJerome Forissier      * Handle particular types of records
4603*11fa71b9SJerome Forissier      */
4604*11fa71b9SJerome Forissier     if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
4605*11fa71b9SJerome Forissier     {
4606*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
4607*11fa71b9SJerome Forissier         {
4608*11fa71b9SJerome Forissier             return( ret );
4609*11fa71b9SJerome Forissier         }
4610*11fa71b9SJerome Forissier     }
4611*11fa71b9SJerome Forissier 
4612*11fa71b9SJerome Forissier     if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
4613*11fa71b9SJerome Forissier     {
4614*11fa71b9SJerome Forissier         if( ssl->in_msglen != 1 )
4615*11fa71b9SJerome Forissier         {
4616*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d",
4617*11fa71b9SJerome Forissier                            ssl->in_msglen ) );
4618*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
4619*11fa71b9SJerome Forissier         }
4620*11fa71b9SJerome Forissier 
4621*11fa71b9SJerome Forissier         if( ssl->in_msg[0] != 1 )
4622*11fa71b9SJerome Forissier         {
4623*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x",
4624*11fa71b9SJerome Forissier                                         ssl->in_msg[0] ) );
4625*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
4626*11fa71b9SJerome Forissier         }
4627*11fa71b9SJerome Forissier 
4628*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4629*11fa71b9SJerome Forissier         if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
4630*11fa71b9SJerome Forissier             ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC    &&
4631*11fa71b9SJerome Forissier             ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
4632*11fa71b9SJerome Forissier         {
4633*11fa71b9SJerome Forissier             if( ssl->handshake == NULL )
4634*11fa71b9SJerome Forissier             {
4635*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) );
4636*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
4637*11fa71b9SJerome Forissier             }
4638*11fa71b9SJerome Forissier 
4639*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) );
4640*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
4641*11fa71b9SJerome Forissier         }
4642*11fa71b9SJerome Forissier #endif
4643*11fa71b9SJerome Forissier     }
4644*11fa71b9SJerome Forissier 
4645*11fa71b9SJerome Forissier     if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
4646*11fa71b9SJerome Forissier     {
4647*11fa71b9SJerome Forissier         if( ssl->in_msglen != 2 )
4648*11fa71b9SJerome Forissier         {
4649*11fa71b9SJerome Forissier             /* Note: Standard allows for more than one 2 byte alert
4650*11fa71b9SJerome Forissier                to be packed in a single message, but Mbed TLS doesn't
4651*11fa71b9SJerome Forissier                currently support this. */
4652*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d",
4653*11fa71b9SJerome Forissier                            ssl->in_msglen ) );
4654*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INVALID_RECORD );
4655*11fa71b9SJerome Forissier         }
4656*11fa71b9SJerome Forissier 
4657*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
4658*11fa71b9SJerome Forissier                        ssl->in_msg[0], ssl->in_msg[1] ) );
4659*11fa71b9SJerome Forissier 
4660*11fa71b9SJerome Forissier         /*
4661*11fa71b9SJerome Forissier          * Ignore non-fatal alerts, except close_notify and no_renegotiation
4662*11fa71b9SJerome Forissier          */
4663*11fa71b9SJerome Forissier         if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
4664*11fa71b9SJerome Forissier         {
4665*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
4666*11fa71b9SJerome Forissier                            ssl->in_msg[1] ) );
4667*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
4668*11fa71b9SJerome Forissier         }
4669*11fa71b9SJerome Forissier 
4670*11fa71b9SJerome Forissier         if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
4671*11fa71b9SJerome Forissier             ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
4672*11fa71b9SJerome Forissier         {
4673*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
4674*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
4675*11fa71b9SJerome Forissier         }
4676*11fa71b9SJerome Forissier 
4677*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
4678*11fa71b9SJerome Forissier         if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
4679*11fa71b9SJerome Forissier             ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
4680*11fa71b9SJerome Forissier         {
4681*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) );
4682*11fa71b9SJerome Forissier             /* Will be handled when trying to parse ServerHello */
4683*11fa71b9SJerome Forissier             return( 0 );
4684*11fa71b9SJerome Forissier         }
4685*11fa71b9SJerome Forissier #endif
4686*11fa71b9SJerome Forissier 
4687*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
4688*11fa71b9SJerome Forissier         if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
4689*11fa71b9SJerome Forissier             ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
4690*11fa71b9SJerome Forissier             ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
4691*11fa71b9SJerome Forissier             ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
4692*11fa71b9SJerome Forissier         {
4693*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
4694*11fa71b9SJerome Forissier             /* Will be handled in mbedtls_ssl_parse_certificate() */
4695*11fa71b9SJerome Forissier             return( 0 );
4696*11fa71b9SJerome Forissier         }
4697*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
4698*11fa71b9SJerome Forissier 
4699*11fa71b9SJerome Forissier         /* Silently ignore: fetch new message */
4700*11fa71b9SJerome Forissier         return MBEDTLS_ERR_SSL_NON_FATAL;
4701*11fa71b9SJerome Forissier     }
4702*11fa71b9SJerome Forissier 
4703*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4704*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4705*11fa71b9SJerome Forissier     {
4706*11fa71b9SJerome Forissier         /* Drop unexpected ApplicationData records,
4707*11fa71b9SJerome Forissier          * except at the beginning of renegotiations */
4708*11fa71b9SJerome Forissier         if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
4709*11fa71b9SJerome Forissier             ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
4710*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
4711*11fa71b9SJerome Forissier             && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
4712*11fa71b9SJerome Forissier                    ssl->state == MBEDTLS_SSL_SERVER_HELLO )
4713*11fa71b9SJerome Forissier #endif
4714*11fa71b9SJerome Forissier             )
4715*11fa71b9SJerome Forissier         {
4716*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
4717*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_NON_FATAL );
4718*11fa71b9SJerome Forissier         }
4719*11fa71b9SJerome Forissier 
4720*11fa71b9SJerome Forissier         if( ssl->handshake != NULL &&
4721*11fa71b9SJerome Forissier             ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER  )
4722*11fa71b9SJerome Forissier         {
4723*11fa71b9SJerome Forissier             mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
4724*11fa71b9SJerome Forissier         }
4725*11fa71b9SJerome Forissier     }
4726*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
4727*11fa71b9SJerome Forissier 
4728*11fa71b9SJerome Forissier     return( 0 );
4729*11fa71b9SJerome Forissier }
4730*11fa71b9SJerome Forissier 
4731*11fa71b9SJerome Forissier int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
4732*11fa71b9SJerome Forissier {
4733*11fa71b9SJerome Forissier     return( mbedtls_ssl_send_alert_message( ssl,
4734*11fa71b9SJerome Forissier                   MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4735*11fa71b9SJerome Forissier                   MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) );
4736*11fa71b9SJerome Forissier }
4737*11fa71b9SJerome Forissier 
4738*11fa71b9SJerome Forissier int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
4739*11fa71b9SJerome Forissier                             unsigned char level,
4740*11fa71b9SJerome Forissier                             unsigned char message )
4741*11fa71b9SJerome Forissier {
4742*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4743*11fa71b9SJerome Forissier 
4744*11fa71b9SJerome Forissier     if( ssl == NULL || ssl->conf == NULL )
4745*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
4746*11fa71b9SJerome Forissier 
4747*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
4748*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
4749*11fa71b9SJerome Forissier 
4750*11fa71b9SJerome Forissier     ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
4751*11fa71b9SJerome Forissier     ssl->out_msglen = 2;
4752*11fa71b9SJerome Forissier     ssl->out_msg[0] = level;
4753*11fa71b9SJerome Forissier     ssl->out_msg[1] = message;
4754*11fa71b9SJerome Forissier 
4755*11fa71b9SJerome Forissier     if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
4756*11fa71b9SJerome Forissier     {
4757*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
4758*11fa71b9SJerome Forissier         return( ret );
4759*11fa71b9SJerome Forissier     }
4760*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
4761*11fa71b9SJerome Forissier 
4762*11fa71b9SJerome Forissier     return( 0 );
4763*11fa71b9SJerome Forissier }
4764*11fa71b9SJerome Forissier 
4765*11fa71b9SJerome Forissier int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
4766*11fa71b9SJerome Forissier {
4767*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4768*11fa71b9SJerome Forissier 
4769*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
4770*11fa71b9SJerome Forissier 
4771*11fa71b9SJerome Forissier     ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
4772*11fa71b9SJerome Forissier     ssl->out_msglen  = 1;
4773*11fa71b9SJerome Forissier     ssl->out_msg[0]  = 1;
4774*11fa71b9SJerome Forissier 
4775*11fa71b9SJerome Forissier     ssl->state++;
4776*11fa71b9SJerome Forissier 
4777*11fa71b9SJerome Forissier     if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
4778*11fa71b9SJerome Forissier     {
4779*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
4780*11fa71b9SJerome Forissier         return( ret );
4781*11fa71b9SJerome Forissier     }
4782*11fa71b9SJerome Forissier 
4783*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
4784*11fa71b9SJerome Forissier 
4785*11fa71b9SJerome Forissier     return( 0 );
4786*11fa71b9SJerome Forissier }
4787*11fa71b9SJerome Forissier 
4788*11fa71b9SJerome Forissier int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
4789*11fa71b9SJerome Forissier {
4790*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4791*11fa71b9SJerome Forissier 
4792*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
4793*11fa71b9SJerome Forissier 
4794*11fa71b9SJerome Forissier     if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
4795*11fa71b9SJerome Forissier     {
4796*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
4797*11fa71b9SJerome Forissier         return( ret );
4798*11fa71b9SJerome Forissier     }
4799*11fa71b9SJerome Forissier 
4800*11fa71b9SJerome Forissier     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
4801*11fa71b9SJerome Forissier     {
4802*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
4803*11fa71b9SJerome Forissier         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4804*11fa71b9SJerome Forissier                                         MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
4805*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
4806*11fa71b9SJerome Forissier     }
4807*11fa71b9SJerome Forissier 
4808*11fa71b9SJerome Forissier     /* CCS records are only accepted if they have length 1 and content '1',
4809*11fa71b9SJerome Forissier      * so we don't need to check this here. */
4810*11fa71b9SJerome Forissier 
4811*11fa71b9SJerome Forissier     /*
4812*11fa71b9SJerome Forissier      * Switch to our negotiated transform and session parameters for inbound
4813*11fa71b9SJerome Forissier      * data.
4814*11fa71b9SJerome Forissier      */
4815*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
4816*11fa71b9SJerome Forissier     ssl->transform_in = ssl->transform_negotiate;
4817*11fa71b9SJerome Forissier     ssl->session_in = ssl->session_negotiate;
4818*11fa71b9SJerome Forissier 
4819*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4820*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4821*11fa71b9SJerome Forissier     {
4822*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
4823*11fa71b9SJerome Forissier         mbedtls_ssl_dtls_replay_reset( ssl );
4824*11fa71b9SJerome Forissier #endif
4825*11fa71b9SJerome Forissier 
4826*11fa71b9SJerome Forissier         /* Increment epoch */
4827*11fa71b9SJerome Forissier         if( ++ssl->in_epoch == 0 )
4828*11fa71b9SJerome Forissier         {
4829*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
4830*11fa71b9SJerome Forissier             /* This is highly unlikely to happen for legitimate reasons, so
4831*11fa71b9SJerome Forissier                treat it as an attack and don't send an alert. */
4832*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
4833*11fa71b9SJerome Forissier         }
4834*11fa71b9SJerome Forissier     }
4835*11fa71b9SJerome Forissier     else
4836*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
4837*11fa71b9SJerome Forissier     memset( ssl->in_ctr, 0, 8 );
4838*11fa71b9SJerome Forissier 
4839*11fa71b9SJerome Forissier     mbedtls_ssl_update_in_pointers( ssl );
4840*11fa71b9SJerome Forissier 
4841*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
4842*11fa71b9SJerome Forissier     if( mbedtls_ssl_hw_record_activate != NULL )
4843*11fa71b9SJerome Forissier     {
4844*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
4845*11fa71b9SJerome Forissier         {
4846*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
4847*11fa71b9SJerome Forissier             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4848*11fa71b9SJerome Forissier                                             MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
4849*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
4850*11fa71b9SJerome Forissier         }
4851*11fa71b9SJerome Forissier     }
4852*11fa71b9SJerome Forissier #endif
4853*11fa71b9SJerome Forissier 
4854*11fa71b9SJerome Forissier     ssl->state++;
4855*11fa71b9SJerome Forissier 
4856*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
4857*11fa71b9SJerome Forissier 
4858*11fa71b9SJerome Forissier     return( 0 );
4859*11fa71b9SJerome Forissier }
4860*11fa71b9SJerome Forissier 
4861*11fa71b9SJerome Forissier /* Once ssl->out_hdr as the address of the beginning of the
4862*11fa71b9SJerome Forissier  * next outgoing record is set, deduce the other pointers.
4863*11fa71b9SJerome Forissier  *
4864*11fa71b9SJerome Forissier  * Note: For TLS, we save the implicit record sequence number
4865*11fa71b9SJerome Forissier  *       (entering MAC computation) in the 8 bytes before ssl->out_hdr,
4866*11fa71b9SJerome Forissier  *       and the caller has to make sure there's space for this.
4867*11fa71b9SJerome Forissier  */
4868*11fa71b9SJerome Forissier 
4869*11fa71b9SJerome Forissier void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl,
4870*11fa71b9SJerome Forissier                                       mbedtls_ssl_transform *transform )
4871*11fa71b9SJerome Forissier {
4872*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4873*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4874*11fa71b9SJerome Forissier     {
4875*11fa71b9SJerome Forissier         ssl->out_ctr = ssl->out_hdr +  3;
4876*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4877*11fa71b9SJerome Forissier         ssl->out_cid = ssl->out_ctr +  8;
4878*11fa71b9SJerome Forissier         ssl->out_len = ssl->out_cid;
4879*11fa71b9SJerome Forissier         if( transform != NULL )
4880*11fa71b9SJerome Forissier             ssl->out_len += transform->out_cid_len;
4881*11fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4882*11fa71b9SJerome Forissier         ssl->out_len = ssl->out_ctr + 8;
4883*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4884*11fa71b9SJerome Forissier         ssl->out_iv  = ssl->out_len + 2;
4885*11fa71b9SJerome Forissier     }
4886*11fa71b9SJerome Forissier     else
4887*11fa71b9SJerome Forissier #endif
4888*11fa71b9SJerome Forissier     {
4889*11fa71b9SJerome Forissier         ssl->out_ctr = ssl->out_hdr - 8;
4890*11fa71b9SJerome Forissier         ssl->out_len = ssl->out_hdr + 3;
4891*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4892*11fa71b9SJerome Forissier         ssl->out_cid = ssl->out_len;
4893*11fa71b9SJerome Forissier #endif
4894*11fa71b9SJerome Forissier         ssl->out_iv  = ssl->out_hdr + 5;
4895*11fa71b9SJerome Forissier     }
4896*11fa71b9SJerome Forissier 
4897*11fa71b9SJerome Forissier     /* Adjust out_msg to make space for explicit IV, if used. */
4898*11fa71b9SJerome Forissier     if( transform != NULL &&
4899*11fa71b9SJerome Forissier         ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
4900*11fa71b9SJerome Forissier     {
4901*11fa71b9SJerome Forissier         ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen;
4902*11fa71b9SJerome Forissier     }
4903*11fa71b9SJerome Forissier     else
4904*11fa71b9SJerome Forissier         ssl->out_msg = ssl->out_iv;
4905*11fa71b9SJerome Forissier }
4906*11fa71b9SJerome Forissier 
4907*11fa71b9SJerome Forissier /* Once ssl->in_hdr as the address of the beginning of the
4908*11fa71b9SJerome Forissier  * next incoming record is set, deduce the other pointers.
4909*11fa71b9SJerome Forissier  *
4910*11fa71b9SJerome Forissier  * Note: For TLS, we save the implicit record sequence number
4911*11fa71b9SJerome Forissier  *       (entering MAC computation) in the 8 bytes before ssl->in_hdr,
4912*11fa71b9SJerome Forissier  *       and the caller has to make sure there's space for this.
4913*11fa71b9SJerome Forissier  */
4914*11fa71b9SJerome Forissier 
4915*11fa71b9SJerome Forissier void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl )
4916*11fa71b9SJerome Forissier {
4917*11fa71b9SJerome Forissier     /* This function sets the pointers to match the case
4918*11fa71b9SJerome Forissier      * of unprotected TLS/DTLS records, with both  ssl->in_iv
4919*11fa71b9SJerome Forissier      * and ssl->in_msg pointing to the beginning of the record
4920*11fa71b9SJerome Forissier      * content.
4921*11fa71b9SJerome Forissier      *
4922*11fa71b9SJerome Forissier      * When decrypting a protected record, ssl->in_msg
4923*11fa71b9SJerome Forissier      * will be shifted to point to the beginning of the
4924*11fa71b9SJerome Forissier      * record plaintext.
4925*11fa71b9SJerome Forissier      */
4926*11fa71b9SJerome Forissier 
4927*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4928*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4929*11fa71b9SJerome Forissier     {
4930*11fa71b9SJerome Forissier         /* This sets the header pointers to match records
4931*11fa71b9SJerome Forissier          * without CID. When we receive a record containing
4932*11fa71b9SJerome Forissier          * a CID, the fields are shifted accordingly in
4933*11fa71b9SJerome Forissier          * ssl_parse_record_header(). */
4934*11fa71b9SJerome Forissier         ssl->in_ctr = ssl->in_hdr +  3;
4935*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4936*11fa71b9SJerome Forissier         ssl->in_cid = ssl->in_ctr +  8;
4937*11fa71b9SJerome Forissier         ssl->in_len = ssl->in_cid; /* Default: no CID */
4938*11fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4939*11fa71b9SJerome Forissier         ssl->in_len = ssl->in_ctr + 8;
4940*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4941*11fa71b9SJerome Forissier         ssl->in_iv  = ssl->in_len + 2;
4942*11fa71b9SJerome Forissier     }
4943*11fa71b9SJerome Forissier     else
4944*11fa71b9SJerome Forissier #endif
4945*11fa71b9SJerome Forissier     {
4946*11fa71b9SJerome Forissier         ssl->in_ctr = ssl->in_hdr - 8;
4947*11fa71b9SJerome Forissier         ssl->in_len = ssl->in_hdr + 3;
4948*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4949*11fa71b9SJerome Forissier         ssl->in_cid = ssl->in_len;
4950*11fa71b9SJerome Forissier #endif
4951*11fa71b9SJerome Forissier         ssl->in_iv  = ssl->in_hdr + 5;
4952*11fa71b9SJerome Forissier     }
4953*11fa71b9SJerome Forissier 
4954*11fa71b9SJerome Forissier     /* This will be adjusted at record decryption time. */
4955*11fa71b9SJerome Forissier     ssl->in_msg = ssl->in_iv;
4956*11fa71b9SJerome Forissier }
4957*11fa71b9SJerome Forissier 
4958*11fa71b9SJerome Forissier /*
4959*11fa71b9SJerome Forissier  * Setup an SSL context
4960*11fa71b9SJerome Forissier  */
4961*11fa71b9SJerome Forissier 
4962*11fa71b9SJerome Forissier void mbedtls_ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
4963*11fa71b9SJerome Forissier {
4964*11fa71b9SJerome Forissier     /* Set the incoming and outgoing record pointers. */
4965*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4966*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4967*11fa71b9SJerome Forissier     {
4968*11fa71b9SJerome Forissier         ssl->out_hdr = ssl->out_buf;
4969*11fa71b9SJerome Forissier         ssl->in_hdr  = ssl->in_buf;
4970*11fa71b9SJerome Forissier     }
4971*11fa71b9SJerome Forissier     else
4972*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
4973*11fa71b9SJerome Forissier     {
4974*11fa71b9SJerome Forissier         ssl->out_hdr = ssl->out_buf + 8;
4975*11fa71b9SJerome Forissier         ssl->in_hdr  = ssl->in_buf  + 8;
4976*11fa71b9SJerome Forissier     }
4977*11fa71b9SJerome Forissier 
4978*11fa71b9SJerome Forissier     /* Derive other internal pointers. */
4979*11fa71b9SJerome Forissier     mbedtls_ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
4980*11fa71b9SJerome Forissier     mbedtls_ssl_update_in_pointers ( ssl );
4981*11fa71b9SJerome Forissier }
4982*11fa71b9SJerome Forissier 
4983*11fa71b9SJerome Forissier /*
4984*11fa71b9SJerome Forissier  * SSL get accessors
4985*11fa71b9SJerome Forissier  */
4986*11fa71b9SJerome Forissier size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
4987*11fa71b9SJerome Forissier {
4988*11fa71b9SJerome Forissier     return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
4989*11fa71b9SJerome Forissier }
4990*11fa71b9SJerome Forissier 
4991*11fa71b9SJerome Forissier int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
4992*11fa71b9SJerome Forissier {
4993*11fa71b9SJerome Forissier     /*
4994*11fa71b9SJerome Forissier      * Case A: We're currently holding back
4995*11fa71b9SJerome Forissier      * a message for further processing.
4996*11fa71b9SJerome Forissier      */
4997*11fa71b9SJerome Forissier 
4998*11fa71b9SJerome Forissier     if( ssl->keep_current_message == 1 )
4999*11fa71b9SJerome Forissier     {
5000*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) );
5001*11fa71b9SJerome Forissier         return( 1 );
5002*11fa71b9SJerome Forissier     }
5003*11fa71b9SJerome Forissier 
5004*11fa71b9SJerome Forissier     /*
5005*11fa71b9SJerome Forissier      * Case B: Further records are pending in the current datagram.
5006*11fa71b9SJerome Forissier      */
5007*11fa71b9SJerome Forissier 
5008*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5009*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5010*11fa71b9SJerome Forissier         ssl->in_left > ssl->next_record_offset )
5011*11fa71b9SJerome Forissier     {
5012*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
5013*11fa71b9SJerome Forissier         return( 1 );
5014*11fa71b9SJerome Forissier     }
5015*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
5016*11fa71b9SJerome Forissier 
5017*11fa71b9SJerome Forissier     /*
5018*11fa71b9SJerome Forissier      * Case C: A handshake message is being processed.
5019*11fa71b9SJerome Forissier      */
5020*11fa71b9SJerome Forissier 
5021*11fa71b9SJerome Forissier     if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
5022*11fa71b9SJerome Forissier     {
5023*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) );
5024*11fa71b9SJerome Forissier         return( 1 );
5025*11fa71b9SJerome Forissier     }
5026*11fa71b9SJerome Forissier 
5027*11fa71b9SJerome Forissier     /*
5028*11fa71b9SJerome Forissier      * Case D: An application data message is being processed
5029*11fa71b9SJerome Forissier      */
5030*11fa71b9SJerome Forissier     if( ssl->in_offt != NULL )
5031*11fa71b9SJerome Forissier     {
5032*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) );
5033*11fa71b9SJerome Forissier         return( 1 );
5034*11fa71b9SJerome Forissier     }
5035*11fa71b9SJerome Forissier 
5036*11fa71b9SJerome Forissier     /*
5037*11fa71b9SJerome Forissier      * In all other cases, the rest of the message can be dropped.
5038*11fa71b9SJerome Forissier      * As in ssl_get_next_record, this needs to be adapted if
5039*11fa71b9SJerome Forissier      * we implement support for multiple alerts in single records.
5040*11fa71b9SJerome Forissier      */
5041*11fa71b9SJerome Forissier 
5042*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
5043*11fa71b9SJerome Forissier     return( 0 );
5044*11fa71b9SJerome Forissier }
5045*11fa71b9SJerome Forissier 
5046*11fa71b9SJerome Forissier 
5047*11fa71b9SJerome Forissier int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
5048*11fa71b9SJerome Forissier {
5049*11fa71b9SJerome Forissier     size_t transform_expansion = 0;
5050*11fa71b9SJerome Forissier     const mbedtls_ssl_transform *transform = ssl->transform_out;
5051*11fa71b9SJerome Forissier     unsigned block_size;
5052*11fa71b9SJerome Forissier 
5053*11fa71b9SJerome Forissier     size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl );
5054*11fa71b9SJerome Forissier 
5055*11fa71b9SJerome Forissier     if( transform == NULL )
5056*11fa71b9SJerome Forissier         return( (int) out_hdr_len );
5057*11fa71b9SJerome Forissier 
5058*11fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT)
5059*11fa71b9SJerome Forissier     if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
5060*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
5061*11fa71b9SJerome Forissier #endif
5062*11fa71b9SJerome Forissier 
5063*11fa71b9SJerome Forissier     switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
5064*11fa71b9SJerome Forissier     {
5065*11fa71b9SJerome Forissier         case MBEDTLS_MODE_GCM:
5066*11fa71b9SJerome Forissier         case MBEDTLS_MODE_CCM:
5067*11fa71b9SJerome Forissier         case MBEDTLS_MODE_CHACHAPOLY:
5068*11fa71b9SJerome Forissier         case MBEDTLS_MODE_STREAM:
5069*11fa71b9SJerome Forissier             transform_expansion = transform->minlen;
5070*11fa71b9SJerome Forissier             break;
5071*11fa71b9SJerome Forissier 
5072*11fa71b9SJerome Forissier         case MBEDTLS_MODE_CBC:
5073*11fa71b9SJerome Forissier 
5074*11fa71b9SJerome Forissier             block_size = mbedtls_cipher_get_block_size(
5075*11fa71b9SJerome Forissier                 &transform->cipher_ctx_enc );
5076*11fa71b9SJerome Forissier 
5077*11fa71b9SJerome Forissier             /* Expansion due to the addition of the MAC. */
5078*11fa71b9SJerome Forissier             transform_expansion += transform->maclen;
5079*11fa71b9SJerome Forissier 
5080*11fa71b9SJerome Forissier             /* Expansion due to the addition of CBC padding;
5081*11fa71b9SJerome Forissier              * Theoretically up to 256 bytes, but we never use
5082*11fa71b9SJerome Forissier              * more than the block size of the underlying cipher. */
5083*11fa71b9SJerome Forissier             transform_expansion += block_size;
5084*11fa71b9SJerome Forissier 
5085*11fa71b9SJerome Forissier             /* For TLS 1.1 or higher, an explicit IV is added
5086*11fa71b9SJerome Forissier              * after the record header. */
5087*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
5088*11fa71b9SJerome Forissier             if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
5089*11fa71b9SJerome Forissier                 transform_expansion += block_size;
5090*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
5091*11fa71b9SJerome Forissier 
5092*11fa71b9SJerome Forissier             break;
5093*11fa71b9SJerome Forissier 
5094*11fa71b9SJerome Forissier         default:
5095*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
5096*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
5097*11fa71b9SJerome Forissier     }
5098*11fa71b9SJerome Forissier 
5099*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
5100*11fa71b9SJerome Forissier     if( transform->out_cid_len != 0 )
5101*11fa71b9SJerome Forissier         transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
5102*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5103*11fa71b9SJerome Forissier 
5104*11fa71b9SJerome Forissier     return( (int)( out_hdr_len + transform_expansion ) );
5105*11fa71b9SJerome Forissier }
5106*11fa71b9SJerome Forissier 
5107*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
5108*11fa71b9SJerome Forissier /*
5109*11fa71b9SJerome Forissier  * Check record counters and renegotiate if they're above the limit.
5110*11fa71b9SJerome Forissier  */
5111*11fa71b9SJerome Forissier static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
5112*11fa71b9SJerome Forissier {
5113*11fa71b9SJerome Forissier     size_t ep_len = mbedtls_ssl_ep_len( ssl );
5114*11fa71b9SJerome Forissier     int in_ctr_cmp;
5115*11fa71b9SJerome Forissier     int out_ctr_cmp;
5116*11fa71b9SJerome Forissier 
5117*11fa71b9SJerome Forissier     if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
5118*11fa71b9SJerome Forissier         ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
5119*11fa71b9SJerome Forissier         ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
5120*11fa71b9SJerome Forissier     {
5121*11fa71b9SJerome Forissier         return( 0 );
5122*11fa71b9SJerome Forissier     }
5123*11fa71b9SJerome Forissier 
5124*11fa71b9SJerome Forissier     in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
5125*11fa71b9SJerome Forissier                         ssl->conf->renego_period + ep_len, 8 - ep_len );
5126*11fa71b9SJerome Forissier     out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
5127*11fa71b9SJerome Forissier                           ssl->conf->renego_period + ep_len, 8 - ep_len );
5128*11fa71b9SJerome Forissier 
5129*11fa71b9SJerome Forissier     if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
5130*11fa71b9SJerome Forissier     {
5131*11fa71b9SJerome Forissier         return( 0 );
5132*11fa71b9SJerome Forissier     }
5133*11fa71b9SJerome Forissier 
5134*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
5135*11fa71b9SJerome Forissier     return( mbedtls_ssl_renegotiate( ssl ) );
5136*11fa71b9SJerome Forissier }
5137*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */
5138*11fa71b9SJerome Forissier 
5139*11fa71b9SJerome Forissier /*
5140*11fa71b9SJerome Forissier  * Receive application data decrypted from the SSL layer
5141*11fa71b9SJerome Forissier  */
5142*11fa71b9SJerome Forissier int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
5143*11fa71b9SJerome Forissier {
5144*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5145*11fa71b9SJerome Forissier     size_t n;
5146*11fa71b9SJerome Forissier 
5147*11fa71b9SJerome Forissier     if( ssl == NULL || ssl->conf == NULL )
5148*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
5149*11fa71b9SJerome Forissier 
5150*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
5151*11fa71b9SJerome Forissier 
5152*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5153*11fa71b9SJerome Forissier     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5154*11fa71b9SJerome Forissier     {
5155*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
5156*11fa71b9SJerome Forissier             return( ret );
5157*11fa71b9SJerome Forissier 
5158*11fa71b9SJerome Forissier         if( ssl->handshake != NULL &&
5159*11fa71b9SJerome Forissier             ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
5160*11fa71b9SJerome Forissier         {
5161*11fa71b9SJerome Forissier             if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
5162*11fa71b9SJerome Forissier                 return( ret );
5163*11fa71b9SJerome Forissier         }
5164*11fa71b9SJerome Forissier     }
5165*11fa71b9SJerome Forissier #endif
5166*11fa71b9SJerome Forissier 
5167*11fa71b9SJerome Forissier     /*
5168*11fa71b9SJerome Forissier      * Check if renegotiation is necessary and/or handshake is
5169*11fa71b9SJerome Forissier      * in process. If yes, perform/continue, and fall through
5170*11fa71b9SJerome Forissier      * if an unexpected packet is received while the client
5171*11fa71b9SJerome Forissier      * is waiting for the ServerHello.
5172*11fa71b9SJerome Forissier      *
5173*11fa71b9SJerome Forissier      * (There is no equivalent to the last condition on
5174*11fa71b9SJerome Forissier      *  the server-side as it is not treated as within
5175*11fa71b9SJerome Forissier      *  a handshake while waiting for the ClientHello
5176*11fa71b9SJerome Forissier      *  after a renegotiation request.)
5177*11fa71b9SJerome Forissier      */
5178*11fa71b9SJerome Forissier 
5179*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
5180*11fa71b9SJerome Forissier     ret = ssl_check_ctr_renegotiate( ssl );
5181*11fa71b9SJerome Forissier     if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5182*11fa71b9SJerome Forissier         ret != 0 )
5183*11fa71b9SJerome Forissier     {
5184*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
5185*11fa71b9SJerome Forissier         return( ret );
5186*11fa71b9SJerome Forissier     }
5187*11fa71b9SJerome Forissier #endif
5188*11fa71b9SJerome Forissier 
5189*11fa71b9SJerome Forissier     if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
5190*11fa71b9SJerome Forissier     {
5191*11fa71b9SJerome Forissier         ret = mbedtls_ssl_handshake( ssl );
5192*11fa71b9SJerome Forissier         if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5193*11fa71b9SJerome Forissier             ret != 0 )
5194*11fa71b9SJerome Forissier         {
5195*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
5196*11fa71b9SJerome Forissier             return( ret );
5197*11fa71b9SJerome Forissier         }
5198*11fa71b9SJerome Forissier     }
5199*11fa71b9SJerome Forissier 
5200*11fa71b9SJerome Forissier     /* Loop as long as no application data record is available */
5201*11fa71b9SJerome Forissier     while( ssl->in_offt == NULL )
5202*11fa71b9SJerome Forissier     {
5203*11fa71b9SJerome Forissier         /* Start timer if not already running */
5204*11fa71b9SJerome Forissier         if( ssl->f_get_timer != NULL &&
5205*11fa71b9SJerome Forissier             ssl->f_get_timer( ssl->p_timer ) == -1 )
5206*11fa71b9SJerome Forissier         {
5207*11fa71b9SJerome Forissier             mbedtls_ssl_set_timer( ssl, ssl->conf->read_timeout );
5208*11fa71b9SJerome Forissier         }
5209*11fa71b9SJerome Forissier 
5210*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
5211*11fa71b9SJerome Forissier         {
5212*11fa71b9SJerome Forissier             if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
5213*11fa71b9SJerome Forissier                 return( 0 );
5214*11fa71b9SJerome Forissier 
5215*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
5216*11fa71b9SJerome Forissier             return( ret );
5217*11fa71b9SJerome Forissier         }
5218*11fa71b9SJerome Forissier 
5219*11fa71b9SJerome Forissier         if( ssl->in_msglen  == 0 &&
5220*11fa71b9SJerome Forissier             ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
5221*11fa71b9SJerome Forissier         {
5222*11fa71b9SJerome Forissier             /*
5223*11fa71b9SJerome Forissier              * OpenSSL sends empty messages to randomize the IV
5224*11fa71b9SJerome Forissier              */
5225*11fa71b9SJerome Forissier             if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
5226*11fa71b9SJerome Forissier             {
5227*11fa71b9SJerome Forissier                 if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
5228*11fa71b9SJerome Forissier                     return( 0 );
5229*11fa71b9SJerome Forissier 
5230*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
5231*11fa71b9SJerome Forissier                 return( ret );
5232*11fa71b9SJerome Forissier             }
5233*11fa71b9SJerome Forissier         }
5234*11fa71b9SJerome Forissier 
5235*11fa71b9SJerome Forissier         if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
5236*11fa71b9SJerome Forissier         {
5237*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
5238*11fa71b9SJerome Forissier 
5239*11fa71b9SJerome Forissier             /*
5240*11fa71b9SJerome Forissier              * - For client-side, expect SERVER_HELLO_REQUEST.
5241*11fa71b9SJerome Forissier              * - For server-side, expect CLIENT_HELLO.
5242*11fa71b9SJerome Forissier              * - Fail (TLS) or silently drop record (DTLS) in other cases.
5243*11fa71b9SJerome Forissier              */
5244*11fa71b9SJerome Forissier 
5245*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CLI_C)
5246*11fa71b9SJerome Forissier             if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
5247*11fa71b9SJerome Forissier                 ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
5248*11fa71b9SJerome Forissier                   ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) ) )
5249*11fa71b9SJerome Forissier             {
5250*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
5251*11fa71b9SJerome Forissier 
5252*11fa71b9SJerome Forissier                 /* With DTLS, drop the packet (probably from last handshake) */
5253*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5254*11fa71b9SJerome Forissier                 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5255*11fa71b9SJerome Forissier                 {
5256*11fa71b9SJerome Forissier                     continue;
5257*11fa71b9SJerome Forissier                 }
5258*11fa71b9SJerome Forissier #endif
5259*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
5260*11fa71b9SJerome Forissier             }
5261*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_CLI_C */
5262*11fa71b9SJerome Forissier 
5263*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C)
5264*11fa71b9SJerome Forissier             if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
5265*11fa71b9SJerome Forissier                 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
5266*11fa71b9SJerome Forissier             {
5267*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
5268*11fa71b9SJerome Forissier 
5269*11fa71b9SJerome Forissier                 /* With DTLS, drop the packet (probably from last handshake) */
5270*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5271*11fa71b9SJerome Forissier                 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5272*11fa71b9SJerome Forissier                 {
5273*11fa71b9SJerome Forissier                     continue;
5274*11fa71b9SJerome Forissier                 }
5275*11fa71b9SJerome Forissier #endif
5276*11fa71b9SJerome Forissier                 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
5277*11fa71b9SJerome Forissier             }
5278*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C */
5279*11fa71b9SJerome Forissier 
5280*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
5281*11fa71b9SJerome Forissier             /* Determine whether renegotiation attempt should be accepted */
5282*11fa71b9SJerome Forissier             if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
5283*11fa71b9SJerome Forissier                     ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
5284*11fa71b9SJerome Forissier                       ssl->conf->allow_legacy_renegotiation ==
5285*11fa71b9SJerome Forissier                                                    MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
5286*11fa71b9SJerome Forissier             {
5287*11fa71b9SJerome Forissier                 /*
5288*11fa71b9SJerome Forissier                  * Accept renegotiation request
5289*11fa71b9SJerome Forissier                  */
5290*11fa71b9SJerome Forissier 
5291*11fa71b9SJerome Forissier                 /* DTLS clients need to know renego is server-initiated */
5292*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5293*11fa71b9SJerome Forissier                 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5294*11fa71b9SJerome Forissier                     ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
5295*11fa71b9SJerome Forissier                 {
5296*11fa71b9SJerome Forissier                     ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
5297*11fa71b9SJerome Forissier                 }
5298*11fa71b9SJerome Forissier #endif
5299*11fa71b9SJerome Forissier                 ret = mbedtls_ssl_start_renegotiation( ssl );
5300*11fa71b9SJerome Forissier                 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5301*11fa71b9SJerome Forissier                     ret != 0 )
5302*11fa71b9SJerome Forissier                 {
5303*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_start_renegotiation",
5304*11fa71b9SJerome Forissier                                            ret );
5305*11fa71b9SJerome Forissier                     return( ret );
5306*11fa71b9SJerome Forissier                 }
5307*11fa71b9SJerome Forissier             }
5308*11fa71b9SJerome Forissier             else
5309*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */
5310*11fa71b9SJerome Forissier             {
5311*11fa71b9SJerome Forissier                 /*
5312*11fa71b9SJerome Forissier                  * Refuse renegotiation
5313*11fa71b9SJerome Forissier                  */
5314*11fa71b9SJerome Forissier 
5315*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
5316*11fa71b9SJerome Forissier 
5317*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3)
5318*11fa71b9SJerome Forissier                 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
5319*11fa71b9SJerome Forissier                 {
5320*11fa71b9SJerome Forissier                     /* SSLv3 does not have a "no_renegotiation" warning, so
5321*11fa71b9SJerome Forissier                        we send a fatal alert and abort the connection. */
5322*11fa71b9SJerome Forissier                     mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
5323*11fa71b9SJerome Forissier                                                     MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
5324*11fa71b9SJerome Forissier                     return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
5325*11fa71b9SJerome Forissier                 }
5326*11fa71b9SJerome Forissier                 else
5327*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */
5328*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
5329*11fa71b9SJerome Forissier     defined(MBEDTLS_SSL_PROTO_TLS1_2)
5330*11fa71b9SJerome Forissier                 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
5331*11fa71b9SJerome Forissier                 {
5332*11fa71b9SJerome Forissier                     if( ( ret = mbedtls_ssl_send_alert_message( ssl,
5333*11fa71b9SJerome Forissier                                     MBEDTLS_SSL_ALERT_LEVEL_WARNING,
5334*11fa71b9SJerome Forissier                                     MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
5335*11fa71b9SJerome Forissier                     {
5336*11fa71b9SJerome Forissier                         return( ret );
5337*11fa71b9SJerome Forissier                     }
5338*11fa71b9SJerome Forissier                 }
5339*11fa71b9SJerome Forissier                 else
5340*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
5341*11fa71b9SJerome Forissier           MBEDTLS_SSL_PROTO_TLS1_2 */
5342*11fa71b9SJerome Forissier                 {
5343*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
5344*11fa71b9SJerome Forissier                     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
5345*11fa71b9SJerome Forissier                 }
5346*11fa71b9SJerome Forissier             }
5347*11fa71b9SJerome Forissier 
5348*11fa71b9SJerome Forissier             /* At this point, we don't know whether the renegotiation has been
5349*11fa71b9SJerome Forissier              * completed or not. The cases to consider are the following:
5350*11fa71b9SJerome Forissier              * 1) The renegotiation is complete. In this case, no new record
5351*11fa71b9SJerome Forissier              *    has been read yet.
5352*11fa71b9SJerome Forissier              * 2) The renegotiation is incomplete because the client received
5353*11fa71b9SJerome Forissier              *    an application data record while awaiting the ServerHello.
5354*11fa71b9SJerome Forissier              * 3) The renegotiation is incomplete because the client received
5355*11fa71b9SJerome Forissier              *    a non-handshake, non-application data message while awaiting
5356*11fa71b9SJerome Forissier              *    the ServerHello.
5357*11fa71b9SJerome Forissier              * In each of these case, looping will be the proper action:
5358*11fa71b9SJerome Forissier              * - For 1), the next iteration will read a new record and check
5359*11fa71b9SJerome Forissier              *   if it's application data.
5360*11fa71b9SJerome Forissier              * - For 2), the loop condition isn't satisfied as application data
5361*11fa71b9SJerome Forissier              *   is present, hence continue is the same as break
5362*11fa71b9SJerome Forissier              * - For 3), the loop condition is satisfied and read_record
5363*11fa71b9SJerome Forissier              *   will re-deliver the message that was held back by the client
5364*11fa71b9SJerome Forissier              *   when expecting the ServerHello.
5365*11fa71b9SJerome Forissier              */
5366*11fa71b9SJerome Forissier             continue;
5367*11fa71b9SJerome Forissier         }
5368*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
5369*11fa71b9SJerome Forissier         else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
5370*11fa71b9SJerome Forissier         {
5371*11fa71b9SJerome Forissier             if( ssl->conf->renego_max_records >= 0 )
5372*11fa71b9SJerome Forissier             {
5373*11fa71b9SJerome Forissier                 if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
5374*11fa71b9SJerome Forissier                 {
5375*11fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
5376*11fa71b9SJerome Forissier                                         "but not honored by client" ) );
5377*11fa71b9SJerome Forissier                     return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
5378*11fa71b9SJerome Forissier                 }
5379*11fa71b9SJerome Forissier             }
5380*11fa71b9SJerome Forissier         }
5381*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */
5382*11fa71b9SJerome Forissier 
5383*11fa71b9SJerome Forissier         /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
5384*11fa71b9SJerome Forissier         if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
5385*11fa71b9SJerome Forissier         {
5386*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
5387*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_WANT_READ );
5388*11fa71b9SJerome Forissier         }
5389*11fa71b9SJerome Forissier 
5390*11fa71b9SJerome Forissier         if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
5391*11fa71b9SJerome Forissier         {
5392*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
5393*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
5394*11fa71b9SJerome Forissier         }
5395*11fa71b9SJerome Forissier 
5396*11fa71b9SJerome Forissier         ssl->in_offt = ssl->in_msg;
5397*11fa71b9SJerome Forissier 
5398*11fa71b9SJerome Forissier         /* We're going to return something now, cancel timer,
5399*11fa71b9SJerome Forissier          * except if handshake (renegotiation) is in progress */
5400*11fa71b9SJerome Forissier         if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
5401*11fa71b9SJerome Forissier             mbedtls_ssl_set_timer( ssl, 0 );
5402*11fa71b9SJerome Forissier 
5403*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5404*11fa71b9SJerome Forissier         /* If we requested renego but received AppData, resend HelloRequest.
5405*11fa71b9SJerome Forissier          * Do it now, after setting in_offt, to avoid taking this branch
5406*11fa71b9SJerome Forissier          * again if ssl_write_hello_request() returns WANT_WRITE */
5407*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
5408*11fa71b9SJerome Forissier         if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
5409*11fa71b9SJerome Forissier             ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
5410*11fa71b9SJerome Forissier         {
5411*11fa71b9SJerome Forissier             if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 )
5412*11fa71b9SJerome Forissier             {
5413*11fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request",
5414*11fa71b9SJerome Forissier                                        ret );
5415*11fa71b9SJerome Forissier                 return( ret );
5416*11fa71b9SJerome Forissier             }
5417*11fa71b9SJerome Forissier         }
5418*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
5419*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
5420*11fa71b9SJerome Forissier     }
5421*11fa71b9SJerome Forissier 
5422*11fa71b9SJerome Forissier     n = ( len < ssl->in_msglen )
5423*11fa71b9SJerome Forissier         ? len : ssl->in_msglen;
5424*11fa71b9SJerome Forissier 
5425*11fa71b9SJerome Forissier     memcpy( buf, ssl->in_offt, n );
5426*11fa71b9SJerome Forissier     ssl->in_msglen -= n;
5427*11fa71b9SJerome Forissier 
5428*11fa71b9SJerome Forissier     if( ssl->in_msglen == 0 )
5429*11fa71b9SJerome Forissier     {
5430*11fa71b9SJerome Forissier         /* all bytes consumed */
5431*11fa71b9SJerome Forissier         ssl->in_offt = NULL;
5432*11fa71b9SJerome Forissier         ssl->keep_current_message = 0;
5433*11fa71b9SJerome Forissier     }
5434*11fa71b9SJerome Forissier     else
5435*11fa71b9SJerome Forissier     {
5436*11fa71b9SJerome Forissier         /* more data available */
5437*11fa71b9SJerome Forissier         ssl->in_offt += n;
5438*11fa71b9SJerome Forissier     }
5439*11fa71b9SJerome Forissier 
5440*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
5441*11fa71b9SJerome Forissier 
5442*11fa71b9SJerome Forissier     return( (int) n );
5443*11fa71b9SJerome Forissier }
5444*11fa71b9SJerome Forissier 
5445*11fa71b9SJerome Forissier /*
5446*11fa71b9SJerome Forissier  * Send application data to be encrypted by the SSL layer, taking care of max
5447*11fa71b9SJerome Forissier  * fragment length and buffer size.
5448*11fa71b9SJerome Forissier  *
5449*11fa71b9SJerome Forissier  * According to RFC 5246 Section 6.2.1:
5450*11fa71b9SJerome Forissier  *
5451*11fa71b9SJerome Forissier  *      Zero-length fragments of Application data MAY be sent as they are
5452*11fa71b9SJerome Forissier  *      potentially useful as a traffic analysis countermeasure.
5453*11fa71b9SJerome Forissier  *
5454*11fa71b9SJerome Forissier  * Therefore, it is possible that the input message length is 0 and the
5455*11fa71b9SJerome Forissier  * corresponding return code is 0 on success.
5456*11fa71b9SJerome Forissier  */
5457*11fa71b9SJerome Forissier static int ssl_write_real( mbedtls_ssl_context *ssl,
5458*11fa71b9SJerome Forissier                            const unsigned char *buf, size_t len )
5459*11fa71b9SJerome Forissier {
5460*11fa71b9SJerome Forissier     int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
5461*11fa71b9SJerome Forissier     const size_t max_len = (size_t) ret;
5462*11fa71b9SJerome Forissier 
5463*11fa71b9SJerome Forissier     if( ret < 0 )
5464*11fa71b9SJerome Forissier     {
5465*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret );
5466*11fa71b9SJerome Forissier         return( ret );
5467*11fa71b9SJerome Forissier     }
5468*11fa71b9SJerome Forissier 
5469*11fa71b9SJerome Forissier     if( len > max_len )
5470*11fa71b9SJerome Forissier     {
5471*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5472*11fa71b9SJerome Forissier         if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5473*11fa71b9SJerome Forissier         {
5474*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
5475*11fa71b9SJerome Forissier                                 "maximum fragment length: %d > %d",
5476*11fa71b9SJerome Forissier                                 len, max_len ) );
5477*11fa71b9SJerome Forissier             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
5478*11fa71b9SJerome Forissier         }
5479*11fa71b9SJerome Forissier         else
5480*11fa71b9SJerome Forissier #endif
5481*11fa71b9SJerome Forissier             len = max_len;
5482*11fa71b9SJerome Forissier     }
5483*11fa71b9SJerome Forissier 
5484*11fa71b9SJerome Forissier     if( ssl->out_left != 0 )
5485*11fa71b9SJerome Forissier     {
5486*11fa71b9SJerome Forissier         /*
5487*11fa71b9SJerome Forissier          * The user has previously tried to send the data and
5488*11fa71b9SJerome Forissier          * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
5489*11fa71b9SJerome Forissier          * written. In this case, we expect the high-level write function
5490*11fa71b9SJerome Forissier          * (e.g. mbedtls_ssl_write()) to be called with the same parameters
5491*11fa71b9SJerome Forissier          */
5492*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
5493*11fa71b9SJerome Forissier         {
5494*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
5495*11fa71b9SJerome Forissier             return( ret );
5496*11fa71b9SJerome Forissier         }
5497*11fa71b9SJerome Forissier     }
5498*11fa71b9SJerome Forissier     else
5499*11fa71b9SJerome Forissier     {
5500*11fa71b9SJerome Forissier         /*
5501*11fa71b9SJerome Forissier          * The user is trying to send a message the first time, so we need to
5502*11fa71b9SJerome Forissier          * copy the data into the internal buffers and setup the data structure
5503*11fa71b9SJerome Forissier          * to keep track of partial writes
5504*11fa71b9SJerome Forissier          */
5505*11fa71b9SJerome Forissier         ssl->out_msglen  = len;
5506*11fa71b9SJerome Forissier         ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
5507*11fa71b9SJerome Forissier         memcpy( ssl->out_msg, buf, len );
5508*11fa71b9SJerome Forissier 
5509*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
5510*11fa71b9SJerome Forissier         {
5511*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
5512*11fa71b9SJerome Forissier             return( ret );
5513*11fa71b9SJerome Forissier         }
5514*11fa71b9SJerome Forissier     }
5515*11fa71b9SJerome Forissier 
5516*11fa71b9SJerome Forissier     return( (int) len );
5517*11fa71b9SJerome Forissier }
5518*11fa71b9SJerome Forissier 
5519*11fa71b9SJerome Forissier /*
5520*11fa71b9SJerome Forissier  * Write application data, doing 1/n-1 splitting if necessary.
5521*11fa71b9SJerome Forissier  *
5522*11fa71b9SJerome Forissier  * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
5523*11fa71b9SJerome Forissier  * then the caller will call us again with the same arguments, so
5524*11fa71b9SJerome Forissier  * remember whether we already did the split or not.
5525*11fa71b9SJerome Forissier  */
5526*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
5527*11fa71b9SJerome Forissier static int ssl_write_split( mbedtls_ssl_context *ssl,
5528*11fa71b9SJerome Forissier                             const unsigned char *buf, size_t len )
5529*11fa71b9SJerome Forissier {
5530*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5531*11fa71b9SJerome Forissier 
5532*11fa71b9SJerome Forissier     if( ssl->conf->cbc_record_splitting ==
5533*11fa71b9SJerome Forissier             MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
5534*11fa71b9SJerome Forissier         len <= 1 ||
5535*11fa71b9SJerome Forissier         ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
5536*11fa71b9SJerome Forissier         mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
5537*11fa71b9SJerome Forissier                                 != MBEDTLS_MODE_CBC )
5538*11fa71b9SJerome Forissier     {
5539*11fa71b9SJerome Forissier         return( ssl_write_real( ssl, buf, len ) );
5540*11fa71b9SJerome Forissier     }
5541*11fa71b9SJerome Forissier 
5542*11fa71b9SJerome Forissier     if( ssl->split_done == 0 )
5543*11fa71b9SJerome Forissier     {
5544*11fa71b9SJerome Forissier         if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
5545*11fa71b9SJerome Forissier             return( ret );
5546*11fa71b9SJerome Forissier         ssl->split_done = 1;
5547*11fa71b9SJerome Forissier     }
5548*11fa71b9SJerome Forissier 
5549*11fa71b9SJerome Forissier     if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
5550*11fa71b9SJerome Forissier         return( ret );
5551*11fa71b9SJerome Forissier     ssl->split_done = 0;
5552*11fa71b9SJerome Forissier 
5553*11fa71b9SJerome Forissier     return( ret + 1 );
5554*11fa71b9SJerome Forissier }
5555*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
5556*11fa71b9SJerome Forissier 
5557*11fa71b9SJerome Forissier /*
5558*11fa71b9SJerome Forissier  * Write application data (public-facing wrapper)
5559*11fa71b9SJerome Forissier  */
5560*11fa71b9SJerome Forissier int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
5561*11fa71b9SJerome Forissier {
5562*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5563*11fa71b9SJerome Forissier 
5564*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
5565*11fa71b9SJerome Forissier 
5566*11fa71b9SJerome Forissier     if( ssl == NULL || ssl->conf == NULL )
5567*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
5568*11fa71b9SJerome Forissier 
5569*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
5570*11fa71b9SJerome Forissier     if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
5571*11fa71b9SJerome Forissier     {
5572*11fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
5573*11fa71b9SJerome Forissier         return( ret );
5574*11fa71b9SJerome Forissier     }
5575*11fa71b9SJerome Forissier #endif
5576*11fa71b9SJerome Forissier 
5577*11fa71b9SJerome Forissier     if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
5578*11fa71b9SJerome Forissier     {
5579*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
5580*11fa71b9SJerome Forissier         {
5581*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
5582*11fa71b9SJerome Forissier             return( ret );
5583*11fa71b9SJerome Forissier         }
5584*11fa71b9SJerome Forissier     }
5585*11fa71b9SJerome Forissier 
5586*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
5587*11fa71b9SJerome Forissier     ret = ssl_write_split( ssl, buf, len );
5588*11fa71b9SJerome Forissier #else
5589*11fa71b9SJerome Forissier     ret = ssl_write_real( ssl, buf, len );
5590*11fa71b9SJerome Forissier #endif
5591*11fa71b9SJerome Forissier 
5592*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
5593*11fa71b9SJerome Forissier 
5594*11fa71b9SJerome Forissier     return( ret );
5595*11fa71b9SJerome Forissier }
5596*11fa71b9SJerome Forissier 
5597*11fa71b9SJerome Forissier /*
5598*11fa71b9SJerome Forissier  * Notify the peer that the connection is being closed
5599*11fa71b9SJerome Forissier  */
5600*11fa71b9SJerome Forissier int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
5601*11fa71b9SJerome Forissier {
5602*11fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5603*11fa71b9SJerome Forissier 
5604*11fa71b9SJerome Forissier     if( ssl == NULL || ssl->conf == NULL )
5605*11fa71b9SJerome Forissier         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
5606*11fa71b9SJerome Forissier 
5607*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
5608*11fa71b9SJerome Forissier 
5609*11fa71b9SJerome Forissier     if( ssl->out_left != 0 )
5610*11fa71b9SJerome Forissier         return( mbedtls_ssl_flush_output( ssl ) );
5611*11fa71b9SJerome Forissier 
5612*11fa71b9SJerome Forissier     if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
5613*11fa71b9SJerome Forissier     {
5614*11fa71b9SJerome Forissier         if( ( ret = mbedtls_ssl_send_alert_message( ssl,
5615*11fa71b9SJerome Forissier                         MBEDTLS_SSL_ALERT_LEVEL_WARNING,
5616*11fa71b9SJerome Forissier                         MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
5617*11fa71b9SJerome Forissier         {
5618*11fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
5619*11fa71b9SJerome Forissier             return( ret );
5620*11fa71b9SJerome Forissier         }
5621*11fa71b9SJerome Forissier     }
5622*11fa71b9SJerome Forissier 
5623*11fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
5624*11fa71b9SJerome Forissier 
5625*11fa71b9SJerome Forissier     return( 0 );
5626*11fa71b9SJerome Forissier }
5627*11fa71b9SJerome Forissier 
5628*11fa71b9SJerome Forissier void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
5629*11fa71b9SJerome Forissier {
5630*11fa71b9SJerome Forissier     if( transform == NULL )
5631*11fa71b9SJerome Forissier         return;
5632*11fa71b9SJerome Forissier 
5633*11fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT)
5634*11fa71b9SJerome Forissier     deflateEnd( &transform->ctx_deflate );
5635*11fa71b9SJerome Forissier     inflateEnd( &transform->ctx_inflate );
5636*11fa71b9SJerome Forissier #endif
5637*11fa71b9SJerome Forissier 
5638*11fa71b9SJerome Forissier     mbedtls_cipher_free( &transform->cipher_ctx_enc );
5639*11fa71b9SJerome Forissier     mbedtls_cipher_free( &transform->cipher_ctx_dec );
5640*11fa71b9SJerome Forissier 
5641*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
5642*11fa71b9SJerome Forissier     mbedtls_md_free( &transform->md_ctx_enc );
5643*11fa71b9SJerome Forissier     mbedtls_md_free( &transform->md_ctx_dec );
5644*11fa71b9SJerome Forissier #endif
5645*11fa71b9SJerome Forissier 
5646*11fa71b9SJerome Forissier     mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
5647*11fa71b9SJerome Forissier }
5648*11fa71b9SJerome Forissier 
5649*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5650*11fa71b9SJerome Forissier 
5651*11fa71b9SJerome Forissier void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl )
5652*11fa71b9SJerome Forissier {
5653*11fa71b9SJerome Forissier     unsigned offset;
5654*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
5655*11fa71b9SJerome Forissier 
5656*11fa71b9SJerome Forissier     if( hs == NULL )
5657*11fa71b9SJerome Forissier         return;
5658*11fa71b9SJerome Forissier 
5659*11fa71b9SJerome Forissier     ssl_free_buffered_record( ssl );
5660*11fa71b9SJerome Forissier 
5661*11fa71b9SJerome Forissier     for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
5662*11fa71b9SJerome Forissier         ssl_buffering_free_slot( ssl, offset );
5663*11fa71b9SJerome Forissier }
5664*11fa71b9SJerome Forissier 
5665*11fa71b9SJerome Forissier static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
5666*11fa71b9SJerome Forissier                                      uint8_t slot )
5667*11fa71b9SJerome Forissier {
5668*11fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
5669*11fa71b9SJerome Forissier     mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
5670*11fa71b9SJerome Forissier 
5671*11fa71b9SJerome Forissier     if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS )
5672*11fa71b9SJerome Forissier         return;
5673*11fa71b9SJerome Forissier 
5674*11fa71b9SJerome Forissier     if( hs_buf->is_valid == 1 )
5675*11fa71b9SJerome Forissier     {
5676*11fa71b9SJerome Forissier         hs->buffering.total_bytes_buffered -= hs_buf->data_len;
5677*11fa71b9SJerome Forissier         mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len );
5678*11fa71b9SJerome Forissier         mbedtls_free( hs_buf->data );
5679*11fa71b9SJerome Forissier         memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
5680*11fa71b9SJerome Forissier     }
5681*11fa71b9SJerome Forissier }
5682*11fa71b9SJerome Forissier 
5683*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
5684*11fa71b9SJerome Forissier 
5685*11fa71b9SJerome Forissier /*
5686*11fa71b9SJerome Forissier  * Convert version numbers to/from wire format
5687*11fa71b9SJerome Forissier  * and, for DTLS, to/from TLS equivalent.
5688*11fa71b9SJerome Forissier  *
5689*11fa71b9SJerome Forissier  * For TLS this is the identity.
5690*11fa71b9SJerome Forissier  * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
5691*11fa71b9SJerome Forissier  * 1.0 <-> 3.2      (DTLS 1.0 is based on TLS 1.1)
5692*11fa71b9SJerome Forissier  * 1.x <-> 3.x+1    for x != 0 (DTLS 1.2 based on TLS 1.2)
5693*11fa71b9SJerome Forissier  */
5694*11fa71b9SJerome Forissier void mbedtls_ssl_write_version( int major, int minor, int transport,
5695*11fa71b9SJerome Forissier                         unsigned char ver[2] )
5696*11fa71b9SJerome Forissier {
5697*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5698*11fa71b9SJerome Forissier     if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5699*11fa71b9SJerome Forissier     {
5700*11fa71b9SJerome Forissier         if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
5701*11fa71b9SJerome Forissier             --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
5702*11fa71b9SJerome Forissier 
5703*11fa71b9SJerome Forissier         ver[0] = (unsigned char)( 255 - ( major - 2 ) );
5704*11fa71b9SJerome Forissier         ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
5705*11fa71b9SJerome Forissier     }
5706*11fa71b9SJerome Forissier     else
5707*11fa71b9SJerome Forissier #else
5708*11fa71b9SJerome Forissier     ((void) transport);
5709*11fa71b9SJerome Forissier #endif
5710*11fa71b9SJerome Forissier     {
5711*11fa71b9SJerome Forissier         ver[0] = (unsigned char) major;
5712*11fa71b9SJerome Forissier         ver[1] = (unsigned char) minor;
5713*11fa71b9SJerome Forissier     }
5714*11fa71b9SJerome Forissier }
5715*11fa71b9SJerome Forissier 
5716*11fa71b9SJerome Forissier void mbedtls_ssl_read_version( int *major, int *minor, int transport,
5717*11fa71b9SJerome Forissier                        const unsigned char ver[2] )
5718*11fa71b9SJerome Forissier {
5719*11fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
5720*11fa71b9SJerome Forissier     if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5721*11fa71b9SJerome Forissier     {
5722*11fa71b9SJerome Forissier         *major = 255 - ver[0] + 2;
5723*11fa71b9SJerome Forissier         *minor = 255 - ver[1] + 1;
5724*11fa71b9SJerome Forissier 
5725*11fa71b9SJerome Forissier         if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
5726*11fa71b9SJerome Forissier             ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
5727*11fa71b9SJerome Forissier     }
5728*11fa71b9SJerome Forissier     else
5729*11fa71b9SJerome Forissier #else
5730*11fa71b9SJerome Forissier     ((void) transport);
5731*11fa71b9SJerome Forissier #endif
5732*11fa71b9SJerome Forissier     {
5733*11fa71b9SJerome Forissier         *major = ver[0];
5734*11fa71b9SJerome Forissier         *minor = ver[1];
5735*11fa71b9SJerome Forissier     }
5736*11fa71b9SJerome Forissier }
5737*11fa71b9SJerome Forissier 
5738*11fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_TLS_C */
5739