Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /*
marcozecchini 0:9fca2b23d0ba 2 * SSLv3/TLSv1 shared functions
marcozecchini 0:9fca2b23d0ba 3 *
marcozecchini 0:9fca2b23d0ba 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
marcozecchini 0:9fca2b23d0ba 5 * SPDX-License-Identifier: Apache-2.0
marcozecchini 0:9fca2b23d0ba 6 *
marcozecchini 0:9fca2b23d0ba 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
marcozecchini 0:9fca2b23d0ba 8 * not use this file except in compliance with the License.
marcozecchini 0:9fca2b23d0ba 9 * You may obtain a copy of the License at
marcozecchini 0:9fca2b23d0ba 10 *
marcozecchini 0:9fca2b23d0ba 11 * http://www.apache.org/licenses/LICENSE-2.0
marcozecchini 0:9fca2b23d0ba 12 *
marcozecchini 0:9fca2b23d0ba 13 * Unless required by applicable law or agreed to in writing, software
marcozecchini 0:9fca2b23d0ba 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
marcozecchini 0:9fca2b23d0ba 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
marcozecchini 0:9fca2b23d0ba 16 * See the License for the specific language governing permissions and
marcozecchini 0:9fca2b23d0ba 17 * limitations under the License.
marcozecchini 0:9fca2b23d0ba 18 *
marcozecchini 0:9fca2b23d0ba 19 * This file is part of mbed TLS (https://tls.mbed.org)
marcozecchini 0:9fca2b23d0ba 20 */
marcozecchini 0:9fca2b23d0ba 21 /*
marcozecchini 0:9fca2b23d0ba 22 * The SSL 3.0 specification was drafted by Netscape in 1996,
marcozecchini 0:9fca2b23d0ba 23 * and became an IETF standard in 1999.
marcozecchini 0:9fca2b23d0ba 24 *
marcozecchini 0:9fca2b23d0ba 25 * http://wp.netscape.com/eng/ssl3/
marcozecchini 0:9fca2b23d0ba 26 * http://www.ietf.org/rfc/rfc2246.txt
marcozecchini 0:9fca2b23d0ba 27 * http://www.ietf.org/rfc/rfc4346.txt
marcozecchini 0:9fca2b23d0ba 28 */
marcozecchini 0:9fca2b23d0ba 29
marcozecchini 0:9fca2b23d0ba 30 #if !defined(MBEDTLS_CONFIG_FILE)
marcozecchini 0:9fca2b23d0ba 31 #include "mbedtls/config.h"
marcozecchini 0:9fca2b23d0ba 32 #else
marcozecchini 0:9fca2b23d0ba 33 #include MBEDTLS_CONFIG_FILE
marcozecchini 0:9fca2b23d0ba 34 #endif
marcozecchini 0:9fca2b23d0ba 35
marcozecchini 0:9fca2b23d0ba 36 #if defined(MBEDTLS_SSL_TLS_C)
marcozecchini 0:9fca2b23d0ba 37
marcozecchini 0:9fca2b23d0ba 38 #if defined(MBEDTLS_PLATFORM_C)
marcozecchini 0:9fca2b23d0ba 39 #include "mbedtls/platform.h"
marcozecchini 0:9fca2b23d0ba 40 #else
marcozecchini 0:9fca2b23d0ba 41 #include <stdlib.h>
marcozecchini 0:9fca2b23d0ba 42 #define mbedtls_calloc calloc
marcozecchini 0:9fca2b23d0ba 43 #define mbedtls_free free
marcozecchini 0:9fca2b23d0ba 44 #endif
marcozecchini 0:9fca2b23d0ba 45
marcozecchini 0:9fca2b23d0ba 46 #include "mbedtls/debug.h"
marcozecchini 0:9fca2b23d0ba 47 #include "mbedtls/ssl.h"
marcozecchini 0:9fca2b23d0ba 48 #include "mbedtls/ssl_internal.h"
marcozecchini 0:9fca2b23d0ba 49
marcozecchini 0:9fca2b23d0ba 50 #include <string.h>
marcozecchini 0:9fca2b23d0ba 51
marcozecchini 0:9fca2b23d0ba 52 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 53 #include "mbedtls/oid.h"
marcozecchini 0:9fca2b23d0ba 54 #endif
marcozecchini 0:9fca2b23d0ba 55
marcozecchini 0:9fca2b23d0ba 56 /* Implementation that should never be optimized out by the compiler */
marcozecchini 0:9fca2b23d0ba 57 static void mbedtls_zeroize( void *v, size_t n ) {
marcozecchini 0:9fca2b23d0ba 58 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
marcozecchini 0:9fca2b23d0ba 59 }
marcozecchini 0:9fca2b23d0ba 60
marcozecchini 0:9fca2b23d0ba 61 /* Length of the "epoch" field in the record header */
marcozecchini 0:9fca2b23d0ba 62 static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 63 {
marcozecchini 0:9fca2b23d0ba 64 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 65 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 66 return( 2 );
marcozecchini 0:9fca2b23d0ba 67 #else
marcozecchini 0:9fca2b23d0ba 68 ((void) ssl);
marcozecchini 0:9fca2b23d0ba 69 #endif
marcozecchini 0:9fca2b23d0ba 70 return( 0 );
marcozecchini 0:9fca2b23d0ba 71 }
marcozecchini 0:9fca2b23d0ba 72
marcozecchini 0:9fca2b23d0ba 73 /*
marcozecchini 0:9fca2b23d0ba 74 * Start a timer.
marcozecchini 0:9fca2b23d0ba 75 * Passing millisecs = 0 cancels a running timer.
marcozecchini 0:9fca2b23d0ba 76 */
marcozecchini 0:9fca2b23d0ba 77 static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
marcozecchini 0:9fca2b23d0ba 78 {
marcozecchini 0:9fca2b23d0ba 79 if( ssl->f_set_timer == NULL )
marcozecchini 0:9fca2b23d0ba 80 return;
marcozecchini 0:9fca2b23d0ba 81
marcozecchini 0:9fca2b23d0ba 82 MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
marcozecchini 0:9fca2b23d0ba 83 ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
marcozecchini 0:9fca2b23d0ba 84 }
marcozecchini 0:9fca2b23d0ba 85
marcozecchini 0:9fca2b23d0ba 86 /*
marcozecchini 0:9fca2b23d0ba 87 * Return -1 is timer is expired, 0 if it isn't.
marcozecchini 0:9fca2b23d0ba 88 */
marcozecchini 0:9fca2b23d0ba 89 static int ssl_check_timer( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 90 {
marcozecchini 0:9fca2b23d0ba 91 if( ssl->f_get_timer == NULL )
marcozecchini 0:9fca2b23d0ba 92 return( 0 );
marcozecchini 0:9fca2b23d0ba 93
marcozecchini 0:9fca2b23d0ba 94 if( ssl->f_get_timer( ssl->p_timer ) == 2 )
marcozecchini 0:9fca2b23d0ba 95 {
marcozecchini 0:9fca2b23d0ba 96 MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
marcozecchini 0:9fca2b23d0ba 97 return( -1 );
marcozecchini 0:9fca2b23d0ba 98 }
marcozecchini 0:9fca2b23d0ba 99
marcozecchini 0:9fca2b23d0ba 100 return( 0 );
marcozecchini 0:9fca2b23d0ba 101 }
marcozecchini 0:9fca2b23d0ba 102
marcozecchini 0:9fca2b23d0ba 103 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 104 /*
marcozecchini 0:9fca2b23d0ba 105 * Double the retransmit timeout value, within the allowed range,
marcozecchini 0:9fca2b23d0ba 106 * returning -1 if the maximum value has already been reached.
marcozecchini 0:9fca2b23d0ba 107 */
marcozecchini 0:9fca2b23d0ba 108 static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 109 {
marcozecchini 0:9fca2b23d0ba 110 uint32_t new_timeout;
marcozecchini 0:9fca2b23d0ba 111
marcozecchini 0:9fca2b23d0ba 112 if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
marcozecchini 0:9fca2b23d0ba 113 return( -1 );
marcozecchini 0:9fca2b23d0ba 114
marcozecchini 0:9fca2b23d0ba 115 new_timeout = 2 * ssl->handshake->retransmit_timeout;
marcozecchini 0:9fca2b23d0ba 116
marcozecchini 0:9fca2b23d0ba 117 /* Avoid arithmetic overflow and range overflow */
marcozecchini 0:9fca2b23d0ba 118 if( new_timeout < ssl->handshake->retransmit_timeout ||
marcozecchini 0:9fca2b23d0ba 119 new_timeout > ssl->conf->hs_timeout_max )
marcozecchini 0:9fca2b23d0ba 120 {
marcozecchini 0:9fca2b23d0ba 121 new_timeout = ssl->conf->hs_timeout_max;
marcozecchini 0:9fca2b23d0ba 122 }
marcozecchini 0:9fca2b23d0ba 123
marcozecchini 0:9fca2b23d0ba 124 ssl->handshake->retransmit_timeout = new_timeout;
marcozecchini 0:9fca2b23d0ba 125 MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
marcozecchini 0:9fca2b23d0ba 126 ssl->handshake->retransmit_timeout ) );
marcozecchini 0:9fca2b23d0ba 127
marcozecchini 0:9fca2b23d0ba 128 return( 0 );
marcozecchini 0:9fca2b23d0ba 129 }
marcozecchini 0:9fca2b23d0ba 130
marcozecchini 0:9fca2b23d0ba 131 static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 132 {
marcozecchini 0:9fca2b23d0ba 133 ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
marcozecchini 0:9fca2b23d0ba 134 MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
marcozecchini 0:9fca2b23d0ba 135 ssl->handshake->retransmit_timeout ) );
marcozecchini 0:9fca2b23d0ba 136 }
marcozecchini 0:9fca2b23d0ba 137 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 138
marcozecchini 0:9fca2b23d0ba 139 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
marcozecchini 0:9fca2b23d0ba 140 /*
marcozecchini 0:9fca2b23d0ba 141 * Convert max_fragment_length codes to length.
marcozecchini 0:9fca2b23d0ba 142 * RFC 6066 says:
marcozecchini 0:9fca2b23d0ba 143 * enum{
marcozecchini 0:9fca2b23d0ba 144 * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
marcozecchini 0:9fca2b23d0ba 145 * } MaxFragmentLength;
marcozecchini 0:9fca2b23d0ba 146 * and we add 0 -> extension unused
marcozecchini 0:9fca2b23d0ba 147 */
marcozecchini 0:9fca2b23d0ba 148 static unsigned int mfl_code_to_length[MBEDTLS_SSL_MAX_FRAG_LEN_INVALID] =
marcozecchini 0:9fca2b23d0ba 149 {
marcozecchini 0:9fca2b23d0ba 150 MBEDTLS_SSL_MAX_CONTENT_LEN, /* MBEDTLS_SSL_MAX_FRAG_LEN_NONE */
marcozecchini 0:9fca2b23d0ba 151 512, /* MBEDTLS_SSL_MAX_FRAG_LEN_512 */
marcozecchini 0:9fca2b23d0ba 152 1024, /* MBEDTLS_SSL_MAX_FRAG_LEN_1024 */
marcozecchini 0:9fca2b23d0ba 153 2048, /* MBEDTLS_SSL_MAX_FRAG_LEN_2048 */
marcozecchini 0:9fca2b23d0ba 154 4096, /* MBEDTLS_SSL_MAX_FRAG_LEN_4096 */
marcozecchini 0:9fca2b23d0ba 155 };
marcozecchini 0:9fca2b23d0ba 156 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
marcozecchini 0:9fca2b23d0ba 157
marcozecchini 0:9fca2b23d0ba 158 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 159 static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src )
marcozecchini 0:9fca2b23d0ba 160 {
marcozecchini 0:9fca2b23d0ba 161 mbedtls_ssl_session_free( dst );
marcozecchini 0:9fca2b23d0ba 162 memcpy( dst, src, sizeof( mbedtls_ssl_session ) );
marcozecchini 0:9fca2b23d0ba 163
marcozecchini 0:9fca2b23d0ba 164 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 165 if( src->peer_cert != NULL )
marcozecchini 0:9fca2b23d0ba 166 {
marcozecchini 0:9fca2b23d0ba 167 int ret;
marcozecchini 0:9fca2b23d0ba 168
marcozecchini 0:9fca2b23d0ba 169 dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) );
marcozecchini 0:9fca2b23d0ba 170 if( dst->peer_cert == NULL )
marcozecchini 0:9fca2b23d0ba 171 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 172
marcozecchini 0:9fca2b23d0ba 173 mbedtls_x509_crt_init( dst->peer_cert );
marcozecchini 0:9fca2b23d0ba 174
marcozecchini 0:9fca2b23d0ba 175 if( ( ret = mbedtls_x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p,
marcozecchini 0:9fca2b23d0ba 176 src->peer_cert->raw.len ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 177 {
marcozecchini 0:9fca2b23d0ba 178 mbedtls_free( dst->peer_cert );
marcozecchini 0:9fca2b23d0ba 179 dst->peer_cert = NULL;
marcozecchini 0:9fca2b23d0ba 180 return( ret );
marcozecchini 0:9fca2b23d0ba 181 }
marcozecchini 0:9fca2b23d0ba 182 }
marcozecchini 0:9fca2b23d0ba 183 #endif /* MBEDTLS_X509_CRT_PARSE_C */
marcozecchini 0:9fca2b23d0ba 184
marcozecchini 0:9fca2b23d0ba 185 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 186 if( src->ticket != NULL )
marcozecchini 0:9fca2b23d0ba 187 {
marcozecchini 0:9fca2b23d0ba 188 dst->ticket = mbedtls_calloc( 1, src->ticket_len );
marcozecchini 0:9fca2b23d0ba 189 if( dst->ticket == NULL )
marcozecchini 0:9fca2b23d0ba 190 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 191
marcozecchini 0:9fca2b23d0ba 192 memcpy( dst->ticket, src->ticket, src->ticket_len );
marcozecchini 0:9fca2b23d0ba 193 }
marcozecchini 0:9fca2b23d0ba 194 #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 195
marcozecchini 0:9fca2b23d0ba 196 return( 0 );
marcozecchini 0:9fca2b23d0ba 197 }
marcozecchini 0:9fca2b23d0ba 198 #endif /* MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 199
marcozecchini 0:9fca2b23d0ba 200 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 201 int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 202 const unsigned char *key_enc, const unsigned char *key_dec,
marcozecchini 0:9fca2b23d0ba 203 size_t keylen,
marcozecchini 0:9fca2b23d0ba 204 const unsigned char *iv_enc, const unsigned char *iv_dec,
marcozecchini 0:9fca2b23d0ba 205 size_t ivlen,
marcozecchini 0:9fca2b23d0ba 206 const unsigned char *mac_enc, const unsigned char *mac_dec,
marcozecchini 0:9fca2b23d0ba 207 size_t maclen ) = NULL;
marcozecchini 0:9fca2b23d0ba 208 int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
marcozecchini 0:9fca2b23d0ba 209 int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
marcozecchini 0:9fca2b23d0ba 210 int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
marcozecchini 0:9fca2b23d0ba 211 int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
marcozecchini 0:9fca2b23d0ba 212 int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
marcozecchini 0:9fca2b23d0ba 213 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
marcozecchini 0:9fca2b23d0ba 214
marcozecchini 0:9fca2b23d0ba 215 /*
marcozecchini 0:9fca2b23d0ba 216 * Key material generation
marcozecchini 0:9fca2b23d0ba 217 */
marcozecchini 0:9fca2b23d0ba 218 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 219 static int ssl3_prf( const unsigned char *secret, size_t slen,
marcozecchini 0:9fca2b23d0ba 220 const char *label,
marcozecchini 0:9fca2b23d0ba 221 const unsigned char *random, size_t rlen,
marcozecchini 0:9fca2b23d0ba 222 unsigned char *dstbuf, size_t dlen )
marcozecchini 0:9fca2b23d0ba 223 {
marcozecchini 0:9fca2b23d0ba 224 size_t i;
marcozecchini 0:9fca2b23d0ba 225 mbedtls_md5_context md5;
marcozecchini 0:9fca2b23d0ba 226 mbedtls_sha1_context sha1;
marcozecchini 0:9fca2b23d0ba 227 unsigned char padding[16];
marcozecchini 0:9fca2b23d0ba 228 unsigned char sha1sum[20];
marcozecchini 0:9fca2b23d0ba 229 ((void)label);
marcozecchini 0:9fca2b23d0ba 230
marcozecchini 0:9fca2b23d0ba 231 mbedtls_md5_init( &md5 );
marcozecchini 0:9fca2b23d0ba 232 mbedtls_sha1_init( &sha1 );
marcozecchini 0:9fca2b23d0ba 233
marcozecchini 0:9fca2b23d0ba 234 /*
marcozecchini 0:9fca2b23d0ba 235 * SSLv3:
marcozecchini 0:9fca2b23d0ba 236 * block =
marcozecchini 0:9fca2b23d0ba 237 * MD5( secret + SHA1( 'A' + secret + random ) ) +
marcozecchini 0:9fca2b23d0ba 238 * MD5( secret + SHA1( 'BB' + secret + random ) ) +
marcozecchini 0:9fca2b23d0ba 239 * MD5( secret + SHA1( 'CCC' + secret + random ) ) +
marcozecchini 0:9fca2b23d0ba 240 * ...
marcozecchini 0:9fca2b23d0ba 241 */
marcozecchini 0:9fca2b23d0ba 242 for( i = 0; i < dlen / 16; i++ )
marcozecchini 0:9fca2b23d0ba 243 {
marcozecchini 0:9fca2b23d0ba 244 memset( padding, (unsigned char) ('A' + i), 1 + i );
marcozecchini 0:9fca2b23d0ba 245
marcozecchini 0:9fca2b23d0ba 246 mbedtls_sha1_starts( &sha1 );
marcozecchini 0:9fca2b23d0ba 247 mbedtls_sha1_update( &sha1, padding, 1 + i );
marcozecchini 0:9fca2b23d0ba 248 mbedtls_sha1_update( &sha1, secret, slen );
marcozecchini 0:9fca2b23d0ba 249 mbedtls_sha1_update( &sha1, random, rlen );
marcozecchini 0:9fca2b23d0ba 250 mbedtls_sha1_finish( &sha1, sha1sum );
marcozecchini 0:9fca2b23d0ba 251
marcozecchini 0:9fca2b23d0ba 252 mbedtls_md5_starts( &md5 );
marcozecchini 0:9fca2b23d0ba 253 mbedtls_md5_update( &md5, secret, slen );
marcozecchini 0:9fca2b23d0ba 254 mbedtls_md5_update( &md5, sha1sum, 20 );
marcozecchini 0:9fca2b23d0ba 255 mbedtls_md5_finish( &md5, dstbuf + i * 16 );
marcozecchini 0:9fca2b23d0ba 256 }
marcozecchini 0:9fca2b23d0ba 257
marcozecchini 0:9fca2b23d0ba 258 mbedtls_md5_free( &md5 );
marcozecchini 0:9fca2b23d0ba 259 mbedtls_sha1_free( &sha1 );
marcozecchini 0:9fca2b23d0ba 260
marcozecchini 0:9fca2b23d0ba 261 mbedtls_zeroize( padding, sizeof( padding ) );
marcozecchini 0:9fca2b23d0ba 262 mbedtls_zeroize( sha1sum, sizeof( sha1sum ) );
marcozecchini 0:9fca2b23d0ba 263
marcozecchini 0:9fca2b23d0ba 264 return( 0 );
marcozecchini 0:9fca2b23d0ba 265 }
marcozecchini 0:9fca2b23d0ba 266 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 267
marcozecchini 0:9fca2b23d0ba 268 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 269 static int tls1_prf( const unsigned char *secret, size_t slen,
marcozecchini 0:9fca2b23d0ba 270 const char *label,
marcozecchini 0:9fca2b23d0ba 271 const unsigned char *random, size_t rlen,
marcozecchini 0:9fca2b23d0ba 272 unsigned char *dstbuf, size_t dlen )
marcozecchini 0:9fca2b23d0ba 273 {
marcozecchini 0:9fca2b23d0ba 274 size_t nb, hs;
marcozecchini 0:9fca2b23d0ba 275 size_t i, j, k;
marcozecchini 0:9fca2b23d0ba 276 const unsigned char *S1, *S2;
marcozecchini 0:9fca2b23d0ba 277 unsigned char tmp[128];
marcozecchini 0:9fca2b23d0ba 278 unsigned char h_i[20];
marcozecchini 0:9fca2b23d0ba 279 const mbedtls_md_info_t *md_info;
marcozecchini 0:9fca2b23d0ba 280 mbedtls_md_context_t md_ctx;
marcozecchini 0:9fca2b23d0ba 281 int ret;
marcozecchini 0:9fca2b23d0ba 282
marcozecchini 0:9fca2b23d0ba 283 mbedtls_md_init( &md_ctx );
marcozecchini 0:9fca2b23d0ba 284
marcozecchini 0:9fca2b23d0ba 285 if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
marcozecchini 0:9fca2b23d0ba 286 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 287
marcozecchini 0:9fca2b23d0ba 288 hs = ( slen + 1 ) / 2;
marcozecchini 0:9fca2b23d0ba 289 S1 = secret;
marcozecchini 0:9fca2b23d0ba 290 S2 = secret + slen - hs;
marcozecchini 0:9fca2b23d0ba 291
marcozecchini 0:9fca2b23d0ba 292 nb = strlen( label );
marcozecchini 0:9fca2b23d0ba 293 memcpy( tmp + 20, label, nb );
marcozecchini 0:9fca2b23d0ba 294 memcpy( tmp + 20 + nb, random, rlen );
marcozecchini 0:9fca2b23d0ba 295 nb += rlen;
marcozecchini 0:9fca2b23d0ba 296
marcozecchini 0:9fca2b23d0ba 297 /*
marcozecchini 0:9fca2b23d0ba 298 * First compute P_md5(secret,label+random)[0..dlen]
marcozecchini 0:9fca2b23d0ba 299 */
marcozecchini 0:9fca2b23d0ba 300 if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 301 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 302
marcozecchini 0:9fca2b23d0ba 303 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 304 return( ret );
marcozecchini 0:9fca2b23d0ba 305
marcozecchini 0:9fca2b23d0ba 306 mbedtls_md_hmac_starts( &md_ctx, S1, hs );
marcozecchini 0:9fca2b23d0ba 307 mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
marcozecchini 0:9fca2b23d0ba 308 mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
marcozecchini 0:9fca2b23d0ba 309
marcozecchini 0:9fca2b23d0ba 310 for( i = 0; i < dlen; i += 16 )
marcozecchini 0:9fca2b23d0ba 311 {
marcozecchini 0:9fca2b23d0ba 312 mbedtls_md_hmac_reset ( &md_ctx );
marcozecchini 0:9fca2b23d0ba 313 mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb );
marcozecchini 0:9fca2b23d0ba 314 mbedtls_md_hmac_finish( &md_ctx, h_i );
marcozecchini 0:9fca2b23d0ba 315
marcozecchini 0:9fca2b23d0ba 316 mbedtls_md_hmac_reset ( &md_ctx );
marcozecchini 0:9fca2b23d0ba 317 mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 );
marcozecchini 0:9fca2b23d0ba 318 mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
marcozecchini 0:9fca2b23d0ba 319
marcozecchini 0:9fca2b23d0ba 320 k = ( i + 16 > dlen ) ? dlen % 16 : 16;
marcozecchini 0:9fca2b23d0ba 321
marcozecchini 0:9fca2b23d0ba 322 for( j = 0; j < k; j++ )
marcozecchini 0:9fca2b23d0ba 323 dstbuf[i + j] = h_i[j];
marcozecchini 0:9fca2b23d0ba 324 }
marcozecchini 0:9fca2b23d0ba 325
marcozecchini 0:9fca2b23d0ba 326 mbedtls_md_free( &md_ctx );
marcozecchini 0:9fca2b23d0ba 327
marcozecchini 0:9fca2b23d0ba 328 /*
marcozecchini 0:9fca2b23d0ba 329 * XOR out with P_sha1(secret,label+random)[0..dlen]
marcozecchini 0:9fca2b23d0ba 330 */
marcozecchini 0:9fca2b23d0ba 331 if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 332 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 333
marcozecchini 0:9fca2b23d0ba 334 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 335 return( ret );
marcozecchini 0:9fca2b23d0ba 336
marcozecchini 0:9fca2b23d0ba 337 mbedtls_md_hmac_starts( &md_ctx, S2, hs );
marcozecchini 0:9fca2b23d0ba 338 mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
marcozecchini 0:9fca2b23d0ba 339 mbedtls_md_hmac_finish( &md_ctx, tmp );
marcozecchini 0:9fca2b23d0ba 340
marcozecchini 0:9fca2b23d0ba 341 for( i = 0; i < dlen; i += 20 )
marcozecchini 0:9fca2b23d0ba 342 {
marcozecchini 0:9fca2b23d0ba 343 mbedtls_md_hmac_reset ( &md_ctx );
marcozecchini 0:9fca2b23d0ba 344 mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb );
marcozecchini 0:9fca2b23d0ba 345 mbedtls_md_hmac_finish( &md_ctx, h_i );
marcozecchini 0:9fca2b23d0ba 346
marcozecchini 0:9fca2b23d0ba 347 mbedtls_md_hmac_reset ( &md_ctx );
marcozecchini 0:9fca2b23d0ba 348 mbedtls_md_hmac_update( &md_ctx, tmp, 20 );
marcozecchini 0:9fca2b23d0ba 349 mbedtls_md_hmac_finish( &md_ctx, tmp );
marcozecchini 0:9fca2b23d0ba 350
marcozecchini 0:9fca2b23d0ba 351 k = ( i + 20 > dlen ) ? dlen % 20 : 20;
marcozecchini 0:9fca2b23d0ba 352
marcozecchini 0:9fca2b23d0ba 353 for( j = 0; j < k; j++ )
marcozecchini 0:9fca2b23d0ba 354 dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
marcozecchini 0:9fca2b23d0ba 355 }
marcozecchini 0:9fca2b23d0ba 356
marcozecchini 0:9fca2b23d0ba 357 mbedtls_md_free( &md_ctx );
marcozecchini 0:9fca2b23d0ba 358
marcozecchini 0:9fca2b23d0ba 359 mbedtls_zeroize( tmp, sizeof( tmp ) );
marcozecchini 0:9fca2b23d0ba 360 mbedtls_zeroize( h_i, sizeof( h_i ) );
marcozecchini 0:9fca2b23d0ba 361
marcozecchini 0:9fca2b23d0ba 362 return( 0 );
marcozecchini 0:9fca2b23d0ba 363 }
marcozecchini 0:9fca2b23d0ba 364 #endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
marcozecchini 0:9fca2b23d0ba 365
marcozecchini 0:9fca2b23d0ba 366 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 367 static int tls_prf_generic( mbedtls_md_type_t md_type,
marcozecchini 0:9fca2b23d0ba 368 const unsigned char *secret, size_t slen,
marcozecchini 0:9fca2b23d0ba 369 const char *label,
marcozecchini 0:9fca2b23d0ba 370 const unsigned char *random, size_t rlen,
marcozecchini 0:9fca2b23d0ba 371 unsigned char *dstbuf, size_t dlen )
marcozecchini 0:9fca2b23d0ba 372 {
marcozecchini 0:9fca2b23d0ba 373 size_t nb;
marcozecchini 0:9fca2b23d0ba 374 size_t i, j, k, md_len;
marcozecchini 0:9fca2b23d0ba 375 unsigned char tmp[128];
marcozecchini 0:9fca2b23d0ba 376 unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
marcozecchini 0:9fca2b23d0ba 377 const mbedtls_md_info_t *md_info;
marcozecchini 0:9fca2b23d0ba 378 mbedtls_md_context_t md_ctx;
marcozecchini 0:9fca2b23d0ba 379 int ret;
marcozecchini 0:9fca2b23d0ba 380
marcozecchini 0:9fca2b23d0ba 381 mbedtls_md_init( &md_ctx );
marcozecchini 0:9fca2b23d0ba 382
marcozecchini 0:9fca2b23d0ba 383 if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 384 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 385
marcozecchini 0:9fca2b23d0ba 386 md_len = mbedtls_md_get_size( md_info );
marcozecchini 0:9fca2b23d0ba 387
marcozecchini 0:9fca2b23d0ba 388 if( sizeof( tmp ) < md_len + strlen( label ) + rlen )
marcozecchini 0:9fca2b23d0ba 389 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 390
marcozecchini 0:9fca2b23d0ba 391 nb = strlen( label );
marcozecchini 0:9fca2b23d0ba 392 memcpy( tmp + md_len, label, nb );
marcozecchini 0:9fca2b23d0ba 393 memcpy( tmp + md_len + nb, random, rlen );
marcozecchini 0:9fca2b23d0ba 394 nb += rlen;
marcozecchini 0:9fca2b23d0ba 395
marcozecchini 0:9fca2b23d0ba 396 /*
marcozecchini 0:9fca2b23d0ba 397 * Compute P_<hash>(secret, label + random)[0..dlen]
marcozecchini 0:9fca2b23d0ba 398 */
marcozecchini 0:9fca2b23d0ba 399 if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 400 return( ret );
marcozecchini 0:9fca2b23d0ba 401
marcozecchini 0:9fca2b23d0ba 402 mbedtls_md_hmac_starts( &md_ctx, secret, slen );
marcozecchini 0:9fca2b23d0ba 403 mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
marcozecchini 0:9fca2b23d0ba 404 mbedtls_md_hmac_finish( &md_ctx, tmp );
marcozecchini 0:9fca2b23d0ba 405
marcozecchini 0:9fca2b23d0ba 406 for( i = 0; i < dlen; i += md_len )
marcozecchini 0:9fca2b23d0ba 407 {
marcozecchini 0:9fca2b23d0ba 408 mbedtls_md_hmac_reset ( &md_ctx );
marcozecchini 0:9fca2b23d0ba 409 mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
marcozecchini 0:9fca2b23d0ba 410 mbedtls_md_hmac_finish( &md_ctx, h_i );
marcozecchini 0:9fca2b23d0ba 411
marcozecchini 0:9fca2b23d0ba 412 mbedtls_md_hmac_reset ( &md_ctx );
marcozecchini 0:9fca2b23d0ba 413 mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
marcozecchini 0:9fca2b23d0ba 414 mbedtls_md_hmac_finish( &md_ctx, tmp );
marcozecchini 0:9fca2b23d0ba 415
marcozecchini 0:9fca2b23d0ba 416 k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
marcozecchini 0:9fca2b23d0ba 417
marcozecchini 0:9fca2b23d0ba 418 for( j = 0; j < k; j++ )
marcozecchini 0:9fca2b23d0ba 419 dstbuf[i + j] = h_i[j];
marcozecchini 0:9fca2b23d0ba 420 }
marcozecchini 0:9fca2b23d0ba 421
marcozecchini 0:9fca2b23d0ba 422 mbedtls_md_free( &md_ctx );
marcozecchini 0:9fca2b23d0ba 423
marcozecchini 0:9fca2b23d0ba 424 mbedtls_zeroize( tmp, sizeof( tmp ) );
marcozecchini 0:9fca2b23d0ba 425 mbedtls_zeroize( h_i, sizeof( h_i ) );
marcozecchini 0:9fca2b23d0ba 426
marcozecchini 0:9fca2b23d0ba 427 return( 0 );
marcozecchini 0:9fca2b23d0ba 428 }
marcozecchini 0:9fca2b23d0ba 429
marcozecchini 0:9fca2b23d0ba 430 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 431 static int tls_prf_sha256( const unsigned char *secret, size_t slen,
marcozecchini 0:9fca2b23d0ba 432 const char *label,
marcozecchini 0:9fca2b23d0ba 433 const unsigned char *random, size_t rlen,
marcozecchini 0:9fca2b23d0ba 434 unsigned char *dstbuf, size_t dlen )
marcozecchini 0:9fca2b23d0ba 435 {
marcozecchini 0:9fca2b23d0ba 436 return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen,
marcozecchini 0:9fca2b23d0ba 437 label, random, rlen, dstbuf, dlen ) );
marcozecchini 0:9fca2b23d0ba 438 }
marcozecchini 0:9fca2b23d0ba 439 #endif /* MBEDTLS_SHA256_C */
marcozecchini 0:9fca2b23d0ba 440
marcozecchini 0:9fca2b23d0ba 441 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 442 static int tls_prf_sha384( const unsigned char *secret, size_t slen,
marcozecchini 0:9fca2b23d0ba 443 const char *label,
marcozecchini 0:9fca2b23d0ba 444 const unsigned char *random, size_t rlen,
marcozecchini 0:9fca2b23d0ba 445 unsigned char *dstbuf, size_t dlen )
marcozecchini 0:9fca2b23d0ba 446 {
marcozecchini 0:9fca2b23d0ba 447 return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen,
marcozecchini 0:9fca2b23d0ba 448 label, random, rlen, dstbuf, dlen ) );
marcozecchini 0:9fca2b23d0ba 449 }
marcozecchini 0:9fca2b23d0ba 450 #endif /* MBEDTLS_SHA512_C */
marcozecchini 0:9fca2b23d0ba 451 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 452
marcozecchini 0:9fca2b23d0ba 453 static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t );
marcozecchini 0:9fca2b23d0ba 454
marcozecchini 0:9fca2b23d0ba 455 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
marcozecchini 0:9fca2b23d0ba 456 defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 457 static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t );
marcozecchini 0:9fca2b23d0ba 458 #endif
marcozecchini 0:9fca2b23d0ba 459
marcozecchini 0:9fca2b23d0ba 460 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 461 static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * );
marcozecchini 0:9fca2b23d0ba 462 static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int );
marcozecchini 0:9fca2b23d0ba 463 #endif
marcozecchini 0:9fca2b23d0ba 464
marcozecchini 0:9fca2b23d0ba 465 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 466 static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * );
marcozecchini 0:9fca2b23d0ba 467 static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int );
marcozecchini 0:9fca2b23d0ba 468 #endif
marcozecchini 0:9fca2b23d0ba 469
marcozecchini 0:9fca2b23d0ba 470 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 471 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 472 static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
marcozecchini 0:9fca2b23d0ba 473 static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * );
marcozecchini 0:9fca2b23d0ba 474 static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
marcozecchini 0:9fca2b23d0ba 475 #endif
marcozecchini 0:9fca2b23d0ba 476
marcozecchini 0:9fca2b23d0ba 477 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 478 static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t );
marcozecchini 0:9fca2b23d0ba 479 static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * );
marcozecchini 0:9fca2b23d0ba 480 static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
marcozecchini 0:9fca2b23d0ba 481 #endif
marcozecchini 0:9fca2b23d0ba 482 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 483
marcozecchini 0:9fca2b23d0ba 484 int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 485 {
marcozecchini 0:9fca2b23d0ba 486 int ret = 0;
marcozecchini 0:9fca2b23d0ba 487 unsigned char tmp[64];
marcozecchini 0:9fca2b23d0ba 488 unsigned char keyblk[256];
marcozecchini 0:9fca2b23d0ba 489 unsigned char *key1;
marcozecchini 0:9fca2b23d0ba 490 unsigned char *key2;
marcozecchini 0:9fca2b23d0ba 491 unsigned char *mac_enc;
marcozecchini 0:9fca2b23d0ba 492 unsigned char *mac_dec;
marcozecchini 0:9fca2b23d0ba 493 size_t iv_copy_len;
marcozecchini 0:9fca2b23d0ba 494 const mbedtls_cipher_info_t *cipher_info;
marcozecchini 0:9fca2b23d0ba 495 const mbedtls_md_info_t *md_info;
marcozecchini 0:9fca2b23d0ba 496
marcozecchini 0:9fca2b23d0ba 497 mbedtls_ssl_session *session = ssl->session_negotiate;
marcozecchini 0:9fca2b23d0ba 498 mbedtls_ssl_transform *transform = ssl->transform_negotiate;
marcozecchini 0:9fca2b23d0ba 499 mbedtls_ssl_handshake_params *handshake = ssl->handshake;
marcozecchini 0:9fca2b23d0ba 500
marcozecchini 0:9fca2b23d0ba 501 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
marcozecchini 0:9fca2b23d0ba 502
marcozecchini 0:9fca2b23d0ba 503 cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher );
marcozecchini 0:9fca2b23d0ba 504 if( cipher_info == NULL )
marcozecchini 0:9fca2b23d0ba 505 {
marcozecchini 0:9fca2b23d0ba 506 MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
marcozecchini 0:9fca2b23d0ba 507 transform->ciphersuite_info->cipher ) );
marcozecchini 0:9fca2b23d0ba 508 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 509 }
marcozecchini 0:9fca2b23d0ba 510
marcozecchini 0:9fca2b23d0ba 511 md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac );
marcozecchini 0:9fca2b23d0ba 512 if( md_info == NULL )
marcozecchini 0:9fca2b23d0ba 513 {
marcozecchini 0:9fca2b23d0ba 514 MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found",
marcozecchini 0:9fca2b23d0ba 515 transform->ciphersuite_info->mac ) );
marcozecchini 0:9fca2b23d0ba 516 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 517 }
marcozecchini 0:9fca2b23d0ba 518
marcozecchini 0:9fca2b23d0ba 519 /*
marcozecchini 0:9fca2b23d0ba 520 * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
marcozecchini 0:9fca2b23d0ba 521 */
marcozecchini 0:9fca2b23d0ba 522 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 523 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 524 {
marcozecchini 0:9fca2b23d0ba 525 handshake->tls_prf = ssl3_prf;
marcozecchini 0:9fca2b23d0ba 526 handshake->calc_verify = ssl_calc_verify_ssl;
marcozecchini 0:9fca2b23d0ba 527 handshake->calc_finished = ssl_calc_finished_ssl;
marcozecchini 0:9fca2b23d0ba 528 }
marcozecchini 0:9fca2b23d0ba 529 else
marcozecchini 0:9fca2b23d0ba 530 #endif
marcozecchini 0:9fca2b23d0ba 531 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 532 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
marcozecchini 0:9fca2b23d0ba 533 {
marcozecchini 0:9fca2b23d0ba 534 handshake->tls_prf = tls1_prf;
marcozecchini 0:9fca2b23d0ba 535 handshake->calc_verify = ssl_calc_verify_tls;
marcozecchini 0:9fca2b23d0ba 536 handshake->calc_finished = ssl_calc_finished_tls;
marcozecchini 0:9fca2b23d0ba 537 }
marcozecchini 0:9fca2b23d0ba 538 else
marcozecchini 0:9fca2b23d0ba 539 #endif
marcozecchini 0:9fca2b23d0ba 540 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 541 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 542 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
marcozecchini 0:9fca2b23d0ba 543 transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
marcozecchini 0:9fca2b23d0ba 544 {
marcozecchini 0:9fca2b23d0ba 545 handshake->tls_prf = tls_prf_sha384;
marcozecchini 0:9fca2b23d0ba 546 handshake->calc_verify = ssl_calc_verify_tls_sha384;
marcozecchini 0:9fca2b23d0ba 547 handshake->calc_finished = ssl_calc_finished_tls_sha384;
marcozecchini 0:9fca2b23d0ba 548 }
marcozecchini 0:9fca2b23d0ba 549 else
marcozecchini 0:9fca2b23d0ba 550 #endif
marcozecchini 0:9fca2b23d0ba 551 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 552 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
marcozecchini 0:9fca2b23d0ba 553 {
marcozecchini 0:9fca2b23d0ba 554 handshake->tls_prf = tls_prf_sha256;
marcozecchini 0:9fca2b23d0ba 555 handshake->calc_verify = ssl_calc_verify_tls_sha256;
marcozecchini 0:9fca2b23d0ba 556 handshake->calc_finished = ssl_calc_finished_tls_sha256;
marcozecchini 0:9fca2b23d0ba 557 }
marcozecchini 0:9fca2b23d0ba 558 else
marcozecchini 0:9fca2b23d0ba 559 #endif
marcozecchini 0:9fca2b23d0ba 560 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 561 {
marcozecchini 0:9fca2b23d0ba 562 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 563 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 564 }
marcozecchini 0:9fca2b23d0ba 565
marcozecchini 0:9fca2b23d0ba 566 /*
marcozecchini 0:9fca2b23d0ba 567 * SSLv3:
marcozecchini 0:9fca2b23d0ba 568 * master =
marcozecchini 0:9fca2b23d0ba 569 * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) +
marcozecchini 0:9fca2b23d0ba 570 * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) +
marcozecchini 0:9fca2b23d0ba 571 * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
marcozecchini 0:9fca2b23d0ba 572 *
marcozecchini 0:9fca2b23d0ba 573 * TLSv1+:
marcozecchini 0:9fca2b23d0ba 574 * master = PRF( premaster, "master secret", randbytes )[0..47]
marcozecchini 0:9fca2b23d0ba 575 */
marcozecchini 0:9fca2b23d0ba 576 if( handshake->resume == 0 )
marcozecchini 0:9fca2b23d0ba 577 {
marcozecchini 0:9fca2b23d0ba 578 MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
marcozecchini 0:9fca2b23d0ba 579 handshake->pmslen );
marcozecchini 0:9fca2b23d0ba 580
marcozecchini 0:9fca2b23d0ba 581 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
marcozecchini 0:9fca2b23d0ba 582 if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
marcozecchini 0:9fca2b23d0ba 583 {
marcozecchini 0:9fca2b23d0ba 584 unsigned char session_hash[48];
marcozecchini 0:9fca2b23d0ba 585 size_t hash_len;
marcozecchini 0:9fca2b23d0ba 586
marcozecchini 0:9fca2b23d0ba 587 MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) );
marcozecchini 0:9fca2b23d0ba 588
marcozecchini 0:9fca2b23d0ba 589 ssl->handshake->calc_verify( ssl, session_hash );
marcozecchini 0:9fca2b23d0ba 590
marcozecchini 0:9fca2b23d0ba 591 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 592 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
marcozecchini 0:9fca2b23d0ba 593 {
marcozecchini 0:9fca2b23d0ba 594 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 595 if( ssl->transform_negotiate->ciphersuite_info->mac ==
marcozecchini 0:9fca2b23d0ba 596 MBEDTLS_MD_SHA384 )
marcozecchini 0:9fca2b23d0ba 597 {
marcozecchini 0:9fca2b23d0ba 598 hash_len = 48;
marcozecchini 0:9fca2b23d0ba 599 }
marcozecchini 0:9fca2b23d0ba 600 else
marcozecchini 0:9fca2b23d0ba 601 #endif
marcozecchini 0:9fca2b23d0ba 602 hash_len = 32;
marcozecchini 0:9fca2b23d0ba 603 }
marcozecchini 0:9fca2b23d0ba 604 else
marcozecchini 0:9fca2b23d0ba 605 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 606 hash_len = 36;
marcozecchini 0:9fca2b23d0ba 607
marcozecchini 0:9fca2b23d0ba 608 MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len );
marcozecchini 0:9fca2b23d0ba 609
marcozecchini 0:9fca2b23d0ba 610 ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
marcozecchini 0:9fca2b23d0ba 611 "extended master secret",
marcozecchini 0:9fca2b23d0ba 612 session_hash, hash_len,
marcozecchini 0:9fca2b23d0ba 613 session->master, 48 );
marcozecchini 0:9fca2b23d0ba 614 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 615 {
marcozecchini 0:9fca2b23d0ba 616 MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
marcozecchini 0:9fca2b23d0ba 617 return( ret );
marcozecchini 0:9fca2b23d0ba 618 }
marcozecchini 0:9fca2b23d0ba 619
marcozecchini 0:9fca2b23d0ba 620 }
marcozecchini 0:9fca2b23d0ba 621 else
marcozecchini 0:9fca2b23d0ba 622 #endif
marcozecchini 0:9fca2b23d0ba 623 ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
marcozecchini 0:9fca2b23d0ba 624 "master secret",
marcozecchini 0:9fca2b23d0ba 625 handshake->randbytes, 64,
marcozecchini 0:9fca2b23d0ba 626 session->master, 48 );
marcozecchini 0:9fca2b23d0ba 627 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 628 {
marcozecchini 0:9fca2b23d0ba 629 MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
marcozecchini 0:9fca2b23d0ba 630 return( ret );
marcozecchini 0:9fca2b23d0ba 631 }
marcozecchini 0:9fca2b23d0ba 632
marcozecchini 0:9fca2b23d0ba 633 mbedtls_zeroize( handshake->premaster, sizeof(handshake->premaster) );
marcozecchini 0:9fca2b23d0ba 634 }
marcozecchini 0:9fca2b23d0ba 635 else
marcozecchini 0:9fca2b23d0ba 636 MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
marcozecchini 0:9fca2b23d0ba 637
marcozecchini 0:9fca2b23d0ba 638 /*
marcozecchini 0:9fca2b23d0ba 639 * Swap the client and server random values.
marcozecchini 0:9fca2b23d0ba 640 */
marcozecchini 0:9fca2b23d0ba 641 memcpy( tmp, handshake->randbytes, 64 );
marcozecchini 0:9fca2b23d0ba 642 memcpy( handshake->randbytes, tmp + 32, 32 );
marcozecchini 0:9fca2b23d0ba 643 memcpy( handshake->randbytes + 32, tmp, 32 );
marcozecchini 0:9fca2b23d0ba 644 mbedtls_zeroize( tmp, sizeof( tmp ) );
marcozecchini 0:9fca2b23d0ba 645
marcozecchini 0:9fca2b23d0ba 646 /*
marcozecchini 0:9fca2b23d0ba 647 * SSLv3:
marcozecchini 0:9fca2b23d0ba 648 * key block =
marcozecchini 0:9fca2b23d0ba 649 * MD5( master + SHA1( 'A' + master + randbytes ) ) +
marcozecchini 0:9fca2b23d0ba 650 * MD5( master + SHA1( 'BB' + master + randbytes ) ) +
marcozecchini 0:9fca2b23d0ba 651 * MD5( master + SHA1( 'CCC' + master + randbytes ) ) +
marcozecchini 0:9fca2b23d0ba 652 * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
marcozecchini 0:9fca2b23d0ba 653 * ...
marcozecchini 0:9fca2b23d0ba 654 *
marcozecchini 0:9fca2b23d0ba 655 * TLSv1:
marcozecchini 0:9fca2b23d0ba 656 * key block = PRF( master, "key expansion", randbytes )
marcozecchini 0:9fca2b23d0ba 657 */
marcozecchini 0:9fca2b23d0ba 658 ret = handshake->tls_prf( session->master, 48, "key expansion",
marcozecchini 0:9fca2b23d0ba 659 handshake->randbytes, 64, keyblk, 256 );
marcozecchini 0:9fca2b23d0ba 660 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 661 {
marcozecchini 0:9fca2b23d0ba 662 MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
marcozecchini 0:9fca2b23d0ba 663 return( ret );
marcozecchini 0:9fca2b23d0ba 664 }
marcozecchini 0:9fca2b23d0ba 665
marcozecchini 0:9fca2b23d0ba 666 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
marcozecchini 0:9fca2b23d0ba 667 mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) );
marcozecchini 0:9fca2b23d0ba 668 MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 );
marcozecchini 0:9fca2b23d0ba 669 MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
marcozecchini 0:9fca2b23d0ba 670 MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
marcozecchini 0:9fca2b23d0ba 671
marcozecchini 0:9fca2b23d0ba 672 mbedtls_zeroize( handshake->randbytes, sizeof( handshake->randbytes ) );
marcozecchini 0:9fca2b23d0ba 673
marcozecchini 0:9fca2b23d0ba 674 /*
marcozecchini 0:9fca2b23d0ba 675 * Determine the appropriate key, IV and MAC length.
marcozecchini 0:9fca2b23d0ba 676 */
marcozecchini 0:9fca2b23d0ba 677
marcozecchini 0:9fca2b23d0ba 678 transform->keylen = cipher_info->key_bitlen / 8;
marcozecchini 0:9fca2b23d0ba 679
marcozecchini 0:9fca2b23d0ba 680 if( cipher_info->mode == MBEDTLS_MODE_GCM ||
marcozecchini 0:9fca2b23d0ba 681 cipher_info->mode == MBEDTLS_MODE_CCM )
marcozecchini 0:9fca2b23d0ba 682 {
marcozecchini 0:9fca2b23d0ba 683 transform->maclen = 0;
marcozecchini 0:9fca2b23d0ba 684
marcozecchini 0:9fca2b23d0ba 685 transform->ivlen = 12;
marcozecchini 0:9fca2b23d0ba 686 transform->fixed_ivlen = 4;
marcozecchini 0:9fca2b23d0ba 687
marcozecchini 0:9fca2b23d0ba 688 /* Minimum length is expicit IV + tag */
marcozecchini 0:9fca2b23d0ba 689 transform->minlen = transform->ivlen - transform->fixed_ivlen
marcozecchini 0:9fca2b23d0ba 690 + ( transform->ciphersuite_info->flags &
marcozecchini 0:9fca2b23d0ba 691 MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16 );
marcozecchini 0:9fca2b23d0ba 692 }
marcozecchini 0:9fca2b23d0ba 693 else
marcozecchini 0:9fca2b23d0ba 694 {
marcozecchini 0:9fca2b23d0ba 695 /* Initialize HMAC contexts */
marcozecchini 0:9fca2b23d0ba 696 if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
marcozecchini 0:9fca2b23d0ba 697 ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 698 {
marcozecchini 0:9fca2b23d0ba 699 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
marcozecchini 0:9fca2b23d0ba 700 return( ret );
marcozecchini 0:9fca2b23d0ba 701 }
marcozecchini 0:9fca2b23d0ba 702
marcozecchini 0:9fca2b23d0ba 703 /* Get MAC length */
marcozecchini 0:9fca2b23d0ba 704 transform->maclen = mbedtls_md_get_size( md_info );
marcozecchini 0:9fca2b23d0ba 705
marcozecchini 0:9fca2b23d0ba 706 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
marcozecchini 0:9fca2b23d0ba 707 /*
marcozecchini 0:9fca2b23d0ba 708 * If HMAC is to be truncated, we shall keep the leftmost bytes,
marcozecchini 0:9fca2b23d0ba 709 * (rfc 6066 page 13 or rfc 2104 section 4),
marcozecchini 0:9fca2b23d0ba 710 * so we only need to adjust the length here.
marcozecchini 0:9fca2b23d0ba 711 */
marcozecchini 0:9fca2b23d0ba 712 if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
marcozecchini 0:9fca2b23d0ba 713 transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
marcozecchini 0:9fca2b23d0ba 714 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
marcozecchini 0:9fca2b23d0ba 715
marcozecchini 0:9fca2b23d0ba 716 /* IV length */
marcozecchini 0:9fca2b23d0ba 717 transform->ivlen = cipher_info->iv_size;
marcozecchini 0:9fca2b23d0ba 718
marcozecchini 0:9fca2b23d0ba 719 /* Minimum length */
marcozecchini 0:9fca2b23d0ba 720 if( cipher_info->mode == MBEDTLS_MODE_STREAM )
marcozecchini 0:9fca2b23d0ba 721 transform->minlen = transform->maclen;
marcozecchini 0:9fca2b23d0ba 722 else
marcozecchini 0:9fca2b23d0ba 723 {
marcozecchini 0:9fca2b23d0ba 724 /*
marcozecchini 0:9fca2b23d0ba 725 * GenericBlockCipher:
marcozecchini 0:9fca2b23d0ba 726 * 1. if EtM is in use: one block plus MAC
marcozecchini 0:9fca2b23d0ba 727 * otherwise: * first multiple of blocklen greater than maclen
marcozecchini 0:9fca2b23d0ba 728 * 2. IV except for SSL3 and TLS 1.0
marcozecchini 0:9fca2b23d0ba 729 */
marcozecchini 0:9fca2b23d0ba 730 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
marcozecchini 0:9fca2b23d0ba 731 if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
marcozecchini 0:9fca2b23d0ba 732 {
marcozecchini 0:9fca2b23d0ba 733 transform->minlen = transform->maclen
marcozecchini 0:9fca2b23d0ba 734 + cipher_info->block_size;
marcozecchini 0:9fca2b23d0ba 735 }
marcozecchini 0:9fca2b23d0ba 736 else
marcozecchini 0:9fca2b23d0ba 737 #endif
marcozecchini 0:9fca2b23d0ba 738 {
marcozecchini 0:9fca2b23d0ba 739 transform->minlen = transform->maclen
marcozecchini 0:9fca2b23d0ba 740 + cipher_info->block_size
marcozecchini 0:9fca2b23d0ba 741 - transform->maclen % cipher_info->block_size;
marcozecchini 0:9fca2b23d0ba 742 }
marcozecchini 0:9fca2b23d0ba 743
marcozecchini 0:9fca2b23d0ba 744 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
marcozecchini 0:9fca2b23d0ba 745 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
marcozecchini 0:9fca2b23d0ba 746 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 )
marcozecchini 0:9fca2b23d0ba 747 ; /* No need to adjust minlen */
marcozecchini 0:9fca2b23d0ba 748 else
marcozecchini 0:9fca2b23d0ba 749 #endif
marcozecchini 0:9fca2b23d0ba 750 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 751 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
marcozecchini 0:9fca2b23d0ba 752 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
marcozecchini 0:9fca2b23d0ba 753 {
marcozecchini 0:9fca2b23d0ba 754 transform->minlen += transform->ivlen;
marcozecchini 0:9fca2b23d0ba 755 }
marcozecchini 0:9fca2b23d0ba 756 else
marcozecchini 0:9fca2b23d0ba 757 #endif
marcozecchini 0:9fca2b23d0ba 758 {
marcozecchini 0:9fca2b23d0ba 759 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 760 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 761 }
marcozecchini 0:9fca2b23d0ba 762 }
marcozecchini 0:9fca2b23d0ba 763 }
marcozecchini 0:9fca2b23d0ba 764
marcozecchini 0:9fca2b23d0ba 765 MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
marcozecchini 0:9fca2b23d0ba 766 transform->keylen, transform->minlen, transform->ivlen,
marcozecchini 0:9fca2b23d0ba 767 transform->maclen ) );
marcozecchini 0:9fca2b23d0ba 768
marcozecchini 0:9fca2b23d0ba 769 /*
marcozecchini 0:9fca2b23d0ba 770 * Finally setup the cipher contexts, IVs and MAC secrets.
marcozecchini 0:9fca2b23d0ba 771 */
marcozecchini 0:9fca2b23d0ba 772 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 773 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 774 {
marcozecchini 0:9fca2b23d0ba 775 key1 = keyblk + transform->maclen * 2;
marcozecchini 0:9fca2b23d0ba 776 key2 = keyblk + transform->maclen * 2 + transform->keylen;
marcozecchini 0:9fca2b23d0ba 777
marcozecchini 0:9fca2b23d0ba 778 mac_enc = keyblk;
marcozecchini 0:9fca2b23d0ba 779 mac_dec = keyblk + transform->maclen;
marcozecchini 0:9fca2b23d0ba 780
marcozecchini 0:9fca2b23d0ba 781 /*
marcozecchini 0:9fca2b23d0ba 782 * This is not used in TLS v1.1.
marcozecchini 0:9fca2b23d0ba 783 */
marcozecchini 0:9fca2b23d0ba 784 iv_copy_len = ( transform->fixed_ivlen ) ?
marcozecchini 0:9fca2b23d0ba 785 transform->fixed_ivlen : transform->ivlen;
marcozecchini 0:9fca2b23d0ba 786 memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len );
marcozecchini 0:9fca2b23d0ba 787 memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len,
marcozecchini 0:9fca2b23d0ba 788 iv_copy_len );
marcozecchini 0:9fca2b23d0ba 789 }
marcozecchini 0:9fca2b23d0ba 790 else
marcozecchini 0:9fca2b23d0ba 791 #endif /* MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 792 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 793 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 794 {
marcozecchini 0:9fca2b23d0ba 795 key1 = keyblk + transform->maclen * 2 + transform->keylen;
marcozecchini 0:9fca2b23d0ba 796 key2 = keyblk + transform->maclen * 2;
marcozecchini 0:9fca2b23d0ba 797
marcozecchini 0:9fca2b23d0ba 798 mac_enc = keyblk + transform->maclen;
marcozecchini 0:9fca2b23d0ba 799 mac_dec = keyblk;
marcozecchini 0:9fca2b23d0ba 800
marcozecchini 0:9fca2b23d0ba 801 /*
marcozecchini 0:9fca2b23d0ba 802 * This is not used in TLS v1.1.
marcozecchini 0:9fca2b23d0ba 803 */
marcozecchini 0:9fca2b23d0ba 804 iv_copy_len = ( transform->fixed_ivlen ) ?
marcozecchini 0:9fca2b23d0ba 805 transform->fixed_ivlen : transform->ivlen;
marcozecchini 0:9fca2b23d0ba 806 memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len );
marcozecchini 0:9fca2b23d0ba 807 memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len,
marcozecchini 0:9fca2b23d0ba 808 iv_copy_len );
marcozecchini 0:9fca2b23d0ba 809 }
marcozecchini 0:9fca2b23d0ba 810 else
marcozecchini 0:9fca2b23d0ba 811 #endif /* MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 812 {
marcozecchini 0:9fca2b23d0ba 813 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 814 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 815 }
marcozecchini 0:9fca2b23d0ba 816
marcozecchini 0:9fca2b23d0ba 817 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 818 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 819 {
marcozecchini 0:9fca2b23d0ba 820 if( transform->maclen > sizeof transform->mac_enc )
marcozecchini 0:9fca2b23d0ba 821 {
marcozecchini 0:9fca2b23d0ba 822 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 823 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 824 }
marcozecchini 0:9fca2b23d0ba 825
marcozecchini 0:9fca2b23d0ba 826 memcpy( transform->mac_enc, mac_enc, transform->maclen );
marcozecchini 0:9fca2b23d0ba 827 memcpy( transform->mac_dec, mac_dec, transform->maclen );
marcozecchini 0:9fca2b23d0ba 828 }
marcozecchini 0:9fca2b23d0ba 829 else
marcozecchini 0:9fca2b23d0ba 830 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 831 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
marcozecchini 0:9fca2b23d0ba 832 defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 833 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
marcozecchini 0:9fca2b23d0ba 834 {
marcozecchini 0:9fca2b23d0ba 835 mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen );
marcozecchini 0:9fca2b23d0ba 836 mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen );
marcozecchini 0:9fca2b23d0ba 837 }
marcozecchini 0:9fca2b23d0ba 838 else
marcozecchini 0:9fca2b23d0ba 839 #endif
marcozecchini 0:9fca2b23d0ba 840 {
marcozecchini 0:9fca2b23d0ba 841 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 842 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 843 }
marcozecchini 0:9fca2b23d0ba 844
marcozecchini 0:9fca2b23d0ba 845 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 846 if( mbedtls_ssl_hw_record_init != NULL )
marcozecchini 0:9fca2b23d0ba 847 {
marcozecchini 0:9fca2b23d0ba 848 int ret = 0;
marcozecchini 0:9fca2b23d0ba 849
marcozecchini 0:9fca2b23d0ba 850 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
marcozecchini 0:9fca2b23d0ba 851
marcozecchini 0:9fca2b23d0ba 852 if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen,
marcozecchini 0:9fca2b23d0ba 853 transform->iv_enc, transform->iv_dec,
marcozecchini 0:9fca2b23d0ba 854 iv_copy_len,
marcozecchini 0:9fca2b23d0ba 855 mac_enc, mac_dec,
marcozecchini 0:9fca2b23d0ba 856 transform->maclen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 857 {
marcozecchini 0:9fca2b23d0ba 858 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
marcozecchini 0:9fca2b23d0ba 859 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
marcozecchini 0:9fca2b23d0ba 860 }
marcozecchini 0:9fca2b23d0ba 861 }
marcozecchini 0:9fca2b23d0ba 862 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
marcozecchini 0:9fca2b23d0ba 863
marcozecchini 0:9fca2b23d0ba 864 #if defined(MBEDTLS_SSL_EXPORT_KEYS)
marcozecchini 0:9fca2b23d0ba 865 if( ssl->conf->f_export_keys != NULL )
marcozecchini 0:9fca2b23d0ba 866 {
marcozecchini 0:9fca2b23d0ba 867 ssl->conf->f_export_keys( ssl->conf->p_export_keys,
marcozecchini 0:9fca2b23d0ba 868 session->master, keyblk,
marcozecchini 0:9fca2b23d0ba 869 transform->maclen, transform->keylen,
marcozecchini 0:9fca2b23d0ba 870 iv_copy_len );
marcozecchini 0:9fca2b23d0ba 871 }
marcozecchini 0:9fca2b23d0ba 872 #endif
marcozecchini 0:9fca2b23d0ba 873
marcozecchini 0:9fca2b23d0ba 874 if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
marcozecchini 0:9fca2b23d0ba 875 cipher_info ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 876 {
marcozecchini 0:9fca2b23d0ba 877 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
marcozecchini 0:9fca2b23d0ba 878 return( ret );
marcozecchini 0:9fca2b23d0ba 879 }
marcozecchini 0:9fca2b23d0ba 880
marcozecchini 0:9fca2b23d0ba 881 if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
marcozecchini 0:9fca2b23d0ba 882 cipher_info ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 883 {
marcozecchini 0:9fca2b23d0ba 884 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
marcozecchini 0:9fca2b23d0ba 885 return( ret );
marcozecchini 0:9fca2b23d0ba 886 }
marcozecchini 0:9fca2b23d0ba 887
marcozecchini 0:9fca2b23d0ba 888 if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
marcozecchini 0:9fca2b23d0ba 889 cipher_info->key_bitlen,
marcozecchini 0:9fca2b23d0ba 890 MBEDTLS_ENCRYPT ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 891 {
marcozecchini 0:9fca2b23d0ba 892 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
marcozecchini 0:9fca2b23d0ba 893 return( ret );
marcozecchini 0:9fca2b23d0ba 894 }
marcozecchini 0:9fca2b23d0ba 895
marcozecchini 0:9fca2b23d0ba 896 if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
marcozecchini 0:9fca2b23d0ba 897 cipher_info->key_bitlen,
marcozecchini 0:9fca2b23d0ba 898 MBEDTLS_DECRYPT ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 899 {
marcozecchini 0:9fca2b23d0ba 900 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
marcozecchini 0:9fca2b23d0ba 901 return( ret );
marcozecchini 0:9fca2b23d0ba 902 }
marcozecchini 0:9fca2b23d0ba 903
marcozecchini 0:9fca2b23d0ba 904 #if defined(MBEDTLS_CIPHER_MODE_CBC)
marcozecchini 0:9fca2b23d0ba 905 if( cipher_info->mode == MBEDTLS_MODE_CBC )
marcozecchini 0:9fca2b23d0ba 906 {
marcozecchini 0:9fca2b23d0ba 907 if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
marcozecchini 0:9fca2b23d0ba 908 MBEDTLS_PADDING_NONE ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 909 {
marcozecchini 0:9fca2b23d0ba 910 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
marcozecchini 0:9fca2b23d0ba 911 return( ret );
marcozecchini 0:9fca2b23d0ba 912 }
marcozecchini 0:9fca2b23d0ba 913
marcozecchini 0:9fca2b23d0ba 914 if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
marcozecchini 0:9fca2b23d0ba 915 MBEDTLS_PADDING_NONE ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 916 {
marcozecchini 0:9fca2b23d0ba 917 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
marcozecchini 0:9fca2b23d0ba 918 return( ret );
marcozecchini 0:9fca2b23d0ba 919 }
marcozecchini 0:9fca2b23d0ba 920 }
marcozecchini 0:9fca2b23d0ba 921 #endif /* MBEDTLS_CIPHER_MODE_CBC */
marcozecchini 0:9fca2b23d0ba 922
marcozecchini 0:9fca2b23d0ba 923 mbedtls_zeroize( keyblk, sizeof( keyblk ) );
marcozecchini 0:9fca2b23d0ba 924
marcozecchini 0:9fca2b23d0ba 925 #if defined(MBEDTLS_ZLIB_SUPPORT)
marcozecchini 0:9fca2b23d0ba 926 // Initialize compression
marcozecchini 0:9fca2b23d0ba 927 //
marcozecchini 0:9fca2b23d0ba 928 if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
marcozecchini 0:9fca2b23d0ba 929 {
marcozecchini 0:9fca2b23d0ba 930 if( ssl->compress_buf == NULL )
marcozecchini 0:9fca2b23d0ba 931 {
marcozecchini 0:9fca2b23d0ba 932 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
marcozecchini 0:9fca2b23d0ba 933 ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_BUFFER_LEN );
marcozecchini 0:9fca2b23d0ba 934 if( ssl->compress_buf == NULL )
marcozecchini 0:9fca2b23d0ba 935 {
marcozecchini 0:9fca2b23d0ba 936 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
marcozecchini 0:9fca2b23d0ba 937 MBEDTLS_SSL_BUFFER_LEN ) );
marcozecchini 0:9fca2b23d0ba 938 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 939 }
marcozecchini 0:9fca2b23d0ba 940 }
marcozecchini 0:9fca2b23d0ba 941
marcozecchini 0:9fca2b23d0ba 942 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) );
marcozecchini 0:9fca2b23d0ba 943
marcozecchini 0:9fca2b23d0ba 944 memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) );
marcozecchini 0:9fca2b23d0ba 945 memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) );
marcozecchini 0:9fca2b23d0ba 946
marcozecchini 0:9fca2b23d0ba 947 if( deflateInit( &transform->ctx_deflate,
marcozecchini 0:9fca2b23d0ba 948 Z_DEFAULT_COMPRESSION ) != Z_OK ||
marcozecchini 0:9fca2b23d0ba 949 inflateInit( &transform->ctx_inflate ) != Z_OK )
marcozecchini 0:9fca2b23d0ba 950 {
marcozecchini 0:9fca2b23d0ba 951 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
marcozecchini 0:9fca2b23d0ba 952 return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
marcozecchini 0:9fca2b23d0ba 953 }
marcozecchini 0:9fca2b23d0ba 954 }
marcozecchini 0:9fca2b23d0ba 955 #endif /* MBEDTLS_ZLIB_SUPPORT */
marcozecchini 0:9fca2b23d0ba 956
marcozecchini 0:9fca2b23d0ba 957 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
marcozecchini 0:9fca2b23d0ba 958
marcozecchini 0:9fca2b23d0ba 959 return( 0 );
marcozecchini 0:9fca2b23d0ba 960 }
marcozecchini 0:9fca2b23d0ba 961
marcozecchini 0:9fca2b23d0ba 962 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 963 void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
marcozecchini 0:9fca2b23d0ba 964 {
marcozecchini 0:9fca2b23d0ba 965 mbedtls_md5_context md5;
marcozecchini 0:9fca2b23d0ba 966 mbedtls_sha1_context sha1;
marcozecchini 0:9fca2b23d0ba 967 unsigned char pad_1[48];
marcozecchini 0:9fca2b23d0ba 968 unsigned char pad_2[48];
marcozecchini 0:9fca2b23d0ba 969
marcozecchini 0:9fca2b23d0ba 970 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) );
marcozecchini 0:9fca2b23d0ba 971
marcozecchini 0:9fca2b23d0ba 972 mbedtls_md5_init( &md5 );
marcozecchini 0:9fca2b23d0ba 973 mbedtls_sha1_init( &sha1 );
marcozecchini 0:9fca2b23d0ba 974
marcozecchini 0:9fca2b23d0ba 975 mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
marcozecchini 0:9fca2b23d0ba 976 mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
marcozecchini 0:9fca2b23d0ba 977
marcozecchini 0:9fca2b23d0ba 978 memset( pad_1, 0x36, 48 );
marcozecchini 0:9fca2b23d0ba 979 memset( pad_2, 0x5C, 48 );
marcozecchini 0:9fca2b23d0ba 980
marcozecchini 0:9fca2b23d0ba 981 mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 );
marcozecchini 0:9fca2b23d0ba 982 mbedtls_md5_update( &md5, pad_1, 48 );
marcozecchini 0:9fca2b23d0ba 983 mbedtls_md5_finish( &md5, hash );
marcozecchini 0:9fca2b23d0ba 984
marcozecchini 0:9fca2b23d0ba 985 mbedtls_md5_starts( &md5 );
marcozecchini 0:9fca2b23d0ba 986 mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 );
marcozecchini 0:9fca2b23d0ba 987 mbedtls_md5_update( &md5, pad_2, 48 );
marcozecchini 0:9fca2b23d0ba 988 mbedtls_md5_update( &md5, hash, 16 );
marcozecchini 0:9fca2b23d0ba 989 mbedtls_md5_finish( &md5, hash );
marcozecchini 0:9fca2b23d0ba 990
marcozecchini 0:9fca2b23d0ba 991 mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 );
marcozecchini 0:9fca2b23d0ba 992 mbedtls_sha1_update( &sha1, pad_1, 40 );
marcozecchini 0:9fca2b23d0ba 993 mbedtls_sha1_finish( &sha1, hash + 16 );
marcozecchini 0:9fca2b23d0ba 994
marcozecchini 0:9fca2b23d0ba 995 mbedtls_sha1_starts( &sha1 );
marcozecchini 0:9fca2b23d0ba 996 mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 );
marcozecchini 0:9fca2b23d0ba 997 mbedtls_sha1_update( &sha1, pad_2, 40 );
marcozecchini 0:9fca2b23d0ba 998 mbedtls_sha1_update( &sha1, hash + 16, 20 );
marcozecchini 0:9fca2b23d0ba 999 mbedtls_sha1_finish( &sha1, hash + 16 );
marcozecchini 0:9fca2b23d0ba 1000
marcozecchini 0:9fca2b23d0ba 1001 MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
marcozecchini 0:9fca2b23d0ba 1002 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
marcozecchini 0:9fca2b23d0ba 1003
marcozecchini 0:9fca2b23d0ba 1004 mbedtls_md5_free( &md5 );
marcozecchini 0:9fca2b23d0ba 1005 mbedtls_sha1_free( &sha1 );
marcozecchini 0:9fca2b23d0ba 1006
marcozecchini 0:9fca2b23d0ba 1007 return;
marcozecchini 0:9fca2b23d0ba 1008 }
marcozecchini 0:9fca2b23d0ba 1009 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 1010
marcozecchini 0:9fca2b23d0ba 1011 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 1012 void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
marcozecchini 0:9fca2b23d0ba 1013 {
marcozecchini 0:9fca2b23d0ba 1014 mbedtls_md5_context md5;
marcozecchini 0:9fca2b23d0ba 1015 mbedtls_sha1_context sha1;
marcozecchini 0:9fca2b23d0ba 1016
marcozecchini 0:9fca2b23d0ba 1017 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) );
marcozecchini 0:9fca2b23d0ba 1018
marcozecchini 0:9fca2b23d0ba 1019 mbedtls_md5_init( &md5 );
marcozecchini 0:9fca2b23d0ba 1020 mbedtls_sha1_init( &sha1 );
marcozecchini 0:9fca2b23d0ba 1021
marcozecchini 0:9fca2b23d0ba 1022 mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
marcozecchini 0:9fca2b23d0ba 1023 mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
marcozecchini 0:9fca2b23d0ba 1024
marcozecchini 0:9fca2b23d0ba 1025 mbedtls_md5_finish( &md5, hash );
marcozecchini 0:9fca2b23d0ba 1026 mbedtls_sha1_finish( &sha1, hash + 16 );
marcozecchini 0:9fca2b23d0ba 1027
marcozecchini 0:9fca2b23d0ba 1028 MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
marcozecchini 0:9fca2b23d0ba 1029 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
marcozecchini 0:9fca2b23d0ba 1030
marcozecchini 0:9fca2b23d0ba 1031 mbedtls_md5_free( &md5 );
marcozecchini 0:9fca2b23d0ba 1032 mbedtls_sha1_free( &sha1 );
marcozecchini 0:9fca2b23d0ba 1033
marcozecchini 0:9fca2b23d0ba 1034 return;
marcozecchini 0:9fca2b23d0ba 1035 }
marcozecchini 0:9fca2b23d0ba 1036 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
marcozecchini 0:9fca2b23d0ba 1037
marcozecchini 0:9fca2b23d0ba 1038 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 1039 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 1040 void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] )
marcozecchini 0:9fca2b23d0ba 1041 {
marcozecchini 0:9fca2b23d0ba 1042 mbedtls_sha256_context sha256;
marcozecchini 0:9fca2b23d0ba 1043
marcozecchini 0:9fca2b23d0ba 1044 mbedtls_sha256_init( &sha256 );
marcozecchini 0:9fca2b23d0ba 1045
marcozecchini 0:9fca2b23d0ba 1046 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
marcozecchini 0:9fca2b23d0ba 1047
marcozecchini 0:9fca2b23d0ba 1048 mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
marcozecchini 0:9fca2b23d0ba 1049 mbedtls_sha256_finish( &sha256, hash );
marcozecchini 0:9fca2b23d0ba 1050
marcozecchini 0:9fca2b23d0ba 1051 MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
marcozecchini 0:9fca2b23d0ba 1052 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
marcozecchini 0:9fca2b23d0ba 1053
marcozecchini 0:9fca2b23d0ba 1054 mbedtls_sha256_free( &sha256 );
marcozecchini 0:9fca2b23d0ba 1055
marcozecchini 0:9fca2b23d0ba 1056 return;
marcozecchini 0:9fca2b23d0ba 1057 }
marcozecchini 0:9fca2b23d0ba 1058 #endif /* MBEDTLS_SHA256_C */
marcozecchini 0:9fca2b23d0ba 1059
marcozecchini 0:9fca2b23d0ba 1060 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 1061 void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] )
marcozecchini 0:9fca2b23d0ba 1062 {
marcozecchini 0:9fca2b23d0ba 1063 mbedtls_sha512_context sha512;
marcozecchini 0:9fca2b23d0ba 1064
marcozecchini 0:9fca2b23d0ba 1065 mbedtls_sha512_init( &sha512 );
marcozecchini 0:9fca2b23d0ba 1066
marcozecchini 0:9fca2b23d0ba 1067 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
marcozecchini 0:9fca2b23d0ba 1068
marcozecchini 0:9fca2b23d0ba 1069 mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
marcozecchini 0:9fca2b23d0ba 1070 mbedtls_sha512_finish( &sha512, hash );
marcozecchini 0:9fca2b23d0ba 1071
marcozecchini 0:9fca2b23d0ba 1072 MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
marcozecchini 0:9fca2b23d0ba 1073 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
marcozecchini 0:9fca2b23d0ba 1074
marcozecchini 0:9fca2b23d0ba 1075 mbedtls_sha512_free( &sha512 );
marcozecchini 0:9fca2b23d0ba 1076
marcozecchini 0:9fca2b23d0ba 1077 return;
marcozecchini 0:9fca2b23d0ba 1078 }
marcozecchini 0:9fca2b23d0ba 1079 #endif /* MBEDTLS_SHA512_C */
marcozecchini 0:9fca2b23d0ba 1080 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 1081
marcozecchini 0:9fca2b23d0ba 1082 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
marcozecchini 0:9fca2b23d0ba 1083 int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
marcozecchini 0:9fca2b23d0ba 1084 {
marcozecchini 0:9fca2b23d0ba 1085 unsigned char *p = ssl->handshake->premaster;
marcozecchini 0:9fca2b23d0ba 1086 unsigned char *end = p + sizeof( ssl->handshake->premaster );
marcozecchini 0:9fca2b23d0ba 1087 const unsigned char *psk = ssl->conf->psk;
marcozecchini 0:9fca2b23d0ba 1088 size_t psk_len = ssl->conf->psk_len;
marcozecchini 0:9fca2b23d0ba 1089
marcozecchini 0:9fca2b23d0ba 1090 /* If the psk callback was called, use its result */
marcozecchini 0:9fca2b23d0ba 1091 if( ssl->handshake->psk != NULL )
marcozecchini 0:9fca2b23d0ba 1092 {
marcozecchini 0:9fca2b23d0ba 1093 psk = ssl->handshake->psk;
marcozecchini 0:9fca2b23d0ba 1094 psk_len = ssl->handshake->psk_len;
marcozecchini 0:9fca2b23d0ba 1095 }
marcozecchini 0:9fca2b23d0ba 1096
marcozecchini 0:9fca2b23d0ba 1097 /*
marcozecchini 0:9fca2b23d0ba 1098 * PMS = struct {
marcozecchini 0:9fca2b23d0ba 1099 * opaque other_secret<0..2^16-1>;
marcozecchini 0:9fca2b23d0ba 1100 * opaque psk<0..2^16-1>;
marcozecchini 0:9fca2b23d0ba 1101 * };
marcozecchini 0:9fca2b23d0ba 1102 * with "other_secret" depending on the particular key exchange
marcozecchini 0:9fca2b23d0ba 1103 */
marcozecchini 0:9fca2b23d0ba 1104 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
marcozecchini 0:9fca2b23d0ba 1105 if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK )
marcozecchini 0:9fca2b23d0ba 1106 {
marcozecchini 0:9fca2b23d0ba 1107 if( end - p < 2 )
marcozecchini 0:9fca2b23d0ba 1108 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 1109
marcozecchini 0:9fca2b23d0ba 1110 *(p++) = (unsigned char)( psk_len >> 8 );
marcozecchini 0:9fca2b23d0ba 1111 *(p++) = (unsigned char)( psk_len );
marcozecchini 0:9fca2b23d0ba 1112
marcozecchini 0:9fca2b23d0ba 1113 if( end < p || (size_t)( end - p ) < psk_len )
marcozecchini 0:9fca2b23d0ba 1114 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 1115
marcozecchini 0:9fca2b23d0ba 1116 memset( p, 0, psk_len );
marcozecchini 0:9fca2b23d0ba 1117 p += psk_len;
marcozecchini 0:9fca2b23d0ba 1118 }
marcozecchini 0:9fca2b23d0ba 1119 else
marcozecchini 0:9fca2b23d0ba 1120 #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
marcozecchini 0:9fca2b23d0ba 1121 #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
marcozecchini 0:9fca2b23d0ba 1122 if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
marcozecchini 0:9fca2b23d0ba 1123 {
marcozecchini 0:9fca2b23d0ba 1124 /*
marcozecchini 0:9fca2b23d0ba 1125 * other_secret already set by the ClientKeyExchange message,
marcozecchini 0:9fca2b23d0ba 1126 * and is 48 bytes long
marcozecchini 0:9fca2b23d0ba 1127 */
marcozecchini 0:9fca2b23d0ba 1128 *p++ = 0;
marcozecchini 0:9fca2b23d0ba 1129 *p++ = 48;
marcozecchini 0:9fca2b23d0ba 1130 p += 48;
marcozecchini 0:9fca2b23d0ba 1131 }
marcozecchini 0:9fca2b23d0ba 1132 else
marcozecchini 0:9fca2b23d0ba 1133 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
marcozecchini 0:9fca2b23d0ba 1134 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
marcozecchini 0:9fca2b23d0ba 1135 if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
marcozecchini 0:9fca2b23d0ba 1136 {
marcozecchini 0:9fca2b23d0ba 1137 int ret;
marcozecchini 0:9fca2b23d0ba 1138 size_t len;
marcozecchini 0:9fca2b23d0ba 1139
marcozecchini 0:9fca2b23d0ba 1140 /* Write length only when we know the actual value */
marcozecchini 0:9fca2b23d0ba 1141 if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
marcozecchini 0:9fca2b23d0ba 1142 p + 2, end - ( p + 2 ), &len,
marcozecchini 0:9fca2b23d0ba 1143 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1144 {
marcozecchini 0:9fca2b23d0ba 1145 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
marcozecchini 0:9fca2b23d0ba 1146 return( ret );
marcozecchini 0:9fca2b23d0ba 1147 }
marcozecchini 0:9fca2b23d0ba 1148 *(p++) = (unsigned char)( len >> 8 );
marcozecchini 0:9fca2b23d0ba 1149 *(p++) = (unsigned char)( len );
marcozecchini 0:9fca2b23d0ba 1150 p += len;
marcozecchini 0:9fca2b23d0ba 1151
marcozecchini 0:9fca2b23d0ba 1152 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
marcozecchini 0:9fca2b23d0ba 1153 }
marcozecchini 0:9fca2b23d0ba 1154 else
marcozecchini 0:9fca2b23d0ba 1155 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
marcozecchini 0:9fca2b23d0ba 1156 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
marcozecchini 0:9fca2b23d0ba 1157 if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
marcozecchini 0:9fca2b23d0ba 1158 {
marcozecchini 0:9fca2b23d0ba 1159 int ret;
marcozecchini 0:9fca2b23d0ba 1160 size_t zlen;
marcozecchini 0:9fca2b23d0ba 1161
marcozecchini 0:9fca2b23d0ba 1162 if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
marcozecchini 0:9fca2b23d0ba 1163 p + 2, end - ( p + 2 ),
marcozecchini 0:9fca2b23d0ba 1164 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1165 {
marcozecchini 0:9fca2b23d0ba 1166 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
marcozecchini 0:9fca2b23d0ba 1167 return( ret );
marcozecchini 0:9fca2b23d0ba 1168 }
marcozecchini 0:9fca2b23d0ba 1169
marcozecchini 0:9fca2b23d0ba 1170 *(p++) = (unsigned char)( zlen >> 8 );
marcozecchini 0:9fca2b23d0ba 1171 *(p++) = (unsigned char)( zlen );
marcozecchini 0:9fca2b23d0ba 1172 p += zlen;
marcozecchini 0:9fca2b23d0ba 1173
marcozecchini 0:9fca2b23d0ba 1174 MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
marcozecchini 0:9fca2b23d0ba 1175 }
marcozecchini 0:9fca2b23d0ba 1176 else
marcozecchini 0:9fca2b23d0ba 1177 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
marcozecchini 0:9fca2b23d0ba 1178 {
marcozecchini 0:9fca2b23d0ba 1179 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1180 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1181 }
marcozecchini 0:9fca2b23d0ba 1182
marcozecchini 0:9fca2b23d0ba 1183 /* opaque psk<0..2^16-1>; */
marcozecchini 0:9fca2b23d0ba 1184 if( end - p < 2 )
marcozecchini 0:9fca2b23d0ba 1185 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 1186
marcozecchini 0:9fca2b23d0ba 1187 *(p++) = (unsigned char)( psk_len >> 8 );
marcozecchini 0:9fca2b23d0ba 1188 *(p++) = (unsigned char)( psk_len );
marcozecchini 0:9fca2b23d0ba 1189
marcozecchini 0:9fca2b23d0ba 1190 if( end < p || (size_t)( end - p ) < psk_len )
marcozecchini 0:9fca2b23d0ba 1191 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 1192
marcozecchini 0:9fca2b23d0ba 1193 memcpy( p, psk, psk_len );
marcozecchini 0:9fca2b23d0ba 1194 p += psk_len;
marcozecchini 0:9fca2b23d0ba 1195
marcozecchini 0:9fca2b23d0ba 1196 ssl->handshake->pmslen = p - ssl->handshake->premaster;
marcozecchini 0:9fca2b23d0ba 1197
marcozecchini 0:9fca2b23d0ba 1198 return( 0 );
marcozecchini 0:9fca2b23d0ba 1199 }
marcozecchini 0:9fca2b23d0ba 1200 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
marcozecchini 0:9fca2b23d0ba 1201
marcozecchini 0:9fca2b23d0ba 1202 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 1203 /*
marcozecchini 0:9fca2b23d0ba 1204 * SSLv3.0 MAC functions
marcozecchini 0:9fca2b23d0ba 1205 */
marcozecchini 0:9fca2b23d0ba 1206 static void ssl_mac( mbedtls_md_context_t *md_ctx, unsigned char *secret,
marcozecchini 0:9fca2b23d0ba 1207 unsigned char *buf, size_t len,
marcozecchini 0:9fca2b23d0ba 1208 unsigned char *ctr, int type )
marcozecchini 0:9fca2b23d0ba 1209 {
marcozecchini 0:9fca2b23d0ba 1210 unsigned char header[11];
marcozecchini 0:9fca2b23d0ba 1211 unsigned char padding[48];
marcozecchini 0:9fca2b23d0ba 1212 int padlen;
marcozecchini 0:9fca2b23d0ba 1213 int md_size = mbedtls_md_get_size( md_ctx->md_info );
marcozecchini 0:9fca2b23d0ba 1214 int md_type = mbedtls_md_get_type( md_ctx->md_info );
marcozecchini 0:9fca2b23d0ba 1215
marcozecchini 0:9fca2b23d0ba 1216 /* Only MD5 and SHA-1 supported */
marcozecchini 0:9fca2b23d0ba 1217 if( md_type == MBEDTLS_MD_MD5 )
marcozecchini 0:9fca2b23d0ba 1218 padlen = 48;
marcozecchini 0:9fca2b23d0ba 1219 else
marcozecchini 0:9fca2b23d0ba 1220 padlen = 40;
marcozecchini 0:9fca2b23d0ba 1221
marcozecchini 0:9fca2b23d0ba 1222 memcpy( header, ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1223 header[ 8] = (unsigned char) type;
marcozecchini 0:9fca2b23d0ba 1224 header[ 9] = (unsigned char)( len >> 8 );
marcozecchini 0:9fca2b23d0ba 1225 header[10] = (unsigned char)( len );
marcozecchini 0:9fca2b23d0ba 1226
marcozecchini 0:9fca2b23d0ba 1227 memset( padding, 0x36, padlen );
marcozecchini 0:9fca2b23d0ba 1228 mbedtls_md_starts( md_ctx );
marcozecchini 0:9fca2b23d0ba 1229 mbedtls_md_update( md_ctx, secret, md_size );
marcozecchini 0:9fca2b23d0ba 1230 mbedtls_md_update( md_ctx, padding, padlen );
marcozecchini 0:9fca2b23d0ba 1231 mbedtls_md_update( md_ctx, header, 11 );
marcozecchini 0:9fca2b23d0ba 1232 mbedtls_md_update( md_ctx, buf, len );
marcozecchini 0:9fca2b23d0ba 1233 mbedtls_md_finish( md_ctx, buf + len );
marcozecchini 0:9fca2b23d0ba 1234
marcozecchini 0:9fca2b23d0ba 1235 memset( padding, 0x5C, padlen );
marcozecchini 0:9fca2b23d0ba 1236 mbedtls_md_starts( md_ctx );
marcozecchini 0:9fca2b23d0ba 1237 mbedtls_md_update( md_ctx, secret, md_size );
marcozecchini 0:9fca2b23d0ba 1238 mbedtls_md_update( md_ctx, padding, padlen );
marcozecchini 0:9fca2b23d0ba 1239 mbedtls_md_update( md_ctx, buf + len, md_size );
marcozecchini 0:9fca2b23d0ba 1240 mbedtls_md_finish( md_ctx, buf + len );
marcozecchini 0:9fca2b23d0ba 1241 }
marcozecchini 0:9fca2b23d0ba 1242 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 1243
marcozecchini 0:9fca2b23d0ba 1244 #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
marcozecchini 0:9fca2b23d0ba 1245 ( defined(MBEDTLS_CIPHER_MODE_CBC) && \
marcozecchini 0:9fca2b23d0ba 1246 ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) )
marcozecchini 0:9fca2b23d0ba 1247 #define SSL_SOME_MODES_USE_MAC
marcozecchini 0:9fca2b23d0ba 1248 #endif
marcozecchini 0:9fca2b23d0ba 1249
marcozecchini 0:9fca2b23d0ba 1250 /*
marcozecchini 0:9fca2b23d0ba 1251 * Encryption/decryption functions
marcozecchini 0:9fca2b23d0ba 1252 */
marcozecchini 0:9fca2b23d0ba 1253 static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 1254 {
marcozecchini 0:9fca2b23d0ba 1255 mbedtls_cipher_mode_t mode;
marcozecchini 0:9fca2b23d0ba 1256 int auth_done = 0;
marcozecchini 0:9fca2b23d0ba 1257
marcozecchini 0:9fca2b23d0ba 1258 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
marcozecchini 0:9fca2b23d0ba 1259
marcozecchini 0:9fca2b23d0ba 1260 if( ssl->session_out == NULL || ssl->transform_out == NULL )
marcozecchini 0:9fca2b23d0ba 1261 {
marcozecchini 0:9fca2b23d0ba 1262 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1263 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1264 }
marcozecchini 0:9fca2b23d0ba 1265
marcozecchini 0:9fca2b23d0ba 1266 mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc );
marcozecchini 0:9fca2b23d0ba 1267
marcozecchini 0:9fca2b23d0ba 1268 MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
marcozecchini 0:9fca2b23d0ba 1269 ssl->out_msg, ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 1270
marcozecchini 0:9fca2b23d0ba 1271 /*
marcozecchini 0:9fca2b23d0ba 1272 * Add MAC before if needed
marcozecchini 0:9fca2b23d0ba 1273 */
marcozecchini 0:9fca2b23d0ba 1274 #if defined(SSL_SOME_MODES_USE_MAC)
marcozecchini 0:9fca2b23d0ba 1275 if( mode == MBEDTLS_MODE_STREAM ||
marcozecchini 0:9fca2b23d0ba 1276 ( mode == MBEDTLS_MODE_CBC
marcozecchini 0:9fca2b23d0ba 1277 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
marcozecchini 0:9fca2b23d0ba 1278 && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
marcozecchini 0:9fca2b23d0ba 1279 #endif
marcozecchini 0:9fca2b23d0ba 1280 ) )
marcozecchini 0:9fca2b23d0ba 1281 {
marcozecchini 0:9fca2b23d0ba 1282 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 1283 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 1284 {
marcozecchini 0:9fca2b23d0ba 1285 ssl_mac( &ssl->transform_out->md_ctx_enc,
marcozecchini 0:9fca2b23d0ba 1286 ssl->transform_out->mac_enc,
marcozecchini 0:9fca2b23d0ba 1287 ssl->out_msg, ssl->out_msglen,
marcozecchini 0:9fca2b23d0ba 1288 ssl->out_ctr, ssl->out_msgtype );
marcozecchini 0:9fca2b23d0ba 1289 }
marcozecchini 0:9fca2b23d0ba 1290 else
marcozecchini 0:9fca2b23d0ba 1291 #endif
marcozecchini 0:9fca2b23d0ba 1292 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
marcozecchini 0:9fca2b23d0ba 1293 defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 1294 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
marcozecchini 0:9fca2b23d0ba 1295 {
marcozecchini 0:9fca2b23d0ba 1296 mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1297 mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 );
marcozecchini 0:9fca2b23d0ba 1298 mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 );
marcozecchini 0:9fca2b23d0ba 1299 mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
marcozecchini 0:9fca2b23d0ba 1300 ssl->out_msg, ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 1301 mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc,
marcozecchini 0:9fca2b23d0ba 1302 ssl->out_msg + ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 1303 mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
marcozecchini 0:9fca2b23d0ba 1304 }
marcozecchini 0:9fca2b23d0ba 1305 else
marcozecchini 0:9fca2b23d0ba 1306 #endif
marcozecchini 0:9fca2b23d0ba 1307 {
marcozecchini 0:9fca2b23d0ba 1308 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1309 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1310 }
marcozecchini 0:9fca2b23d0ba 1311
marcozecchini 0:9fca2b23d0ba 1312 MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac",
marcozecchini 0:9fca2b23d0ba 1313 ssl->out_msg + ssl->out_msglen,
marcozecchini 0:9fca2b23d0ba 1314 ssl->transform_out->maclen );
marcozecchini 0:9fca2b23d0ba 1315
marcozecchini 0:9fca2b23d0ba 1316 ssl->out_msglen += ssl->transform_out->maclen;
marcozecchini 0:9fca2b23d0ba 1317 auth_done++;
marcozecchini 0:9fca2b23d0ba 1318 }
marcozecchini 0:9fca2b23d0ba 1319 #endif /* AEAD not the only option */
marcozecchini 0:9fca2b23d0ba 1320
marcozecchini 0:9fca2b23d0ba 1321 /*
marcozecchini 0:9fca2b23d0ba 1322 * Encrypt
marcozecchini 0:9fca2b23d0ba 1323 */
marcozecchini 0:9fca2b23d0ba 1324 #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
marcozecchini 0:9fca2b23d0ba 1325 if( mode == MBEDTLS_MODE_STREAM )
marcozecchini 0:9fca2b23d0ba 1326 {
marcozecchini 0:9fca2b23d0ba 1327 int ret;
marcozecchini 0:9fca2b23d0ba 1328 size_t olen = 0;
marcozecchini 0:9fca2b23d0ba 1329
marcozecchini 0:9fca2b23d0ba 1330 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
marcozecchini 0:9fca2b23d0ba 1331 "including %d bytes of padding",
marcozecchini 0:9fca2b23d0ba 1332 ssl->out_msglen, 0 ) );
marcozecchini 0:9fca2b23d0ba 1333
marcozecchini 0:9fca2b23d0ba 1334 if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
marcozecchini 0:9fca2b23d0ba 1335 ssl->transform_out->iv_enc,
marcozecchini 0:9fca2b23d0ba 1336 ssl->transform_out->ivlen,
marcozecchini 0:9fca2b23d0ba 1337 ssl->out_msg, ssl->out_msglen,
marcozecchini 0:9fca2b23d0ba 1338 ssl->out_msg, &olen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1339 {
marcozecchini 0:9fca2b23d0ba 1340 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
marcozecchini 0:9fca2b23d0ba 1341 return( ret );
marcozecchini 0:9fca2b23d0ba 1342 }
marcozecchini 0:9fca2b23d0ba 1343
marcozecchini 0:9fca2b23d0ba 1344 if( ssl->out_msglen != olen )
marcozecchini 0:9fca2b23d0ba 1345 {
marcozecchini 0:9fca2b23d0ba 1346 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1347 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1348 }
marcozecchini 0:9fca2b23d0ba 1349 }
marcozecchini 0:9fca2b23d0ba 1350 else
marcozecchini 0:9fca2b23d0ba 1351 #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
marcozecchini 0:9fca2b23d0ba 1352 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
marcozecchini 0:9fca2b23d0ba 1353 if( mode == MBEDTLS_MODE_GCM ||
marcozecchini 0:9fca2b23d0ba 1354 mode == MBEDTLS_MODE_CCM )
marcozecchini 0:9fca2b23d0ba 1355 {
marcozecchini 0:9fca2b23d0ba 1356 int ret;
marcozecchini 0:9fca2b23d0ba 1357 size_t enc_msglen, olen;
marcozecchini 0:9fca2b23d0ba 1358 unsigned char *enc_msg;
marcozecchini 0:9fca2b23d0ba 1359 unsigned char add_data[13];
marcozecchini 0:9fca2b23d0ba 1360 unsigned char taglen = ssl->transform_out->ciphersuite_info->flags &
marcozecchini 0:9fca2b23d0ba 1361 MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
marcozecchini 0:9fca2b23d0ba 1362
marcozecchini 0:9fca2b23d0ba 1363 memcpy( add_data, ssl->out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1364 add_data[8] = ssl->out_msgtype;
marcozecchini 0:9fca2b23d0ba 1365 mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
marcozecchini 0:9fca2b23d0ba 1366 ssl->conf->transport, add_data + 9 );
marcozecchini 0:9fca2b23d0ba 1367 add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF;
marcozecchini 0:9fca2b23d0ba 1368 add_data[12] = ssl->out_msglen & 0xFF;
marcozecchini 0:9fca2b23d0ba 1369
marcozecchini 0:9fca2b23d0ba 1370 MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
marcozecchini 0:9fca2b23d0ba 1371 add_data, 13 );
marcozecchini 0:9fca2b23d0ba 1372
marcozecchini 0:9fca2b23d0ba 1373 /*
marcozecchini 0:9fca2b23d0ba 1374 * Generate IV
marcozecchini 0:9fca2b23d0ba 1375 */
marcozecchini 0:9fca2b23d0ba 1376 if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 )
marcozecchini 0:9fca2b23d0ba 1377 {
marcozecchini 0:9fca2b23d0ba 1378 /* Reminder if we ever add an AEAD mode with a different size */
marcozecchini 0:9fca2b23d0ba 1379 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1380 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1381 }
marcozecchini 0:9fca2b23d0ba 1382
marcozecchini 0:9fca2b23d0ba 1383 memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
marcozecchini 0:9fca2b23d0ba 1384 ssl->out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1385 memcpy( ssl->out_iv, ssl->out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1386
marcozecchini 0:9fca2b23d0ba 1387 MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv,
marcozecchini 0:9fca2b23d0ba 1388 ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
marcozecchini 0:9fca2b23d0ba 1389
marcozecchini 0:9fca2b23d0ba 1390 /*
marcozecchini 0:9fca2b23d0ba 1391 * Fix pointer positions and message length with added IV
marcozecchini 0:9fca2b23d0ba 1392 */
marcozecchini 0:9fca2b23d0ba 1393 enc_msg = ssl->out_msg;
marcozecchini 0:9fca2b23d0ba 1394 enc_msglen = ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 1395 ssl->out_msglen += ssl->transform_out->ivlen -
marcozecchini 0:9fca2b23d0ba 1396 ssl->transform_out->fixed_ivlen;
marcozecchini 0:9fca2b23d0ba 1397
marcozecchini 0:9fca2b23d0ba 1398 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
marcozecchini 0:9fca2b23d0ba 1399 "including %d bytes of padding",
marcozecchini 0:9fca2b23d0ba 1400 ssl->out_msglen, 0 ) );
marcozecchini 0:9fca2b23d0ba 1401
marcozecchini 0:9fca2b23d0ba 1402 /*
marcozecchini 0:9fca2b23d0ba 1403 * Encrypt and authenticate
marcozecchini 0:9fca2b23d0ba 1404 */
marcozecchini 0:9fca2b23d0ba 1405 if( ( ret = mbedtls_cipher_auth_encrypt( &ssl->transform_out->cipher_ctx_enc,
marcozecchini 0:9fca2b23d0ba 1406 ssl->transform_out->iv_enc,
marcozecchini 0:9fca2b23d0ba 1407 ssl->transform_out->ivlen,
marcozecchini 0:9fca2b23d0ba 1408 add_data, 13,
marcozecchini 0:9fca2b23d0ba 1409 enc_msg, enc_msglen,
marcozecchini 0:9fca2b23d0ba 1410 enc_msg, &olen,
marcozecchini 0:9fca2b23d0ba 1411 enc_msg + enc_msglen, taglen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1412 {
marcozecchini 0:9fca2b23d0ba 1413 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
marcozecchini 0:9fca2b23d0ba 1414 return( ret );
marcozecchini 0:9fca2b23d0ba 1415 }
marcozecchini 0:9fca2b23d0ba 1416
marcozecchini 0:9fca2b23d0ba 1417 if( olen != enc_msglen )
marcozecchini 0:9fca2b23d0ba 1418 {
marcozecchini 0:9fca2b23d0ba 1419 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1420 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1421 }
marcozecchini 0:9fca2b23d0ba 1422
marcozecchini 0:9fca2b23d0ba 1423 ssl->out_msglen += taglen;
marcozecchini 0:9fca2b23d0ba 1424 auth_done++;
marcozecchini 0:9fca2b23d0ba 1425
marcozecchini 0:9fca2b23d0ba 1426 MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen );
marcozecchini 0:9fca2b23d0ba 1427 }
marcozecchini 0:9fca2b23d0ba 1428 else
marcozecchini 0:9fca2b23d0ba 1429 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
marcozecchini 0:9fca2b23d0ba 1430 #if defined(MBEDTLS_CIPHER_MODE_CBC) && \
marcozecchini 0:9fca2b23d0ba 1431 ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) )
marcozecchini 0:9fca2b23d0ba 1432 if( mode == MBEDTLS_MODE_CBC )
marcozecchini 0:9fca2b23d0ba 1433 {
marcozecchini 0:9fca2b23d0ba 1434 int ret;
marcozecchini 0:9fca2b23d0ba 1435 unsigned char *enc_msg;
marcozecchini 0:9fca2b23d0ba 1436 size_t enc_msglen, padlen, olen = 0, i;
marcozecchini 0:9fca2b23d0ba 1437
marcozecchini 0:9fca2b23d0ba 1438 padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) %
marcozecchini 0:9fca2b23d0ba 1439 ssl->transform_out->ivlen;
marcozecchini 0:9fca2b23d0ba 1440 if( padlen == ssl->transform_out->ivlen )
marcozecchini 0:9fca2b23d0ba 1441 padlen = 0;
marcozecchini 0:9fca2b23d0ba 1442
marcozecchini 0:9fca2b23d0ba 1443 for( i = 0; i <= padlen; i++ )
marcozecchini 0:9fca2b23d0ba 1444 ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen;
marcozecchini 0:9fca2b23d0ba 1445
marcozecchini 0:9fca2b23d0ba 1446 ssl->out_msglen += padlen + 1;
marcozecchini 0:9fca2b23d0ba 1447
marcozecchini 0:9fca2b23d0ba 1448 enc_msglen = ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 1449 enc_msg = ssl->out_msg;
marcozecchini 0:9fca2b23d0ba 1450
marcozecchini 0:9fca2b23d0ba 1451 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 1452 /*
marcozecchini 0:9fca2b23d0ba 1453 * Prepend per-record IV for block cipher in TLS v1.1 and up as per
marcozecchini 0:9fca2b23d0ba 1454 * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
marcozecchini 0:9fca2b23d0ba 1455 */
marcozecchini 0:9fca2b23d0ba 1456 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 1457 {
marcozecchini 0:9fca2b23d0ba 1458 /*
marcozecchini 0:9fca2b23d0ba 1459 * Generate IV
marcozecchini 0:9fca2b23d0ba 1460 */
marcozecchini 0:9fca2b23d0ba 1461 ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc,
marcozecchini 0:9fca2b23d0ba 1462 ssl->transform_out->ivlen );
marcozecchini 0:9fca2b23d0ba 1463 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 1464 return( ret );
marcozecchini 0:9fca2b23d0ba 1465
marcozecchini 0:9fca2b23d0ba 1466 memcpy( ssl->out_iv, ssl->transform_out->iv_enc,
marcozecchini 0:9fca2b23d0ba 1467 ssl->transform_out->ivlen );
marcozecchini 0:9fca2b23d0ba 1468
marcozecchini 0:9fca2b23d0ba 1469 /*
marcozecchini 0:9fca2b23d0ba 1470 * Fix pointer positions and message length with added IV
marcozecchini 0:9fca2b23d0ba 1471 */
marcozecchini 0:9fca2b23d0ba 1472 enc_msg = ssl->out_msg;
marcozecchini 0:9fca2b23d0ba 1473 enc_msglen = ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 1474 ssl->out_msglen += ssl->transform_out->ivlen;
marcozecchini 0:9fca2b23d0ba 1475 }
marcozecchini 0:9fca2b23d0ba 1476 #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 1477
marcozecchini 0:9fca2b23d0ba 1478 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
marcozecchini 0:9fca2b23d0ba 1479 "including %d bytes of IV and %d bytes of padding",
marcozecchini 0:9fca2b23d0ba 1480 ssl->out_msglen, ssl->transform_out->ivlen,
marcozecchini 0:9fca2b23d0ba 1481 padlen + 1 ) );
marcozecchini 0:9fca2b23d0ba 1482
marcozecchini 0:9fca2b23d0ba 1483 if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
marcozecchini 0:9fca2b23d0ba 1484 ssl->transform_out->iv_enc,
marcozecchini 0:9fca2b23d0ba 1485 ssl->transform_out->ivlen,
marcozecchini 0:9fca2b23d0ba 1486 enc_msg, enc_msglen,
marcozecchini 0:9fca2b23d0ba 1487 enc_msg, &olen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1488 {
marcozecchini 0:9fca2b23d0ba 1489 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
marcozecchini 0:9fca2b23d0ba 1490 return( ret );
marcozecchini 0:9fca2b23d0ba 1491 }
marcozecchini 0:9fca2b23d0ba 1492
marcozecchini 0:9fca2b23d0ba 1493 if( enc_msglen != olen )
marcozecchini 0:9fca2b23d0ba 1494 {
marcozecchini 0:9fca2b23d0ba 1495 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1496 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1497 }
marcozecchini 0:9fca2b23d0ba 1498
marcozecchini 0:9fca2b23d0ba 1499 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
marcozecchini 0:9fca2b23d0ba 1500 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 1501 {
marcozecchini 0:9fca2b23d0ba 1502 /*
marcozecchini 0:9fca2b23d0ba 1503 * Save IV in SSL3 and TLS1
marcozecchini 0:9fca2b23d0ba 1504 */
marcozecchini 0:9fca2b23d0ba 1505 memcpy( ssl->transform_out->iv_enc,
marcozecchini 0:9fca2b23d0ba 1506 ssl->transform_out->cipher_ctx_enc.iv,
marcozecchini 0:9fca2b23d0ba 1507 ssl->transform_out->ivlen );
marcozecchini 0:9fca2b23d0ba 1508 }
marcozecchini 0:9fca2b23d0ba 1509 #endif
marcozecchini 0:9fca2b23d0ba 1510
marcozecchini 0:9fca2b23d0ba 1511 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
marcozecchini 0:9fca2b23d0ba 1512 if( auth_done == 0 )
marcozecchini 0:9fca2b23d0ba 1513 {
marcozecchini 0:9fca2b23d0ba 1514 /*
marcozecchini 0:9fca2b23d0ba 1515 * MAC(MAC_write_key, seq_num +
marcozecchini 0:9fca2b23d0ba 1516 * TLSCipherText.type +
marcozecchini 0:9fca2b23d0ba 1517 * TLSCipherText.version +
marcozecchini 0:9fca2b23d0ba 1518 * length_of( (IV +) ENC(...) ) +
marcozecchini 0:9fca2b23d0ba 1519 * IV + // except for TLS 1.0
marcozecchini 0:9fca2b23d0ba 1520 * ENC(content + padding + padding_length));
marcozecchini 0:9fca2b23d0ba 1521 */
marcozecchini 0:9fca2b23d0ba 1522 unsigned char pseudo_hdr[13];
marcozecchini 0:9fca2b23d0ba 1523
marcozecchini 0:9fca2b23d0ba 1524 MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
marcozecchini 0:9fca2b23d0ba 1525
marcozecchini 0:9fca2b23d0ba 1526 memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1527 memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 );
marcozecchini 0:9fca2b23d0ba 1528 pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF );
marcozecchini 0:9fca2b23d0ba 1529 pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF );
marcozecchini 0:9fca2b23d0ba 1530
marcozecchini 0:9fca2b23d0ba 1531 MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
marcozecchini 0:9fca2b23d0ba 1532
marcozecchini 0:9fca2b23d0ba 1533 mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 );
marcozecchini 0:9fca2b23d0ba 1534 mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
marcozecchini 0:9fca2b23d0ba 1535 ssl->out_iv, ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 1536 mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc,
marcozecchini 0:9fca2b23d0ba 1537 ssl->out_iv + ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 1538 mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
marcozecchini 0:9fca2b23d0ba 1539
marcozecchini 0:9fca2b23d0ba 1540 ssl->out_msglen += ssl->transform_out->maclen;
marcozecchini 0:9fca2b23d0ba 1541 auth_done++;
marcozecchini 0:9fca2b23d0ba 1542 }
marcozecchini 0:9fca2b23d0ba 1543 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
marcozecchini 0:9fca2b23d0ba 1544 }
marcozecchini 0:9fca2b23d0ba 1545 else
marcozecchini 0:9fca2b23d0ba 1546 #endif /* MBEDTLS_CIPHER_MODE_CBC &&
marcozecchini 0:9fca2b23d0ba 1547 ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */
marcozecchini 0:9fca2b23d0ba 1548 {
marcozecchini 0:9fca2b23d0ba 1549 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1550 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1551 }
marcozecchini 0:9fca2b23d0ba 1552
marcozecchini 0:9fca2b23d0ba 1553 /* Make extra sure authentication was performed, exactly once */
marcozecchini 0:9fca2b23d0ba 1554 if( auth_done != 1 )
marcozecchini 0:9fca2b23d0ba 1555 {
marcozecchini 0:9fca2b23d0ba 1556 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1557 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1558 }
marcozecchini 0:9fca2b23d0ba 1559
marcozecchini 0:9fca2b23d0ba 1560 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
marcozecchini 0:9fca2b23d0ba 1561
marcozecchini 0:9fca2b23d0ba 1562 return( 0 );
marcozecchini 0:9fca2b23d0ba 1563 }
marcozecchini 0:9fca2b23d0ba 1564
marcozecchini 0:9fca2b23d0ba 1565 #define SSL_MAX_MAC_SIZE 48
marcozecchini 0:9fca2b23d0ba 1566
marcozecchini 0:9fca2b23d0ba 1567 static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 1568 {
marcozecchini 0:9fca2b23d0ba 1569 size_t i;
marcozecchini 0:9fca2b23d0ba 1570 mbedtls_cipher_mode_t mode;
marcozecchini 0:9fca2b23d0ba 1571 int auth_done = 0;
marcozecchini 0:9fca2b23d0ba 1572 #if defined(SSL_SOME_MODES_USE_MAC)
marcozecchini 0:9fca2b23d0ba 1573 size_t padlen = 0, correct = 1;
marcozecchini 0:9fca2b23d0ba 1574 #endif
marcozecchini 0:9fca2b23d0ba 1575
marcozecchini 0:9fca2b23d0ba 1576 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
marcozecchini 0:9fca2b23d0ba 1577
marcozecchini 0:9fca2b23d0ba 1578 if( ssl->session_in == NULL || ssl->transform_in == NULL )
marcozecchini 0:9fca2b23d0ba 1579 {
marcozecchini 0:9fca2b23d0ba 1580 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1581 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1582 }
marcozecchini 0:9fca2b23d0ba 1583
marcozecchini 0:9fca2b23d0ba 1584 mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec );
marcozecchini 0:9fca2b23d0ba 1585
marcozecchini 0:9fca2b23d0ba 1586 if( ssl->in_msglen < ssl->transform_in->minlen )
marcozecchini 0:9fca2b23d0ba 1587 {
marcozecchini 0:9fca2b23d0ba 1588 MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)",
marcozecchini 0:9fca2b23d0ba 1589 ssl->in_msglen, ssl->transform_in->minlen ) );
marcozecchini 0:9fca2b23d0ba 1590 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 1591 }
marcozecchini 0:9fca2b23d0ba 1592
marcozecchini 0:9fca2b23d0ba 1593 #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
marcozecchini 0:9fca2b23d0ba 1594 if( mode == MBEDTLS_MODE_STREAM )
marcozecchini 0:9fca2b23d0ba 1595 {
marcozecchini 0:9fca2b23d0ba 1596 int ret;
marcozecchini 0:9fca2b23d0ba 1597 size_t olen = 0;
marcozecchini 0:9fca2b23d0ba 1598
marcozecchini 0:9fca2b23d0ba 1599 padlen = 0;
marcozecchini 0:9fca2b23d0ba 1600
marcozecchini 0:9fca2b23d0ba 1601 if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
marcozecchini 0:9fca2b23d0ba 1602 ssl->transform_in->iv_dec,
marcozecchini 0:9fca2b23d0ba 1603 ssl->transform_in->ivlen,
marcozecchini 0:9fca2b23d0ba 1604 ssl->in_msg, ssl->in_msglen,
marcozecchini 0:9fca2b23d0ba 1605 ssl->in_msg, &olen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1606 {
marcozecchini 0:9fca2b23d0ba 1607 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
marcozecchini 0:9fca2b23d0ba 1608 return( ret );
marcozecchini 0:9fca2b23d0ba 1609 }
marcozecchini 0:9fca2b23d0ba 1610
marcozecchini 0:9fca2b23d0ba 1611 if( ssl->in_msglen != olen )
marcozecchini 0:9fca2b23d0ba 1612 {
marcozecchini 0:9fca2b23d0ba 1613 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1614 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1615 }
marcozecchini 0:9fca2b23d0ba 1616 }
marcozecchini 0:9fca2b23d0ba 1617 else
marcozecchini 0:9fca2b23d0ba 1618 #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
marcozecchini 0:9fca2b23d0ba 1619 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
marcozecchini 0:9fca2b23d0ba 1620 if( mode == MBEDTLS_MODE_GCM ||
marcozecchini 0:9fca2b23d0ba 1621 mode == MBEDTLS_MODE_CCM )
marcozecchini 0:9fca2b23d0ba 1622 {
marcozecchini 0:9fca2b23d0ba 1623 int ret;
marcozecchini 0:9fca2b23d0ba 1624 size_t dec_msglen, olen;
marcozecchini 0:9fca2b23d0ba 1625 unsigned char *dec_msg;
marcozecchini 0:9fca2b23d0ba 1626 unsigned char *dec_msg_result;
marcozecchini 0:9fca2b23d0ba 1627 unsigned char add_data[13];
marcozecchini 0:9fca2b23d0ba 1628 unsigned char taglen = ssl->transform_in->ciphersuite_info->flags &
marcozecchini 0:9fca2b23d0ba 1629 MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
marcozecchini 0:9fca2b23d0ba 1630 size_t explicit_iv_len = ssl->transform_in->ivlen -
marcozecchini 0:9fca2b23d0ba 1631 ssl->transform_in->fixed_ivlen;
marcozecchini 0:9fca2b23d0ba 1632
marcozecchini 0:9fca2b23d0ba 1633 if( ssl->in_msglen < explicit_iv_len + taglen )
marcozecchini 0:9fca2b23d0ba 1634 {
marcozecchini 0:9fca2b23d0ba 1635 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) "
marcozecchini 0:9fca2b23d0ba 1636 "+ taglen (%d)", ssl->in_msglen,
marcozecchini 0:9fca2b23d0ba 1637 explicit_iv_len, taglen ) );
marcozecchini 0:9fca2b23d0ba 1638 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 1639 }
marcozecchini 0:9fca2b23d0ba 1640 dec_msglen = ssl->in_msglen - explicit_iv_len - taglen;
marcozecchini 0:9fca2b23d0ba 1641
marcozecchini 0:9fca2b23d0ba 1642 dec_msg = ssl->in_msg;
marcozecchini 0:9fca2b23d0ba 1643 dec_msg_result = ssl->in_msg;
marcozecchini 0:9fca2b23d0ba 1644 ssl->in_msglen = dec_msglen;
marcozecchini 0:9fca2b23d0ba 1645
marcozecchini 0:9fca2b23d0ba 1646 memcpy( add_data, ssl->in_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1647 add_data[8] = ssl->in_msgtype;
marcozecchini 0:9fca2b23d0ba 1648 mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
marcozecchini 0:9fca2b23d0ba 1649 ssl->conf->transport, add_data + 9 );
marcozecchini 0:9fca2b23d0ba 1650 add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
marcozecchini 0:9fca2b23d0ba 1651 add_data[12] = ssl->in_msglen & 0xFF;
marcozecchini 0:9fca2b23d0ba 1652
marcozecchini 0:9fca2b23d0ba 1653 MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
marcozecchini 0:9fca2b23d0ba 1654 add_data, 13 );
marcozecchini 0:9fca2b23d0ba 1655
marcozecchini 0:9fca2b23d0ba 1656 memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
marcozecchini 0:9fca2b23d0ba 1657 ssl->in_iv,
marcozecchini 0:9fca2b23d0ba 1658 ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
marcozecchini 0:9fca2b23d0ba 1659
marcozecchini 0:9fca2b23d0ba 1660 MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec,
marcozecchini 0:9fca2b23d0ba 1661 ssl->transform_in->ivlen );
marcozecchini 0:9fca2b23d0ba 1662 MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen );
marcozecchini 0:9fca2b23d0ba 1663
marcozecchini 0:9fca2b23d0ba 1664 /*
marcozecchini 0:9fca2b23d0ba 1665 * Decrypt and authenticate
marcozecchini 0:9fca2b23d0ba 1666 */
marcozecchini 0:9fca2b23d0ba 1667 if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec,
marcozecchini 0:9fca2b23d0ba 1668 ssl->transform_in->iv_dec,
marcozecchini 0:9fca2b23d0ba 1669 ssl->transform_in->ivlen,
marcozecchini 0:9fca2b23d0ba 1670 add_data, 13,
marcozecchini 0:9fca2b23d0ba 1671 dec_msg, dec_msglen,
marcozecchini 0:9fca2b23d0ba 1672 dec_msg_result, &olen,
marcozecchini 0:9fca2b23d0ba 1673 dec_msg + dec_msglen, taglen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1674 {
marcozecchini 0:9fca2b23d0ba 1675 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
marcozecchini 0:9fca2b23d0ba 1676
marcozecchini 0:9fca2b23d0ba 1677 if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
marcozecchini 0:9fca2b23d0ba 1678 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 1679
marcozecchini 0:9fca2b23d0ba 1680 return( ret );
marcozecchini 0:9fca2b23d0ba 1681 }
marcozecchini 0:9fca2b23d0ba 1682 auth_done++;
marcozecchini 0:9fca2b23d0ba 1683
marcozecchini 0:9fca2b23d0ba 1684 if( olen != dec_msglen )
marcozecchini 0:9fca2b23d0ba 1685 {
marcozecchini 0:9fca2b23d0ba 1686 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1687 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1688 }
marcozecchini 0:9fca2b23d0ba 1689 }
marcozecchini 0:9fca2b23d0ba 1690 else
marcozecchini 0:9fca2b23d0ba 1691 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
marcozecchini 0:9fca2b23d0ba 1692 #if defined(MBEDTLS_CIPHER_MODE_CBC) && \
marcozecchini 0:9fca2b23d0ba 1693 ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) )
marcozecchini 0:9fca2b23d0ba 1694 if( mode == MBEDTLS_MODE_CBC )
marcozecchini 0:9fca2b23d0ba 1695 {
marcozecchini 0:9fca2b23d0ba 1696 /*
marcozecchini 0:9fca2b23d0ba 1697 * Decrypt and check the padding
marcozecchini 0:9fca2b23d0ba 1698 */
marcozecchini 0:9fca2b23d0ba 1699 int ret;
marcozecchini 0:9fca2b23d0ba 1700 unsigned char *dec_msg;
marcozecchini 0:9fca2b23d0ba 1701 unsigned char *dec_msg_result;
marcozecchini 0:9fca2b23d0ba 1702 size_t dec_msglen;
marcozecchini 0:9fca2b23d0ba 1703 size_t minlen = 0;
marcozecchini 0:9fca2b23d0ba 1704 size_t olen = 0;
marcozecchini 0:9fca2b23d0ba 1705
marcozecchini 0:9fca2b23d0ba 1706 /*
marcozecchini 0:9fca2b23d0ba 1707 * Check immediate ciphertext sanity
marcozecchini 0:9fca2b23d0ba 1708 */
marcozecchini 0:9fca2b23d0ba 1709 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 1710 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 1711 minlen += ssl->transform_in->ivlen;
marcozecchini 0:9fca2b23d0ba 1712 #endif
marcozecchini 0:9fca2b23d0ba 1713
marcozecchini 0:9fca2b23d0ba 1714 if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
marcozecchini 0:9fca2b23d0ba 1715 ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
marcozecchini 0:9fca2b23d0ba 1716 {
marcozecchini 0:9fca2b23d0ba 1717 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) "
marcozecchini 0:9fca2b23d0ba 1718 "+ 1 ) ( + expl IV )", ssl->in_msglen,
marcozecchini 0:9fca2b23d0ba 1719 ssl->transform_in->ivlen,
marcozecchini 0:9fca2b23d0ba 1720 ssl->transform_in->maclen ) );
marcozecchini 0:9fca2b23d0ba 1721 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 1722 }
marcozecchini 0:9fca2b23d0ba 1723
marcozecchini 0:9fca2b23d0ba 1724 dec_msglen = ssl->in_msglen;
marcozecchini 0:9fca2b23d0ba 1725 dec_msg = ssl->in_msg;
marcozecchini 0:9fca2b23d0ba 1726 dec_msg_result = ssl->in_msg;
marcozecchini 0:9fca2b23d0ba 1727
marcozecchini 0:9fca2b23d0ba 1728 /*
marcozecchini 0:9fca2b23d0ba 1729 * Authenticate before decrypt if enabled
marcozecchini 0:9fca2b23d0ba 1730 */
marcozecchini 0:9fca2b23d0ba 1731 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
marcozecchini 0:9fca2b23d0ba 1732 if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
marcozecchini 0:9fca2b23d0ba 1733 {
marcozecchini 0:9fca2b23d0ba 1734 unsigned char computed_mac[SSL_MAX_MAC_SIZE];
marcozecchini 0:9fca2b23d0ba 1735 unsigned char pseudo_hdr[13];
marcozecchini 0:9fca2b23d0ba 1736
marcozecchini 0:9fca2b23d0ba 1737 MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
marcozecchini 0:9fca2b23d0ba 1738
marcozecchini 0:9fca2b23d0ba 1739 dec_msglen -= ssl->transform_in->maclen;
marcozecchini 0:9fca2b23d0ba 1740 ssl->in_msglen -= ssl->transform_in->maclen;
marcozecchini 0:9fca2b23d0ba 1741
marcozecchini 0:9fca2b23d0ba 1742 memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1743 memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 );
marcozecchini 0:9fca2b23d0ba 1744 pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF );
marcozecchini 0:9fca2b23d0ba 1745 pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF );
marcozecchini 0:9fca2b23d0ba 1746
marcozecchini 0:9fca2b23d0ba 1747 MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
marcozecchini 0:9fca2b23d0ba 1748
marcozecchini 0:9fca2b23d0ba 1749 mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 );
marcozecchini 0:9fca2b23d0ba 1750 mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec,
marcozecchini 0:9fca2b23d0ba 1751 ssl->in_iv, ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 1752 mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, computed_mac );
marcozecchini 0:9fca2b23d0ba 1753 mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
marcozecchini 0:9fca2b23d0ba 1754
marcozecchini 0:9fca2b23d0ba 1755 MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen,
marcozecchini 0:9fca2b23d0ba 1756 ssl->transform_in->maclen );
marcozecchini 0:9fca2b23d0ba 1757 MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", computed_mac,
marcozecchini 0:9fca2b23d0ba 1758 ssl->transform_in->maclen );
marcozecchini 0:9fca2b23d0ba 1759
marcozecchini 0:9fca2b23d0ba 1760 if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, computed_mac,
marcozecchini 0:9fca2b23d0ba 1761 ssl->transform_in->maclen ) != 0 )
marcozecchini 0:9fca2b23d0ba 1762 {
marcozecchini 0:9fca2b23d0ba 1763 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
marcozecchini 0:9fca2b23d0ba 1764
marcozecchini 0:9fca2b23d0ba 1765 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 1766 }
marcozecchini 0:9fca2b23d0ba 1767 auth_done++;
marcozecchini 0:9fca2b23d0ba 1768 }
marcozecchini 0:9fca2b23d0ba 1769 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
marcozecchini 0:9fca2b23d0ba 1770
marcozecchini 0:9fca2b23d0ba 1771 /*
marcozecchini 0:9fca2b23d0ba 1772 * Check length sanity
marcozecchini 0:9fca2b23d0ba 1773 */
marcozecchini 0:9fca2b23d0ba 1774 if( ssl->in_msglen % ssl->transform_in->ivlen != 0 )
marcozecchini 0:9fca2b23d0ba 1775 {
marcozecchini 0:9fca2b23d0ba 1776 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
marcozecchini 0:9fca2b23d0ba 1777 ssl->in_msglen, ssl->transform_in->ivlen ) );
marcozecchini 0:9fca2b23d0ba 1778 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 1779 }
marcozecchini 0:9fca2b23d0ba 1780
marcozecchini 0:9fca2b23d0ba 1781 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 1782 /*
marcozecchini 0:9fca2b23d0ba 1783 * Initialize for prepended IV for block cipher in TLS v1.1 and up
marcozecchini 0:9fca2b23d0ba 1784 */
marcozecchini 0:9fca2b23d0ba 1785 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 1786 {
marcozecchini 0:9fca2b23d0ba 1787 dec_msglen -= ssl->transform_in->ivlen;
marcozecchini 0:9fca2b23d0ba 1788 ssl->in_msglen -= ssl->transform_in->ivlen;
marcozecchini 0:9fca2b23d0ba 1789
marcozecchini 0:9fca2b23d0ba 1790 for( i = 0; i < ssl->transform_in->ivlen; i++ )
marcozecchini 0:9fca2b23d0ba 1791 ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
marcozecchini 0:9fca2b23d0ba 1792 }
marcozecchini 0:9fca2b23d0ba 1793 #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 1794
marcozecchini 0:9fca2b23d0ba 1795 if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
marcozecchini 0:9fca2b23d0ba 1796 ssl->transform_in->iv_dec,
marcozecchini 0:9fca2b23d0ba 1797 ssl->transform_in->ivlen,
marcozecchini 0:9fca2b23d0ba 1798 dec_msg, dec_msglen,
marcozecchini 0:9fca2b23d0ba 1799 dec_msg_result, &olen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1800 {
marcozecchini 0:9fca2b23d0ba 1801 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
marcozecchini 0:9fca2b23d0ba 1802 return( ret );
marcozecchini 0:9fca2b23d0ba 1803 }
marcozecchini 0:9fca2b23d0ba 1804
marcozecchini 0:9fca2b23d0ba 1805 if( dec_msglen != olen )
marcozecchini 0:9fca2b23d0ba 1806 {
marcozecchini 0:9fca2b23d0ba 1807 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1808 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1809 }
marcozecchini 0:9fca2b23d0ba 1810
marcozecchini 0:9fca2b23d0ba 1811 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
marcozecchini 0:9fca2b23d0ba 1812 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 1813 {
marcozecchini 0:9fca2b23d0ba 1814 /*
marcozecchini 0:9fca2b23d0ba 1815 * Save IV in SSL3 and TLS1
marcozecchini 0:9fca2b23d0ba 1816 */
marcozecchini 0:9fca2b23d0ba 1817 memcpy( ssl->transform_in->iv_dec,
marcozecchini 0:9fca2b23d0ba 1818 ssl->transform_in->cipher_ctx_dec.iv,
marcozecchini 0:9fca2b23d0ba 1819 ssl->transform_in->ivlen );
marcozecchini 0:9fca2b23d0ba 1820 }
marcozecchini 0:9fca2b23d0ba 1821 #endif
marcozecchini 0:9fca2b23d0ba 1822
marcozecchini 0:9fca2b23d0ba 1823 padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
marcozecchini 0:9fca2b23d0ba 1824
marcozecchini 0:9fca2b23d0ba 1825 if( ssl->in_msglen < ssl->transform_in->maclen + padlen &&
marcozecchini 0:9fca2b23d0ba 1826 auth_done == 0 )
marcozecchini 0:9fca2b23d0ba 1827 {
marcozecchini 0:9fca2b23d0ba 1828 #if defined(MBEDTLS_SSL_DEBUG_ALL)
marcozecchini 0:9fca2b23d0ba 1829 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
marcozecchini 0:9fca2b23d0ba 1830 ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
marcozecchini 0:9fca2b23d0ba 1831 #endif
marcozecchini 0:9fca2b23d0ba 1832 padlen = 0;
marcozecchini 0:9fca2b23d0ba 1833 correct = 0;
marcozecchini 0:9fca2b23d0ba 1834 }
marcozecchini 0:9fca2b23d0ba 1835
marcozecchini 0:9fca2b23d0ba 1836 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 1837 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 1838 {
marcozecchini 0:9fca2b23d0ba 1839 if( padlen > ssl->transform_in->ivlen )
marcozecchini 0:9fca2b23d0ba 1840 {
marcozecchini 0:9fca2b23d0ba 1841 #if defined(MBEDTLS_SSL_DEBUG_ALL)
marcozecchini 0:9fca2b23d0ba 1842 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
marcozecchini 0:9fca2b23d0ba 1843 "should be no more than %d",
marcozecchini 0:9fca2b23d0ba 1844 padlen, ssl->transform_in->ivlen ) );
marcozecchini 0:9fca2b23d0ba 1845 #endif
marcozecchini 0:9fca2b23d0ba 1846 correct = 0;
marcozecchini 0:9fca2b23d0ba 1847 }
marcozecchini 0:9fca2b23d0ba 1848 }
marcozecchini 0:9fca2b23d0ba 1849 else
marcozecchini 0:9fca2b23d0ba 1850 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 1851 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
marcozecchini 0:9fca2b23d0ba 1852 defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 1853 if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 1854 {
marcozecchini 0:9fca2b23d0ba 1855 /*
marcozecchini 0:9fca2b23d0ba 1856 * TLSv1+: always check the padding up to the first failure
marcozecchini 0:9fca2b23d0ba 1857 * and fake check up to 256 bytes of padding
marcozecchini 0:9fca2b23d0ba 1858 */
marcozecchini 0:9fca2b23d0ba 1859 size_t pad_count = 0, real_count = 1;
marcozecchini 0:9fca2b23d0ba 1860 size_t padding_idx = ssl->in_msglen - padlen - 1;
marcozecchini 0:9fca2b23d0ba 1861
marcozecchini 0:9fca2b23d0ba 1862 /*
marcozecchini 0:9fca2b23d0ba 1863 * Padding is guaranteed to be incorrect if:
marcozecchini 0:9fca2b23d0ba 1864 * 1. padlen >= ssl->in_msglen
marcozecchini 0:9fca2b23d0ba 1865 *
marcozecchini 0:9fca2b23d0ba 1866 * 2. padding_idx >= MBEDTLS_SSL_MAX_CONTENT_LEN +
marcozecchini 0:9fca2b23d0ba 1867 * ssl->transform_in->maclen
marcozecchini 0:9fca2b23d0ba 1868 *
marcozecchini 0:9fca2b23d0ba 1869 * In both cases we reset padding_idx to a safe value (0) to
marcozecchini 0:9fca2b23d0ba 1870 * prevent out-of-buffer reads.
marcozecchini 0:9fca2b23d0ba 1871 */
marcozecchini 0:9fca2b23d0ba 1872 correct &= ( ssl->in_msglen >= padlen + 1 );
marcozecchini 0:9fca2b23d0ba 1873 correct &= ( padding_idx < MBEDTLS_SSL_MAX_CONTENT_LEN +
marcozecchini 0:9fca2b23d0ba 1874 ssl->transform_in->maclen );
marcozecchini 0:9fca2b23d0ba 1875
marcozecchini 0:9fca2b23d0ba 1876 padding_idx *= correct;
marcozecchini 0:9fca2b23d0ba 1877
marcozecchini 0:9fca2b23d0ba 1878 for( i = 1; i <= 256; i++ )
marcozecchini 0:9fca2b23d0ba 1879 {
marcozecchini 0:9fca2b23d0ba 1880 real_count &= ( i <= padlen );
marcozecchini 0:9fca2b23d0ba 1881 pad_count += real_count *
marcozecchini 0:9fca2b23d0ba 1882 ( ssl->in_msg[padding_idx + i] == padlen - 1 );
marcozecchini 0:9fca2b23d0ba 1883 }
marcozecchini 0:9fca2b23d0ba 1884
marcozecchini 0:9fca2b23d0ba 1885 correct &= ( pad_count == padlen ); /* Only 1 on correct padding */
marcozecchini 0:9fca2b23d0ba 1886
marcozecchini 0:9fca2b23d0ba 1887 #if defined(MBEDTLS_SSL_DEBUG_ALL)
marcozecchini 0:9fca2b23d0ba 1888 if( padlen > 0 && correct == 0 )
marcozecchini 0:9fca2b23d0ba 1889 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
marcozecchini 0:9fca2b23d0ba 1890 #endif
marcozecchini 0:9fca2b23d0ba 1891 padlen &= correct * 0x1FF;
marcozecchini 0:9fca2b23d0ba 1892 }
marcozecchini 0:9fca2b23d0ba 1893 else
marcozecchini 0:9fca2b23d0ba 1894 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
marcozecchini 0:9fca2b23d0ba 1895 MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 1896 {
marcozecchini 0:9fca2b23d0ba 1897 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1898 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1899 }
marcozecchini 0:9fca2b23d0ba 1900
marcozecchini 0:9fca2b23d0ba 1901 ssl->in_msglen -= padlen;
marcozecchini 0:9fca2b23d0ba 1902 }
marcozecchini 0:9fca2b23d0ba 1903 else
marcozecchini 0:9fca2b23d0ba 1904 #endif /* MBEDTLS_CIPHER_MODE_CBC &&
marcozecchini 0:9fca2b23d0ba 1905 ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */
marcozecchini 0:9fca2b23d0ba 1906 {
marcozecchini 0:9fca2b23d0ba 1907 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1908 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1909 }
marcozecchini 0:9fca2b23d0ba 1910
marcozecchini 0:9fca2b23d0ba 1911 MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
marcozecchini 0:9fca2b23d0ba 1912 ssl->in_msg, ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 1913
marcozecchini 0:9fca2b23d0ba 1914 /*
marcozecchini 0:9fca2b23d0ba 1915 * Authenticate if not done yet.
marcozecchini 0:9fca2b23d0ba 1916 * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
marcozecchini 0:9fca2b23d0ba 1917 */
marcozecchini 0:9fca2b23d0ba 1918 #if defined(SSL_SOME_MODES_USE_MAC)
marcozecchini 0:9fca2b23d0ba 1919 if( auth_done == 0 )
marcozecchini 0:9fca2b23d0ba 1920 {
marcozecchini 0:9fca2b23d0ba 1921 unsigned char tmp[SSL_MAX_MAC_SIZE];
marcozecchini 0:9fca2b23d0ba 1922
marcozecchini 0:9fca2b23d0ba 1923 ssl->in_msglen -= ssl->transform_in->maclen;
marcozecchini 0:9fca2b23d0ba 1924
marcozecchini 0:9fca2b23d0ba 1925 ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 );
marcozecchini 0:9fca2b23d0ba 1926 ssl->in_len[1] = (unsigned char)( ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 1927
marcozecchini 0:9fca2b23d0ba 1928 memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen );
marcozecchini 0:9fca2b23d0ba 1929
marcozecchini 0:9fca2b23d0ba 1930 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 1931 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 1932 {
marcozecchini 0:9fca2b23d0ba 1933 ssl_mac( &ssl->transform_in->md_ctx_dec,
marcozecchini 0:9fca2b23d0ba 1934 ssl->transform_in->mac_dec,
marcozecchini 0:9fca2b23d0ba 1935 ssl->in_msg, ssl->in_msglen,
marcozecchini 0:9fca2b23d0ba 1936 ssl->in_ctr, ssl->in_msgtype );
marcozecchini 0:9fca2b23d0ba 1937 }
marcozecchini 0:9fca2b23d0ba 1938 else
marcozecchini 0:9fca2b23d0ba 1939 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 1940 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
marcozecchini 0:9fca2b23d0ba 1941 defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 1942 if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 1943 {
marcozecchini 0:9fca2b23d0ba 1944 /*
marcozecchini 0:9fca2b23d0ba 1945 * Process MAC and always update for padlen afterwards to make
marcozecchini 0:9fca2b23d0ba 1946 * total time independent of padlen
marcozecchini 0:9fca2b23d0ba 1947 *
marcozecchini 0:9fca2b23d0ba 1948 * extra_run compensates MAC check for padlen
marcozecchini 0:9fca2b23d0ba 1949 *
marcozecchini 0:9fca2b23d0ba 1950 * Known timing attacks:
marcozecchini 0:9fca2b23d0ba 1951 * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
marcozecchini 0:9fca2b23d0ba 1952 *
marcozecchini 0:9fca2b23d0ba 1953 * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values
marcozecchini 0:9fca2b23d0ba 1954 * correctly. (We round down instead of up, so -56 is the correct
marcozecchini 0:9fca2b23d0ba 1955 * value for our calculations instead of -55)
marcozecchini 0:9fca2b23d0ba 1956 */
marcozecchini 0:9fca2b23d0ba 1957 size_t j, extra_run = 0;
marcozecchini 0:9fca2b23d0ba 1958 extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
marcozecchini 0:9fca2b23d0ba 1959 ( 13 + ssl->in_msglen + 8 ) / 64;
marcozecchini 0:9fca2b23d0ba 1960
marcozecchini 0:9fca2b23d0ba 1961 extra_run &= correct * 0xFF;
marcozecchini 0:9fca2b23d0ba 1962
marcozecchini 0:9fca2b23d0ba 1963 mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 1964 mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 );
marcozecchini 0:9fca2b23d0ba 1965 mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
marcozecchini 0:9fca2b23d0ba 1966 mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
marcozecchini 0:9fca2b23d0ba 1967 ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 1968 mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec,
marcozecchini 0:9fca2b23d0ba 1969 ssl->in_msg + ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 1970 /* Call mbedtls_md_process at least once due to cache attacks */
marcozecchini 0:9fca2b23d0ba 1971 for( j = 0; j < extra_run + 1; j++ )
marcozecchini 0:9fca2b23d0ba 1972 mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
marcozecchini 0:9fca2b23d0ba 1973
marcozecchini 0:9fca2b23d0ba 1974 mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
marcozecchini 0:9fca2b23d0ba 1975 }
marcozecchini 0:9fca2b23d0ba 1976 else
marcozecchini 0:9fca2b23d0ba 1977 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
marcozecchini 0:9fca2b23d0ba 1978 MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 1979 {
marcozecchini 0:9fca2b23d0ba 1980 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 1981 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 1982 }
marcozecchini 0:9fca2b23d0ba 1983
marcozecchini 0:9fca2b23d0ba 1984 MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen );
marcozecchini 0:9fca2b23d0ba 1985 MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen,
marcozecchini 0:9fca2b23d0ba 1986 ssl->transform_in->maclen );
marcozecchini 0:9fca2b23d0ba 1987
marcozecchini 0:9fca2b23d0ba 1988 if( mbedtls_ssl_safer_memcmp( tmp, ssl->in_msg + ssl->in_msglen,
marcozecchini 0:9fca2b23d0ba 1989 ssl->transform_in->maclen ) != 0 )
marcozecchini 0:9fca2b23d0ba 1990 {
marcozecchini 0:9fca2b23d0ba 1991 #if defined(MBEDTLS_SSL_DEBUG_ALL)
marcozecchini 0:9fca2b23d0ba 1992 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
marcozecchini 0:9fca2b23d0ba 1993 #endif
marcozecchini 0:9fca2b23d0ba 1994 correct = 0;
marcozecchini 0:9fca2b23d0ba 1995 }
marcozecchini 0:9fca2b23d0ba 1996 auth_done++;
marcozecchini 0:9fca2b23d0ba 1997
marcozecchini 0:9fca2b23d0ba 1998 /*
marcozecchini 0:9fca2b23d0ba 1999 * Finally check the correct flag
marcozecchini 0:9fca2b23d0ba 2000 */
marcozecchini 0:9fca2b23d0ba 2001 if( correct == 0 )
marcozecchini 0:9fca2b23d0ba 2002 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 2003 }
marcozecchini 0:9fca2b23d0ba 2004 #endif /* SSL_SOME_MODES_USE_MAC */
marcozecchini 0:9fca2b23d0ba 2005
marcozecchini 0:9fca2b23d0ba 2006 /* Make extra sure authentication was performed, exactly once */
marcozecchini 0:9fca2b23d0ba 2007 if( auth_done != 1 )
marcozecchini 0:9fca2b23d0ba 2008 {
marcozecchini 0:9fca2b23d0ba 2009 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 2010 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 2011 }
marcozecchini 0:9fca2b23d0ba 2012
marcozecchini 0:9fca2b23d0ba 2013 if( ssl->in_msglen == 0 )
marcozecchini 0:9fca2b23d0ba 2014 {
marcozecchini 0:9fca2b23d0ba 2015 ssl->nb_zero++;
marcozecchini 0:9fca2b23d0ba 2016
marcozecchini 0:9fca2b23d0ba 2017 /*
marcozecchini 0:9fca2b23d0ba 2018 * Three or more empty messages may be a DoS attack
marcozecchini 0:9fca2b23d0ba 2019 * (excessive CPU consumption).
marcozecchini 0:9fca2b23d0ba 2020 */
marcozecchini 0:9fca2b23d0ba 2021 if( ssl->nb_zero > 3 )
marcozecchini 0:9fca2b23d0ba 2022 {
marcozecchini 0:9fca2b23d0ba 2023 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
marcozecchini 0:9fca2b23d0ba 2024 "messages, possible DoS attack" ) );
marcozecchini 0:9fca2b23d0ba 2025 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 2026 }
marcozecchini 0:9fca2b23d0ba 2027 }
marcozecchini 0:9fca2b23d0ba 2028 else
marcozecchini 0:9fca2b23d0ba 2029 ssl->nb_zero = 0;
marcozecchini 0:9fca2b23d0ba 2030
marcozecchini 0:9fca2b23d0ba 2031 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 2032 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 2033 {
marcozecchini 0:9fca2b23d0ba 2034 ; /* in_ctr read from peer, not maintained internally */
marcozecchini 0:9fca2b23d0ba 2035 }
marcozecchini 0:9fca2b23d0ba 2036 else
marcozecchini 0:9fca2b23d0ba 2037 #endif
marcozecchini 0:9fca2b23d0ba 2038 {
marcozecchini 0:9fca2b23d0ba 2039 for( i = 8; i > ssl_ep_len( ssl ); i-- )
marcozecchini 0:9fca2b23d0ba 2040 if( ++ssl->in_ctr[i - 1] != 0 )
marcozecchini 0:9fca2b23d0ba 2041 break;
marcozecchini 0:9fca2b23d0ba 2042
marcozecchini 0:9fca2b23d0ba 2043 /* The loop goes to its end iff the counter is wrapping */
marcozecchini 0:9fca2b23d0ba 2044 if( i == ssl_ep_len( ssl ) )
marcozecchini 0:9fca2b23d0ba 2045 {
marcozecchini 0:9fca2b23d0ba 2046 MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
marcozecchini 0:9fca2b23d0ba 2047 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
marcozecchini 0:9fca2b23d0ba 2048 }
marcozecchini 0:9fca2b23d0ba 2049 }
marcozecchini 0:9fca2b23d0ba 2050
marcozecchini 0:9fca2b23d0ba 2051 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
marcozecchini 0:9fca2b23d0ba 2052
marcozecchini 0:9fca2b23d0ba 2053 return( 0 );
marcozecchini 0:9fca2b23d0ba 2054 }
marcozecchini 0:9fca2b23d0ba 2055
marcozecchini 0:9fca2b23d0ba 2056 #undef MAC_NONE
marcozecchini 0:9fca2b23d0ba 2057 #undef MAC_PLAINTEXT
marcozecchini 0:9fca2b23d0ba 2058 #undef MAC_CIPHERTEXT
marcozecchini 0:9fca2b23d0ba 2059
marcozecchini 0:9fca2b23d0ba 2060 #if defined(MBEDTLS_ZLIB_SUPPORT)
marcozecchini 0:9fca2b23d0ba 2061 /*
marcozecchini 0:9fca2b23d0ba 2062 * Compression/decompression functions
marcozecchini 0:9fca2b23d0ba 2063 */
marcozecchini 0:9fca2b23d0ba 2064 static int ssl_compress_buf( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2065 {
marcozecchini 0:9fca2b23d0ba 2066 int ret;
marcozecchini 0:9fca2b23d0ba 2067 unsigned char *msg_post = ssl->out_msg;
marcozecchini 0:9fca2b23d0ba 2068 size_t len_pre = ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 2069 unsigned char *msg_pre = ssl->compress_buf;
marcozecchini 0:9fca2b23d0ba 2070
marcozecchini 0:9fca2b23d0ba 2071 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
marcozecchini 0:9fca2b23d0ba 2072
marcozecchini 0:9fca2b23d0ba 2073 if( len_pre == 0 )
marcozecchini 0:9fca2b23d0ba 2074 return( 0 );
marcozecchini 0:9fca2b23d0ba 2075
marcozecchini 0:9fca2b23d0ba 2076 memcpy( msg_pre, ssl->out_msg, len_pre );
marcozecchini 0:9fca2b23d0ba 2077
marcozecchini 0:9fca2b23d0ba 2078 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ",
marcozecchini 0:9fca2b23d0ba 2079 ssl->out_msglen ) );
marcozecchini 0:9fca2b23d0ba 2080
marcozecchini 0:9fca2b23d0ba 2081 MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
marcozecchini 0:9fca2b23d0ba 2082 ssl->out_msg, ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 2083
marcozecchini 0:9fca2b23d0ba 2084 ssl->transform_out->ctx_deflate.next_in = msg_pre;
marcozecchini 0:9fca2b23d0ba 2085 ssl->transform_out->ctx_deflate.avail_in = len_pre;
marcozecchini 0:9fca2b23d0ba 2086 ssl->transform_out->ctx_deflate.next_out = msg_post;
marcozecchini 0:9fca2b23d0ba 2087 ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN;
marcozecchini 0:9fca2b23d0ba 2088
marcozecchini 0:9fca2b23d0ba 2089 ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
marcozecchini 0:9fca2b23d0ba 2090 if( ret != Z_OK )
marcozecchini 0:9fca2b23d0ba 2091 {
marcozecchini 0:9fca2b23d0ba 2092 MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
marcozecchini 0:9fca2b23d0ba 2093 return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
marcozecchini 0:9fca2b23d0ba 2094 }
marcozecchini 0:9fca2b23d0ba 2095
marcozecchini 0:9fca2b23d0ba 2096 ssl->out_msglen = MBEDTLS_SSL_BUFFER_LEN -
marcozecchini 0:9fca2b23d0ba 2097 ssl->transform_out->ctx_deflate.avail_out;
marcozecchini 0:9fca2b23d0ba 2098
marcozecchini 0:9fca2b23d0ba 2099 MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
marcozecchini 0:9fca2b23d0ba 2100 ssl->out_msglen ) );
marcozecchini 0:9fca2b23d0ba 2101
marcozecchini 0:9fca2b23d0ba 2102 MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
marcozecchini 0:9fca2b23d0ba 2103 ssl->out_msg, ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 2104
marcozecchini 0:9fca2b23d0ba 2105 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
marcozecchini 0:9fca2b23d0ba 2106
marcozecchini 0:9fca2b23d0ba 2107 return( 0 );
marcozecchini 0:9fca2b23d0ba 2108 }
marcozecchini 0:9fca2b23d0ba 2109
marcozecchini 0:9fca2b23d0ba 2110 static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2111 {
marcozecchini 0:9fca2b23d0ba 2112 int ret;
marcozecchini 0:9fca2b23d0ba 2113 unsigned char *msg_post = ssl->in_msg;
marcozecchini 0:9fca2b23d0ba 2114 size_t len_pre = ssl->in_msglen;
marcozecchini 0:9fca2b23d0ba 2115 unsigned char *msg_pre = ssl->compress_buf;
marcozecchini 0:9fca2b23d0ba 2116
marcozecchini 0:9fca2b23d0ba 2117 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
marcozecchini 0:9fca2b23d0ba 2118
marcozecchini 0:9fca2b23d0ba 2119 if( len_pre == 0 )
marcozecchini 0:9fca2b23d0ba 2120 return( 0 );
marcozecchini 0:9fca2b23d0ba 2121
marcozecchini 0:9fca2b23d0ba 2122 memcpy( msg_pre, ssl->in_msg, len_pre );
marcozecchini 0:9fca2b23d0ba 2123
marcozecchini 0:9fca2b23d0ba 2124 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ",
marcozecchini 0:9fca2b23d0ba 2125 ssl->in_msglen ) );
marcozecchini 0:9fca2b23d0ba 2126
marcozecchini 0:9fca2b23d0ba 2127 MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
marcozecchini 0:9fca2b23d0ba 2128 ssl->in_msg, ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 2129
marcozecchini 0:9fca2b23d0ba 2130 ssl->transform_in->ctx_inflate.next_in = msg_pre;
marcozecchini 0:9fca2b23d0ba 2131 ssl->transform_in->ctx_inflate.avail_in = len_pre;
marcozecchini 0:9fca2b23d0ba 2132 ssl->transform_in->ctx_inflate.next_out = msg_post;
marcozecchini 0:9fca2b23d0ba 2133 ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_MAX_CONTENT_LEN;
marcozecchini 0:9fca2b23d0ba 2134
marcozecchini 0:9fca2b23d0ba 2135 ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
marcozecchini 0:9fca2b23d0ba 2136 if( ret != Z_OK )
marcozecchini 0:9fca2b23d0ba 2137 {
marcozecchini 0:9fca2b23d0ba 2138 MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
marcozecchini 0:9fca2b23d0ba 2139 return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
marcozecchini 0:9fca2b23d0ba 2140 }
marcozecchini 0:9fca2b23d0ba 2141
marcozecchini 0:9fca2b23d0ba 2142 ssl->in_msglen = MBEDTLS_SSL_MAX_CONTENT_LEN -
marcozecchini 0:9fca2b23d0ba 2143 ssl->transform_in->ctx_inflate.avail_out;
marcozecchini 0:9fca2b23d0ba 2144
marcozecchini 0:9fca2b23d0ba 2145 MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
marcozecchini 0:9fca2b23d0ba 2146 ssl->in_msglen ) );
marcozecchini 0:9fca2b23d0ba 2147
marcozecchini 0:9fca2b23d0ba 2148 MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
marcozecchini 0:9fca2b23d0ba 2149 ssl->in_msg, ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 2150
marcozecchini 0:9fca2b23d0ba 2151 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
marcozecchini 0:9fca2b23d0ba 2152
marcozecchini 0:9fca2b23d0ba 2153 return( 0 );
marcozecchini 0:9fca2b23d0ba 2154 }
marcozecchini 0:9fca2b23d0ba 2155 #endif /* MBEDTLS_ZLIB_SUPPORT */
marcozecchini 0:9fca2b23d0ba 2156
marcozecchini 0:9fca2b23d0ba 2157 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 2158 static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
marcozecchini 0:9fca2b23d0ba 2159
marcozecchini 0:9fca2b23d0ba 2160 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 2161 static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2162 {
marcozecchini 0:9fca2b23d0ba 2163 /* If renegotiation is not enforced, retransmit until we would reach max
marcozecchini 0:9fca2b23d0ba 2164 * timeout if we were using the usual handshake doubling scheme */
marcozecchini 0:9fca2b23d0ba 2165 if( ssl->conf->renego_max_records < 0 )
marcozecchini 0:9fca2b23d0ba 2166 {
marcozecchini 0:9fca2b23d0ba 2167 uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
marcozecchini 0:9fca2b23d0ba 2168 unsigned char doublings = 1;
marcozecchini 0:9fca2b23d0ba 2169
marcozecchini 0:9fca2b23d0ba 2170 while( ratio != 0 )
marcozecchini 0:9fca2b23d0ba 2171 {
marcozecchini 0:9fca2b23d0ba 2172 ++doublings;
marcozecchini 0:9fca2b23d0ba 2173 ratio >>= 1;
marcozecchini 0:9fca2b23d0ba 2174 }
marcozecchini 0:9fca2b23d0ba 2175
marcozecchini 0:9fca2b23d0ba 2176 if( ++ssl->renego_records_seen > doublings )
marcozecchini 0:9fca2b23d0ba 2177 {
marcozecchini 0:9fca2b23d0ba 2178 MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) );
marcozecchini 0:9fca2b23d0ba 2179 return( 0 );
marcozecchini 0:9fca2b23d0ba 2180 }
marcozecchini 0:9fca2b23d0ba 2181 }
marcozecchini 0:9fca2b23d0ba 2182
marcozecchini 0:9fca2b23d0ba 2183 return( ssl_write_hello_request( ssl ) );
marcozecchini 0:9fca2b23d0ba 2184 }
marcozecchini 0:9fca2b23d0ba 2185 #endif
marcozecchini 0:9fca2b23d0ba 2186 #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
marcozecchini 0:9fca2b23d0ba 2187
marcozecchini 0:9fca2b23d0ba 2188 /*
marcozecchini 0:9fca2b23d0ba 2189 * Fill the input message buffer by appending data to it.
marcozecchini 0:9fca2b23d0ba 2190 * The amount of data already fetched is in ssl->in_left.
marcozecchini 0:9fca2b23d0ba 2191 *
marcozecchini 0:9fca2b23d0ba 2192 * If we return 0, is it guaranteed that (at least) nb_want bytes are
marcozecchini 0:9fca2b23d0ba 2193 * available (from this read and/or a previous one). Otherwise, an error code
marcozecchini 0:9fca2b23d0ba 2194 * is returned (possibly EOF or WANT_READ).
marcozecchini 0:9fca2b23d0ba 2195 *
marcozecchini 0:9fca2b23d0ba 2196 * With stream transport (TLS) on success ssl->in_left == nb_want, but
marcozecchini 0:9fca2b23d0ba 2197 * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
marcozecchini 0:9fca2b23d0ba 2198 * since we always read a whole datagram at once.
marcozecchini 0:9fca2b23d0ba 2199 *
marcozecchini 0:9fca2b23d0ba 2200 * For DTLS, it is up to the caller to set ssl->next_record_offset when
marcozecchini 0:9fca2b23d0ba 2201 * they're done reading a record.
marcozecchini 0:9fca2b23d0ba 2202 */
marcozecchini 0:9fca2b23d0ba 2203 int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
marcozecchini 0:9fca2b23d0ba 2204 {
marcozecchini 0:9fca2b23d0ba 2205 int ret;
marcozecchini 0:9fca2b23d0ba 2206 size_t len;
marcozecchini 0:9fca2b23d0ba 2207
marcozecchini 0:9fca2b23d0ba 2208 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
marcozecchini 0:9fca2b23d0ba 2209
marcozecchini 0:9fca2b23d0ba 2210 if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
marcozecchini 0:9fca2b23d0ba 2211 {
marcozecchini 0:9fca2b23d0ba 2212 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
marcozecchini 0:9fca2b23d0ba 2213 "or mbedtls_ssl_set_bio()" ) );
marcozecchini 0:9fca2b23d0ba 2214 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 2215 }
marcozecchini 0:9fca2b23d0ba 2216
marcozecchini 0:9fca2b23d0ba 2217 if( nb_want > MBEDTLS_SSL_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) )
marcozecchini 0:9fca2b23d0ba 2218 {
marcozecchini 0:9fca2b23d0ba 2219 MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
marcozecchini 0:9fca2b23d0ba 2220 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 2221 }
marcozecchini 0:9fca2b23d0ba 2222
marcozecchini 0:9fca2b23d0ba 2223 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 2224 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 2225 {
marcozecchini 0:9fca2b23d0ba 2226 uint32_t timeout;
marcozecchini 0:9fca2b23d0ba 2227
marcozecchini 0:9fca2b23d0ba 2228 /* Just to be sure */
marcozecchini 0:9fca2b23d0ba 2229 if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
marcozecchini 0:9fca2b23d0ba 2230 {
marcozecchini 0:9fca2b23d0ba 2231 MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
marcozecchini 0:9fca2b23d0ba 2232 "mbedtls_ssl_set_timer_cb() for DTLS" ) );
marcozecchini 0:9fca2b23d0ba 2233 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 2234 }
marcozecchini 0:9fca2b23d0ba 2235
marcozecchini 0:9fca2b23d0ba 2236 /*
marcozecchini 0:9fca2b23d0ba 2237 * The point is, we need to always read a full datagram at once, so we
marcozecchini 0:9fca2b23d0ba 2238 * sometimes read more then requested, and handle the additional data.
marcozecchini 0:9fca2b23d0ba 2239 * It could be the rest of the current record (while fetching the
marcozecchini 0:9fca2b23d0ba 2240 * header) and/or some other records in the same datagram.
marcozecchini 0:9fca2b23d0ba 2241 */
marcozecchini 0:9fca2b23d0ba 2242
marcozecchini 0:9fca2b23d0ba 2243 /*
marcozecchini 0:9fca2b23d0ba 2244 * Move to the next record in the already read datagram if applicable
marcozecchini 0:9fca2b23d0ba 2245 */
marcozecchini 0:9fca2b23d0ba 2246 if( ssl->next_record_offset != 0 )
marcozecchini 0:9fca2b23d0ba 2247 {
marcozecchini 0:9fca2b23d0ba 2248 if( ssl->in_left < ssl->next_record_offset )
marcozecchini 0:9fca2b23d0ba 2249 {
marcozecchini 0:9fca2b23d0ba 2250 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 2251 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 2252 }
marcozecchini 0:9fca2b23d0ba 2253
marcozecchini 0:9fca2b23d0ba 2254 ssl->in_left -= ssl->next_record_offset;
marcozecchini 0:9fca2b23d0ba 2255
marcozecchini 0:9fca2b23d0ba 2256 if( ssl->in_left != 0 )
marcozecchini 0:9fca2b23d0ba 2257 {
marcozecchini 0:9fca2b23d0ba 2258 MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d",
marcozecchini 0:9fca2b23d0ba 2259 ssl->next_record_offset ) );
marcozecchini 0:9fca2b23d0ba 2260 memmove( ssl->in_hdr,
marcozecchini 0:9fca2b23d0ba 2261 ssl->in_hdr + ssl->next_record_offset,
marcozecchini 0:9fca2b23d0ba 2262 ssl->in_left );
marcozecchini 0:9fca2b23d0ba 2263 }
marcozecchini 0:9fca2b23d0ba 2264
marcozecchini 0:9fca2b23d0ba 2265 ssl->next_record_offset = 0;
marcozecchini 0:9fca2b23d0ba 2266 }
marcozecchini 0:9fca2b23d0ba 2267
marcozecchini 0:9fca2b23d0ba 2268 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
marcozecchini 0:9fca2b23d0ba 2269 ssl->in_left, nb_want ) );
marcozecchini 0:9fca2b23d0ba 2270
marcozecchini 0:9fca2b23d0ba 2271 /*
marcozecchini 0:9fca2b23d0ba 2272 * Done if we already have enough data.
marcozecchini 0:9fca2b23d0ba 2273 */
marcozecchini 0:9fca2b23d0ba 2274 if( nb_want <= ssl->in_left)
marcozecchini 0:9fca2b23d0ba 2275 {
marcozecchini 0:9fca2b23d0ba 2276 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
marcozecchini 0:9fca2b23d0ba 2277 return( 0 );
marcozecchini 0:9fca2b23d0ba 2278 }
marcozecchini 0:9fca2b23d0ba 2279
marcozecchini 0:9fca2b23d0ba 2280 /*
marcozecchini 0:9fca2b23d0ba 2281 * A record can't be split accross datagrams. If we need to read but
marcozecchini 0:9fca2b23d0ba 2282 * are not at the beginning of a new record, the caller did something
marcozecchini 0:9fca2b23d0ba 2283 * wrong.
marcozecchini 0:9fca2b23d0ba 2284 */
marcozecchini 0:9fca2b23d0ba 2285 if( ssl->in_left != 0 )
marcozecchini 0:9fca2b23d0ba 2286 {
marcozecchini 0:9fca2b23d0ba 2287 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 2288 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 2289 }
marcozecchini 0:9fca2b23d0ba 2290
marcozecchini 0:9fca2b23d0ba 2291 /*
marcozecchini 0:9fca2b23d0ba 2292 * Don't even try to read if time's out already.
marcozecchini 0:9fca2b23d0ba 2293 * This avoids by-passing the timer when repeatedly receiving messages
marcozecchini 0:9fca2b23d0ba 2294 * that will end up being dropped.
marcozecchini 0:9fca2b23d0ba 2295 */
marcozecchini 0:9fca2b23d0ba 2296 if( ssl_check_timer( ssl ) != 0 )
marcozecchini 0:9fca2b23d0ba 2297 ret = MBEDTLS_ERR_SSL_TIMEOUT;
marcozecchini 0:9fca2b23d0ba 2298 else
marcozecchini 0:9fca2b23d0ba 2299 {
marcozecchini 0:9fca2b23d0ba 2300 len = MBEDTLS_SSL_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
marcozecchini 0:9fca2b23d0ba 2301
marcozecchini 0:9fca2b23d0ba 2302 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 2303 timeout = ssl->handshake->retransmit_timeout;
marcozecchini 0:9fca2b23d0ba 2304 else
marcozecchini 0:9fca2b23d0ba 2305 timeout = ssl->conf->read_timeout;
marcozecchini 0:9fca2b23d0ba 2306
marcozecchini 0:9fca2b23d0ba 2307 MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
marcozecchini 0:9fca2b23d0ba 2308
marcozecchini 0:9fca2b23d0ba 2309 if( ssl->f_recv_timeout != NULL )
marcozecchini 0:9fca2b23d0ba 2310 ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
marcozecchini 0:9fca2b23d0ba 2311 timeout );
marcozecchini 0:9fca2b23d0ba 2312 else
marcozecchini 0:9fca2b23d0ba 2313 ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
marcozecchini 0:9fca2b23d0ba 2314
marcozecchini 0:9fca2b23d0ba 2315 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
marcozecchini 0:9fca2b23d0ba 2316
marcozecchini 0:9fca2b23d0ba 2317 if( ret == 0 )
marcozecchini 0:9fca2b23d0ba 2318 return( MBEDTLS_ERR_SSL_CONN_EOF );
marcozecchini 0:9fca2b23d0ba 2319 }
marcozecchini 0:9fca2b23d0ba 2320
marcozecchini 0:9fca2b23d0ba 2321 if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
marcozecchini 0:9fca2b23d0ba 2322 {
marcozecchini 0:9fca2b23d0ba 2323 MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
marcozecchini 0:9fca2b23d0ba 2324 ssl_set_timer( ssl, 0 );
marcozecchini 0:9fca2b23d0ba 2325
marcozecchini 0:9fca2b23d0ba 2326 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 2327 {
marcozecchini 0:9fca2b23d0ba 2328 if( ssl_double_retransmit_timeout( ssl ) != 0 )
marcozecchini 0:9fca2b23d0ba 2329 {
marcozecchini 0:9fca2b23d0ba 2330 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
marcozecchini 0:9fca2b23d0ba 2331 return( MBEDTLS_ERR_SSL_TIMEOUT );
marcozecchini 0:9fca2b23d0ba 2332 }
marcozecchini 0:9fca2b23d0ba 2333
marcozecchini 0:9fca2b23d0ba 2334 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 2335 {
marcozecchini 0:9fca2b23d0ba 2336 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
marcozecchini 0:9fca2b23d0ba 2337 return( ret );
marcozecchini 0:9fca2b23d0ba 2338 }
marcozecchini 0:9fca2b23d0ba 2339
marcozecchini 0:9fca2b23d0ba 2340 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 2341 }
marcozecchini 0:9fca2b23d0ba 2342 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 2343 else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 2344 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
marcozecchini 0:9fca2b23d0ba 2345 {
marcozecchini 0:9fca2b23d0ba 2346 if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 2347 {
marcozecchini 0:9fca2b23d0ba 2348 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
marcozecchini 0:9fca2b23d0ba 2349 return( ret );
marcozecchini 0:9fca2b23d0ba 2350 }
marcozecchini 0:9fca2b23d0ba 2351
marcozecchini 0:9fca2b23d0ba 2352 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 2353 }
marcozecchini 0:9fca2b23d0ba 2354 #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
marcozecchini 0:9fca2b23d0ba 2355 }
marcozecchini 0:9fca2b23d0ba 2356
marcozecchini 0:9fca2b23d0ba 2357 if( ret < 0 )
marcozecchini 0:9fca2b23d0ba 2358 return( ret );
marcozecchini 0:9fca2b23d0ba 2359
marcozecchini 0:9fca2b23d0ba 2360 ssl->in_left = ret;
marcozecchini 0:9fca2b23d0ba 2361 }
marcozecchini 0:9fca2b23d0ba 2362 else
marcozecchini 0:9fca2b23d0ba 2363 #endif
marcozecchini 0:9fca2b23d0ba 2364 {
marcozecchini 0:9fca2b23d0ba 2365 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
marcozecchini 0:9fca2b23d0ba 2366 ssl->in_left, nb_want ) );
marcozecchini 0:9fca2b23d0ba 2367
marcozecchini 0:9fca2b23d0ba 2368 while( ssl->in_left < nb_want )
marcozecchini 0:9fca2b23d0ba 2369 {
marcozecchini 0:9fca2b23d0ba 2370 len = nb_want - ssl->in_left;
marcozecchini 0:9fca2b23d0ba 2371
marcozecchini 0:9fca2b23d0ba 2372 if( ssl_check_timer( ssl ) != 0 )
marcozecchini 0:9fca2b23d0ba 2373 ret = MBEDTLS_ERR_SSL_TIMEOUT;
marcozecchini 0:9fca2b23d0ba 2374 else
marcozecchini 0:9fca2b23d0ba 2375 {
marcozecchini 0:9fca2b23d0ba 2376 if( ssl->f_recv_timeout != NULL )
marcozecchini 0:9fca2b23d0ba 2377 {
marcozecchini 0:9fca2b23d0ba 2378 ret = ssl->f_recv_timeout( ssl->p_bio,
marcozecchini 0:9fca2b23d0ba 2379 ssl->in_hdr + ssl->in_left, len,
marcozecchini 0:9fca2b23d0ba 2380 ssl->conf->read_timeout );
marcozecchini 0:9fca2b23d0ba 2381 }
marcozecchini 0:9fca2b23d0ba 2382 else
marcozecchini 0:9fca2b23d0ba 2383 {
marcozecchini 0:9fca2b23d0ba 2384 ret = ssl->f_recv( ssl->p_bio,
marcozecchini 0:9fca2b23d0ba 2385 ssl->in_hdr + ssl->in_left, len );
marcozecchini 0:9fca2b23d0ba 2386 }
marcozecchini 0:9fca2b23d0ba 2387 }
marcozecchini 0:9fca2b23d0ba 2388
marcozecchini 0:9fca2b23d0ba 2389 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
marcozecchini 0:9fca2b23d0ba 2390 ssl->in_left, nb_want ) );
marcozecchini 0:9fca2b23d0ba 2391 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
marcozecchini 0:9fca2b23d0ba 2392
marcozecchini 0:9fca2b23d0ba 2393 if( ret == 0 )
marcozecchini 0:9fca2b23d0ba 2394 return( MBEDTLS_ERR_SSL_CONN_EOF );
marcozecchini 0:9fca2b23d0ba 2395
marcozecchini 0:9fca2b23d0ba 2396 if( ret < 0 )
marcozecchini 0:9fca2b23d0ba 2397 return( ret );
marcozecchini 0:9fca2b23d0ba 2398
marcozecchini 0:9fca2b23d0ba 2399 ssl->in_left += ret;
marcozecchini 0:9fca2b23d0ba 2400 }
marcozecchini 0:9fca2b23d0ba 2401 }
marcozecchini 0:9fca2b23d0ba 2402
marcozecchini 0:9fca2b23d0ba 2403 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
marcozecchini 0:9fca2b23d0ba 2404
marcozecchini 0:9fca2b23d0ba 2405 return( 0 );
marcozecchini 0:9fca2b23d0ba 2406 }
marcozecchini 0:9fca2b23d0ba 2407
marcozecchini 0:9fca2b23d0ba 2408 /*
marcozecchini 0:9fca2b23d0ba 2409 * Flush any data not yet written
marcozecchini 0:9fca2b23d0ba 2410 */
marcozecchini 0:9fca2b23d0ba 2411 int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2412 {
marcozecchini 0:9fca2b23d0ba 2413 int ret;
marcozecchini 0:9fca2b23d0ba 2414 unsigned char *buf, i;
marcozecchini 0:9fca2b23d0ba 2415
marcozecchini 0:9fca2b23d0ba 2416 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
marcozecchini 0:9fca2b23d0ba 2417
marcozecchini 0:9fca2b23d0ba 2418 if( ssl->f_send == NULL )
marcozecchini 0:9fca2b23d0ba 2419 {
marcozecchini 0:9fca2b23d0ba 2420 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
marcozecchini 0:9fca2b23d0ba 2421 "or mbedtls_ssl_set_bio()" ) );
marcozecchini 0:9fca2b23d0ba 2422 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 2423 }
marcozecchini 0:9fca2b23d0ba 2424
marcozecchini 0:9fca2b23d0ba 2425 /* Avoid incrementing counter if data is flushed */
marcozecchini 0:9fca2b23d0ba 2426 if( ssl->out_left == 0 )
marcozecchini 0:9fca2b23d0ba 2427 {
marcozecchini 0:9fca2b23d0ba 2428 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
marcozecchini 0:9fca2b23d0ba 2429 return( 0 );
marcozecchini 0:9fca2b23d0ba 2430 }
marcozecchini 0:9fca2b23d0ba 2431
marcozecchini 0:9fca2b23d0ba 2432 while( ssl->out_left > 0 )
marcozecchini 0:9fca2b23d0ba 2433 {
marcozecchini 0:9fca2b23d0ba 2434 MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
marcozecchini 0:9fca2b23d0ba 2435 mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
marcozecchini 0:9fca2b23d0ba 2436
marcozecchini 0:9fca2b23d0ba 2437 buf = ssl->out_hdr + mbedtls_ssl_hdr_len( ssl ) +
marcozecchini 0:9fca2b23d0ba 2438 ssl->out_msglen - ssl->out_left;
marcozecchini 0:9fca2b23d0ba 2439 ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
marcozecchini 0:9fca2b23d0ba 2440
marcozecchini 0:9fca2b23d0ba 2441 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
marcozecchini 0:9fca2b23d0ba 2442
marcozecchini 0:9fca2b23d0ba 2443 if( ret <= 0 )
marcozecchini 0:9fca2b23d0ba 2444 return( ret );
marcozecchini 0:9fca2b23d0ba 2445
marcozecchini 0:9fca2b23d0ba 2446 ssl->out_left -= ret;
marcozecchini 0:9fca2b23d0ba 2447 }
marcozecchini 0:9fca2b23d0ba 2448
marcozecchini 0:9fca2b23d0ba 2449 for( i = 8; i > ssl_ep_len( ssl ); i-- )
marcozecchini 0:9fca2b23d0ba 2450 if( ++ssl->out_ctr[i - 1] != 0 )
marcozecchini 0:9fca2b23d0ba 2451 break;
marcozecchini 0:9fca2b23d0ba 2452
marcozecchini 0:9fca2b23d0ba 2453 /* The loop goes to its end iff the counter is wrapping */
marcozecchini 0:9fca2b23d0ba 2454 if( i == ssl_ep_len( ssl ) )
marcozecchini 0:9fca2b23d0ba 2455 {
marcozecchini 0:9fca2b23d0ba 2456 MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
marcozecchini 0:9fca2b23d0ba 2457 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
marcozecchini 0:9fca2b23d0ba 2458 }
marcozecchini 0:9fca2b23d0ba 2459
marcozecchini 0:9fca2b23d0ba 2460 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
marcozecchini 0:9fca2b23d0ba 2461
marcozecchini 0:9fca2b23d0ba 2462 return( 0 );
marcozecchini 0:9fca2b23d0ba 2463 }
marcozecchini 0:9fca2b23d0ba 2464
marcozecchini 0:9fca2b23d0ba 2465 /*
marcozecchini 0:9fca2b23d0ba 2466 * Functions to handle the DTLS retransmission state machine
marcozecchini 0:9fca2b23d0ba 2467 */
marcozecchini 0:9fca2b23d0ba 2468 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 2469 /*
marcozecchini 0:9fca2b23d0ba 2470 * Append current handshake message to current outgoing flight
marcozecchini 0:9fca2b23d0ba 2471 */
marcozecchini 0:9fca2b23d0ba 2472 static int ssl_flight_append( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2473 {
marcozecchini 0:9fca2b23d0ba 2474 mbedtls_ssl_flight_item *msg;
marcozecchini 0:9fca2b23d0ba 2475
marcozecchini 0:9fca2b23d0ba 2476 /* Allocate space for current message */
marcozecchini 0:9fca2b23d0ba 2477 if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 2478 {
marcozecchini 0:9fca2b23d0ba 2479 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed",
marcozecchini 0:9fca2b23d0ba 2480 sizeof( mbedtls_ssl_flight_item ) ) );
marcozecchini 0:9fca2b23d0ba 2481 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 2482 }
marcozecchini 0:9fca2b23d0ba 2483
marcozecchini 0:9fca2b23d0ba 2484 if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 2485 {
marcozecchini 0:9fca2b23d0ba 2486 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) );
marcozecchini 0:9fca2b23d0ba 2487 mbedtls_free( msg );
marcozecchini 0:9fca2b23d0ba 2488 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 2489 }
marcozecchini 0:9fca2b23d0ba 2490
marcozecchini 0:9fca2b23d0ba 2491 /* Copy current handshake message with headers */
marcozecchini 0:9fca2b23d0ba 2492 memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 2493 msg->len = ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 2494 msg->type = ssl->out_msgtype;
marcozecchini 0:9fca2b23d0ba 2495 msg->next = NULL;
marcozecchini 0:9fca2b23d0ba 2496
marcozecchini 0:9fca2b23d0ba 2497 /* Append to the current flight */
marcozecchini 0:9fca2b23d0ba 2498 if( ssl->handshake->flight == NULL )
marcozecchini 0:9fca2b23d0ba 2499 ssl->handshake->flight = msg;
marcozecchini 0:9fca2b23d0ba 2500 else
marcozecchini 0:9fca2b23d0ba 2501 {
marcozecchini 0:9fca2b23d0ba 2502 mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
marcozecchini 0:9fca2b23d0ba 2503 while( cur->next != NULL )
marcozecchini 0:9fca2b23d0ba 2504 cur = cur->next;
marcozecchini 0:9fca2b23d0ba 2505 cur->next = msg;
marcozecchini 0:9fca2b23d0ba 2506 }
marcozecchini 0:9fca2b23d0ba 2507
marcozecchini 0:9fca2b23d0ba 2508 return( 0 );
marcozecchini 0:9fca2b23d0ba 2509 }
marcozecchini 0:9fca2b23d0ba 2510
marcozecchini 0:9fca2b23d0ba 2511 /*
marcozecchini 0:9fca2b23d0ba 2512 * Free the current flight of handshake messages
marcozecchini 0:9fca2b23d0ba 2513 */
marcozecchini 0:9fca2b23d0ba 2514 static void ssl_flight_free( mbedtls_ssl_flight_item *flight )
marcozecchini 0:9fca2b23d0ba 2515 {
marcozecchini 0:9fca2b23d0ba 2516 mbedtls_ssl_flight_item *cur = flight;
marcozecchini 0:9fca2b23d0ba 2517 mbedtls_ssl_flight_item *next;
marcozecchini 0:9fca2b23d0ba 2518
marcozecchini 0:9fca2b23d0ba 2519 while( cur != NULL )
marcozecchini 0:9fca2b23d0ba 2520 {
marcozecchini 0:9fca2b23d0ba 2521 next = cur->next;
marcozecchini 0:9fca2b23d0ba 2522
marcozecchini 0:9fca2b23d0ba 2523 mbedtls_free( cur->p );
marcozecchini 0:9fca2b23d0ba 2524 mbedtls_free( cur );
marcozecchini 0:9fca2b23d0ba 2525
marcozecchini 0:9fca2b23d0ba 2526 cur = next;
marcozecchini 0:9fca2b23d0ba 2527 }
marcozecchini 0:9fca2b23d0ba 2528 }
marcozecchini 0:9fca2b23d0ba 2529
marcozecchini 0:9fca2b23d0ba 2530 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
marcozecchini 0:9fca2b23d0ba 2531 static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
marcozecchini 0:9fca2b23d0ba 2532 #endif
marcozecchini 0:9fca2b23d0ba 2533
marcozecchini 0:9fca2b23d0ba 2534 /*
marcozecchini 0:9fca2b23d0ba 2535 * Swap transform_out and out_ctr with the alternative ones
marcozecchini 0:9fca2b23d0ba 2536 */
marcozecchini 0:9fca2b23d0ba 2537 static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2538 {
marcozecchini 0:9fca2b23d0ba 2539 mbedtls_ssl_transform *tmp_transform;
marcozecchini 0:9fca2b23d0ba 2540 unsigned char tmp_out_ctr[8];
marcozecchini 0:9fca2b23d0ba 2541
marcozecchini 0:9fca2b23d0ba 2542 if( ssl->transform_out == ssl->handshake->alt_transform_out )
marcozecchini 0:9fca2b23d0ba 2543 {
marcozecchini 0:9fca2b23d0ba 2544 MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
marcozecchini 0:9fca2b23d0ba 2545 return;
marcozecchini 0:9fca2b23d0ba 2546 }
marcozecchini 0:9fca2b23d0ba 2547
marcozecchini 0:9fca2b23d0ba 2548 MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
marcozecchini 0:9fca2b23d0ba 2549
marcozecchini 0:9fca2b23d0ba 2550 /* Swap transforms */
marcozecchini 0:9fca2b23d0ba 2551 tmp_transform = ssl->transform_out;
marcozecchini 0:9fca2b23d0ba 2552 ssl->transform_out = ssl->handshake->alt_transform_out;
marcozecchini 0:9fca2b23d0ba 2553 ssl->handshake->alt_transform_out = tmp_transform;
marcozecchini 0:9fca2b23d0ba 2554
marcozecchini 0:9fca2b23d0ba 2555 /* Swap epoch + sequence_number */
marcozecchini 0:9fca2b23d0ba 2556 memcpy( tmp_out_ctr, ssl->out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 2557 memcpy( ssl->out_ctr, ssl->handshake->alt_out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 2558 memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 2559
marcozecchini 0:9fca2b23d0ba 2560 /* Adjust to the newly activated transform */
marcozecchini 0:9fca2b23d0ba 2561 if( ssl->transform_out != NULL &&
marcozecchini 0:9fca2b23d0ba 2562 ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 2563 {
marcozecchini 0:9fca2b23d0ba 2564 ssl->out_msg = ssl->out_iv + ssl->transform_out->ivlen -
marcozecchini 0:9fca2b23d0ba 2565 ssl->transform_out->fixed_ivlen;
marcozecchini 0:9fca2b23d0ba 2566 }
marcozecchini 0:9fca2b23d0ba 2567 else
marcozecchini 0:9fca2b23d0ba 2568 ssl->out_msg = ssl->out_iv;
marcozecchini 0:9fca2b23d0ba 2569
marcozecchini 0:9fca2b23d0ba 2570 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 2571 if( mbedtls_ssl_hw_record_activate != NULL )
marcozecchini 0:9fca2b23d0ba 2572 {
marcozecchini 0:9fca2b23d0ba 2573 if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 2574 {
marcozecchini 0:9fca2b23d0ba 2575 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
marcozecchini 0:9fca2b23d0ba 2576 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
marcozecchini 0:9fca2b23d0ba 2577 }
marcozecchini 0:9fca2b23d0ba 2578 }
marcozecchini 0:9fca2b23d0ba 2579 #endif
marcozecchini 0:9fca2b23d0ba 2580 }
marcozecchini 0:9fca2b23d0ba 2581
marcozecchini 0:9fca2b23d0ba 2582 /*
marcozecchini 0:9fca2b23d0ba 2583 * Retransmit the current flight of messages.
marcozecchini 0:9fca2b23d0ba 2584 *
marcozecchini 0:9fca2b23d0ba 2585 * Need to remember the current message in case flush_output returns
marcozecchini 0:9fca2b23d0ba 2586 * WANT_WRITE, causing us to exit this function and come back later.
marcozecchini 0:9fca2b23d0ba 2587 * This function must be called until state is no longer SENDING.
marcozecchini 0:9fca2b23d0ba 2588 */
marcozecchini 0:9fca2b23d0ba 2589 int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2590 {
marcozecchini 0:9fca2b23d0ba 2591 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
marcozecchini 0:9fca2b23d0ba 2592
marcozecchini 0:9fca2b23d0ba 2593 if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
marcozecchini 0:9fca2b23d0ba 2594 {
marcozecchini 0:9fca2b23d0ba 2595 MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise resending" ) );
marcozecchini 0:9fca2b23d0ba 2596
marcozecchini 0:9fca2b23d0ba 2597 ssl->handshake->cur_msg = ssl->handshake->flight;
marcozecchini 0:9fca2b23d0ba 2598 ssl_swap_epochs( ssl );
marcozecchini 0:9fca2b23d0ba 2599
marcozecchini 0:9fca2b23d0ba 2600 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
marcozecchini 0:9fca2b23d0ba 2601 }
marcozecchini 0:9fca2b23d0ba 2602
marcozecchini 0:9fca2b23d0ba 2603 while( ssl->handshake->cur_msg != NULL )
marcozecchini 0:9fca2b23d0ba 2604 {
marcozecchini 0:9fca2b23d0ba 2605 int ret;
marcozecchini 0:9fca2b23d0ba 2606 mbedtls_ssl_flight_item *cur = ssl->handshake->cur_msg;
marcozecchini 0:9fca2b23d0ba 2607
marcozecchini 0:9fca2b23d0ba 2608 /* Swap epochs before sending Finished: we can't do it after
marcozecchini 0:9fca2b23d0ba 2609 * sending ChangeCipherSpec, in case write returns WANT_READ.
marcozecchini 0:9fca2b23d0ba 2610 * Must be done before copying, may change out_msg pointer */
marcozecchini 0:9fca2b23d0ba 2611 if( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
marcozecchini 0:9fca2b23d0ba 2612 cur->p[0] == MBEDTLS_SSL_HS_FINISHED )
marcozecchini 0:9fca2b23d0ba 2613 {
marcozecchini 0:9fca2b23d0ba 2614 ssl_swap_epochs( ssl );
marcozecchini 0:9fca2b23d0ba 2615 }
marcozecchini 0:9fca2b23d0ba 2616
marcozecchini 0:9fca2b23d0ba 2617 memcpy( ssl->out_msg, cur->p, cur->len );
marcozecchini 0:9fca2b23d0ba 2618 ssl->out_msglen = cur->len;
marcozecchini 0:9fca2b23d0ba 2619 ssl->out_msgtype = cur->type;
marcozecchini 0:9fca2b23d0ba 2620
marcozecchini 0:9fca2b23d0ba 2621 ssl->handshake->cur_msg = cur->next;
marcozecchini 0:9fca2b23d0ba 2622
marcozecchini 0:9fca2b23d0ba 2623 MBEDTLS_SSL_DEBUG_BUF( 3, "resent handshake message header", ssl->out_msg, 12 );
marcozecchini 0:9fca2b23d0ba 2624
marcozecchini 0:9fca2b23d0ba 2625 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 2626 {
marcozecchini 0:9fca2b23d0ba 2627 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
marcozecchini 0:9fca2b23d0ba 2628 return( ret );
marcozecchini 0:9fca2b23d0ba 2629 }
marcozecchini 0:9fca2b23d0ba 2630 }
marcozecchini 0:9fca2b23d0ba 2631
marcozecchini 0:9fca2b23d0ba 2632 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 2633 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
marcozecchini 0:9fca2b23d0ba 2634 else
marcozecchini 0:9fca2b23d0ba 2635 {
marcozecchini 0:9fca2b23d0ba 2636 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
marcozecchini 0:9fca2b23d0ba 2637 ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
marcozecchini 0:9fca2b23d0ba 2638 }
marcozecchini 0:9fca2b23d0ba 2639
marcozecchini 0:9fca2b23d0ba 2640 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
marcozecchini 0:9fca2b23d0ba 2641
marcozecchini 0:9fca2b23d0ba 2642 return( 0 );
marcozecchini 0:9fca2b23d0ba 2643 }
marcozecchini 0:9fca2b23d0ba 2644
marcozecchini 0:9fca2b23d0ba 2645 /*
marcozecchini 0:9fca2b23d0ba 2646 * To be called when the last message of an incoming flight is received.
marcozecchini 0:9fca2b23d0ba 2647 */
marcozecchini 0:9fca2b23d0ba 2648 void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2649 {
marcozecchini 0:9fca2b23d0ba 2650 /* We won't need to resend that one any more */
marcozecchini 0:9fca2b23d0ba 2651 ssl_flight_free( ssl->handshake->flight );
marcozecchini 0:9fca2b23d0ba 2652 ssl->handshake->flight = NULL;
marcozecchini 0:9fca2b23d0ba 2653 ssl->handshake->cur_msg = NULL;
marcozecchini 0:9fca2b23d0ba 2654
marcozecchini 0:9fca2b23d0ba 2655 /* The next incoming flight will start with this msg_seq */
marcozecchini 0:9fca2b23d0ba 2656 ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
marcozecchini 0:9fca2b23d0ba 2657
marcozecchini 0:9fca2b23d0ba 2658 /* Cancel timer */
marcozecchini 0:9fca2b23d0ba 2659 ssl_set_timer( ssl, 0 );
marcozecchini 0:9fca2b23d0ba 2660
marcozecchini 0:9fca2b23d0ba 2661 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
marcozecchini 0:9fca2b23d0ba 2662 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
marcozecchini 0:9fca2b23d0ba 2663 {
marcozecchini 0:9fca2b23d0ba 2664 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
marcozecchini 0:9fca2b23d0ba 2665 }
marcozecchini 0:9fca2b23d0ba 2666 else
marcozecchini 0:9fca2b23d0ba 2667 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
marcozecchini 0:9fca2b23d0ba 2668 }
marcozecchini 0:9fca2b23d0ba 2669
marcozecchini 0:9fca2b23d0ba 2670 /*
marcozecchini 0:9fca2b23d0ba 2671 * To be called when the last message of an outgoing flight is send.
marcozecchini 0:9fca2b23d0ba 2672 */
marcozecchini 0:9fca2b23d0ba 2673 void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2674 {
marcozecchini 0:9fca2b23d0ba 2675 ssl_reset_retransmit_timeout( ssl );
marcozecchini 0:9fca2b23d0ba 2676 ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
marcozecchini 0:9fca2b23d0ba 2677
marcozecchini 0:9fca2b23d0ba 2678 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
marcozecchini 0:9fca2b23d0ba 2679 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
marcozecchini 0:9fca2b23d0ba 2680 {
marcozecchini 0:9fca2b23d0ba 2681 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
marcozecchini 0:9fca2b23d0ba 2682 }
marcozecchini 0:9fca2b23d0ba 2683 else
marcozecchini 0:9fca2b23d0ba 2684 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
marcozecchini 0:9fca2b23d0ba 2685 }
marcozecchini 0:9fca2b23d0ba 2686 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 2687
marcozecchini 0:9fca2b23d0ba 2688 /*
marcozecchini 0:9fca2b23d0ba 2689 * Record layer functions
marcozecchini 0:9fca2b23d0ba 2690 */
marcozecchini 0:9fca2b23d0ba 2691
marcozecchini 0:9fca2b23d0ba 2692 /*
marcozecchini 0:9fca2b23d0ba 2693 * Write current record.
marcozecchini 0:9fca2b23d0ba 2694 * Uses ssl->out_msgtype, ssl->out_msglen and bytes at ssl->out_msg.
marcozecchini 0:9fca2b23d0ba 2695 */
marcozecchini 0:9fca2b23d0ba 2696 int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2697 {
marcozecchini 0:9fca2b23d0ba 2698 int ret, done = 0, out_msg_type;
marcozecchini 0:9fca2b23d0ba 2699 size_t len = ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 2700
marcozecchini 0:9fca2b23d0ba 2701 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
marcozecchini 0:9fca2b23d0ba 2702
marcozecchini 0:9fca2b23d0ba 2703 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 2704 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
marcozecchini 0:9fca2b23d0ba 2705 ssl->handshake != NULL &&
marcozecchini 0:9fca2b23d0ba 2706 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
marcozecchini 0:9fca2b23d0ba 2707 {
marcozecchini 0:9fca2b23d0ba 2708 ; /* Skip special handshake treatment when resending */
marcozecchini 0:9fca2b23d0ba 2709 }
marcozecchini 0:9fca2b23d0ba 2710 else
marcozecchini 0:9fca2b23d0ba 2711 #endif
marcozecchini 0:9fca2b23d0ba 2712 if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
marcozecchini 0:9fca2b23d0ba 2713 {
marcozecchini 0:9fca2b23d0ba 2714 out_msg_type = ssl->out_msg[0];
marcozecchini 0:9fca2b23d0ba 2715
marcozecchini 0:9fca2b23d0ba 2716 if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST &&
marcozecchini 0:9fca2b23d0ba 2717 ssl->handshake == NULL )
marcozecchini 0:9fca2b23d0ba 2718 {
marcozecchini 0:9fca2b23d0ba 2719 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 2720 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 2721 }
marcozecchini 0:9fca2b23d0ba 2722
marcozecchini 0:9fca2b23d0ba 2723 ssl->out_msg[1] = (unsigned char)( ( len - 4 ) >> 16 );
marcozecchini 0:9fca2b23d0ba 2724 ssl->out_msg[2] = (unsigned char)( ( len - 4 ) >> 8 );
marcozecchini 0:9fca2b23d0ba 2725 ssl->out_msg[3] = (unsigned char)( ( len - 4 ) );
marcozecchini 0:9fca2b23d0ba 2726
marcozecchini 0:9fca2b23d0ba 2727 /*
marcozecchini 0:9fca2b23d0ba 2728 * DTLS has additional fields in the Handshake layer,
marcozecchini 0:9fca2b23d0ba 2729 * between the length field and the actual payload:
marcozecchini 0:9fca2b23d0ba 2730 * uint16 message_seq;
marcozecchini 0:9fca2b23d0ba 2731 * uint24 fragment_offset;
marcozecchini 0:9fca2b23d0ba 2732 * uint24 fragment_length;
marcozecchini 0:9fca2b23d0ba 2733 */
marcozecchini 0:9fca2b23d0ba 2734 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 2735 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 2736 {
marcozecchini 0:9fca2b23d0ba 2737 /* Make room for the additional DTLS fields */
marcozecchini 0:9fca2b23d0ba 2738 memmove( ssl->out_msg + 12, ssl->out_msg + 4, len - 4 );
marcozecchini 0:9fca2b23d0ba 2739 ssl->out_msglen += 8;
marcozecchini 0:9fca2b23d0ba 2740 len += 8;
marcozecchini 0:9fca2b23d0ba 2741
marcozecchini 0:9fca2b23d0ba 2742 /* Write message_seq and update it, except for HelloRequest */
marcozecchini 0:9fca2b23d0ba 2743 if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
marcozecchini 0:9fca2b23d0ba 2744 {
marcozecchini 0:9fca2b23d0ba 2745 ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
marcozecchini 0:9fca2b23d0ba 2746 ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF;
marcozecchini 0:9fca2b23d0ba 2747 ++( ssl->handshake->out_msg_seq );
marcozecchini 0:9fca2b23d0ba 2748 }
marcozecchini 0:9fca2b23d0ba 2749 else
marcozecchini 0:9fca2b23d0ba 2750 {
marcozecchini 0:9fca2b23d0ba 2751 ssl->out_msg[4] = 0;
marcozecchini 0:9fca2b23d0ba 2752 ssl->out_msg[5] = 0;
marcozecchini 0:9fca2b23d0ba 2753 }
marcozecchini 0:9fca2b23d0ba 2754
marcozecchini 0:9fca2b23d0ba 2755 /* We don't fragment, so frag_offset = 0 and frag_len = len */
marcozecchini 0:9fca2b23d0ba 2756 memset( ssl->out_msg + 6, 0x00, 3 );
marcozecchini 0:9fca2b23d0ba 2757 memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
marcozecchini 0:9fca2b23d0ba 2758 }
marcozecchini 0:9fca2b23d0ba 2759 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 2760
marcozecchini 0:9fca2b23d0ba 2761 if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
marcozecchini 0:9fca2b23d0ba 2762 ssl->handshake->update_checksum( ssl, ssl->out_msg, len );
marcozecchini 0:9fca2b23d0ba 2763 }
marcozecchini 0:9fca2b23d0ba 2764
marcozecchini 0:9fca2b23d0ba 2765 /* Save handshake and CCS messages for resending */
marcozecchini 0:9fca2b23d0ba 2766 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 2767 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
marcozecchini 0:9fca2b23d0ba 2768 ssl->handshake != NULL &&
marcozecchini 0:9fca2b23d0ba 2769 ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING &&
marcozecchini 0:9fca2b23d0ba 2770 ( ssl->out_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ||
marcozecchini 0:9fca2b23d0ba 2771 ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) )
marcozecchini 0:9fca2b23d0ba 2772 {
marcozecchini 0:9fca2b23d0ba 2773 if( ( ret = ssl_flight_append( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 2774 {
marcozecchini 0:9fca2b23d0ba 2775 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
marcozecchini 0:9fca2b23d0ba 2776 return( ret );
marcozecchini 0:9fca2b23d0ba 2777 }
marcozecchini 0:9fca2b23d0ba 2778 }
marcozecchini 0:9fca2b23d0ba 2779 #endif
marcozecchini 0:9fca2b23d0ba 2780
marcozecchini 0:9fca2b23d0ba 2781 #if defined(MBEDTLS_ZLIB_SUPPORT)
marcozecchini 0:9fca2b23d0ba 2782 if( ssl->transform_out != NULL &&
marcozecchini 0:9fca2b23d0ba 2783 ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
marcozecchini 0:9fca2b23d0ba 2784 {
marcozecchini 0:9fca2b23d0ba 2785 if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 2786 {
marcozecchini 0:9fca2b23d0ba 2787 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
marcozecchini 0:9fca2b23d0ba 2788 return( ret );
marcozecchini 0:9fca2b23d0ba 2789 }
marcozecchini 0:9fca2b23d0ba 2790
marcozecchini 0:9fca2b23d0ba 2791 len = ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 2792 }
marcozecchini 0:9fca2b23d0ba 2793 #endif /*MBEDTLS_ZLIB_SUPPORT */
marcozecchini 0:9fca2b23d0ba 2794
marcozecchini 0:9fca2b23d0ba 2795 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 2796 if( mbedtls_ssl_hw_record_write != NULL )
marcozecchini 0:9fca2b23d0ba 2797 {
marcozecchini 0:9fca2b23d0ba 2798 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
marcozecchini 0:9fca2b23d0ba 2799
marcozecchini 0:9fca2b23d0ba 2800 ret = mbedtls_ssl_hw_record_write( ssl );
marcozecchini 0:9fca2b23d0ba 2801 if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
marcozecchini 0:9fca2b23d0ba 2802 {
marcozecchini 0:9fca2b23d0ba 2803 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
marcozecchini 0:9fca2b23d0ba 2804 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
marcozecchini 0:9fca2b23d0ba 2805 }
marcozecchini 0:9fca2b23d0ba 2806
marcozecchini 0:9fca2b23d0ba 2807 if( ret == 0 )
marcozecchini 0:9fca2b23d0ba 2808 done = 1;
marcozecchini 0:9fca2b23d0ba 2809 }
marcozecchini 0:9fca2b23d0ba 2810 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
marcozecchini 0:9fca2b23d0ba 2811 if( !done )
marcozecchini 0:9fca2b23d0ba 2812 {
marcozecchini 0:9fca2b23d0ba 2813 ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
marcozecchini 0:9fca2b23d0ba 2814 mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
marcozecchini 0:9fca2b23d0ba 2815 ssl->conf->transport, ssl->out_hdr + 1 );
marcozecchini 0:9fca2b23d0ba 2816
marcozecchini 0:9fca2b23d0ba 2817 ssl->out_len[0] = (unsigned char)( len >> 8 );
marcozecchini 0:9fca2b23d0ba 2818 ssl->out_len[1] = (unsigned char)( len );
marcozecchini 0:9fca2b23d0ba 2819
marcozecchini 0:9fca2b23d0ba 2820 if( ssl->transform_out != NULL )
marcozecchini 0:9fca2b23d0ba 2821 {
marcozecchini 0:9fca2b23d0ba 2822 if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 2823 {
marcozecchini 0:9fca2b23d0ba 2824 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
marcozecchini 0:9fca2b23d0ba 2825 return( ret );
marcozecchini 0:9fca2b23d0ba 2826 }
marcozecchini 0:9fca2b23d0ba 2827
marcozecchini 0:9fca2b23d0ba 2828 len = ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 2829 ssl->out_len[0] = (unsigned char)( len >> 8 );
marcozecchini 0:9fca2b23d0ba 2830 ssl->out_len[1] = (unsigned char)( len );
marcozecchini 0:9fca2b23d0ba 2831 }
marcozecchini 0:9fca2b23d0ba 2832
marcozecchini 0:9fca2b23d0ba 2833 ssl->out_left = mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen;
marcozecchini 0:9fca2b23d0ba 2834
marcozecchini 0:9fca2b23d0ba 2835 MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
marcozecchini 0:9fca2b23d0ba 2836 "version = [%d:%d], msglen = %d",
marcozecchini 0:9fca2b23d0ba 2837 ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2],
marcozecchini 0:9fca2b23d0ba 2838 ( ssl->out_len[0] << 8 ) | ssl->out_len[1] ) );
marcozecchini 0:9fca2b23d0ba 2839
marcozecchini 0:9fca2b23d0ba 2840 MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
marcozecchini 0:9fca2b23d0ba 2841 ssl->out_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen );
marcozecchini 0:9fca2b23d0ba 2842 }
marcozecchini 0:9fca2b23d0ba 2843
marcozecchini 0:9fca2b23d0ba 2844 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 2845 {
marcozecchini 0:9fca2b23d0ba 2846 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
marcozecchini 0:9fca2b23d0ba 2847 return( ret );
marcozecchini 0:9fca2b23d0ba 2848 }
marcozecchini 0:9fca2b23d0ba 2849
marcozecchini 0:9fca2b23d0ba 2850 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
marcozecchini 0:9fca2b23d0ba 2851
marcozecchini 0:9fca2b23d0ba 2852 return( 0 );
marcozecchini 0:9fca2b23d0ba 2853 }
marcozecchini 0:9fca2b23d0ba 2854
marcozecchini 0:9fca2b23d0ba 2855 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 2856 /*
marcozecchini 0:9fca2b23d0ba 2857 * Mark bits in bitmask (used for DTLS HS reassembly)
marcozecchini 0:9fca2b23d0ba 2858 */
marcozecchini 0:9fca2b23d0ba 2859 static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
marcozecchini 0:9fca2b23d0ba 2860 {
marcozecchini 0:9fca2b23d0ba 2861 unsigned int start_bits, end_bits;
marcozecchini 0:9fca2b23d0ba 2862
marcozecchini 0:9fca2b23d0ba 2863 start_bits = 8 - ( offset % 8 );
marcozecchini 0:9fca2b23d0ba 2864 if( start_bits != 8 )
marcozecchini 0:9fca2b23d0ba 2865 {
marcozecchini 0:9fca2b23d0ba 2866 size_t first_byte_idx = offset / 8;
marcozecchini 0:9fca2b23d0ba 2867
marcozecchini 0:9fca2b23d0ba 2868 /* Special case */
marcozecchini 0:9fca2b23d0ba 2869 if( len <= start_bits )
marcozecchini 0:9fca2b23d0ba 2870 {
marcozecchini 0:9fca2b23d0ba 2871 for( ; len != 0; len-- )
marcozecchini 0:9fca2b23d0ba 2872 mask[first_byte_idx] |= 1 << ( start_bits - len );
marcozecchini 0:9fca2b23d0ba 2873
marcozecchini 0:9fca2b23d0ba 2874 /* Avoid potential issues with offset or len becoming invalid */
marcozecchini 0:9fca2b23d0ba 2875 return;
marcozecchini 0:9fca2b23d0ba 2876 }
marcozecchini 0:9fca2b23d0ba 2877
marcozecchini 0:9fca2b23d0ba 2878 offset += start_bits; /* Now offset % 8 == 0 */
marcozecchini 0:9fca2b23d0ba 2879 len -= start_bits;
marcozecchini 0:9fca2b23d0ba 2880
marcozecchini 0:9fca2b23d0ba 2881 for( ; start_bits != 0; start_bits-- )
marcozecchini 0:9fca2b23d0ba 2882 mask[first_byte_idx] |= 1 << ( start_bits - 1 );
marcozecchini 0:9fca2b23d0ba 2883 }
marcozecchini 0:9fca2b23d0ba 2884
marcozecchini 0:9fca2b23d0ba 2885 end_bits = len % 8;
marcozecchini 0:9fca2b23d0ba 2886 if( end_bits != 0 )
marcozecchini 0:9fca2b23d0ba 2887 {
marcozecchini 0:9fca2b23d0ba 2888 size_t last_byte_idx = ( offset + len ) / 8;
marcozecchini 0:9fca2b23d0ba 2889
marcozecchini 0:9fca2b23d0ba 2890 len -= end_bits; /* Now len % 8 == 0 */
marcozecchini 0:9fca2b23d0ba 2891
marcozecchini 0:9fca2b23d0ba 2892 for( ; end_bits != 0; end_bits-- )
marcozecchini 0:9fca2b23d0ba 2893 mask[last_byte_idx] |= 1 << ( 8 - end_bits );
marcozecchini 0:9fca2b23d0ba 2894 }
marcozecchini 0:9fca2b23d0ba 2895
marcozecchini 0:9fca2b23d0ba 2896 memset( mask + offset / 8, 0xFF, len / 8 );
marcozecchini 0:9fca2b23d0ba 2897 }
marcozecchini 0:9fca2b23d0ba 2898
marcozecchini 0:9fca2b23d0ba 2899 /*
marcozecchini 0:9fca2b23d0ba 2900 * Check that bitmask is full
marcozecchini 0:9fca2b23d0ba 2901 */
marcozecchini 0:9fca2b23d0ba 2902 static int ssl_bitmask_check( unsigned char *mask, size_t len )
marcozecchini 0:9fca2b23d0ba 2903 {
marcozecchini 0:9fca2b23d0ba 2904 size_t i;
marcozecchini 0:9fca2b23d0ba 2905
marcozecchini 0:9fca2b23d0ba 2906 for( i = 0; i < len / 8; i++ )
marcozecchini 0:9fca2b23d0ba 2907 if( mask[i] != 0xFF )
marcozecchini 0:9fca2b23d0ba 2908 return( -1 );
marcozecchini 0:9fca2b23d0ba 2909
marcozecchini 0:9fca2b23d0ba 2910 for( i = 0; i < len % 8; i++ )
marcozecchini 0:9fca2b23d0ba 2911 if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
marcozecchini 0:9fca2b23d0ba 2912 return( -1 );
marcozecchini 0:9fca2b23d0ba 2913
marcozecchini 0:9fca2b23d0ba 2914 return( 0 );
marcozecchini 0:9fca2b23d0ba 2915 }
marcozecchini 0:9fca2b23d0ba 2916
marcozecchini 0:9fca2b23d0ba 2917 /*
marcozecchini 0:9fca2b23d0ba 2918 * Reassemble fragmented DTLS handshake messages.
marcozecchini 0:9fca2b23d0ba 2919 *
marcozecchini 0:9fca2b23d0ba 2920 * Use a temporary buffer for reassembly, divided in two parts:
marcozecchini 0:9fca2b23d0ba 2921 * - the first holds the reassembled message (including handshake header),
marcozecchini 0:9fca2b23d0ba 2922 * - the second holds a bitmask indicating which parts of the message
marcozecchini 0:9fca2b23d0ba 2923 * (excluding headers) have been received so far.
marcozecchini 0:9fca2b23d0ba 2924 */
marcozecchini 0:9fca2b23d0ba 2925 static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 2926 {
marcozecchini 0:9fca2b23d0ba 2927 unsigned char *msg, *bitmask;
marcozecchini 0:9fca2b23d0ba 2928 size_t frag_len, frag_off;
marcozecchini 0:9fca2b23d0ba 2929 size_t msg_len = ssl->in_hslen - 12; /* Without headers */
marcozecchini 0:9fca2b23d0ba 2930
marcozecchini 0:9fca2b23d0ba 2931 if( ssl->handshake == NULL )
marcozecchini 0:9fca2b23d0ba 2932 {
marcozecchini 0:9fca2b23d0ba 2933 MBEDTLS_SSL_DEBUG_MSG( 1, ( "not supported outside handshake (for now)" ) );
marcozecchini 0:9fca2b23d0ba 2934 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
marcozecchini 0:9fca2b23d0ba 2935 }
marcozecchini 0:9fca2b23d0ba 2936
marcozecchini 0:9fca2b23d0ba 2937 /*
marcozecchini 0:9fca2b23d0ba 2938 * For first fragment, check size and allocate buffer
marcozecchini 0:9fca2b23d0ba 2939 */
marcozecchini 0:9fca2b23d0ba 2940 if( ssl->handshake->hs_msg == NULL )
marcozecchini 0:9fca2b23d0ba 2941 {
marcozecchini 0:9fca2b23d0ba 2942 size_t alloc_len;
marcozecchini 0:9fca2b23d0ba 2943
marcozecchini 0:9fca2b23d0ba 2944 MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d",
marcozecchini 0:9fca2b23d0ba 2945 msg_len ) );
marcozecchini 0:9fca2b23d0ba 2946
marcozecchini 0:9fca2b23d0ba 2947 if( ssl->in_hslen > MBEDTLS_SSL_MAX_CONTENT_LEN )
marcozecchini 0:9fca2b23d0ba 2948 {
marcozecchini 0:9fca2b23d0ba 2949 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too large" ) );
marcozecchini 0:9fca2b23d0ba 2950 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
marcozecchini 0:9fca2b23d0ba 2951 }
marcozecchini 0:9fca2b23d0ba 2952
marcozecchini 0:9fca2b23d0ba 2953 /* The bitmask needs one bit per byte of message excluding header */
marcozecchini 0:9fca2b23d0ba 2954 alloc_len = 12 + msg_len + msg_len / 8 + ( msg_len % 8 != 0 );
marcozecchini 0:9fca2b23d0ba 2955
marcozecchini 0:9fca2b23d0ba 2956 ssl->handshake->hs_msg = mbedtls_calloc( 1, alloc_len );
marcozecchini 0:9fca2b23d0ba 2957 if( ssl->handshake->hs_msg == NULL )
marcozecchini 0:9fca2b23d0ba 2958 {
marcozecchini 0:9fca2b23d0ba 2959 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", alloc_len ) );
marcozecchini 0:9fca2b23d0ba 2960 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 2961 }
marcozecchini 0:9fca2b23d0ba 2962
marcozecchini 0:9fca2b23d0ba 2963 /* Prepare final header: copy msg_type, length and message_seq,
marcozecchini 0:9fca2b23d0ba 2964 * then add standardised fragment_offset and fragment_length */
marcozecchini 0:9fca2b23d0ba 2965 memcpy( ssl->handshake->hs_msg, ssl->in_msg, 6 );
marcozecchini 0:9fca2b23d0ba 2966 memset( ssl->handshake->hs_msg + 6, 0, 3 );
marcozecchini 0:9fca2b23d0ba 2967 memcpy( ssl->handshake->hs_msg + 9,
marcozecchini 0:9fca2b23d0ba 2968 ssl->handshake->hs_msg + 1, 3 );
marcozecchini 0:9fca2b23d0ba 2969 }
marcozecchini 0:9fca2b23d0ba 2970 else
marcozecchini 0:9fca2b23d0ba 2971 {
marcozecchini 0:9fca2b23d0ba 2972 /* Make sure msg_type and length are consistent */
marcozecchini 0:9fca2b23d0ba 2973 if( memcmp( ssl->handshake->hs_msg, ssl->in_msg, 4 ) != 0 )
marcozecchini 0:9fca2b23d0ba 2974 {
marcozecchini 0:9fca2b23d0ba 2975 MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment header mismatch" ) );
marcozecchini 0:9fca2b23d0ba 2976 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 2977 }
marcozecchini 0:9fca2b23d0ba 2978 }
marcozecchini 0:9fca2b23d0ba 2979
marcozecchini 0:9fca2b23d0ba 2980 msg = ssl->handshake->hs_msg + 12;
marcozecchini 0:9fca2b23d0ba 2981 bitmask = msg + msg_len;
marcozecchini 0:9fca2b23d0ba 2982
marcozecchini 0:9fca2b23d0ba 2983 /*
marcozecchini 0:9fca2b23d0ba 2984 * Check and copy current fragment
marcozecchini 0:9fca2b23d0ba 2985 */
marcozecchini 0:9fca2b23d0ba 2986 frag_off = ( ssl->in_msg[6] << 16 ) |
marcozecchini 0:9fca2b23d0ba 2987 ( ssl->in_msg[7] << 8 ) |
marcozecchini 0:9fca2b23d0ba 2988 ssl->in_msg[8];
marcozecchini 0:9fca2b23d0ba 2989 frag_len = ( ssl->in_msg[9] << 16 ) |
marcozecchini 0:9fca2b23d0ba 2990 ( ssl->in_msg[10] << 8 ) |
marcozecchini 0:9fca2b23d0ba 2991 ssl->in_msg[11];
marcozecchini 0:9fca2b23d0ba 2992
marcozecchini 0:9fca2b23d0ba 2993 if( frag_off + frag_len > msg_len )
marcozecchini 0:9fca2b23d0ba 2994 {
marcozecchini 0:9fca2b23d0ba 2995 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid fragment offset/len: %d + %d > %d",
marcozecchini 0:9fca2b23d0ba 2996 frag_off, frag_len, msg_len ) );
marcozecchini 0:9fca2b23d0ba 2997 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 2998 }
marcozecchini 0:9fca2b23d0ba 2999
marcozecchini 0:9fca2b23d0ba 3000 if( frag_len + 12 > ssl->in_msglen )
marcozecchini 0:9fca2b23d0ba 3001 {
marcozecchini 0:9fca2b23d0ba 3002 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid fragment length: %d + 12 > %d",
marcozecchini 0:9fca2b23d0ba 3003 frag_len, ssl->in_msglen ) );
marcozecchini 0:9fca2b23d0ba 3004 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3005 }
marcozecchini 0:9fca2b23d0ba 3006
marcozecchini 0:9fca2b23d0ba 3007 MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d",
marcozecchini 0:9fca2b23d0ba 3008 frag_off, frag_len ) );
marcozecchini 0:9fca2b23d0ba 3009
marcozecchini 0:9fca2b23d0ba 3010 memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
marcozecchini 0:9fca2b23d0ba 3011 ssl_bitmask_set( bitmask, frag_off, frag_len );
marcozecchini 0:9fca2b23d0ba 3012
marcozecchini 0:9fca2b23d0ba 3013 /*
marcozecchini 0:9fca2b23d0ba 3014 * Do we have the complete message by now?
marcozecchini 0:9fca2b23d0ba 3015 * If yes, finalize it, else ask to read the next record.
marcozecchini 0:9fca2b23d0ba 3016 */
marcozecchini 0:9fca2b23d0ba 3017 if( ssl_bitmask_check( bitmask, msg_len ) != 0 )
marcozecchini 0:9fca2b23d0ba 3018 {
marcozecchini 0:9fca2b23d0ba 3019 MBEDTLS_SSL_DEBUG_MSG( 2, ( "message is not complete yet" ) );
marcozecchini 0:9fca2b23d0ba 3020 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 3021 }
marcozecchini 0:9fca2b23d0ba 3022
marcozecchini 0:9fca2b23d0ba 3023 MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake message completed" ) );
marcozecchini 0:9fca2b23d0ba 3024
marcozecchini 0:9fca2b23d0ba 3025 if( frag_len + 12 < ssl->in_msglen )
marcozecchini 0:9fca2b23d0ba 3026 {
marcozecchini 0:9fca2b23d0ba 3027 /*
marcozecchini 0:9fca2b23d0ba 3028 * We'got more handshake messages in the same record.
marcozecchini 0:9fca2b23d0ba 3029 * This case is not handled now because no know implementation does
marcozecchini 0:9fca2b23d0ba 3030 * that and it's hard to test, so we prefer to fail cleanly for now.
marcozecchini 0:9fca2b23d0ba 3031 */
marcozecchini 0:9fca2b23d0ba 3032 MBEDTLS_SSL_DEBUG_MSG( 1, ( "last fragment not alone in its record" ) );
marcozecchini 0:9fca2b23d0ba 3033 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
marcozecchini 0:9fca2b23d0ba 3034 }
marcozecchini 0:9fca2b23d0ba 3035
marcozecchini 0:9fca2b23d0ba 3036 if( ssl->in_left > ssl->next_record_offset )
marcozecchini 0:9fca2b23d0ba 3037 {
marcozecchini 0:9fca2b23d0ba 3038 /*
marcozecchini 0:9fca2b23d0ba 3039 * We've got more data in the buffer after the current record,
marcozecchini 0:9fca2b23d0ba 3040 * that we don't want to overwrite. Move it before writing the
marcozecchini 0:9fca2b23d0ba 3041 * reassembled message, and adjust in_left and next_record_offset.
marcozecchini 0:9fca2b23d0ba 3042 */
marcozecchini 0:9fca2b23d0ba 3043 unsigned char *cur_remain = ssl->in_hdr + ssl->next_record_offset;
marcozecchini 0:9fca2b23d0ba 3044 unsigned char *new_remain = ssl->in_msg + ssl->in_hslen;
marcozecchini 0:9fca2b23d0ba 3045 size_t remain_len = ssl->in_left - ssl->next_record_offset;
marcozecchini 0:9fca2b23d0ba 3046
marcozecchini 0:9fca2b23d0ba 3047 /* First compute and check new lengths */
marcozecchini 0:9fca2b23d0ba 3048 ssl->next_record_offset = new_remain - ssl->in_hdr;
marcozecchini 0:9fca2b23d0ba 3049 ssl->in_left = ssl->next_record_offset + remain_len;
marcozecchini 0:9fca2b23d0ba 3050
marcozecchini 0:9fca2b23d0ba 3051 if( ssl->in_left > MBEDTLS_SSL_BUFFER_LEN -
marcozecchini 0:9fca2b23d0ba 3052 (size_t)( ssl->in_hdr - ssl->in_buf ) )
marcozecchini 0:9fca2b23d0ba 3053 {
marcozecchini 0:9fca2b23d0ba 3054 MBEDTLS_SSL_DEBUG_MSG( 1, ( "reassembled message too large for buffer" ) );
marcozecchini 0:9fca2b23d0ba 3055 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
marcozecchini 0:9fca2b23d0ba 3056 }
marcozecchini 0:9fca2b23d0ba 3057
marcozecchini 0:9fca2b23d0ba 3058 memmove( new_remain, cur_remain, remain_len );
marcozecchini 0:9fca2b23d0ba 3059 }
marcozecchini 0:9fca2b23d0ba 3060
marcozecchini 0:9fca2b23d0ba 3061 memcpy( ssl->in_msg, ssl->handshake->hs_msg, ssl->in_hslen );
marcozecchini 0:9fca2b23d0ba 3062
marcozecchini 0:9fca2b23d0ba 3063 mbedtls_free( ssl->handshake->hs_msg );
marcozecchini 0:9fca2b23d0ba 3064 ssl->handshake->hs_msg = NULL;
marcozecchini 0:9fca2b23d0ba 3065
marcozecchini 0:9fca2b23d0ba 3066 MBEDTLS_SSL_DEBUG_BUF( 3, "reassembled handshake message",
marcozecchini 0:9fca2b23d0ba 3067 ssl->in_msg, ssl->in_hslen );
marcozecchini 0:9fca2b23d0ba 3068
marcozecchini 0:9fca2b23d0ba 3069 return( 0 );
marcozecchini 0:9fca2b23d0ba 3070 }
marcozecchini 0:9fca2b23d0ba 3071 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 3072
marcozecchini 0:9fca2b23d0ba 3073 int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3074 {
marcozecchini 0:9fca2b23d0ba 3075 if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
marcozecchini 0:9fca2b23d0ba 3076 {
marcozecchini 0:9fca2b23d0ba 3077 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d",
marcozecchini 0:9fca2b23d0ba 3078 ssl->in_msglen ) );
marcozecchini 0:9fca2b23d0ba 3079 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3080 }
marcozecchini 0:9fca2b23d0ba 3081
marcozecchini 0:9fca2b23d0ba 3082 ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + (
marcozecchini 0:9fca2b23d0ba 3083 ( ssl->in_msg[1] << 16 ) |
marcozecchini 0:9fca2b23d0ba 3084 ( ssl->in_msg[2] << 8 ) |
marcozecchini 0:9fca2b23d0ba 3085 ssl->in_msg[3] );
marcozecchini 0:9fca2b23d0ba 3086
marcozecchini 0:9fca2b23d0ba 3087 MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
marcozecchini 0:9fca2b23d0ba 3088 " %d, type = %d, hslen = %d",
marcozecchini 0:9fca2b23d0ba 3089 ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
marcozecchini 0:9fca2b23d0ba 3090
marcozecchini 0:9fca2b23d0ba 3091 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 3092 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 3093 {
marcozecchini 0:9fca2b23d0ba 3094 int ret;
marcozecchini 0:9fca2b23d0ba 3095 unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
marcozecchini 0:9fca2b23d0ba 3096
marcozecchini 0:9fca2b23d0ba 3097 /* ssl->handshake is NULL when receiving ClientHello for renego */
marcozecchini 0:9fca2b23d0ba 3098 if( ssl->handshake != NULL &&
marcozecchini 0:9fca2b23d0ba 3099 recv_msg_seq != ssl->handshake->in_msg_seq )
marcozecchini 0:9fca2b23d0ba 3100 {
marcozecchini 0:9fca2b23d0ba 3101 /* Retransmit only on last message from previous flight, to avoid
marcozecchini 0:9fca2b23d0ba 3102 * too many retransmissions.
marcozecchini 0:9fca2b23d0ba 3103 * Besides, No sane server ever retransmits HelloVerifyRequest */
marcozecchini 0:9fca2b23d0ba 3104 if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
marcozecchini 0:9fca2b23d0ba 3105 ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
marcozecchini 0:9fca2b23d0ba 3106 {
marcozecchini 0:9fca2b23d0ba 3107 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
marcozecchini 0:9fca2b23d0ba 3108 "message_seq = %d, start_of_flight = %d",
marcozecchini 0:9fca2b23d0ba 3109 recv_msg_seq,
marcozecchini 0:9fca2b23d0ba 3110 ssl->handshake->in_flight_start_seq ) );
marcozecchini 0:9fca2b23d0ba 3111
marcozecchini 0:9fca2b23d0ba 3112 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3113 {
marcozecchini 0:9fca2b23d0ba 3114 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
marcozecchini 0:9fca2b23d0ba 3115 return( ret );
marcozecchini 0:9fca2b23d0ba 3116 }
marcozecchini 0:9fca2b23d0ba 3117 }
marcozecchini 0:9fca2b23d0ba 3118 else
marcozecchini 0:9fca2b23d0ba 3119 {
marcozecchini 0:9fca2b23d0ba 3120 MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
marcozecchini 0:9fca2b23d0ba 3121 "message_seq = %d, expected = %d",
marcozecchini 0:9fca2b23d0ba 3122 recv_msg_seq,
marcozecchini 0:9fca2b23d0ba 3123 ssl->handshake->in_msg_seq ) );
marcozecchini 0:9fca2b23d0ba 3124 }
marcozecchini 0:9fca2b23d0ba 3125
marcozecchini 0:9fca2b23d0ba 3126 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 3127 }
marcozecchini 0:9fca2b23d0ba 3128 /* Wait until message completion to increment in_msg_seq */
marcozecchini 0:9fca2b23d0ba 3129
marcozecchini 0:9fca2b23d0ba 3130 /* Reassemble if current message is fragmented or reassembly is
marcozecchini 0:9fca2b23d0ba 3131 * already in progress */
marcozecchini 0:9fca2b23d0ba 3132 if( ssl->in_msglen < ssl->in_hslen ||
marcozecchini 0:9fca2b23d0ba 3133 memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
marcozecchini 0:9fca2b23d0ba 3134 memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ||
marcozecchini 0:9fca2b23d0ba 3135 ( ssl->handshake != NULL && ssl->handshake->hs_msg != NULL ) )
marcozecchini 0:9fca2b23d0ba 3136 {
marcozecchini 0:9fca2b23d0ba 3137 MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
marcozecchini 0:9fca2b23d0ba 3138
marcozecchini 0:9fca2b23d0ba 3139 if( ( ret = ssl_reassemble_dtls_handshake( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3140 {
marcozecchini 0:9fca2b23d0ba 3141 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_reassemble_dtls_handshake", ret );
marcozecchini 0:9fca2b23d0ba 3142 return( ret );
marcozecchini 0:9fca2b23d0ba 3143 }
marcozecchini 0:9fca2b23d0ba 3144 }
marcozecchini 0:9fca2b23d0ba 3145 }
marcozecchini 0:9fca2b23d0ba 3146 else
marcozecchini 0:9fca2b23d0ba 3147 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 3148 /* With TLS we don't handle fragmentation (for now) */
marcozecchini 0:9fca2b23d0ba 3149 if( ssl->in_msglen < ssl->in_hslen )
marcozecchini 0:9fca2b23d0ba 3150 {
marcozecchini 0:9fca2b23d0ba 3151 MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
marcozecchini 0:9fca2b23d0ba 3152 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
marcozecchini 0:9fca2b23d0ba 3153 }
marcozecchini 0:9fca2b23d0ba 3154
marcozecchini 0:9fca2b23d0ba 3155 return( 0 );
marcozecchini 0:9fca2b23d0ba 3156 }
marcozecchini 0:9fca2b23d0ba 3157
marcozecchini 0:9fca2b23d0ba 3158 void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3159 {
marcozecchini 0:9fca2b23d0ba 3160
marcozecchini 0:9fca2b23d0ba 3161 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
marcozecchini 0:9fca2b23d0ba 3162 ssl->handshake != NULL )
marcozecchini 0:9fca2b23d0ba 3163 {
marcozecchini 0:9fca2b23d0ba 3164 ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
marcozecchini 0:9fca2b23d0ba 3165 }
marcozecchini 0:9fca2b23d0ba 3166
marcozecchini 0:9fca2b23d0ba 3167 /* Handshake message is complete, increment counter */
marcozecchini 0:9fca2b23d0ba 3168 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 3169 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
marcozecchini 0:9fca2b23d0ba 3170 ssl->handshake != NULL )
marcozecchini 0:9fca2b23d0ba 3171 {
marcozecchini 0:9fca2b23d0ba 3172 ssl->handshake->in_msg_seq++;
marcozecchini 0:9fca2b23d0ba 3173 }
marcozecchini 0:9fca2b23d0ba 3174 #endif
marcozecchini 0:9fca2b23d0ba 3175 }
marcozecchini 0:9fca2b23d0ba 3176
marcozecchini 0:9fca2b23d0ba 3177 /*
marcozecchini 0:9fca2b23d0ba 3178 * DTLS anti-replay: RFC 6347 4.1.2.6
marcozecchini 0:9fca2b23d0ba 3179 *
marcozecchini 0:9fca2b23d0ba 3180 * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
marcozecchini 0:9fca2b23d0ba 3181 * Bit n is set iff record number in_window_top - n has been seen.
marcozecchini 0:9fca2b23d0ba 3182 *
marcozecchini 0:9fca2b23d0ba 3183 * Usually, in_window_top is the last record number seen and the lsb of
marcozecchini 0:9fca2b23d0ba 3184 * in_window is set. The only exception is the initial state (record number 0
marcozecchini 0:9fca2b23d0ba 3185 * not seen yet).
marcozecchini 0:9fca2b23d0ba 3186 */
marcozecchini 0:9fca2b23d0ba 3187 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
marcozecchini 0:9fca2b23d0ba 3188 static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3189 {
marcozecchini 0:9fca2b23d0ba 3190 ssl->in_window_top = 0;
marcozecchini 0:9fca2b23d0ba 3191 ssl->in_window = 0;
marcozecchini 0:9fca2b23d0ba 3192 }
marcozecchini 0:9fca2b23d0ba 3193
marcozecchini 0:9fca2b23d0ba 3194 static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
marcozecchini 0:9fca2b23d0ba 3195 {
marcozecchini 0:9fca2b23d0ba 3196 return( ( (uint64_t) buf[0] << 40 ) |
marcozecchini 0:9fca2b23d0ba 3197 ( (uint64_t) buf[1] << 32 ) |
marcozecchini 0:9fca2b23d0ba 3198 ( (uint64_t) buf[2] << 24 ) |
marcozecchini 0:9fca2b23d0ba 3199 ( (uint64_t) buf[3] << 16 ) |
marcozecchini 0:9fca2b23d0ba 3200 ( (uint64_t) buf[4] << 8 ) |
marcozecchini 0:9fca2b23d0ba 3201 ( (uint64_t) buf[5] ) );
marcozecchini 0:9fca2b23d0ba 3202 }
marcozecchini 0:9fca2b23d0ba 3203
marcozecchini 0:9fca2b23d0ba 3204 /*
marcozecchini 0:9fca2b23d0ba 3205 * Return 0 if sequence number is acceptable, -1 otherwise
marcozecchini 0:9fca2b23d0ba 3206 */
marcozecchini 0:9fca2b23d0ba 3207 int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3208 {
marcozecchini 0:9fca2b23d0ba 3209 uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
marcozecchini 0:9fca2b23d0ba 3210 uint64_t bit;
marcozecchini 0:9fca2b23d0ba 3211
marcozecchini 0:9fca2b23d0ba 3212 if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
marcozecchini 0:9fca2b23d0ba 3213 return( 0 );
marcozecchini 0:9fca2b23d0ba 3214
marcozecchini 0:9fca2b23d0ba 3215 if( rec_seqnum > ssl->in_window_top )
marcozecchini 0:9fca2b23d0ba 3216 return( 0 );
marcozecchini 0:9fca2b23d0ba 3217
marcozecchini 0:9fca2b23d0ba 3218 bit = ssl->in_window_top - rec_seqnum;
marcozecchini 0:9fca2b23d0ba 3219
marcozecchini 0:9fca2b23d0ba 3220 if( bit >= 64 )
marcozecchini 0:9fca2b23d0ba 3221 return( -1 );
marcozecchini 0:9fca2b23d0ba 3222
marcozecchini 0:9fca2b23d0ba 3223 if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3224 return( -1 );
marcozecchini 0:9fca2b23d0ba 3225
marcozecchini 0:9fca2b23d0ba 3226 return( 0 );
marcozecchini 0:9fca2b23d0ba 3227 }
marcozecchini 0:9fca2b23d0ba 3228
marcozecchini 0:9fca2b23d0ba 3229 /*
marcozecchini 0:9fca2b23d0ba 3230 * Update replay window on new validated record
marcozecchini 0:9fca2b23d0ba 3231 */
marcozecchini 0:9fca2b23d0ba 3232 void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3233 {
marcozecchini 0:9fca2b23d0ba 3234 uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
marcozecchini 0:9fca2b23d0ba 3235
marcozecchini 0:9fca2b23d0ba 3236 if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
marcozecchini 0:9fca2b23d0ba 3237 return;
marcozecchini 0:9fca2b23d0ba 3238
marcozecchini 0:9fca2b23d0ba 3239 if( rec_seqnum > ssl->in_window_top )
marcozecchini 0:9fca2b23d0ba 3240 {
marcozecchini 0:9fca2b23d0ba 3241 /* Update window_top and the contents of the window */
marcozecchini 0:9fca2b23d0ba 3242 uint64_t shift = rec_seqnum - ssl->in_window_top;
marcozecchini 0:9fca2b23d0ba 3243
marcozecchini 0:9fca2b23d0ba 3244 if( shift >= 64 )
marcozecchini 0:9fca2b23d0ba 3245 ssl->in_window = 1;
marcozecchini 0:9fca2b23d0ba 3246 else
marcozecchini 0:9fca2b23d0ba 3247 {
marcozecchini 0:9fca2b23d0ba 3248 ssl->in_window <<= shift;
marcozecchini 0:9fca2b23d0ba 3249 ssl->in_window |= 1;
marcozecchini 0:9fca2b23d0ba 3250 }
marcozecchini 0:9fca2b23d0ba 3251
marcozecchini 0:9fca2b23d0ba 3252 ssl->in_window_top = rec_seqnum;
marcozecchini 0:9fca2b23d0ba 3253 }
marcozecchini 0:9fca2b23d0ba 3254 else
marcozecchini 0:9fca2b23d0ba 3255 {
marcozecchini 0:9fca2b23d0ba 3256 /* Mark that number as seen in the current window */
marcozecchini 0:9fca2b23d0ba 3257 uint64_t bit = ssl->in_window_top - rec_seqnum;
marcozecchini 0:9fca2b23d0ba 3258
marcozecchini 0:9fca2b23d0ba 3259 if( bit < 64 ) /* Always true, but be extra sure */
marcozecchini 0:9fca2b23d0ba 3260 ssl->in_window |= (uint64_t) 1 << bit;
marcozecchini 0:9fca2b23d0ba 3261 }
marcozecchini 0:9fca2b23d0ba 3262 }
marcozecchini 0:9fca2b23d0ba 3263 #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
marcozecchini 0:9fca2b23d0ba 3264
marcozecchini 0:9fca2b23d0ba 3265 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 3266 /* Forward declaration */
marcozecchini 0:9fca2b23d0ba 3267 static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
marcozecchini 0:9fca2b23d0ba 3268
marcozecchini 0:9fca2b23d0ba 3269 /*
marcozecchini 0:9fca2b23d0ba 3270 * Without any SSL context, check if a datagram looks like a ClientHello with
marcozecchini 0:9fca2b23d0ba 3271 * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
marcozecchini 0:9fca2b23d0ba 3272 * Both input and output include full DTLS headers.
marcozecchini 0:9fca2b23d0ba 3273 *
marcozecchini 0:9fca2b23d0ba 3274 * - if cookie is valid, return 0
marcozecchini 0:9fca2b23d0ba 3275 * - if ClientHello looks superficially valid but cookie is not,
marcozecchini 0:9fca2b23d0ba 3276 * fill obuf and set olen, then
marcozecchini 0:9fca2b23d0ba 3277 * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
marcozecchini 0:9fca2b23d0ba 3278 * - otherwise return a specific error code
marcozecchini 0:9fca2b23d0ba 3279 */
marcozecchini 0:9fca2b23d0ba 3280 static int ssl_check_dtls_clihlo_cookie(
marcozecchini 0:9fca2b23d0ba 3281 mbedtls_ssl_cookie_write_t *f_cookie_write,
marcozecchini 0:9fca2b23d0ba 3282 mbedtls_ssl_cookie_check_t *f_cookie_check,
marcozecchini 0:9fca2b23d0ba 3283 void *p_cookie,
marcozecchini 0:9fca2b23d0ba 3284 const unsigned char *cli_id, size_t cli_id_len,
marcozecchini 0:9fca2b23d0ba 3285 const unsigned char *in, size_t in_len,
marcozecchini 0:9fca2b23d0ba 3286 unsigned char *obuf, size_t buf_len, size_t *olen )
marcozecchini 0:9fca2b23d0ba 3287 {
marcozecchini 0:9fca2b23d0ba 3288 size_t sid_len, cookie_len;
marcozecchini 0:9fca2b23d0ba 3289 unsigned char *p;
marcozecchini 0:9fca2b23d0ba 3290
marcozecchini 0:9fca2b23d0ba 3291 if( f_cookie_write == NULL || f_cookie_check == NULL )
marcozecchini 0:9fca2b23d0ba 3292 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 3293
marcozecchini 0:9fca2b23d0ba 3294 /*
marcozecchini 0:9fca2b23d0ba 3295 * Structure of ClientHello with record and handshake headers,
marcozecchini 0:9fca2b23d0ba 3296 * and expected values. We don't need to check a lot, more checks will be
marcozecchini 0:9fca2b23d0ba 3297 * done when actually parsing the ClientHello - skipping those checks
marcozecchini 0:9fca2b23d0ba 3298 * avoids code duplication and does not make cookie forging any easier.
marcozecchini 0:9fca2b23d0ba 3299 *
marcozecchini 0:9fca2b23d0ba 3300 * 0-0 ContentType type; copied, must be handshake
marcozecchini 0:9fca2b23d0ba 3301 * 1-2 ProtocolVersion version; copied
marcozecchini 0:9fca2b23d0ba 3302 * 3-4 uint16 epoch; copied, must be 0
marcozecchini 0:9fca2b23d0ba 3303 * 5-10 uint48 sequence_number; copied
marcozecchini 0:9fca2b23d0ba 3304 * 11-12 uint16 length; (ignored)
marcozecchini 0:9fca2b23d0ba 3305 *
marcozecchini 0:9fca2b23d0ba 3306 * 13-13 HandshakeType msg_type; (ignored)
marcozecchini 0:9fca2b23d0ba 3307 * 14-16 uint24 length; (ignored)
marcozecchini 0:9fca2b23d0ba 3308 * 17-18 uint16 message_seq; copied
marcozecchini 0:9fca2b23d0ba 3309 * 19-21 uint24 fragment_offset; copied, must be 0
marcozecchini 0:9fca2b23d0ba 3310 * 22-24 uint24 fragment_length; (ignored)
marcozecchini 0:9fca2b23d0ba 3311 *
marcozecchini 0:9fca2b23d0ba 3312 * 25-26 ProtocolVersion client_version; (ignored)
marcozecchini 0:9fca2b23d0ba 3313 * 27-58 Random random; (ignored)
marcozecchini 0:9fca2b23d0ba 3314 * 59-xx SessionID session_id; 1 byte len + sid_len content
marcozecchini 0:9fca2b23d0ba 3315 * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
marcozecchini 0:9fca2b23d0ba 3316 * ...
marcozecchini 0:9fca2b23d0ba 3317 *
marcozecchini 0:9fca2b23d0ba 3318 * Minimum length is 61 bytes.
marcozecchini 0:9fca2b23d0ba 3319 */
marcozecchini 0:9fca2b23d0ba 3320 if( in_len < 61 ||
marcozecchini 0:9fca2b23d0ba 3321 in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
marcozecchini 0:9fca2b23d0ba 3322 in[3] != 0 || in[4] != 0 ||
marcozecchini 0:9fca2b23d0ba 3323 in[19] != 0 || in[20] != 0 || in[21] != 0 )
marcozecchini 0:9fca2b23d0ba 3324 {
marcozecchini 0:9fca2b23d0ba 3325 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
marcozecchini 0:9fca2b23d0ba 3326 }
marcozecchini 0:9fca2b23d0ba 3327
marcozecchini 0:9fca2b23d0ba 3328 sid_len = in[59];
marcozecchini 0:9fca2b23d0ba 3329 if( sid_len > in_len - 61 )
marcozecchini 0:9fca2b23d0ba 3330 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
marcozecchini 0:9fca2b23d0ba 3331
marcozecchini 0:9fca2b23d0ba 3332 cookie_len = in[60 + sid_len];
marcozecchini 0:9fca2b23d0ba 3333 if( cookie_len > in_len - 60 )
marcozecchini 0:9fca2b23d0ba 3334 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
marcozecchini 0:9fca2b23d0ba 3335
marcozecchini 0:9fca2b23d0ba 3336 if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
marcozecchini 0:9fca2b23d0ba 3337 cli_id, cli_id_len ) == 0 )
marcozecchini 0:9fca2b23d0ba 3338 {
marcozecchini 0:9fca2b23d0ba 3339 /* Valid cookie */
marcozecchini 0:9fca2b23d0ba 3340 return( 0 );
marcozecchini 0:9fca2b23d0ba 3341 }
marcozecchini 0:9fca2b23d0ba 3342
marcozecchini 0:9fca2b23d0ba 3343 /*
marcozecchini 0:9fca2b23d0ba 3344 * If we get here, we've got an invalid cookie, let's prepare HVR.
marcozecchini 0:9fca2b23d0ba 3345 *
marcozecchini 0:9fca2b23d0ba 3346 * 0-0 ContentType type; copied
marcozecchini 0:9fca2b23d0ba 3347 * 1-2 ProtocolVersion version; copied
marcozecchini 0:9fca2b23d0ba 3348 * 3-4 uint16 epoch; copied
marcozecchini 0:9fca2b23d0ba 3349 * 5-10 uint48 sequence_number; copied
marcozecchini 0:9fca2b23d0ba 3350 * 11-12 uint16 length; olen - 13
marcozecchini 0:9fca2b23d0ba 3351 *
marcozecchini 0:9fca2b23d0ba 3352 * 13-13 HandshakeType msg_type; hello_verify_request
marcozecchini 0:9fca2b23d0ba 3353 * 14-16 uint24 length; olen - 25
marcozecchini 0:9fca2b23d0ba 3354 * 17-18 uint16 message_seq; copied
marcozecchini 0:9fca2b23d0ba 3355 * 19-21 uint24 fragment_offset; copied
marcozecchini 0:9fca2b23d0ba 3356 * 22-24 uint24 fragment_length; olen - 25
marcozecchini 0:9fca2b23d0ba 3357 *
marcozecchini 0:9fca2b23d0ba 3358 * 25-26 ProtocolVersion server_version; 0xfe 0xff
marcozecchini 0:9fca2b23d0ba 3359 * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
marcozecchini 0:9fca2b23d0ba 3360 *
marcozecchini 0:9fca2b23d0ba 3361 * Minimum length is 28.
marcozecchini 0:9fca2b23d0ba 3362 */
marcozecchini 0:9fca2b23d0ba 3363 if( buf_len < 28 )
marcozecchini 0:9fca2b23d0ba 3364 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
marcozecchini 0:9fca2b23d0ba 3365
marcozecchini 0:9fca2b23d0ba 3366 /* Copy most fields and adapt others */
marcozecchini 0:9fca2b23d0ba 3367 memcpy( obuf, in, 25 );
marcozecchini 0:9fca2b23d0ba 3368 obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
marcozecchini 0:9fca2b23d0ba 3369 obuf[25] = 0xfe;
marcozecchini 0:9fca2b23d0ba 3370 obuf[26] = 0xff;
marcozecchini 0:9fca2b23d0ba 3371
marcozecchini 0:9fca2b23d0ba 3372 /* Generate and write actual cookie */
marcozecchini 0:9fca2b23d0ba 3373 p = obuf + 28;
marcozecchini 0:9fca2b23d0ba 3374 if( f_cookie_write( p_cookie,
marcozecchini 0:9fca2b23d0ba 3375 &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
marcozecchini 0:9fca2b23d0ba 3376 {
marcozecchini 0:9fca2b23d0ba 3377 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 3378 }
marcozecchini 0:9fca2b23d0ba 3379
marcozecchini 0:9fca2b23d0ba 3380 *olen = p - obuf;
marcozecchini 0:9fca2b23d0ba 3381
marcozecchini 0:9fca2b23d0ba 3382 /* Go back and fill length fields */
marcozecchini 0:9fca2b23d0ba 3383 obuf[27] = (unsigned char)( *olen - 28 );
marcozecchini 0:9fca2b23d0ba 3384
marcozecchini 0:9fca2b23d0ba 3385 obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 );
marcozecchini 0:9fca2b23d0ba 3386 obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 );
marcozecchini 0:9fca2b23d0ba 3387 obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) );
marcozecchini 0:9fca2b23d0ba 3388
marcozecchini 0:9fca2b23d0ba 3389 obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 );
marcozecchini 0:9fca2b23d0ba 3390 obuf[12] = (unsigned char)( ( *olen - 13 ) );
marcozecchini 0:9fca2b23d0ba 3391
marcozecchini 0:9fca2b23d0ba 3392 return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
marcozecchini 0:9fca2b23d0ba 3393 }
marcozecchini 0:9fca2b23d0ba 3394
marcozecchini 0:9fca2b23d0ba 3395 /*
marcozecchini 0:9fca2b23d0ba 3396 * Handle possible client reconnect with the same UDP quadruplet
marcozecchini 0:9fca2b23d0ba 3397 * (RFC 6347 Section 4.2.8).
marcozecchini 0:9fca2b23d0ba 3398 *
marcozecchini 0:9fca2b23d0ba 3399 * Called by ssl_parse_record_header() in case we receive an epoch 0 record
marcozecchini 0:9fca2b23d0ba 3400 * that looks like a ClientHello.
marcozecchini 0:9fca2b23d0ba 3401 *
marcozecchini 0:9fca2b23d0ba 3402 * - if the input looks like a ClientHello without cookies,
marcozecchini 0:9fca2b23d0ba 3403 * send back HelloVerifyRequest, then
marcozecchini 0:9fca2b23d0ba 3404 * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
marcozecchini 0:9fca2b23d0ba 3405 * - if the input looks like a ClientHello with a valid cookie,
marcozecchini 0:9fca2b23d0ba 3406 * reset the session of the current context, and
marcozecchini 0:9fca2b23d0ba 3407 * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
marcozecchini 0:9fca2b23d0ba 3408 * - if anything goes wrong, return a specific error code
marcozecchini 0:9fca2b23d0ba 3409 *
marcozecchini 0:9fca2b23d0ba 3410 * mbedtls_ssl_read_record() will ignore the record if anything else than
marcozecchini 0:9fca2b23d0ba 3411 * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function
marcozecchini 0:9fca2b23d0ba 3412 * cannot not return 0.
marcozecchini 0:9fca2b23d0ba 3413 */
marcozecchini 0:9fca2b23d0ba 3414 static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3415 {
marcozecchini 0:9fca2b23d0ba 3416 int ret;
marcozecchini 0:9fca2b23d0ba 3417 size_t len;
marcozecchini 0:9fca2b23d0ba 3418
marcozecchini 0:9fca2b23d0ba 3419 ret = ssl_check_dtls_clihlo_cookie(
marcozecchini 0:9fca2b23d0ba 3420 ssl->conf->f_cookie_write,
marcozecchini 0:9fca2b23d0ba 3421 ssl->conf->f_cookie_check,
marcozecchini 0:9fca2b23d0ba 3422 ssl->conf->p_cookie,
marcozecchini 0:9fca2b23d0ba 3423 ssl->cli_id, ssl->cli_id_len,
marcozecchini 0:9fca2b23d0ba 3424 ssl->in_buf, ssl->in_left,
marcozecchini 0:9fca2b23d0ba 3425 ssl->out_buf, MBEDTLS_SSL_MAX_CONTENT_LEN, &len );
marcozecchini 0:9fca2b23d0ba 3426
marcozecchini 0:9fca2b23d0ba 3427 MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
marcozecchini 0:9fca2b23d0ba 3428
marcozecchini 0:9fca2b23d0ba 3429 if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
marcozecchini 0:9fca2b23d0ba 3430 {
marcozecchini 0:9fca2b23d0ba 3431 /* Don't check write errors as we can't do anything here.
marcozecchini 0:9fca2b23d0ba 3432 * If the error is permanent we'll catch it later,
marcozecchini 0:9fca2b23d0ba 3433 * if it's not, then hopefully it'll work next time. */
marcozecchini 0:9fca2b23d0ba 3434 (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
marcozecchini 0:9fca2b23d0ba 3435
marcozecchini 0:9fca2b23d0ba 3436 return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
marcozecchini 0:9fca2b23d0ba 3437 }
marcozecchini 0:9fca2b23d0ba 3438
marcozecchini 0:9fca2b23d0ba 3439 if( ret == 0 )
marcozecchini 0:9fca2b23d0ba 3440 {
marcozecchini 0:9fca2b23d0ba 3441 /* Got a valid cookie, partially reset context */
marcozecchini 0:9fca2b23d0ba 3442 if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3443 {
marcozecchini 0:9fca2b23d0ba 3444 MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
marcozecchini 0:9fca2b23d0ba 3445 return( ret );
marcozecchini 0:9fca2b23d0ba 3446 }
marcozecchini 0:9fca2b23d0ba 3447
marcozecchini 0:9fca2b23d0ba 3448 return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
marcozecchini 0:9fca2b23d0ba 3449 }
marcozecchini 0:9fca2b23d0ba 3450
marcozecchini 0:9fca2b23d0ba 3451 return( ret );
marcozecchini 0:9fca2b23d0ba 3452 }
marcozecchini 0:9fca2b23d0ba 3453 #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 3454
marcozecchini 0:9fca2b23d0ba 3455 /*
marcozecchini 0:9fca2b23d0ba 3456 * ContentType type;
marcozecchini 0:9fca2b23d0ba 3457 * ProtocolVersion version;
marcozecchini 0:9fca2b23d0ba 3458 * uint16 epoch; // DTLS only
marcozecchini 0:9fca2b23d0ba 3459 * uint48 sequence_number; // DTLS only
marcozecchini 0:9fca2b23d0ba 3460 * uint16 length;
marcozecchini 0:9fca2b23d0ba 3461 *
marcozecchini 0:9fca2b23d0ba 3462 * Return 0 if header looks sane (and, for DTLS, the record is expected)
marcozecchini 0:9fca2b23d0ba 3463 * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
marcozecchini 0:9fca2b23d0ba 3464 * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
marcozecchini 0:9fca2b23d0ba 3465 *
marcozecchini 0:9fca2b23d0ba 3466 * With DTLS, mbedtls_ssl_read_record() will:
marcozecchini 0:9fca2b23d0ba 3467 * 1. proceed with the record if this function returns 0
marcozecchini 0:9fca2b23d0ba 3468 * 2. drop only the current record if this function returns UNEXPECTED_RECORD
marcozecchini 0:9fca2b23d0ba 3469 * 3. return CLIENT_RECONNECT if this function return that value
marcozecchini 0:9fca2b23d0ba 3470 * 4. drop the whole datagram if this function returns anything else.
marcozecchini 0:9fca2b23d0ba 3471 * Point 2 is needed when the peer is resending, and we have already received
marcozecchini 0:9fca2b23d0ba 3472 * the first record from a datagram but are still waiting for the others.
marcozecchini 0:9fca2b23d0ba 3473 */
marcozecchini 0:9fca2b23d0ba 3474 static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3475 {
marcozecchini 0:9fca2b23d0ba 3476 int major_ver, minor_ver;
marcozecchini 0:9fca2b23d0ba 3477
marcozecchini 0:9fca2b23d0ba 3478 MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) );
marcozecchini 0:9fca2b23d0ba 3479
marcozecchini 0:9fca2b23d0ba 3480 ssl->in_msgtype = ssl->in_hdr[0];
marcozecchini 0:9fca2b23d0ba 3481 ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
marcozecchini 0:9fca2b23d0ba 3482 mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 );
marcozecchini 0:9fca2b23d0ba 3483
marcozecchini 0:9fca2b23d0ba 3484 MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
marcozecchini 0:9fca2b23d0ba 3485 "version = [%d:%d], msglen = %d",
marcozecchini 0:9fca2b23d0ba 3486 ssl->in_msgtype,
marcozecchini 0:9fca2b23d0ba 3487 major_ver, minor_ver, ssl->in_msglen ) );
marcozecchini 0:9fca2b23d0ba 3488
marcozecchini 0:9fca2b23d0ba 3489 /* Check record type */
marcozecchini 0:9fca2b23d0ba 3490 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
marcozecchini 0:9fca2b23d0ba 3491 ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT &&
marcozecchini 0:9fca2b23d0ba 3492 ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
marcozecchini 0:9fca2b23d0ba 3493 ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
marcozecchini 0:9fca2b23d0ba 3494 {
marcozecchini 0:9fca2b23d0ba 3495 MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
marcozecchini 0:9fca2b23d0ba 3496 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 3497 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 3498 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3499 }
marcozecchini 0:9fca2b23d0ba 3500
marcozecchini 0:9fca2b23d0ba 3501 /* Check version */
marcozecchini 0:9fca2b23d0ba 3502 if( major_ver != ssl->major_ver )
marcozecchini 0:9fca2b23d0ba 3503 {
marcozecchini 0:9fca2b23d0ba 3504 MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
marcozecchini 0:9fca2b23d0ba 3505 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3506 }
marcozecchini 0:9fca2b23d0ba 3507
marcozecchini 0:9fca2b23d0ba 3508 if( minor_ver > ssl->conf->max_minor_ver )
marcozecchini 0:9fca2b23d0ba 3509 {
marcozecchini 0:9fca2b23d0ba 3510 MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
marcozecchini 0:9fca2b23d0ba 3511 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3512 }
marcozecchini 0:9fca2b23d0ba 3513
marcozecchini 0:9fca2b23d0ba 3514 /* Check length against the size of our buffer */
marcozecchini 0:9fca2b23d0ba 3515 if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN
marcozecchini 0:9fca2b23d0ba 3516 - (size_t)( ssl->in_msg - ssl->in_buf ) )
marcozecchini 0:9fca2b23d0ba 3517 {
marcozecchini 0:9fca2b23d0ba 3518 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
marcozecchini 0:9fca2b23d0ba 3519 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3520 }
marcozecchini 0:9fca2b23d0ba 3521
marcozecchini 0:9fca2b23d0ba 3522 /* Check length against bounds of the current transform and version */
marcozecchini 0:9fca2b23d0ba 3523 if( ssl->transform_in == NULL )
marcozecchini 0:9fca2b23d0ba 3524 {
marcozecchini 0:9fca2b23d0ba 3525 if( ssl->in_msglen < 1 ||
marcozecchini 0:9fca2b23d0ba 3526 ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
marcozecchini 0:9fca2b23d0ba 3527 {
marcozecchini 0:9fca2b23d0ba 3528 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
marcozecchini 0:9fca2b23d0ba 3529 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3530 }
marcozecchini 0:9fca2b23d0ba 3531 }
marcozecchini 0:9fca2b23d0ba 3532 else
marcozecchini 0:9fca2b23d0ba 3533 {
marcozecchini 0:9fca2b23d0ba 3534 if( ssl->in_msglen < ssl->transform_in->minlen )
marcozecchini 0:9fca2b23d0ba 3535 {
marcozecchini 0:9fca2b23d0ba 3536 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
marcozecchini 0:9fca2b23d0ba 3537 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3538 }
marcozecchini 0:9fca2b23d0ba 3539
marcozecchini 0:9fca2b23d0ba 3540 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 3541 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
marcozecchini 0:9fca2b23d0ba 3542 ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN )
marcozecchini 0:9fca2b23d0ba 3543 {
marcozecchini 0:9fca2b23d0ba 3544 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
marcozecchini 0:9fca2b23d0ba 3545 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3546 }
marcozecchini 0:9fca2b23d0ba 3547 #endif
marcozecchini 0:9fca2b23d0ba 3548 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
marcozecchini 0:9fca2b23d0ba 3549 defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 3550 /*
marcozecchini 0:9fca2b23d0ba 3551 * TLS encrypted messages can have up to 256 bytes of padding
marcozecchini 0:9fca2b23d0ba 3552 */
marcozecchini 0:9fca2b23d0ba 3553 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
marcozecchini 0:9fca2b23d0ba 3554 ssl->in_msglen > ssl->transform_in->minlen +
marcozecchini 0:9fca2b23d0ba 3555 MBEDTLS_SSL_MAX_CONTENT_LEN + 256 )
marcozecchini 0:9fca2b23d0ba 3556 {
marcozecchini 0:9fca2b23d0ba 3557 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
marcozecchini 0:9fca2b23d0ba 3558 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3559 }
marcozecchini 0:9fca2b23d0ba 3560 #endif
marcozecchini 0:9fca2b23d0ba 3561 }
marcozecchini 0:9fca2b23d0ba 3562
marcozecchini 0:9fca2b23d0ba 3563 /*
marcozecchini 0:9fca2b23d0ba 3564 * DTLS-related tests done last, because most of them may result in
marcozecchini 0:9fca2b23d0ba 3565 * silently dropping the record (but not the whole datagram), and we only
marcozecchini 0:9fca2b23d0ba 3566 * want to consider that after ensuring that the "basic" fields (type,
marcozecchini 0:9fca2b23d0ba 3567 * version, length) are sane.
marcozecchini 0:9fca2b23d0ba 3568 */
marcozecchini 0:9fca2b23d0ba 3569 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 3570 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 3571 {
marcozecchini 0:9fca2b23d0ba 3572 unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
marcozecchini 0:9fca2b23d0ba 3573
marcozecchini 0:9fca2b23d0ba 3574 /* Drop unexpected ChangeCipherSpec messages */
marcozecchini 0:9fca2b23d0ba 3575 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
marcozecchini 0:9fca2b23d0ba 3576 ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
marcozecchini 0:9fca2b23d0ba 3577 ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
marcozecchini 0:9fca2b23d0ba 3578 {
marcozecchini 0:9fca2b23d0ba 3579 MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) );
marcozecchini 0:9fca2b23d0ba 3580 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
marcozecchini 0:9fca2b23d0ba 3581 }
marcozecchini 0:9fca2b23d0ba 3582
marcozecchini 0:9fca2b23d0ba 3583 /* Drop unexpected ApplicationData records,
marcozecchini 0:9fca2b23d0ba 3584 * except at the beginning of renegotiations */
marcozecchini 0:9fca2b23d0ba 3585 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
marcozecchini 0:9fca2b23d0ba 3586 ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
marcozecchini 0:9fca2b23d0ba 3587 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 3588 && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
marcozecchini 0:9fca2b23d0ba 3589 ssl->state == MBEDTLS_SSL_SERVER_HELLO )
marcozecchini 0:9fca2b23d0ba 3590 #endif
marcozecchini 0:9fca2b23d0ba 3591 )
marcozecchini 0:9fca2b23d0ba 3592 {
marcozecchini 0:9fca2b23d0ba 3593 MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
marcozecchini 0:9fca2b23d0ba 3594 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
marcozecchini 0:9fca2b23d0ba 3595 }
marcozecchini 0:9fca2b23d0ba 3596
marcozecchini 0:9fca2b23d0ba 3597 /* Check epoch (and sequence number) with DTLS */
marcozecchini 0:9fca2b23d0ba 3598 if( rec_epoch != ssl->in_epoch )
marcozecchini 0:9fca2b23d0ba 3599 {
marcozecchini 0:9fca2b23d0ba 3600 MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
marcozecchini 0:9fca2b23d0ba 3601 "expected %d, received %d",
marcozecchini 0:9fca2b23d0ba 3602 ssl->in_epoch, rec_epoch ) );
marcozecchini 0:9fca2b23d0ba 3603
marcozecchini 0:9fca2b23d0ba 3604 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 3605 /*
marcozecchini 0:9fca2b23d0ba 3606 * Check for an epoch 0 ClientHello. We can't use in_msg here to
marcozecchini 0:9fca2b23d0ba 3607 * access the first byte of record content (handshake type), as we
marcozecchini 0:9fca2b23d0ba 3608 * have an active transform (possibly iv_len != 0), so use the
marcozecchini 0:9fca2b23d0ba 3609 * fact that the record header len is 13 instead.
marcozecchini 0:9fca2b23d0ba 3610 */
marcozecchini 0:9fca2b23d0ba 3611 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 3612 ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
marcozecchini 0:9fca2b23d0ba 3613 rec_epoch == 0 &&
marcozecchini 0:9fca2b23d0ba 3614 ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
marcozecchini 0:9fca2b23d0ba 3615 ssl->in_left > 13 &&
marcozecchini 0:9fca2b23d0ba 3616 ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
marcozecchini 0:9fca2b23d0ba 3617 {
marcozecchini 0:9fca2b23d0ba 3618 MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
marcozecchini 0:9fca2b23d0ba 3619 "from the same port" ) );
marcozecchini 0:9fca2b23d0ba 3620 return( ssl_handle_possible_reconnect( ssl ) );
marcozecchini 0:9fca2b23d0ba 3621 }
marcozecchini 0:9fca2b23d0ba 3622 else
marcozecchini 0:9fca2b23d0ba 3623 #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 3624 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
marcozecchini 0:9fca2b23d0ba 3625 }
marcozecchini 0:9fca2b23d0ba 3626
marcozecchini 0:9fca2b23d0ba 3627 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
marcozecchini 0:9fca2b23d0ba 3628 /* Replay detection only works for the current epoch */
marcozecchini 0:9fca2b23d0ba 3629 if( rec_epoch == ssl->in_epoch &&
marcozecchini 0:9fca2b23d0ba 3630 mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
marcozecchini 0:9fca2b23d0ba 3631 {
marcozecchini 0:9fca2b23d0ba 3632 MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
marcozecchini 0:9fca2b23d0ba 3633 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
marcozecchini 0:9fca2b23d0ba 3634 }
marcozecchini 0:9fca2b23d0ba 3635 #endif
marcozecchini 0:9fca2b23d0ba 3636 }
marcozecchini 0:9fca2b23d0ba 3637 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 3638
marcozecchini 0:9fca2b23d0ba 3639 return( 0 );
marcozecchini 0:9fca2b23d0ba 3640 }
marcozecchini 0:9fca2b23d0ba 3641
marcozecchini 0:9fca2b23d0ba 3642 /*
marcozecchini 0:9fca2b23d0ba 3643 * If applicable, decrypt (and decompress) record content
marcozecchini 0:9fca2b23d0ba 3644 */
marcozecchini 0:9fca2b23d0ba 3645 static int ssl_prepare_record_content( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3646 {
marcozecchini 0:9fca2b23d0ba 3647 int ret, done = 0;
marcozecchini 0:9fca2b23d0ba 3648
marcozecchini 0:9fca2b23d0ba 3649 MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
marcozecchini 0:9fca2b23d0ba 3650 ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 3651
marcozecchini 0:9fca2b23d0ba 3652 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 3653 if( mbedtls_ssl_hw_record_read != NULL )
marcozecchini 0:9fca2b23d0ba 3654 {
marcozecchini 0:9fca2b23d0ba 3655 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
marcozecchini 0:9fca2b23d0ba 3656
marcozecchini 0:9fca2b23d0ba 3657 ret = mbedtls_ssl_hw_record_read( ssl );
marcozecchini 0:9fca2b23d0ba 3658 if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
marcozecchini 0:9fca2b23d0ba 3659 {
marcozecchini 0:9fca2b23d0ba 3660 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
marcozecchini 0:9fca2b23d0ba 3661 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
marcozecchini 0:9fca2b23d0ba 3662 }
marcozecchini 0:9fca2b23d0ba 3663
marcozecchini 0:9fca2b23d0ba 3664 if( ret == 0 )
marcozecchini 0:9fca2b23d0ba 3665 done = 1;
marcozecchini 0:9fca2b23d0ba 3666 }
marcozecchini 0:9fca2b23d0ba 3667 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
marcozecchini 0:9fca2b23d0ba 3668 if( !done && ssl->transform_in != NULL )
marcozecchini 0:9fca2b23d0ba 3669 {
marcozecchini 0:9fca2b23d0ba 3670 if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3671 {
marcozecchini 0:9fca2b23d0ba 3672 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
marcozecchini 0:9fca2b23d0ba 3673 return( ret );
marcozecchini 0:9fca2b23d0ba 3674 }
marcozecchini 0:9fca2b23d0ba 3675
marcozecchini 0:9fca2b23d0ba 3676 MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
marcozecchini 0:9fca2b23d0ba 3677 ssl->in_msg, ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 3678
marcozecchini 0:9fca2b23d0ba 3679 if( ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
marcozecchini 0:9fca2b23d0ba 3680 {
marcozecchini 0:9fca2b23d0ba 3681 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
marcozecchini 0:9fca2b23d0ba 3682 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
marcozecchini 0:9fca2b23d0ba 3683 }
marcozecchini 0:9fca2b23d0ba 3684 }
marcozecchini 0:9fca2b23d0ba 3685
marcozecchini 0:9fca2b23d0ba 3686 #if defined(MBEDTLS_ZLIB_SUPPORT)
marcozecchini 0:9fca2b23d0ba 3687 if( ssl->transform_in != NULL &&
marcozecchini 0:9fca2b23d0ba 3688 ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
marcozecchini 0:9fca2b23d0ba 3689 {
marcozecchini 0:9fca2b23d0ba 3690 if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3691 {
marcozecchini 0:9fca2b23d0ba 3692 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
marcozecchini 0:9fca2b23d0ba 3693 return( ret );
marcozecchini 0:9fca2b23d0ba 3694 }
marcozecchini 0:9fca2b23d0ba 3695 }
marcozecchini 0:9fca2b23d0ba 3696 #endif /* MBEDTLS_ZLIB_SUPPORT */
marcozecchini 0:9fca2b23d0ba 3697
marcozecchini 0:9fca2b23d0ba 3698 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
marcozecchini 0:9fca2b23d0ba 3699 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 3700 {
marcozecchini 0:9fca2b23d0ba 3701 mbedtls_ssl_dtls_replay_update( ssl );
marcozecchini 0:9fca2b23d0ba 3702 }
marcozecchini 0:9fca2b23d0ba 3703 #endif
marcozecchini 0:9fca2b23d0ba 3704
marcozecchini 0:9fca2b23d0ba 3705 return( 0 );
marcozecchini 0:9fca2b23d0ba 3706 }
marcozecchini 0:9fca2b23d0ba 3707
marcozecchini 0:9fca2b23d0ba 3708 static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
marcozecchini 0:9fca2b23d0ba 3709
marcozecchini 0:9fca2b23d0ba 3710 /*
marcozecchini 0:9fca2b23d0ba 3711 * Read a record.
marcozecchini 0:9fca2b23d0ba 3712 *
marcozecchini 0:9fca2b23d0ba 3713 * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
marcozecchini 0:9fca2b23d0ba 3714 * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
marcozecchini 0:9fca2b23d0ba 3715 *
marcozecchini 0:9fca2b23d0ba 3716 */
marcozecchini 0:9fca2b23d0ba 3717 int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3718 {
marcozecchini 0:9fca2b23d0ba 3719 int ret;
marcozecchini 0:9fca2b23d0ba 3720
marcozecchini 0:9fca2b23d0ba 3721 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
marcozecchini 0:9fca2b23d0ba 3722
marcozecchini 0:9fca2b23d0ba 3723 if( ssl->keep_current_message == 0 )
marcozecchini 0:9fca2b23d0ba 3724 {
marcozecchini 0:9fca2b23d0ba 3725 do {
marcozecchini 0:9fca2b23d0ba 3726
marcozecchini 0:9fca2b23d0ba 3727 if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3728 {
marcozecchini 0:9fca2b23d0ba 3729 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret );
marcozecchini 0:9fca2b23d0ba 3730 return( ret );
marcozecchini 0:9fca2b23d0ba 3731 }
marcozecchini 0:9fca2b23d0ba 3732
marcozecchini 0:9fca2b23d0ba 3733 ret = mbedtls_ssl_handle_message_type( ssl );
marcozecchini 0:9fca2b23d0ba 3734
marcozecchini 0:9fca2b23d0ba 3735 } while( MBEDTLS_ERR_SSL_NON_FATAL == ret );
marcozecchini 0:9fca2b23d0ba 3736
marcozecchini 0:9fca2b23d0ba 3737 if( 0 != ret )
marcozecchini 0:9fca2b23d0ba 3738 {
marcozecchini 0:9fca2b23d0ba 3739 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret );
marcozecchini 0:9fca2b23d0ba 3740 return( ret );
marcozecchini 0:9fca2b23d0ba 3741 }
marcozecchini 0:9fca2b23d0ba 3742
marcozecchini 0:9fca2b23d0ba 3743 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
marcozecchini 0:9fca2b23d0ba 3744 {
marcozecchini 0:9fca2b23d0ba 3745 mbedtls_ssl_update_handshake_status( ssl );
marcozecchini 0:9fca2b23d0ba 3746 }
marcozecchini 0:9fca2b23d0ba 3747 }
marcozecchini 0:9fca2b23d0ba 3748 else
marcozecchini 0:9fca2b23d0ba 3749 {
marcozecchini 0:9fca2b23d0ba 3750 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= reuse previously read message" ) );
marcozecchini 0:9fca2b23d0ba 3751 ssl->keep_current_message = 0;
marcozecchini 0:9fca2b23d0ba 3752 }
marcozecchini 0:9fca2b23d0ba 3753
marcozecchini 0:9fca2b23d0ba 3754 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
marcozecchini 0:9fca2b23d0ba 3755
marcozecchini 0:9fca2b23d0ba 3756 return( 0 );
marcozecchini 0:9fca2b23d0ba 3757 }
marcozecchini 0:9fca2b23d0ba 3758
marcozecchini 0:9fca2b23d0ba 3759 int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 3760 {
marcozecchini 0:9fca2b23d0ba 3761 int ret;
marcozecchini 0:9fca2b23d0ba 3762
marcozecchini 0:9fca2b23d0ba 3763 /*
marcozecchini 0:9fca2b23d0ba 3764 * Step A
marcozecchini 0:9fca2b23d0ba 3765 *
marcozecchini 0:9fca2b23d0ba 3766 * Consume last content-layer message and potentially
marcozecchini 0:9fca2b23d0ba 3767 * update in_msglen which keeps track of the contents'
marcozecchini 0:9fca2b23d0ba 3768 * consumption state.
marcozecchini 0:9fca2b23d0ba 3769 *
marcozecchini 0:9fca2b23d0ba 3770 * (1) Handshake messages:
marcozecchini 0:9fca2b23d0ba 3771 * Remove last handshake message, move content
marcozecchini 0:9fca2b23d0ba 3772 * and adapt in_msglen.
marcozecchini 0:9fca2b23d0ba 3773 *
marcozecchini 0:9fca2b23d0ba 3774 * (2) Alert messages:
marcozecchini 0:9fca2b23d0ba 3775 * Consume whole record content, in_msglen = 0.
marcozecchini 0:9fca2b23d0ba 3776 *
marcozecchini 0:9fca2b23d0ba 3777 * NOTE: This needs to be fixed, since like for
marcozecchini 0:9fca2b23d0ba 3778 * handshake messages it is allowed to have
marcozecchini 0:9fca2b23d0ba 3779 * multiple alerts witin a single record.
marcozecchini 0:9fca2b23d0ba 3780 * Internal reference IOTSSL-1321.
marcozecchini 0:9fca2b23d0ba 3781 *
marcozecchini 0:9fca2b23d0ba 3782 * (3) Change cipher spec:
marcozecchini 0:9fca2b23d0ba 3783 * Consume whole record content, in_msglen = 0.
marcozecchini 0:9fca2b23d0ba 3784 *
marcozecchini 0:9fca2b23d0ba 3785 * (4) Application data:
marcozecchini 0:9fca2b23d0ba 3786 * Don't do anything - the record layer provides
marcozecchini 0:9fca2b23d0ba 3787 * the application data as a stream transport
marcozecchini 0:9fca2b23d0ba 3788 * and consumes through mbedtls_ssl_read only.
marcozecchini 0:9fca2b23d0ba 3789 *
marcozecchini 0:9fca2b23d0ba 3790 */
marcozecchini 0:9fca2b23d0ba 3791
marcozecchini 0:9fca2b23d0ba 3792 /* Case (1): Handshake messages */
marcozecchini 0:9fca2b23d0ba 3793 if( ssl->in_hslen != 0 )
marcozecchini 0:9fca2b23d0ba 3794 {
marcozecchini 0:9fca2b23d0ba 3795 /* Hard assertion to be sure that no application data
marcozecchini 0:9fca2b23d0ba 3796 * is in flight, as corrupting ssl->in_msglen during
marcozecchini 0:9fca2b23d0ba 3797 * ssl->in_offt != NULL is fatal. */
marcozecchini 0:9fca2b23d0ba 3798 if( ssl->in_offt != NULL )
marcozecchini 0:9fca2b23d0ba 3799 {
marcozecchini 0:9fca2b23d0ba 3800 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 3801 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 3802 }
marcozecchini 0:9fca2b23d0ba 3803
marcozecchini 0:9fca2b23d0ba 3804 /*
marcozecchini 0:9fca2b23d0ba 3805 * Get next Handshake message in the current record
marcozecchini 0:9fca2b23d0ba 3806 */
marcozecchini 0:9fca2b23d0ba 3807
marcozecchini 0:9fca2b23d0ba 3808 /* Notes:
marcozecchini 0:9fca2b23d0ba 3809 * (1) in_hslen is *NOT* necessarily the size of the
marcozecchini 0:9fca2b23d0ba 3810 * current handshake content: If DTLS handshake
marcozecchini 0:9fca2b23d0ba 3811 * fragmentation is used, that's the fragment
marcozecchini 0:9fca2b23d0ba 3812 * size instead. Using the total handshake message
marcozecchini 0:9fca2b23d0ba 3813 * size here is FAULTY and should be changed at
marcozecchini 0:9fca2b23d0ba 3814 * some point. Internal reference IOTSSL-1414.
marcozecchini 0:9fca2b23d0ba 3815 * (2) While it doesn't seem to cause problems, one
marcozecchini 0:9fca2b23d0ba 3816 * has to be very careful not to assume that in_hslen
marcozecchini 0:9fca2b23d0ba 3817 * is always <= in_msglen in a sensible communication.
marcozecchini 0:9fca2b23d0ba 3818 * Again, it's wrong for DTLS handshake fragmentation.
marcozecchini 0:9fca2b23d0ba 3819 * The following check is therefore mandatory, and
marcozecchini 0:9fca2b23d0ba 3820 * should not be treated as a silently corrected assertion.
marcozecchini 0:9fca2b23d0ba 3821 * Additionally, ssl->in_hslen might be arbitrarily out of
marcozecchini 0:9fca2b23d0ba 3822 * bounds after handling a DTLS message with an unexpected
marcozecchini 0:9fca2b23d0ba 3823 * sequence number, see mbedtls_ssl_prepare_handshake_record.
marcozecchini 0:9fca2b23d0ba 3824 */
marcozecchini 0:9fca2b23d0ba 3825 if( ssl->in_hslen < ssl->in_msglen )
marcozecchini 0:9fca2b23d0ba 3826 {
marcozecchini 0:9fca2b23d0ba 3827 ssl->in_msglen -= ssl->in_hslen;
marcozecchini 0:9fca2b23d0ba 3828 memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
marcozecchini 0:9fca2b23d0ba 3829 ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 3830
marcozecchini 0:9fca2b23d0ba 3831 MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
marcozecchini 0:9fca2b23d0ba 3832 ssl->in_msg, ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 3833 }
marcozecchini 0:9fca2b23d0ba 3834 else
marcozecchini 0:9fca2b23d0ba 3835 {
marcozecchini 0:9fca2b23d0ba 3836 ssl->in_msglen = 0;
marcozecchini 0:9fca2b23d0ba 3837 }
marcozecchini 0:9fca2b23d0ba 3838
marcozecchini 0:9fca2b23d0ba 3839 ssl->in_hslen = 0;
marcozecchini 0:9fca2b23d0ba 3840 }
marcozecchini 0:9fca2b23d0ba 3841 /* Case (4): Application data */
marcozecchini 0:9fca2b23d0ba 3842 else if( ssl->in_offt != NULL )
marcozecchini 0:9fca2b23d0ba 3843 {
marcozecchini 0:9fca2b23d0ba 3844 return( 0 );
marcozecchini 0:9fca2b23d0ba 3845 }
marcozecchini 0:9fca2b23d0ba 3846 /* Everything else (CCS & Alerts) */
marcozecchini 0:9fca2b23d0ba 3847 else
marcozecchini 0:9fca2b23d0ba 3848 {
marcozecchini 0:9fca2b23d0ba 3849 ssl->in_msglen = 0;
marcozecchini 0:9fca2b23d0ba 3850 }
marcozecchini 0:9fca2b23d0ba 3851
marcozecchini 0:9fca2b23d0ba 3852 /*
marcozecchini 0:9fca2b23d0ba 3853 * Step B
marcozecchini 0:9fca2b23d0ba 3854 *
marcozecchini 0:9fca2b23d0ba 3855 * Fetch and decode new record if current one is fully consumed.
marcozecchini 0:9fca2b23d0ba 3856 *
marcozecchini 0:9fca2b23d0ba 3857 */
marcozecchini 0:9fca2b23d0ba 3858
marcozecchini 0:9fca2b23d0ba 3859 if( ssl->in_msglen > 0 )
marcozecchini 0:9fca2b23d0ba 3860 {
marcozecchini 0:9fca2b23d0ba 3861 /* There's something left to be processed in the current record. */
marcozecchini 0:9fca2b23d0ba 3862 return( 0 );
marcozecchini 0:9fca2b23d0ba 3863 }
marcozecchini 0:9fca2b23d0ba 3864
marcozecchini 0:9fca2b23d0ba 3865 /* Need to fetch a new record */
marcozecchini 0:9fca2b23d0ba 3866
marcozecchini 0:9fca2b23d0ba 3867 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 3868 read_record_header:
marcozecchini 0:9fca2b23d0ba 3869 #endif
marcozecchini 0:9fca2b23d0ba 3870
marcozecchini 0:9fca2b23d0ba 3871 /* Current record either fully processed or to be discarded. */
marcozecchini 0:9fca2b23d0ba 3872
marcozecchini 0:9fca2b23d0ba 3873 if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3874 {
marcozecchini 0:9fca2b23d0ba 3875 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
marcozecchini 0:9fca2b23d0ba 3876 return( ret );
marcozecchini 0:9fca2b23d0ba 3877 }
marcozecchini 0:9fca2b23d0ba 3878
marcozecchini 0:9fca2b23d0ba 3879 if( ( ret = ssl_parse_record_header( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3880 {
marcozecchini 0:9fca2b23d0ba 3881 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 3882 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
marcozecchini 0:9fca2b23d0ba 3883 ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
marcozecchini 0:9fca2b23d0ba 3884 {
marcozecchini 0:9fca2b23d0ba 3885 if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
marcozecchini 0:9fca2b23d0ba 3886 {
marcozecchini 0:9fca2b23d0ba 3887 /* Skip unexpected record (but not whole datagram) */
marcozecchini 0:9fca2b23d0ba 3888 ssl->next_record_offset = ssl->in_msglen
marcozecchini 0:9fca2b23d0ba 3889 + mbedtls_ssl_hdr_len( ssl );
marcozecchini 0:9fca2b23d0ba 3890
marcozecchini 0:9fca2b23d0ba 3891 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
marcozecchini 0:9fca2b23d0ba 3892 "(header)" ) );
marcozecchini 0:9fca2b23d0ba 3893 }
marcozecchini 0:9fca2b23d0ba 3894 else
marcozecchini 0:9fca2b23d0ba 3895 {
marcozecchini 0:9fca2b23d0ba 3896 /* Skip invalid record and the rest of the datagram */
marcozecchini 0:9fca2b23d0ba 3897 ssl->next_record_offset = 0;
marcozecchini 0:9fca2b23d0ba 3898 ssl->in_left = 0;
marcozecchini 0:9fca2b23d0ba 3899
marcozecchini 0:9fca2b23d0ba 3900 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
marcozecchini 0:9fca2b23d0ba 3901 "(header)" ) );
marcozecchini 0:9fca2b23d0ba 3902 }
marcozecchini 0:9fca2b23d0ba 3903
marcozecchini 0:9fca2b23d0ba 3904 /* Get next record */
marcozecchini 0:9fca2b23d0ba 3905 goto read_record_header;
marcozecchini 0:9fca2b23d0ba 3906 }
marcozecchini 0:9fca2b23d0ba 3907 #endif
marcozecchini 0:9fca2b23d0ba 3908 return( ret );
marcozecchini 0:9fca2b23d0ba 3909 }
marcozecchini 0:9fca2b23d0ba 3910
marcozecchini 0:9fca2b23d0ba 3911 /*
marcozecchini 0:9fca2b23d0ba 3912 * Read and optionally decrypt the message contents
marcozecchini 0:9fca2b23d0ba 3913 */
marcozecchini 0:9fca2b23d0ba 3914 if( ( ret = mbedtls_ssl_fetch_input( ssl,
marcozecchini 0:9fca2b23d0ba 3915 mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3916 {
marcozecchini 0:9fca2b23d0ba 3917 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
marcozecchini 0:9fca2b23d0ba 3918 return( ret );
marcozecchini 0:9fca2b23d0ba 3919 }
marcozecchini 0:9fca2b23d0ba 3920
marcozecchini 0:9fca2b23d0ba 3921 /* Done reading this record, get ready for the next one */
marcozecchini 0:9fca2b23d0ba 3922 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 3923 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 3924 ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl );
marcozecchini 0:9fca2b23d0ba 3925 else
marcozecchini 0:9fca2b23d0ba 3926 #endif
marcozecchini 0:9fca2b23d0ba 3927 ssl->in_left = 0;
marcozecchini 0:9fca2b23d0ba 3928
marcozecchini 0:9fca2b23d0ba 3929 if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 3930 {
marcozecchini 0:9fca2b23d0ba 3931 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 3932 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 3933 {
marcozecchini 0:9fca2b23d0ba 3934 /* Silently discard invalid records */
marcozecchini 0:9fca2b23d0ba 3935 if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD ||
marcozecchini 0:9fca2b23d0ba 3936 ret == MBEDTLS_ERR_SSL_INVALID_MAC )
marcozecchini 0:9fca2b23d0ba 3937 {
marcozecchini 0:9fca2b23d0ba 3938 /* Except when waiting for Finished as a bad mac here
marcozecchini 0:9fca2b23d0ba 3939 * probably means something went wrong in the handshake
marcozecchini 0:9fca2b23d0ba 3940 * (eg wrong psk used, mitm downgrade attempt, etc.) */
marcozecchini 0:9fca2b23d0ba 3941 if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
marcozecchini 0:9fca2b23d0ba 3942 ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
marcozecchini 0:9fca2b23d0ba 3943 {
marcozecchini 0:9fca2b23d0ba 3944 #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
marcozecchini 0:9fca2b23d0ba 3945 if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
marcozecchini 0:9fca2b23d0ba 3946 {
marcozecchini 0:9fca2b23d0ba 3947 mbedtls_ssl_send_alert_message( ssl,
marcozecchini 0:9fca2b23d0ba 3948 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 3949 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
marcozecchini 0:9fca2b23d0ba 3950 }
marcozecchini 0:9fca2b23d0ba 3951 #endif
marcozecchini 0:9fca2b23d0ba 3952 return( ret );
marcozecchini 0:9fca2b23d0ba 3953 }
marcozecchini 0:9fca2b23d0ba 3954
marcozecchini 0:9fca2b23d0ba 3955 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
marcozecchini 0:9fca2b23d0ba 3956 if( ssl->conf->badmac_limit != 0 &&
marcozecchini 0:9fca2b23d0ba 3957 ++ssl->badmac_seen >= ssl->conf->badmac_limit )
marcozecchini 0:9fca2b23d0ba 3958 {
marcozecchini 0:9fca2b23d0ba 3959 MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
marcozecchini 0:9fca2b23d0ba 3960 return( MBEDTLS_ERR_SSL_INVALID_MAC );
marcozecchini 0:9fca2b23d0ba 3961 }
marcozecchini 0:9fca2b23d0ba 3962 #endif
marcozecchini 0:9fca2b23d0ba 3963
marcozecchini 0:9fca2b23d0ba 3964 /* As above, invalid records cause
marcozecchini 0:9fca2b23d0ba 3965 * dismissal of the whole datagram. */
marcozecchini 0:9fca2b23d0ba 3966
marcozecchini 0:9fca2b23d0ba 3967 ssl->next_record_offset = 0;
marcozecchini 0:9fca2b23d0ba 3968 ssl->in_left = 0;
marcozecchini 0:9fca2b23d0ba 3969
marcozecchini 0:9fca2b23d0ba 3970 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
marcozecchini 0:9fca2b23d0ba 3971 goto read_record_header;
marcozecchini 0:9fca2b23d0ba 3972 }
marcozecchini 0:9fca2b23d0ba 3973
marcozecchini 0:9fca2b23d0ba 3974 return( ret );
marcozecchini 0:9fca2b23d0ba 3975 }
marcozecchini 0:9fca2b23d0ba 3976 else
marcozecchini 0:9fca2b23d0ba 3977 #endif
marcozecchini 0:9fca2b23d0ba 3978 {
marcozecchini 0:9fca2b23d0ba 3979 /* Error out (and send alert) on invalid records */
marcozecchini 0:9fca2b23d0ba 3980 #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
marcozecchini 0:9fca2b23d0ba 3981 if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
marcozecchini 0:9fca2b23d0ba 3982 {
marcozecchini 0:9fca2b23d0ba 3983 mbedtls_ssl_send_alert_message( ssl,
marcozecchini 0:9fca2b23d0ba 3984 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 3985 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
marcozecchini 0:9fca2b23d0ba 3986 }
marcozecchini 0:9fca2b23d0ba 3987 #endif
marcozecchini 0:9fca2b23d0ba 3988 return( ret );
marcozecchini 0:9fca2b23d0ba 3989 }
marcozecchini 0:9fca2b23d0ba 3990 }
marcozecchini 0:9fca2b23d0ba 3991
marcozecchini 0:9fca2b23d0ba 3992 /*
marcozecchini 0:9fca2b23d0ba 3993 * When we sent the last flight of the handshake, we MUST respond to a
marcozecchini 0:9fca2b23d0ba 3994 * retransmit of the peer's previous flight with a retransmit. (In
marcozecchini 0:9fca2b23d0ba 3995 * practice, only the Finished message will make it, other messages
marcozecchini 0:9fca2b23d0ba 3996 * including CCS use the old transform so they're dropped as invalid.)
marcozecchini 0:9fca2b23d0ba 3997 *
marcozecchini 0:9fca2b23d0ba 3998 * If the record we received is not a handshake message, however, it
marcozecchini 0:9fca2b23d0ba 3999 * means the peer received our last flight so we can clean up
marcozecchini 0:9fca2b23d0ba 4000 * handshake info.
marcozecchini 0:9fca2b23d0ba 4001 *
marcozecchini 0:9fca2b23d0ba 4002 * This check needs to be done before prepare_handshake() due to an edge
marcozecchini 0:9fca2b23d0ba 4003 * case: if the client immediately requests renegotiation, this
marcozecchini 0:9fca2b23d0ba 4004 * finishes the current handshake first, avoiding the new ClientHello
marcozecchini 0:9fca2b23d0ba 4005 * being mistaken for an ancient message in the current handshake.
marcozecchini 0:9fca2b23d0ba 4006 */
marcozecchini 0:9fca2b23d0ba 4007 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 4008 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
marcozecchini 0:9fca2b23d0ba 4009 ssl->handshake != NULL &&
marcozecchini 0:9fca2b23d0ba 4010 ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 4011 {
marcozecchini 0:9fca2b23d0ba 4012 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
marcozecchini 0:9fca2b23d0ba 4013 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
marcozecchini 0:9fca2b23d0ba 4014 {
marcozecchini 0:9fca2b23d0ba 4015 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received retransmit of last flight" ) );
marcozecchini 0:9fca2b23d0ba 4016
marcozecchini 0:9fca2b23d0ba 4017 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4018 {
marcozecchini 0:9fca2b23d0ba 4019 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
marcozecchini 0:9fca2b23d0ba 4020 return( ret );
marcozecchini 0:9fca2b23d0ba 4021 }
marcozecchini 0:9fca2b23d0ba 4022
marcozecchini 0:9fca2b23d0ba 4023 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 4024 }
marcozecchini 0:9fca2b23d0ba 4025 else
marcozecchini 0:9fca2b23d0ba 4026 {
marcozecchini 0:9fca2b23d0ba 4027 ssl_handshake_wrapup_free_hs_transform( ssl );
marcozecchini 0:9fca2b23d0ba 4028 }
marcozecchini 0:9fca2b23d0ba 4029 }
marcozecchini 0:9fca2b23d0ba 4030 #endif
marcozecchini 0:9fca2b23d0ba 4031
marcozecchini 0:9fca2b23d0ba 4032 return( 0 );
marcozecchini 0:9fca2b23d0ba 4033 }
marcozecchini 0:9fca2b23d0ba 4034
marcozecchini 0:9fca2b23d0ba 4035 int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4036 {
marcozecchini 0:9fca2b23d0ba 4037 int ret;
marcozecchini 0:9fca2b23d0ba 4038
marcozecchini 0:9fca2b23d0ba 4039 /*
marcozecchini 0:9fca2b23d0ba 4040 * Handle particular types of records
marcozecchini 0:9fca2b23d0ba 4041 */
marcozecchini 0:9fca2b23d0ba 4042 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
marcozecchini 0:9fca2b23d0ba 4043 {
marcozecchini 0:9fca2b23d0ba 4044 if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4045 {
marcozecchini 0:9fca2b23d0ba 4046 return( ret );
marcozecchini 0:9fca2b23d0ba 4047 }
marcozecchini 0:9fca2b23d0ba 4048 }
marcozecchini 0:9fca2b23d0ba 4049
marcozecchini 0:9fca2b23d0ba 4050 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
marcozecchini 0:9fca2b23d0ba 4051 {
marcozecchini 0:9fca2b23d0ba 4052 MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
marcozecchini 0:9fca2b23d0ba 4053 ssl->in_msg[0], ssl->in_msg[1] ) );
marcozecchini 0:9fca2b23d0ba 4054
marcozecchini 0:9fca2b23d0ba 4055 /*
marcozecchini 0:9fca2b23d0ba 4056 * Ignore non-fatal alerts, except close_notify and no_renegotiation
marcozecchini 0:9fca2b23d0ba 4057 */
marcozecchini 0:9fca2b23d0ba 4058 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
marcozecchini 0:9fca2b23d0ba 4059 {
marcozecchini 0:9fca2b23d0ba 4060 MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
marcozecchini 0:9fca2b23d0ba 4061 ssl->in_msg[1] ) );
marcozecchini 0:9fca2b23d0ba 4062 return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
marcozecchini 0:9fca2b23d0ba 4063 }
marcozecchini 0:9fca2b23d0ba 4064
marcozecchini 0:9fca2b23d0ba 4065 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
marcozecchini 0:9fca2b23d0ba 4066 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
marcozecchini 0:9fca2b23d0ba 4067 {
marcozecchini 0:9fca2b23d0ba 4068 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
marcozecchini 0:9fca2b23d0ba 4069 return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
marcozecchini 0:9fca2b23d0ba 4070 }
marcozecchini 0:9fca2b23d0ba 4071
marcozecchini 0:9fca2b23d0ba 4072 #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
marcozecchini 0:9fca2b23d0ba 4073 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
marcozecchini 0:9fca2b23d0ba 4074 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
marcozecchini 0:9fca2b23d0ba 4075 {
marcozecchini 0:9fca2b23d0ba 4076 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
marcozecchini 0:9fca2b23d0ba 4077 /* Will be handled when trying to parse ServerHello */
marcozecchini 0:9fca2b23d0ba 4078 return( 0 );
marcozecchini 0:9fca2b23d0ba 4079 }
marcozecchini 0:9fca2b23d0ba 4080 #endif
marcozecchini 0:9fca2b23d0ba 4081
marcozecchini 0:9fca2b23d0ba 4082 #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 4083 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
marcozecchini 0:9fca2b23d0ba 4084 ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 4085 ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
marcozecchini 0:9fca2b23d0ba 4086 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
marcozecchini 0:9fca2b23d0ba 4087 {
marcozecchini 0:9fca2b23d0ba 4088 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
marcozecchini 0:9fca2b23d0ba 4089 /* Will be handled in mbedtls_ssl_parse_certificate() */
marcozecchini 0:9fca2b23d0ba 4090 return( 0 );
marcozecchini 0:9fca2b23d0ba 4091 }
marcozecchini 0:9fca2b23d0ba 4092 #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 4093
marcozecchini 0:9fca2b23d0ba 4094 /* Silently ignore: fetch new message */
marcozecchini 0:9fca2b23d0ba 4095 return MBEDTLS_ERR_SSL_NON_FATAL;
marcozecchini 0:9fca2b23d0ba 4096 }
marcozecchini 0:9fca2b23d0ba 4097
marcozecchini 0:9fca2b23d0ba 4098 return( 0 );
marcozecchini 0:9fca2b23d0ba 4099 }
marcozecchini 0:9fca2b23d0ba 4100
marcozecchini 0:9fca2b23d0ba 4101 int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4102 {
marcozecchini 0:9fca2b23d0ba 4103 int ret;
marcozecchini 0:9fca2b23d0ba 4104
marcozecchini 0:9fca2b23d0ba 4105 if( ( ret = mbedtls_ssl_send_alert_message( ssl,
marcozecchini 0:9fca2b23d0ba 4106 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4107 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4108 {
marcozecchini 0:9fca2b23d0ba 4109 return( ret );
marcozecchini 0:9fca2b23d0ba 4110 }
marcozecchini 0:9fca2b23d0ba 4111
marcozecchini 0:9fca2b23d0ba 4112 return( 0 );
marcozecchini 0:9fca2b23d0ba 4113 }
marcozecchini 0:9fca2b23d0ba 4114
marcozecchini 0:9fca2b23d0ba 4115 int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 4116 unsigned char level,
marcozecchini 0:9fca2b23d0ba 4117 unsigned char message )
marcozecchini 0:9fca2b23d0ba 4118 {
marcozecchini 0:9fca2b23d0ba 4119 int ret;
marcozecchini 0:9fca2b23d0ba 4120
marcozecchini 0:9fca2b23d0ba 4121 if( ssl == NULL || ssl->conf == NULL )
marcozecchini 0:9fca2b23d0ba 4122 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 4123
marcozecchini 0:9fca2b23d0ba 4124 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
marcozecchini 0:9fca2b23d0ba 4125 MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
marcozecchini 0:9fca2b23d0ba 4126
marcozecchini 0:9fca2b23d0ba 4127 ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
marcozecchini 0:9fca2b23d0ba 4128 ssl->out_msglen = 2;
marcozecchini 0:9fca2b23d0ba 4129 ssl->out_msg[0] = level;
marcozecchini 0:9fca2b23d0ba 4130 ssl->out_msg[1] = message;
marcozecchini 0:9fca2b23d0ba 4131
marcozecchini 0:9fca2b23d0ba 4132 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4133 {
marcozecchini 0:9fca2b23d0ba 4134 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
marcozecchini 0:9fca2b23d0ba 4135 return( ret );
marcozecchini 0:9fca2b23d0ba 4136 }
marcozecchini 0:9fca2b23d0ba 4137 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
marcozecchini 0:9fca2b23d0ba 4138
marcozecchini 0:9fca2b23d0ba 4139 return( 0 );
marcozecchini 0:9fca2b23d0ba 4140 }
marcozecchini 0:9fca2b23d0ba 4141
marcozecchini 0:9fca2b23d0ba 4142 /*
marcozecchini 0:9fca2b23d0ba 4143 * Handshake functions
marcozecchini 0:9fca2b23d0ba 4144 */
marcozecchini 0:9fca2b23d0ba 4145 #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
marcozecchini 0:9fca2b23d0ba 4146 !defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
marcozecchini 0:9fca2b23d0ba 4147 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
marcozecchini 0:9fca2b23d0ba 4148 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
marcozecchini 0:9fca2b23d0ba 4149 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
marcozecchini 0:9fca2b23d0ba 4150 !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
marcozecchini 0:9fca2b23d0ba 4151 !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
marcozecchini 0:9fca2b23d0ba 4152 /* No certificate support -> dummy functions */
marcozecchini 0:9fca2b23d0ba 4153 int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4154 {
marcozecchini 0:9fca2b23d0ba 4155 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
marcozecchini 0:9fca2b23d0ba 4156
marcozecchini 0:9fca2b23d0ba 4157 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
marcozecchini 0:9fca2b23d0ba 4158
marcozecchini 0:9fca2b23d0ba 4159 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
marcozecchini 0:9fca2b23d0ba 4160 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
marcozecchini 0:9fca2b23d0ba 4161 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
marcozecchini 0:9fca2b23d0ba 4162 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
marcozecchini 0:9fca2b23d0ba 4163 {
marcozecchini 0:9fca2b23d0ba 4164 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
marcozecchini 0:9fca2b23d0ba 4165 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4166 return( 0 );
marcozecchini 0:9fca2b23d0ba 4167 }
marcozecchini 0:9fca2b23d0ba 4168
marcozecchini 0:9fca2b23d0ba 4169 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 4170 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 4171 }
marcozecchini 0:9fca2b23d0ba 4172
marcozecchini 0:9fca2b23d0ba 4173 int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4174 {
marcozecchini 0:9fca2b23d0ba 4175 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
marcozecchini 0:9fca2b23d0ba 4176
marcozecchini 0:9fca2b23d0ba 4177 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
marcozecchini 0:9fca2b23d0ba 4178
marcozecchini 0:9fca2b23d0ba 4179 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
marcozecchini 0:9fca2b23d0ba 4180 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
marcozecchini 0:9fca2b23d0ba 4181 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
marcozecchini 0:9fca2b23d0ba 4182 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
marcozecchini 0:9fca2b23d0ba 4183 {
marcozecchini 0:9fca2b23d0ba 4184 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
marcozecchini 0:9fca2b23d0ba 4185 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4186 return( 0 );
marcozecchini 0:9fca2b23d0ba 4187 }
marcozecchini 0:9fca2b23d0ba 4188
marcozecchini 0:9fca2b23d0ba 4189 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 4190 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 4191 }
marcozecchini 0:9fca2b23d0ba 4192
marcozecchini 0:9fca2b23d0ba 4193 #else
marcozecchini 0:9fca2b23d0ba 4194 /* Some certificate support -> implement write and parse */
marcozecchini 0:9fca2b23d0ba 4195
marcozecchini 0:9fca2b23d0ba 4196 int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4197 {
marcozecchini 0:9fca2b23d0ba 4198 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
marcozecchini 0:9fca2b23d0ba 4199 size_t i, n;
marcozecchini 0:9fca2b23d0ba 4200 const mbedtls_x509_crt *crt;
marcozecchini 0:9fca2b23d0ba 4201 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
marcozecchini 0:9fca2b23d0ba 4202
marcozecchini 0:9fca2b23d0ba 4203 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
marcozecchini 0:9fca2b23d0ba 4204
marcozecchini 0:9fca2b23d0ba 4205 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
marcozecchini 0:9fca2b23d0ba 4206 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
marcozecchini 0:9fca2b23d0ba 4207 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
marcozecchini 0:9fca2b23d0ba 4208 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
marcozecchini 0:9fca2b23d0ba 4209 {
marcozecchini 0:9fca2b23d0ba 4210 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
marcozecchini 0:9fca2b23d0ba 4211 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4212 return( 0 );
marcozecchini 0:9fca2b23d0ba 4213 }
marcozecchini 0:9fca2b23d0ba 4214
marcozecchini 0:9fca2b23d0ba 4215 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 4216 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 4217 {
marcozecchini 0:9fca2b23d0ba 4218 if( ssl->client_auth == 0 )
marcozecchini 0:9fca2b23d0ba 4219 {
marcozecchini 0:9fca2b23d0ba 4220 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
marcozecchini 0:9fca2b23d0ba 4221 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4222 return( 0 );
marcozecchini 0:9fca2b23d0ba 4223 }
marcozecchini 0:9fca2b23d0ba 4224
marcozecchini 0:9fca2b23d0ba 4225 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 4226 /*
marcozecchini 0:9fca2b23d0ba 4227 * If using SSLv3 and got no cert, send an Alert message
marcozecchini 0:9fca2b23d0ba 4228 * (otherwise an empty Certificate message will be sent).
marcozecchini 0:9fca2b23d0ba 4229 */
marcozecchini 0:9fca2b23d0ba 4230 if( mbedtls_ssl_own_cert( ssl ) == NULL &&
marcozecchini 0:9fca2b23d0ba 4231 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 4232 {
marcozecchini 0:9fca2b23d0ba 4233 ssl->out_msglen = 2;
marcozecchini 0:9fca2b23d0ba 4234 ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
marcozecchini 0:9fca2b23d0ba 4235 ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING;
marcozecchini 0:9fca2b23d0ba 4236 ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT;
marcozecchini 0:9fca2b23d0ba 4237
marcozecchini 0:9fca2b23d0ba 4238 MBEDTLS_SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) );
marcozecchini 0:9fca2b23d0ba 4239 goto write_msg;
marcozecchini 0:9fca2b23d0ba 4240 }
marcozecchini 0:9fca2b23d0ba 4241 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 4242 }
marcozecchini 0:9fca2b23d0ba 4243 #endif /* MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 4244 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 4245 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 4246 {
marcozecchini 0:9fca2b23d0ba 4247 if( mbedtls_ssl_own_cert( ssl ) == NULL )
marcozecchini 0:9fca2b23d0ba 4248 {
marcozecchini 0:9fca2b23d0ba 4249 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) );
marcozecchini 0:9fca2b23d0ba 4250 return( MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED );
marcozecchini 0:9fca2b23d0ba 4251 }
marcozecchini 0:9fca2b23d0ba 4252 }
marcozecchini 0:9fca2b23d0ba 4253 #endif
marcozecchini 0:9fca2b23d0ba 4254
marcozecchini 0:9fca2b23d0ba 4255 MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) );
marcozecchini 0:9fca2b23d0ba 4256
marcozecchini 0:9fca2b23d0ba 4257 /*
marcozecchini 0:9fca2b23d0ba 4258 * 0 . 0 handshake type
marcozecchini 0:9fca2b23d0ba 4259 * 1 . 3 handshake length
marcozecchini 0:9fca2b23d0ba 4260 * 4 . 6 length of all certs
marcozecchini 0:9fca2b23d0ba 4261 * 7 . 9 length of cert. 1
marcozecchini 0:9fca2b23d0ba 4262 * 10 . n-1 peer certificate
marcozecchini 0:9fca2b23d0ba 4263 * n . n+2 length of cert. 2
marcozecchini 0:9fca2b23d0ba 4264 * n+3 . ... upper level cert, etc.
marcozecchini 0:9fca2b23d0ba 4265 */
marcozecchini 0:9fca2b23d0ba 4266 i = 7;
marcozecchini 0:9fca2b23d0ba 4267 crt = mbedtls_ssl_own_cert( ssl );
marcozecchini 0:9fca2b23d0ba 4268
marcozecchini 0:9fca2b23d0ba 4269 while( crt != NULL )
marcozecchini 0:9fca2b23d0ba 4270 {
marcozecchini 0:9fca2b23d0ba 4271 n = crt->raw.len;
marcozecchini 0:9fca2b23d0ba 4272 if( n > MBEDTLS_SSL_MAX_CONTENT_LEN - 3 - i )
marcozecchini 0:9fca2b23d0ba 4273 {
marcozecchini 0:9fca2b23d0ba 4274 MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d",
marcozecchini 0:9fca2b23d0ba 4275 i + 3 + n, MBEDTLS_SSL_MAX_CONTENT_LEN ) );
marcozecchini 0:9fca2b23d0ba 4276 return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE );
marcozecchini 0:9fca2b23d0ba 4277 }
marcozecchini 0:9fca2b23d0ba 4278
marcozecchini 0:9fca2b23d0ba 4279 ssl->out_msg[i ] = (unsigned char)( n >> 16 );
marcozecchini 0:9fca2b23d0ba 4280 ssl->out_msg[i + 1] = (unsigned char)( n >> 8 );
marcozecchini 0:9fca2b23d0ba 4281 ssl->out_msg[i + 2] = (unsigned char)( n );
marcozecchini 0:9fca2b23d0ba 4282
marcozecchini 0:9fca2b23d0ba 4283 i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
marcozecchini 0:9fca2b23d0ba 4284 i += n; crt = crt->next;
marcozecchini 0:9fca2b23d0ba 4285 }
marcozecchini 0:9fca2b23d0ba 4286
marcozecchini 0:9fca2b23d0ba 4287 ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 );
marcozecchini 0:9fca2b23d0ba 4288 ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 );
marcozecchini 0:9fca2b23d0ba 4289 ssl->out_msg[6] = (unsigned char)( ( i - 7 ) );
marcozecchini 0:9fca2b23d0ba 4290
marcozecchini 0:9fca2b23d0ba 4291 ssl->out_msglen = i;
marcozecchini 0:9fca2b23d0ba 4292 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
marcozecchini 0:9fca2b23d0ba 4293 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE;
marcozecchini 0:9fca2b23d0ba 4294
marcozecchini 0:9fca2b23d0ba 4295 #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 4296 write_msg:
marcozecchini 0:9fca2b23d0ba 4297 #endif
marcozecchini 0:9fca2b23d0ba 4298
marcozecchini 0:9fca2b23d0ba 4299 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4300
marcozecchini 0:9fca2b23d0ba 4301 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4302 {
marcozecchini 0:9fca2b23d0ba 4303 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
marcozecchini 0:9fca2b23d0ba 4304 return( ret );
marcozecchini 0:9fca2b23d0ba 4305 }
marcozecchini 0:9fca2b23d0ba 4306
marcozecchini 0:9fca2b23d0ba 4307 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) );
marcozecchini 0:9fca2b23d0ba 4308
marcozecchini 0:9fca2b23d0ba 4309 return( ret );
marcozecchini 0:9fca2b23d0ba 4310 }
marcozecchini 0:9fca2b23d0ba 4311
marcozecchini 0:9fca2b23d0ba 4312 int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4313 {
marcozecchini 0:9fca2b23d0ba 4314 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
marcozecchini 0:9fca2b23d0ba 4315 size_t i, n;
marcozecchini 0:9fca2b23d0ba 4316 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
marcozecchini 0:9fca2b23d0ba 4317 int authmode = ssl->conf->authmode;
marcozecchini 0:9fca2b23d0ba 4318 uint8_t alert;
marcozecchini 0:9fca2b23d0ba 4319
marcozecchini 0:9fca2b23d0ba 4320 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
marcozecchini 0:9fca2b23d0ba 4321
marcozecchini 0:9fca2b23d0ba 4322 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
marcozecchini 0:9fca2b23d0ba 4323 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
marcozecchini 0:9fca2b23d0ba 4324 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
marcozecchini 0:9fca2b23d0ba 4325 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
marcozecchini 0:9fca2b23d0ba 4326 {
marcozecchini 0:9fca2b23d0ba 4327 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
marcozecchini 0:9fca2b23d0ba 4328 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4329 return( 0 );
marcozecchini 0:9fca2b23d0ba 4330 }
marcozecchini 0:9fca2b23d0ba 4331
marcozecchini 0:9fca2b23d0ba 4332 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 4333 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 4334 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
marcozecchini 0:9fca2b23d0ba 4335 {
marcozecchini 0:9fca2b23d0ba 4336 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
marcozecchini 0:9fca2b23d0ba 4337 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4338 return( 0 );
marcozecchini 0:9fca2b23d0ba 4339 }
marcozecchini 0:9fca2b23d0ba 4340
marcozecchini 0:9fca2b23d0ba 4341 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
marcozecchini 0:9fca2b23d0ba 4342 if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET )
marcozecchini 0:9fca2b23d0ba 4343 authmode = ssl->handshake->sni_authmode;
marcozecchini 0:9fca2b23d0ba 4344 #endif
marcozecchini 0:9fca2b23d0ba 4345
marcozecchini 0:9fca2b23d0ba 4346 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 4347 authmode == MBEDTLS_SSL_VERIFY_NONE )
marcozecchini 0:9fca2b23d0ba 4348 {
marcozecchini 0:9fca2b23d0ba 4349 ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY;
marcozecchini 0:9fca2b23d0ba 4350 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
marcozecchini 0:9fca2b23d0ba 4351 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4352 return( 0 );
marcozecchini 0:9fca2b23d0ba 4353 }
marcozecchini 0:9fca2b23d0ba 4354 #endif
marcozecchini 0:9fca2b23d0ba 4355
marcozecchini 0:9fca2b23d0ba 4356 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4357 {
marcozecchini 0:9fca2b23d0ba 4358 /* mbedtls_ssl_read_record may have sent an alert already. We
marcozecchini 0:9fca2b23d0ba 4359 let it decide whether to alert. */
marcozecchini 0:9fca2b23d0ba 4360 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
marcozecchini 0:9fca2b23d0ba 4361 return( ret );
marcozecchini 0:9fca2b23d0ba 4362 }
marcozecchini 0:9fca2b23d0ba 4363
marcozecchini 0:9fca2b23d0ba 4364 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4365
marcozecchini 0:9fca2b23d0ba 4366 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 4367 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 4368 /*
marcozecchini 0:9fca2b23d0ba 4369 * Check if the client sent an empty certificate
marcozecchini 0:9fca2b23d0ba 4370 */
marcozecchini 0:9fca2b23d0ba 4371 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 4372 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 4373 {
marcozecchini 0:9fca2b23d0ba 4374 if( ssl->in_msglen == 2 &&
marcozecchini 0:9fca2b23d0ba 4375 ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
marcozecchini 0:9fca2b23d0ba 4376 ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
marcozecchini 0:9fca2b23d0ba 4377 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
marcozecchini 0:9fca2b23d0ba 4378 {
marcozecchini 0:9fca2b23d0ba 4379 MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
marcozecchini 0:9fca2b23d0ba 4380
marcozecchini 0:9fca2b23d0ba 4381 /* The client was asked for a certificate but didn't send
marcozecchini 0:9fca2b23d0ba 4382 one. The client should know what's going on, so we
marcozecchini 0:9fca2b23d0ba 4383 don't send an alert. */
marcozecchini 0:9fca2b23d0ba 4384 ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
marcozecchini 0:9fca2b23d0ba 4385 if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
marcozecchini 0:9fca2b23d0ba 4386 return( 0 );
marcozecchini 0:9fca2b23d0ba 4387 else
marcozecchini 0:9fca2b23d0ba 4388 return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
marcozecchini 0:9fca2b23d0ba 4389 }
marcozecchini 0:9fca2b23d0ba 4390 }
marcozecchini 0:9fca2b23d0ba 4391 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 4392
marcozecchini 0:9fca2b23d0ba 4393 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
marcozecchini 0:9fca2b23d0ba 4394 defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 4395 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 4396 ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 4397 {
marcozecchini 0:9fca2b23d0ba 4398 if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
marcozecchini 0:9fca2b23d0ba 4399 ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
marcozecchini 0:9fca2b23d0ba 4400 ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
marcozecchini 0:9fca2b23d0ba 4401 memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
marcozecchini 0:9fca2b23d0ba 4402 {
marcozecchini 0:9fca2b23d0ba 4403 MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
marcozecchini 0:9fca2b23d0ba 4404
marcozecchini 0:9fca2b23d0ba 4405 /* The client was asked for a certificate but didn't send
marcozecchini 0:9fca2b23d0ba 4406 one. The client should know what's going on, so we
marcozecchini 0:9fca2b23d0ba 4407 don't send an alert. */
marcozecchini 0:9fca2b23d0ba 4408 ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
marcozecchini 0:9fca2b23d0ba 4409 if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
marcozecchini 0:9fca2b23d0ba 4410 return( 0 );
marcozecchini 0:9fca2b23d0ba 4411 else
marcozecchini 0:9fca2b23d0ba 4412 return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
marcozecchini 0:9fca2b23d0ba 4413 }
marcozecchini 0:9fca2b23d0ba 4414 }
marcozecchini 0:9fca2b23d0ba 4415 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
marcozecchini 0:9fca2b23d0ba 4416 MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 4417 #endif /* MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 4418
marcozecchini 0:9fca2b23d0ba 4419 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
marcozecchini 0:9fca2b23d0ba 4420 {
marcozecchini 0:9fca2b23d0ba 4421 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
marcozecchini 0:9fca2b23d0ba 4422 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4423 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 4424 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 4425 }
marcozecchini 0:9fca2b23d0ba 4426
marcozecchini 0:9fca2b23d0ba 4427 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE ||
marcozecchini 0:9fca2b23d0ba 4428 ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
marcozecchini 0:9fca2b23d0ba 4429 {
marcozecchini 0:9fca2b23d0ba 4430 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
marcozecchini 0:9fca2b23d0ba 4431 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4432 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
marcozecchini 0:9fca2b23d0ba 4433 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
marcozecchini 0:9fca2b23d0ba 4434 }
marcozecchini 0:9fca2b23d0ba 4435
marcozecchini 0:9fca2b23d0ba 4436 i = mbedtls_ssl_hs_hdr_len( ssl );
marcozecchini 0:9fca2b23d0ba 4437
marcozecchini 0:9fca2b23d0ba 4438 /*
marcozecchini 0:9fca2b23d0ba 4439 * Same message structure as in mbedtls_ssl_write_certificate()
marcozecchini 0:9fca2b23d0ba 4440 */
marcozecchini 0:9fca2b23d0ba 4441 n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2];
marcozecchini 0:9fca2b23d0ba 4442
marcozecchini 0:9fca2b23d0ba 4443 if( ssl->in_msg[i] != 0 ||
marcozecchini 0:9fca2b23d0ba 4444 ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) )
marcozecchini 0:9fca2b23d0ba 4445 {
marcozecchini 0:9fca2b23d0ba 4446 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
marcozecchini 0:9fca2b23d0ba 4447 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4448 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
marcozecchini 0:9fca2b23d0ba 4449 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
marcozecchini 0:9fca2b23d0ba 4450 }
marcozecchini 0:9fca2b23d0ba 4451
marcozecchini 0:9fca2b23d0ba 4452 /* In case we tried to reuse a session but it failed */
marcozecchini 0:9fca2b23d0ba 4453 if( ssl->session_negotiate->peer_cert != NULL )
marcozecchini 0:9fca2b23d0ba 4454 {
marcozecchini 0:9fca2b23d0ba 4455 mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert );
marcozecchini 0:9fca2b23d0ba 4456 mbedtls_free( ssl->session_negotiate->peer_cert );
marcozecchini 0:9fca2b23d0ba 4457 }
marcozecchini 0:9fca2b23d0ba 4458
marcozecchini 0:9fca2b23d0ba 4459 if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1,
marcozecchini 0:9fca2b23d0ba 4460 sizeof( mbedtls_x509_crt ) ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 4461 {
marcozecchini 0:9fca2b23d0ba 4462 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
marcozecchini 0:9fca2b23d0ba 4463 sizeof( mbedtls_x509_crt ) ) );
marcozecchini 0:9fca2b23d0ba 4464 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4465 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 4466 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 4467 }
marcozecchini 0:9fca2b23d0ba 4468
marcozecchini 0:9fca2b23d0ba 4469 mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert );
marcozecchini 0:9fca2b23d0ba 4470
marcozecchini 0:9fca2b23d0ba 4471 i += 3;
marcozecchini 0:9fca2b23d0ba 4472
marcozecchini 0:9fca2b23d0ba 4473 while( i < ssl->in_hslen )
marcozecchini 0:9fca2b23d0ba 4474 {
marcozecchini 0:9fca2b23d0ba 4475 if( ssl->in_msg[i] != 0 )
marcozecchini 0:9fca2b23d0ba 4476 {
marcozecchini 0:9fca2b23d0ba 4477 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
marcozecchini 0:9fca2b23d0ba 4478 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4479 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
marcozecchini 0:9fca2b23d0ba 4480 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
marcozecchini 0:9fca2b23d0ba 4481 }
marcozecchini 0:9fca2b23d0ba 4482
marcozecchini 0:9fca2b23d0ba 4483 n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
marcozecchini 0:9fca2b23d0ba 4484 | (unsigned int) ssl->in_msg[i + 2];
marcozecchini 0:9fca2b23d0ba 4485 i += 3;
marcozecchini 0:9fca2b23d0ba 4486
marcozecchini 0:9fca2b23d0ba 4487 if( n < 128 || i + n > ssl->in_hslen )
marcozecchini 0:9fca2b23d0ba 4488 {
marcozecchini 0:9fca2b23d0ba 4489 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
marcozecchini 0:9fca2b23d0ba 4490 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4491 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
marcozecchini 0:9fca2b23d0ba 4492 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
marcozecchini 0:9fca2b23d0ba 4493 }
marcozecchini 0:9fca2b23d0ba 4494
marcozecchini 0:9fca2b23d0ba 4495 ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert,
marcozecchini 0:9fca2b23d0ba 4496 ssl->in_msg + i, n );
marcozecchini 0:9fca2b23d0ba 4497 switch( ret )
marcozecchini 0:9fca2b23d0ba 4498 {
marcozecchini 0:9fca2b23d0ba 4499 case 0: /*ok*/
marcozecchini 0:9fca2b23d0ba 4500 case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
marcozecchini 0:9fca2b23d0ba 4501 /* Ignore certificate with an unknown algorithm: maybe a
marcozecchini 0:9fca2b23d0ba 4502 prior certificate was already trusted. */
marcozecchini 0:9fca2b23d0ba 4503 break;
marcozecchini 0:9fca2b23d0ba 4504
marcozecchini 0:9fca2b23d0ba 4505 case MBEDTLS_ERR_X509_ALLOC_FAILED:
marcozecchini 0:9fca2b23d0ba 4506 alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
marcozecchini 0:9fca2b23d0ba 4507 goto crt_parse_der_failed;
marcozecchini 0:9fca2b23d0ba 4508
marcozecchini 0:9fca2b23d0ba 4509 case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
marcozecchini 0:9fca2b23d0ba 4510 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
marcozecchini 0:9fca2b23d0ba 4511 goto crt_parse_der_failed;
marcozecchini 0:9fca2b23d0ba 4512
marcozecchini 0:9fca2b23d0ba 4513 default:
marcozecchini 0:9fca2b23d0ba 4514 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
marcozecchini 0:9fca2b23d0ba 4515 crt_parse_der_failed:
marcozecchini 0:9fca2b23d0ba 4516 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
marcozecchini 0:9fca2b23d0ba 4517 MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
marcozecchini 0:9fca2b23d0ba 4518 return( ret );
marcozecchini 0:9fca2b23d0ba 4519 }
marcozecchini 0:9fca2b23d0ba 4520
marcozecchini 0:9fca2b23d0ba 4521 i += n;
marcozecchini 0:9fca2b23d0ba 4522 }
marcozecchini 0:9fca2b23d0ba 4523
marcozecchini 0:9fca2b23d0ba 4524 MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert );
marcozecchini 0:9fca2b23d0ba 4525
marcozecchini 0:9fca2b23d0ba 4526 /*
marcozecchini 0:9fca2b23d0ba 4527 * On client, make sure the server cert doesn't change during renego to
marcozecchini 0:9fca2b23d0ba 4528 * avoid "triple handshake" attack: https://secure-resumption.com/
marcozecchini 0:9fca2b23d0ba 4529 */
marcozecchini 0:9fca2b23d0ba 4530 #if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 4531 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
marcozecchini 0:9fca2b23d0ba 4532 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
marcozecchini 0:9fca2b23d0ba 4533 {
marcozecchini 0:9fca2b23d0ba 4534 if( ssl->session->peer_cert == NULL )
marcozecchini 0:9fca2b23d0ba 4535 {
marcozecchini 0:9fca2b23d0ba 4536 MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
marcozecchini 0:9fca2b23d0ba 4537 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4538 MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
marcozecchini 0:9fca2b23d0ba 4539 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
marcozecchini 0:9fca2b23d0ba 4540 }
marcozecchini 0:9fca2b23d0ba 4541
marcozecchini 0:9fca2b23d0ba 4542 if( ssl->session->peer_cert->raw.len !=
marcozecchini 0:9fca2b23d0ba 4543 ssl->session_negotiate->peer_cert->raw.len ||
marcozecchini 0:9fca2b23d0ba 4544 memcmp( ssl->session->peer_cert->raw.p,
marcozecchini 0:9fca2b23d0ba 4545 ssl->session_negotiate->peer_cert->raw.p,
marcozecchini 0:9fca2b23d0ba 4546 ssl->session->peer_cert->raw.len ) != 0 )
marcozecchini 0:9fca2b23d0ba 4547 {
marcozecchini 0:9fca2b23d0ba 4548 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) );
marcozecchini 0:9fca2b23d0ba 4549 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4550 MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
marcozecchini 0:9fca2b23d0ba 4551 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
marcozecchini 0:9fca2b23d0ba 4552 }
marcozecchini 0:9fca2b23d0ba 4553 }
marcozecchini 0:9fca2b23d0ba 4554 #endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 4555
marcozecchini 0:9fca2b23d0ba 4556 if( authmode != MBEDTLS_SSL_VERIFY_NONE )
marcozecchini 0:9fca2b23d0ba 4557 {
marcozecchini 0:9fca2b23d0ba 4558 mbedtls_x509_crt *ca_chain;
marcozecchini 0:9fca2b23d0ba 4559 mbedtls_x509_crl *ca_crl;
marcozecchini 0:9fca2b23d0ba 4560
marcozecchini 0:9fca2b23d0ba 4561 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
marcozecchini 0:9fca2b23d0ba 4562 if( ssl->handshake->sni_ca_chain != NULL )
marcozecchini 0:9fca2b23d0ba 4563 {
marcozecchini 0:9fca2b23d0ba 4564 ca_chain = ssl->handshake->sni_ca_chain;
marcozecchini 0:9fca2b23d0ba 4565 ca_crl = ssl->handshake->sni_ca_crl;
marcozecchini 0:9fca2b23d0ba 4566 }
marcozecchini 0:9fca2b23d0ba 4567 else
marcozecchini 0:9fca2b23d0ba 4568 #endif
marcozecchini 0:9fca2b23d0ba 4569 {
marcozecchini 0:9fca2b23d0ba 4570 ca_chain = ssl->conf->ca_chain;
marcozecchini 0:9fca2b23d0ba 4571 ca_crl = ssl->conf->ca_crl;
marcozecchini 0:9fca2b23d0ba 4572 }
marcozecchini 0:9fca2b23d0ba 4573
marcozecchini 0:9fca2b23d0ba 4574 /*
marcozecchini 0:9fca2b23d0ba 4575 * Main check: verify certificate
marcozecchini 0:9fca2b23d0ba 4576 */
marcozecchini 0:9fca2b23d0ba 4577 ret = mbedtls_x509_crt_verify_with_profile(
marcozecchini 0:9fca2b23d0ba 4578 ssl->session_negotiate->peer_cert,
marcozecchini 0:9fca2b23d0ba 4579 ca_chain, ca_crl,
marcozecchini 0:9fca2b23d0ba 4580 ssl->conf->cert_profile,
marcozecchini 0:9fca2b23d0ba 4581 ssl->hostname,
marcozecchini 0:9fca2b23d0ba 4582 &ssl->session_negotiate->verify_result,
marcozecchini 0:9fca2b23d0ba 4583 ssl->conf->f_vrfy, ssl->conf->p_vrfy );
marcozecchini 0:9fca2b23d0ba 4584
marcozecchini 0:9fca2b23d0ba 4585 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 4586 {
marcozecchini 0:9fca2b23d0ba 4587 MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
marcozecchini 0:9fca2b23d0ba 4588 }
marcozecchini 0:9fca2b23d0ba 4589
marcozecchini 0:9fca2b23d0ba 4590 /*
marcozecchini 0:9fca2b23d0ba 4591 * Secondary checks: always done, but change 'ret' only if it was 0
marcozecchini 0:9fca2b23d0ba 4592 */
marcozecchini 0:9fca2b23d0ba 4593
marcozecchini 0:9fca2b23d0ba 4594 #if defined(MBEDTLS_ECP_C)
marcozecchini 0:9fca2b23d0ba 4595 {
marcozecchini 0:9fca2b23d0ba 4596 const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk;
marcozecchini 0:9fca2b23d0ba 4597
marcozecchini 0:9fca2b23d0ba 4598 /* If certificate uses an EC key, make sure the curve is OK */
marcozecchini 0:9fca2b23d0ba 4599 if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
marcozecchini 0:9fca2b23d0ba 4600 mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
marcozecchini 0:9fca2b23d0ba 4601 {
marcozecchini 0:9fca2b23d0ba 4602 ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
marcozecchini 0:9fca2b23d0ba 4603
marcozecchini 0:9fca2b23d0ba 4604 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
marcozecchini 0:9fca2b23d0ba 4605 if( ret == 0 )
marcozecchini 0:9fca2b23d0ba 4606 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
marcozecchini 0:9fca2b23d0ba 4607 }
marcozecchini 0:9fca2b23d0ba 4608 }
marcozecchini 0:9fca2b23d0ba 4609 #endif /* MBEDTLS_ECP_C */
marcozecchini 0:9fca2b23d0ba 4610
marcozecchini 0:9fca2b23d0ba 4611 if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
marcozecchini 0:9fca2b23d0ba 4612 ciphersuite_info,
marcozecchini 0:9fca2b23d0ba 4613 ! ssl->conf->endpoint,
marcozecchini 0:9fca2b23d0ba 4614 &ssl->session_negotiate->verify_result ) != 0 )
marcozecchini 0:9fca2b23d0ba 4615 {
marcozecchini 0:9fca2b23d0ba 4616 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
marcozecchini 0:9fca2b23d0ba 4617 if( ret == 0 )
marcozecchini 0:9fca2b23d0ba 4618 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
marcozecchini 0:9fca2b23d0ba 4619 }
marcozecchini 0:9fca2b23d0ba 4620
marcozecchini 0:9fca2b23d0ba 4621 /* mbedtls_x509_crt_verify_with_profile is supposed to report a
marcozecchini 0:9fca2b23d0ba 4622 * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
marcozecchini 0:9fca2b23d0ba 4623 * with details encoded in the verification flags. All other kinds
marcozecchini 0:9fca2b23d0ba 4624 * of error codes, including those from the user provided f_vrfy
marcozecchini 0:9fca2b23d0ba 4625 * functions, are treated as fatal and lead to a failure of
marcozecchini 0:9fca2b23d0ba 4626 * ssl_parse_certificate even if verification was optional. */
marcozecchini 0:9fca2b23d0ba 4627 if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
marcozecchini 0:9fca2b23d0ba 4628 ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
marcozecchini 0:9fca2b23d0ba 4629 ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
marcozecchini 0:9fca2b23d0ba 4630 {
marcozecchini 0:9fca2b23d0ba 4631 ret = 0;
marcozecchini 0:9fca2b23d0ba 4632 }
marcozecchini 0:9fca2b23d0ba 4633
marcozecchini 0:9fca2b23d0ba 4634 if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
marcozecchini 0:9fca2b23d0ba 4635 {
marcozecchini 0:9fca2b23d0ba 4636 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
marcozecchini 0:9fca2b23d0ba 4637 ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
marcozecchini 0:9fca2b23d0ba 4638 }
marcozecchini 0:9fca2b23d0ba 4639
marcozecchini 0:9fca2b23d0ba 4640 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 4641 {
marcozecchini 0:9fca2b23d0ba 4642 /* The certificate may have been rejected for several reasons.
marcozecchini 0:9fca2b23d0ba 4643 Pick one and send the corresponding alert. Which alert to send
marcozecchini 0:9fca2b23d0ba 4644 may be a subject of debate in some cases. */
marcozecchini 0:9fca2b23d0ba 4645 if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
marcozecchini 0:9fca2b23d0ba 4646 alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
marcozecchini 0:9fca2b23d0ba 4647 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
marcozecchini 0:9fca2b23d0ba 4648 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
marcozecchini 0:9fca2b23d0ba 4649 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
marcozecchini 0:9fca2b23d0ba 4650 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
marcozecchini 0:9fca2b23d0ba 4651 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
marcozecchini 0:9fca2b23d0ba 4652 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
marcozecchini 0:9fca2b23d0ba 4653 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
marcozecchini 0:9fca2b23d0ba 4654 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
marcozecchini 0:9fca2b23d0ba 4655 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
marcozecchini 0:9fca2b23d0ba 4656 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
marcozecchini 0:9fca2b23d0ba 4657 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
marcozecchini 0:9fca2b23d0ba 4658 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
marcozecchini 0:9fca2b23d0ba 4659 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
marcozecchini 0:9fca2b23d0ba 4660 alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
marcozecchini 0:9fca2b23d0ba 4661 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
marcozecchini 0:9fca2b23d0ba 4662 alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
marcozecchini 0:9fca2b23d0ba 4663 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
marcozecchini 0:9fca2b23d0ba 4664 alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
marcozecchini 0:9fca2b23d0ba 4665 else
marcozecchini 0:9fca2b23d0ba 4666 alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
marcozecchini 0:9fca2b23d0ba 4667 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4668 alert );
marcozecchini 0:9fca2b23d0ba 4669 }
marcozecchini 0:9fca2b23d0ba 4670
marcozecchini 0:9fca2b23d0ba 4671 #if defined(MBEDTLS_DEBUG_C)
marcozecchini 0:9fca2b23d0ba 4672 if( ssl->session_negotiate->verify_result != 0 )
marcozecchini 0:9fca2b23d0ba 4673 {
marcozecchini 0:9fca2b23d0ba 4674 MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x",
marcozecchini 0:9fca2b23d0ba 4675 ssl->session_negotiate->verify_result ) );
marcozecchini 0:9fca2b23d0ba 4676 }
marcozecchini 0:9fca2b23d0ba 4677 else
marcozecchini 0:9fca2b23d0ba 4678 {
marcozecchini 0:9fca2b23d0ba 4679 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
marcozecchini 0:9fca2b23d0ba 4680 }
marcozecchini 0:9fca2b23d0ba 4681 #endif /* MBEDTLS_DEBUG_C */
marcozecchini 0:9fca2b23d0ba 4682 }
marcozecchini 0:9fca2b23d0ba 4683
marcozecchini 0:9fca2b23d0ba 4684 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
marcozecchini 0:9fca2b23d0ba 4685
marcozecchini 0:9fca2b23d0ba 4686 return( ret );
marcozecchini 0:9fca2b23d0ba 4687 }
marcozecchini 0:9fca2b23d0ba 4688 #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
marcozecchini 0:9fca2b23d0ba 4689 !MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
marcozecchini 0:9fca2b23d0ba 4690 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
marcozecchini 0:9fca2b23d0ba 4691 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
marcozecchini 0:9fca2b23d0ba 4692 !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
marcozecchini 0:9fca2b23d0ba 4693 !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
marcozecchini 0:9fca2b23d0ba 4694 !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
marcozecchini 0:9fca2b23d0ba 4695
marcozecchini 0:9fca2b23d0ba 4696 int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4697 {
marcozecchini 0:9fca2b23d0ba 4698 int ret;
marcozecchini 0:9fca2b23d0ba 4699
marcozecchini 0:9fca2b23d0ba 4700 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
marcozecchini 0:9fca2b23d0ba 4701
marcozecchini 0:9fca2b23d0ba 4702 ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
marcozecchini 0:9fca2b23d0ba 4703 ssl->out_msglen = 1;
marcozecchini 0:9fca2b23d0ba 4704 ssl->out_msg[0] = 1;
marcozecchini 0:9fca2b23d0ba 4705
marcozecchini 0:9fca2b23d0ba 4706 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4707
marcozecchini 0:9fca2b23d0ba 4708 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4709 {
marcozecchini 0:9fca2b23d0ba 4710 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
marcozecchini 0:9fca2b23d0ba 4711 return( ret );
marcozecchini 0:9fca2b23d0ba 4712 }
marcozecchini 0:9fca2b23d0ba 4713
marcozecchini 0:9fca2b23d0ba 4714 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
marcozecchini 0:9fca2b23d0ba 4715
marcozecchini 0:9fca2b23d0ba 4716 return( 0 );
marcozecchini 0:9fca2b23d0ba 4717 }
marcozecchini 0:9fca2b23d0ba 4718
marcozecchini 0:9fca2b23d0ba 4719 int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4720 {
marcozecchini 0:9fca2b23d0ba 4721 int ret;
marcozecchini 0:9fca2b23d0ba 4722
marcozecchini 0:9fca2b23d0ba 4723 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
marcozecchini 0:9fca2b23d0ba 4724
marcozecchini 0:9fca2b23d0ba 4725 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4726 {
marcozecchini 0:9fca2b23d0ba 4727 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
marcozecchini 0:9fca2b23d0ba 4728 return( ret );
marcozecchini 0:9fca2b23d0ba 4729 }
marcozecchini 0:9fca2b23d0ba 4730
marcozecchini 0:9fca2b23d0ba 4731 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
marcozecchini 0:9fca2b23d0ba 4732 {
marcozecchini 0:9fca2b23d0ba 4733 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
marcozecchini 0:9fca2b23d0ba 4734 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4735 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 4736 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 4737 }
marcozecchini 0:9fca2b23d0ba 4738
marcozecchini 0:9fca2b23d0ba 4739 if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 )
marcozecchini 0:9fca2b23d0ba 4740 {
marcozecchini 0:9fca2b23d0ba 4741 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
marcozecchini 0:9fca2b23d0ba 4742 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4743 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
marcozecchini 0:9fca2b23d0ba 4744 return( MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC );
marcozecchini 0:9fca2b23d0ba 4745 }
marcozecchini 0:9fca2b23d0ba 4746
marcozecchini 0:9fca2b23d0ba 4747 /*
marcozecchini 0:9fca2b23d0ba 4748 * Switch to our negotiated transform and session parameters for inbound
marcozecchini 0:9fca2b23d0ba 4749 * data.
marcozecchini 0:9fca2b23d0ba 4750 */
marcozecchini 0:9fca2b23d0ba 4751 MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
marcozecchini 0:9fca2b23d0ba 4752 ssl->transform_in = ssl->transform_negotiate;
marcozecchini 0:9fca2b23d0ba 4753 ssl->session_in = ssl->session_negotiate;
marcozecchini 0:9fca2b23d0ba 4754
marcozecchini 0:9fca2b23d0ba 4755 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 4756 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 4757 {
marcozecchini 0:9fca2b23d0ba 4758 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
marcozecchini 0:9fca2b23d0ba 4759 ssl_dtls_replay_reset( ssl );
marcozecchini 0:9fca2b23d0ba 4760 #endif
marcozecchini 0:9fca2b23d0ba 4761
marcozecchini 0:9fca2b23d0ba 4762 /* Increment epoch */
marcozecchini 0:9fca2b23d0ba 4763 if( ++ssl->in_epoch == 0 )
marcozecchini 0:9fca2b23d0ba 4764 {
marcozecchini 0:9fca2b23d0ba 4765 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
marcozecchini 0:9fca2b23d0ba 4766 /* This is highly unlikely to happen for legitimate reasons, so
marcozecchini 0:9fca2b23d0ba 4767 treat it as an attack and don't send an alert. */
marcozecchini 0:9fca2b23d0ba 4768 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
marcozecchini 0:9fca2b23d0ba 4769 }
marcozecchini 0:9fca2b23d0ba 4770 }
marcozecchini 0:9fca2b23d0ba 4771 else
marcozecchini 0:9fca2b23d0ba 4772 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 4773 memset( ssl->in_ctr, 0, 8 );
marcozecchini 0:9fca2b23d0ba 4774
marcozecchini 0:9fca2b23d0ba 4775 /*
marcozecchini 0:9fca2b23d0ba 4776 * Set the in_msg pointer to the correct location based on IV length
marcozecchini 0:9fca2b23d0ba 4777 */
marcozecchini 0:9fca2b23d0ba 4778 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 4779 {
marcozecchini 0:9fca2b23d0ba 4780 ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen -
marcozecchini 0:9fca2b23d0ba 4781 ssl->transform_negotiate->fixed_ivlen;
marcozecchini 0:9fca2b23d0ba 4782 }
marcozecchini 0:9fca2b23d0ba 4783 else
marcozecchini 0:9fca2b23d0ba 4784 ssl->in_msg = ssl->in_iv;
marcozecchini 0:9fca2b23d0ba 4785
marcozecchini 0:9fca2b23d0ba 4786 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 4787 if( mbedtls_ssl_hw_record_activate != NULL )
marcozecchini 0:9fca2b23d0ba 4788 {
marcozecchini 0:9fca2b23d0ba 4789 if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 4790 {
marcozecchini 0:9fca2b23d0ba 4791 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
marcozecchini 0:9fca2b23d0ba 4792 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 4793 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 4794 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
marcozecchini 0:9fca2b23d0ba 4795 }
marcozecchini 0:9fca2b23d0ba 4796 }
marcozecchini 0:9fca2b23d0ba 4797 #endif
marcozecchini 0:9fca2b23d0ba 4798
marcozecchini 0:9fca2b23d0ba 4799 ssl->state++;
marcozecchini 0:9fca2b23d0ba 4800
marcozecchini 0:9fca2b23d0ba 4801 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
marcozecchini 0:9fca2b23d0ba 4802
marcozecchini 0:9fca2b23d0ba 4803 return( 0 );
marcozecchini 0:9fca2b23d0ba 4804 }
marcozecchini 0:9fca2b23d0ba 4805
marcozecchini 0:9fca2b23d0ba 4806 void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 4807 const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
marcozecchini 0:9fca2b23d0ba 4808 {
marcozecchini 0:9fca2b23d0ba 4809 ((void) ciphersuite_info);
marcozecchini 0:9fca2b23d0ba 4810
marcozecchini 0:9fca2b23d0ba 4811 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
marcozecchini 0:9fca2b23d0ba 4812 defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 4813 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
marcozecchini 0:9fca2b23d0ba 4814 ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
marcozecchini 0:9fca2b23d0ba 4815 else
marcozecchini 0:9fca2b23d0ba 4816 #endif
marcozecchini 0:9fca2b23d0ba 4817 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 4818 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 4819 if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
marcozecchini 0:9fca2b23d0ba 4820 ssl->handshake->update_checksum = ssl_update_checksum_sha384;
marcozecchini 0:9fca2b23d0ba 4821 else
marcozecchini 0:9fca2b23d0ba 4822 #endif
marcozecchini 0:9fca2b23d0ba 4823 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 4824 if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 )
marcozecchini 0:9fca2b23d0ba 4825 ssl->handshake->update_checksum = ssl_update_checksum_sha256;
marcozecchini 0:9fca2b23d0ba 4826 else
marcozecchini 0:9fca2b23d0ba 4827 #endif
marcozecchini 0:9fca2b23d0ba 4828 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 4829 {
marcozecchini 0:9fca2b23d0ba 4830 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 4831 return;
marcozecchini 0:9fca2b23d0ba 4832 }
marcozecchini 0:9fca2b23d0ba 4833 }
marcozecchini 0:9fca2b23d0ba 4834
marcozecchini 0:9fca2b23d0ba 4835 void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 4836 {
marcozecchini 0:9fca2b23d0ba 4837 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
marcozecchini 0:9fca2b23d0ba 4838 defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 4839 mbedtls_md5_starts( &ssl->handshake->fin_md5 );
marcozecchini 0:9fca2b23d0ba 4840 mbedtls_sha1_starts( &ssl->handshake->fin_sha1 );
marcozecchini 0:9fca2b23d0ba 4841 #endif
marcozecchini 0:9fca2b23d0ba 4842 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 4843 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 4844 mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 );
marcozecchini 0:9fca2b23d0ba 4845 #endif
marcozecchini 0:9fca2b23d0ba 4846 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 4847 mbedtls_sha512_starts( &ssl->handshake->fin_sha512, 1 );
marcozecchini 0:9fca2b23d0ba 4848 #endif
marcozecchini 0:9fca2b23d0ba 4849 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 4850 }
marcozecchini 0:9fca2b23d0ba 4851
marcozecchini 0:9fca2b23d0ba 4852 static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 4853 const unsigned char *buf, size_t len )
marcozecchini 0:9fca2b23d0ba 4854 {
marcozecchini 0:9fca2b23d0ba 4855 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
marcozecchini 0:9fca2b23d0ba 4856 defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 4857 mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len );
marcozecchini 0:9fca2b23d0ba 4858 mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len );
marcozecchini 0:9fca2b23d0ba 4859 #endif
marcozecchini 0:9fca2b23d0ba 4860 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 4861 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 4862 mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len );
marcozecchini 0:9fca2b23d0ba 4863 #endif
marcozecchini 0:9fca2b23d0ba 4864 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 4865 mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
marcozecchini 0:9fca2b23d0ba 4866 #endif
marcozecchini 0:9fca2b23d0ba 4867 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 4868 }
marcozecchini 0:9fca2b23d0ba 4869
marcozecchini 0:9fca2b23d0ba 4870 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
marcozecchini 0:9fca2b23d0ba 4871 defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 4872 static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 4873 const unsigned char *buf, size_t len )
marcozecchini 0:9fca2b23d0ba 4874 {
marcozecchini 0:9fca2b23d0ba 4875 mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len );
marcozecchini 0:9fca2b23d0ba 4876 mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len );
marcozecchini 0:9fca2b23d0ba 4877 }
marcozecchini 0:9fca2b23d0ba 4878 #endif
marcozecchini 0:9fca2b23d0ba 4879
marcozecchini 0:9fca2b23d0ba 4880 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 4881 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 4882 static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 4883 const unsigned char *buf, size_t len )
marcozecchini 0:9fca2b23d0ba 4884 {
marcozecchini 0:9fca2b23d0ba 4885 mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len );
marcozecchini 0:9fca2b23d0ba 4886 }
marcozecchini 0:9fca2b23d0ba 4887 #endif
marcozecchini 0:9fca2b23d0ba 4888
marcozecchini 0:9fca2b23d0ba 4889 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 4890 static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 4891 const unsigned char *buf, size_t len )
marcozecchini 0:9fca2b23d0ba 4892 {
marcozecchini 0:9fca2b23d0ba 4893 mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
marcozecchini 0:9fca2b23d0ba 4894 }
marcozecchini 0:9fca2b23d0ba 4895 #endif
marcozecchini 0:9fca2b23d0ba 4896 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 4897
marcozecchini 0:9fca2b23d0ba 4898 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 4899 static void ssl_calc_finished_ssl(
marcozecchini 0:9fca2b23d0ba 4900 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
marcozecchini 0:9fca2b23d0ba 4901 {
marcozecchini 0:9fca2b23d0ba 4902 const char *sender;
marcozecchini 0:9fca2b23d0ba 4903 mbedtls_md5_context md5;
marcozecchini 0:9fca2b23d0ba 4904 mbedtls_sha1_context sha1;
marcozecchini 0:9fca2b23d0ba 4905
marcozecchini 0:9fca2b23d0ba 4906 unsigned char padbuf[48];
marcozecchini 0:9fca2b23d0ba 4907 unsigned char md5sum[16];
marcozecchini 0:9fca2b23d0ba 4908 unsigned char sha1sum[20];
marcozecchini 0:9fca2b23d0ba 4909
marcozecchini 0:9fca2b23d0ba 4910 mbedtls_ssl_session *session = ssl->session_negotiate;
marcozecchini 0:9fca2b23d0ba 4911 if( !session )
marcozecchini 0:9fca2b23d0ba 4912 session = ssl->session;
marcozecchini 0:9fca2b23d0ba 4913
marcozecchini 0:9fca2b23d0ba 4914 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) );
marcozecchini 0:9fca2b23d0ba 4915
marcozecchini 0:9fca2b23d0ba 4916 mbedtls_md5_init( &md5 );
marcozecchini 0:9fca2b23d0ba 4917 mbedtls_sha1_init( &sha1 );
marcozecchini 0:9fca2b23d0ba 4918
marcozecchini 0:9fca2b23d0ba 4919 mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
marcozecchini 0:9fca2b23d0ba 4920 mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
marcozecchini 0:9fca2b23d0ba 4921
marcozecchini 0:9fca2b23d0ba 4922 /*
marcozecchini 0:9fca2b23d0ba 4923 * SSLv3:
marcozecchini 0:9fca2b23d0ba 4924 * hash =
marcozecchini 0:9fca2b23d0ba 4925 * MD5( master + pad2 +
marcozecchini 0:9fca2b23d0ba 4926 * MD5( handshake + sender + master + pad1 ) )
marcozecchini 0:9fca2b23d0ba 4927 * + SHA1( master + pad2 +
marcozecchini 0:9fca2b23d0ba 4928 * SHA1( handshake + sender + master + pad1 ) )
marcozecchini 0:9fca2b23d0ba 4929 */
marcozecchini 0:9fca2b23d0ba 4930
marcozecchini 0:9fca2b23d0ba 4931 #if !defined(MBEDTLS_MD5_ALT)
marcozecchini 0:9fca2b23d0ba 4932 MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
marcozecchini 0:9fca2b23d0ba 4933 md5.state, sizeof( md5.state ) );
marcozecchini 0:9fca2b23d0ba 4934 #endif
marcozecchini 0:9fca2b23d0ba 4935
marcozecchini 0:9fca2b23d0ba 4936 #if !defined(MBEDTLS_SHA1_ALT)
marcozecchini 0:9fca2b23d0ba 4937 MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
marcozecchini 0:9fca2b23d0ba 4938 sha1.state, sizeof( sha1.state ) );
marcozecchini 0:9fca2b23d0ba 4939 #endif
marcozecchini 0:9fca2b23d0ba 4940
marcozecchini 0:9fca2b23d0ba 4941 sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT"
marcozecchini 0:9fca2b23d0ba 4942 : "SRVR";
marcozecchini 0:9fca2b23d0ba 4943
marcozecchini 0:9fca2b23d0ba 4944 memset( padbuf, 0x36, 48 );
marcozecchini 0:9fca2b23d0ba 4945
marcozecchini 0:9fca2b23d0ba 4946 mbedtls_md5_update( &md5, (const unsigned char *) sender, 4 );
marcozecchini 0:9fca2b23d0ba 4947 mbedtls_md5_update( &md5, session->master, 48 );
marcozecchini 0:9fca2b23d0ba 4948 mbedtls_md5_update( &md5, padbuf, 48 );
marcozecchini 0:9fca2b23d0ba 4949 mbedtls_md5_finish( &md5, md5sum );
marcozecchini 0:9fca2b23d0ba 4950
marcozecchini 0:9fca2b23d0ba 4951 mbedtls_sha1_update( &sha1, (const unsigned char *) sender, 4 );
marcozecchini 0:9fca2b23d0ba 4952 mbedtls_sha1_update( &sha1, session->master, 48 );
marcozecchini 0:9fca2b23d0ba 4953 mbedtls_sha1_update( &sha1, padbuf, 40 );
marcozecchini 0:9fca2b23d0ba 4954 mbedtls_sha1_finish( &sha1, sha1sum );
marcozecchini 0:9fca2b23d0ba 4955
marcozecchini 0:9fca2b23d0ba 4956 memset( padbuf, 0x5C, 48 );
marcozecchini 0:9fca2b23d0ba 4957
marcozecchini 0:9fca2b23d0ba 4958 mbedtls_md5_starts( &md5 );
marcozecchini 0:9fca2b23d0ba 4959 mbedtls_md5_update( &md5, session->master, 48 );
marcozecchini 0:9fca2b23d0ba 4960 mbedtls_md5_update( &md5, padbuf, 48 );
marcozecchini 0:9fca2b23d0ba 4961 mbedtls_md5_update( &md5, md5sum, 16 );
marcozecchini 0:9fca2b23d0ba 4962 mbedtls_md5_finish( &md5, buf );
marcozecchini 0:9fca2b23d0ba 4963
marcozecchini 0:9fca2b23d0ba 4964 mbedtls_sha1_starts( &sha1 );
marcozecchini 0:9fca2b23d0ba 4965 mbedtls_sha1_update( &sha1, session->master, 48 );
marcozecchini 0:9fca2b23d0ba 4966 mbedtls_sha1_update( &sha1, padbuf , 40 );
marcozecchini 0:9fca2b23d0ba 4967 mbedtls_sha1_update( &sha1, sha1sum, 20 );
marcozecchini 0:9fca2b23d0ba 4968 mbedtls_sha1_finish( &sha1, buf + 16 );
marcozecchini 0:9fca2b23d0ba 4969
marcozecchini 0:9fca2b23d0ba 4970 MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
marcozecchini 0:9fca2b23d0ba 4971
marcozecchini 0:9fca2b23d0ba 4972 mbedtls_md5_free( &md5 );
marcozecchini 0:9fca2b23d0ba 4973 mbedtls_sha1_free( &sha1 );
marcozecchini 0:9fca2b23d0ba 4974
marcozecchini 0:9fca2b23d0ba 4975 mbedtls_zeroize( padbuf, sizeof( padbuf ) );
marcozecchini 0:9fca2b23d0ba 4976 mbedtls_zeroize( md5sum, sizeof( md5sum ) );
marcozecchini 0:9fca2b23d0ba 4977 mbedtls_zeroize( sha1sum, sizeof( sha1sum ) );
marcozecchini 0:9fca2b23d0ba 4978
marcozecchini 0:9fca2b23d0ba 4979 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
marcozecchini 0:9fca2b23d0ba 4980 }
marcozecchini 0:9fca2b23d0ba 4981 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 4982
marcozecchini 0:9fca2b23d0ba 4983 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 4984 static void ssl_calc_finished_tls(
marcozecchini 0:9fca2b23d0ba 4985 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
marcozecchini 0:9fca2b23d0ba 4986 {
marcozecchini 0:9fca2b23d0ba 4987 int len = 12;
marcozecchini 0:9fca2b23d0ba 4988 const char *sender;
marcozecchini 0:9fca2b23d0ba 4989 mbedtls_md5_context md5;
marcozecchini 0:9fca2b23d0ba 4990 mbedtls_sha1_context sha1;
marcozecchini 0:9fca2b23d0ba 4991 unsigned char padbuf[36];
marcozecchini 0:9fca2b23d0ba 4992
marcozecchini 0:9fca2b23d0ba 4993 mbedtls_ssl_session *session = ssl->session_negotiate;
marcozecchini 0:9fca2b23d0ba 4994 if( !session )
marcozecchini 0:9fca2b23d0ba 4995 session = ssl->session;
marcozecchini 0:9fca2b23d0ba 4996
marcozecchini 0:9fca2b23d0ba 4997 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) );
marcozecchini 0:9fca2b23d0ba 4998
marcozecchini 0:9fca2b23d0ba 4999 mbedtls_md5_init( &md5 );
marcozecchini 0:9fca2b23d0ba 5000 mbedtls_sha1_init( &sha1 );
marcozecchini 0:9fca2b23d0ba 5001
marcozecchini 0:9fca2b23d0ba 5002 mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
marcozecchini 0:9fca2b23d0ba 5003 mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
marcozecchini 0:9fca2b23d0ba 5004
marcozecchini 0:9fca2b23d0ba 5005 /*
marcozecchini 0:9fca2b23d0ba 5006 * TLSv1:
marcozecchini 0:9fca2b23d0ba 5007 * hash = PRF( master, finished_label,
marcozecchini 0:9fca2b23d0ba 5008 * MD5( handshake ) + SHA1( handshake ) )[0..11]
marcozecchini 0:9fca2b23d0ba 5009 */
marcozecchini 0:9fca2b23d0ba 5010
marcozecchini 0:9fca2b23d0ba 5011 #if !defined(MBEDTLS_MD5_ALT)
marcozecchini 0:9fca2b23d0ba 5012 MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
marcozecchini 0:9fca2b23d0ba 5013 md5.state, sizeof( md5.state ) );
marcozecchini 0:9fca2b23d0ba 5014 #endif
marcozecchini 0:9fca2b23d0ba 5015
marcozecchini 0:9fca2b23d0ba 5016 #if !defined(MBEDTLS_SHA1_ALT)
marcozecchini 0:9fca2b23d0ba 5017 MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
marcozecchini 0:9fca2b23d0ba 5018 sha1.state, sizeof( sha1.state ) );
marcozecchini 0:9fca2b23d0ba 5019 #endif
marcozecchini 0:9fca2b23d0ba 5020
marcozecchini 0:9fca2b23d0ba 5021 sender = ( from == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 5022 ? "client finished"
marcozecchini 0:9fca2b23d0ba 5023 : "server finished";
marcozecchini 0:9fca2b23d0ba 5024
marcozecchini 0:9fca2b23d0ba 5025 mbedtls_md5_finish( &md5, padbuf );
marcozecchini 0:9fca2b23d0ba 5026 mbedtls_sha1_finish( &sha1, padbuf + 16 );
marcozecchini 0:9fca2b23d0ba 5027
marcozecchini 0:9fca2b23d0ba 5028 ssl->handshake->tls_prf( session->master, 48, sender,
marcozecchini 0:9fca2b23d0ba 5029 padbuf, 36, buf, len );
marcozecchini 0:9fca2b23d0ba 5030
marcozecchini 0:9fca2b23d0ba 5031 MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
marcozecchini 0:9fca2b23d0ba 5032
marcozecchini 0:9fca2b23d0ba 5033 mbedtls_md5_free( &md5 );
marcozecchini 0:9fca2b23d0ba 5034 mbedtls_sha1_free( &sha1 );
marcozecchini 0:9fca2b23d0ba 5035
marcozecchini 0:9fca2b23d0ba 5036 mbedtls_zeroize( padbuf, sizeof( padbuf ) );
marcozecchini 0:9fca2b23d0ba 5037
marcozecchini 0:9fca2b23d0ba 5038 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
marcozecchini 0:9fca2b23d0ba 5039 }
marcozecchini 0:9fca2b23d0ba 5040 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
marcozecchini 0:9fca2b23d0ba 5041
marcozecchini 0:9fca2b23d0ba 5042 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 5043 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 5044 static void ssl_calc_finished_tls_sha256(
marcozecchini 0:9fca2b23d0ba 5045 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
marcozecchini 0:9fca2b23d0ba 5046 {
marcozecchini 0:9fca2b23d0ba 5047 int len = 12;
marcozecchini 0:9fca2b23d0ba 5048 const char *sender;
marcozecchini 0:9fca2b23d0ba 5049 mbedtls_sha256_context sha256;
marcozecchini 0:9fca2b23d0ba 5050 unsigned char padbuf[32];
marcozecchini 0:9fca2b23d0ba 5051
marcozecchini 0:9fca2b23d0ba 5052 mbedtls_ssl_session *session = ssl->session_negotiate;
marcozecchini 0:9fca2b23d0ba 5053 if( !session )
marcozecchini 0:9fca2b23d0ba 5054 session = ssl->session;
marcozecchini 0:9fca2b23d0ba 5055
marcozecchini 0:9fca2b23d0ba 5056 mbedtls_sha256_init( &sha256 );
marcozecchini 0:9fca2b23d0ba 5057
marcozecchini 0:9fca2b23d0ba 5058 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) );
marcozecchini 0:9fca2b23d0ba 5059
marcozecchini 0:9fca2b23d0ba 5060 mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
marcozecchini 0:9fca2b23d0ba 5061
marcozecchini 0:9fca2b23d0ba 5062 /*
marcozecchini 0:9fca2b23d0ba 5063 * TLSv1.2:
marcozecchini 0:9fca2b23d0ba 5064 * hash = PRF( master, finished_label,
marcozecchini 0:9fca2b23d0ba 5065 * Hash( handshake ) )[0.11]
marcozecchini 0:9fca2b23d0ba 5066 */
marcozecchini 0:9fca2b23d0ba 5067
marcozecchini 0:9fca2b23d0ba 5068 #if !defined(MBEDTLS_SHA256_ALT)
marcozecchini 0:9fca2b23d0ba 5069 MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
marcozecchini 0:9fca2b23d0ba 5070 sha256.state, sizeof( sha256.state ) );
marcozecchini 0:9fca2b23d0ba 5071 #endif
marcozecchini 0:9fca2b23d0ba 5072
marcozecchini 0:9fca2b23d0ba 5073 sender = ( from == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 5074 ? "client finished"
marcozecchini 0:9fca2b23d0ba 5075 : "server finished";
marcozecchini 0:9fca2b23d0ba 5076
marcozecchini 0:9fca2b23d0ba 5077 mbedtls_sha256_finish( &sha256, padbuf );
marcozecchini 0:9fca2b23d0ba 5078
marcozecchini 0:9fca2b23d0ba 5079 ssl->handshake->tls_prf( session->master, 48, sender,
marcozecchini 0:9fca2b23d0ba 5080 padbuf, 32, buf, len );
marcozecchini 0:9fca2b23d0ba 5081
marcozecchini 0:9fca2b23d0ba 5082 MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
marcozecchini 0:9fca2b23d0ba 5083
marcozecchini 0:9fca2b23d0ba 5084 mbedtls_sha256_free( &sha256 );
marcozecchini 0:9fca2b23d0ba 5085
marcozecchini 0:9fca2b23d0ba 5086 mbedtls_zeroize( padbuf, sizeof( padbuf ) );
marcozecchini 0:9fca2b23d0ba 5087
marcozecchini 0:9fca2b23d0ba 5088 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
marcozecchini 0:9fca2b23d0ba 5089 }
marcozecchini 0:9fca2b23d0ba 5090 #endif /* MBEDTLS_SHA256_C */
marcozecchini 0:9fca2b23d0ba 5091
marcozecchini 0:9fca2b23d0ba 5092 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 5093 static void ssl_calc_finished_tls_sha384(
marcozecchini 0:9fca2b23d0ba 5094 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
marcozecchini 0:9fca2b23d0ba 5095 {
marcozecchini 0:9fca2b23d0ba 5096 int len = 12;
marcozecchini 0:9fca2b23d0ba 5097 const char *sender;
marcozecchini 0:9fca2b23d0ba 5098 mbedtls_sha512_context sha512;
marcozecchini 0:9fca2b23d0ba 5099 unsigned char padbuf[48];
marcozecchini 0:9fca2b23d0ba 5100
marcozecchini 0:9fca2b23d0ba 5101 mbedtls_ssl_session *session = ssl->session_negotiate;
marcozecchini 0:9fca2b23d0ba 5102 if( !session )
marcozecchini 0:9fca2b23d0ba 5103 session = ssl->session;
marcozecchini 0:9fca2b23d0ba 5104
marcozecchini 0:9fca2b23d0ba 5105 mbedtls_sha512_init( &sha512 );
marcozecchini 0:9fca2b23d0ba 5106
marcozecchini 0:9fca2b23d0ba 5107 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) );
marcozecchini 0:9fca2b23d0ba 5108
marcozecchini 0:9fca2b23d0ba 5109 mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
marcozecchini 0:9fca2b23d0ba 5110
marcozecchini 0:9fca2b23d0ba 5111 /*
marcozecchini 0:9fca2b23d0ba 5112 * TLSv1.2:
marcozecchini 0:9fca2b23d0ba 5113 * hash = PRF( master, finished_label,
marcozecchini 0:9fca2b23d0ba 5114 * Hash( handshake ) )[0.11]
marcozecchini 0:9fca2b23d0ba 5115 */
marcozecchini 0:9fca2b23d0ba 5116
marcozecchini 0:9fca2b23d0ba 5117 #if !defined(MBEDTLS_SHA512_ALT)
marcozecchini 0:9fca2b23d0ba 5118 MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
marcozecchini 0:9fca2b23d0ba 5119 sha512.state, sizeof( sha512.state ) );
marcozecchini 0:9fca2b23d0ba 5120 #endif
marcozecchini 0:9fca2b23d0ba 5121
marcozecchini 0:9fca2b23d0ba 5122 sender = ( from == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 5123 ? "client finished"
marcozecchini 0:9fca2b23d0ba 5124 : "server finished";
marcozecchini 0:9fca2b23d0ba 5125
marcozecchini 0:9fca2b23d0ba 5126 mbedtls_sha512_finish( &sha512, padbuf );
marcozecchini 0:9fca2b23d0ba 5127
marcozecchini 0:9fca2b23d0ba 5128 ssl->handshake->tls_prf( session->master, 48, sender,
marcozecchini 0:9fca2b23d0ba 5129 padbuf, 48, buf, len );
marcozecchini 0:9fca2b23d0ba 5130
marcozecchini 0:9fca2b23d0ba 5131 MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
marcozecchini 0:9fca2b23d0ba 5132
marcozecchini 0:9fca2b23d0ba 5133 mbedtls_sha512_free( &sha512 );
marcozecchini 0:9fca2b23d0ba 5134
marcozecchini 0:9fca2b23d0ba 5135 mbedtls_zeroize( padbuf, sizeof( padbuf ) );
marcozecchini 0:9fca2b23d0ba 5136
marcozecchini 0:9fca2b23d0ba 5137 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
marcozecchini 0:9fca2b23d0ba 5138 }
marcozecchini 0:9fca2b23d0ba 5139 #endif /* MBEDTLS_SHA512_C */
marcozecchini 0:9fca2b23d0ba 5140 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 5141
marcozecchini 0:9fca2b23d0ba 5142 static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 5143 {
marcozecchini 0:9fca2b23d0ba 5144 MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
marcozecchini 0:9fca2b23d0ba 5145
marcozecchini 0:9fca2b23d0ba 5146 /*
marcozecchini 0:9fca2b23d0ba 5147 * Free our handshake params
marcozecchini 0:9fca2b23d0ba 5148 */
marcozecchini 0:9fca2b23d0ba 5149 mbedtls_ssl_handshake_free( ssl->handshake );
marcozecchini 0:9fca2b23d0ba 5150 mbedtls_free( ssl->handshake );
marcozecchini 0:9fca2b23d0ba 5151 ssl->handshake = NULL;
marcozecchini 0:9fca2b23d0ba 5152
marcozecchini 0:9fca2b23d0ba 5153 /*
marcozecchini 0:9fca2b23d0ba 5154 * Free the previous transform and swith in the current one
marcozecchini 0:9fca2b23d0ba 5155 */
marcozecchini 0:9fca2b23d0ba 5156 if( ssl->transform )
marcozecchini 0:9fca2b23d0ba 5157 {
marcozecchini 0:9fca2b23d0ba 5158 mbedtls_ssl_transform_free( ssl->transform );
marcozecchini 0:9fca2b23d0ba 5159 mbedtls_free( ssl->transform );
marcozecchini 0:9fca2b23d0ba 5160 }
marcozecchini 0:9fca2b23d0ba 5161 ssl->transform = ssl->transform_negotiate;
marcozecchini 0:9fca2b23d0ba 5162 ssl->transform_negotiate = NULL;
marcozecchini 0:9fca2b23d0ba 5163
marcozecchini 0:9fca2b23d0ba 5164 MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) );
marcozecchini 0:9fca2b23d0ba 5165 }
marcozecchini 0:9fca2b23d0ba 5166
marcozecchini 0:9fca2b23d0ba 5167 void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 5168 {
marcozecchini 0:9fca2b23d0ba 5169 int resume = ssl->handshake->resume;
marcozecchini 0:9fca2b23d0ba 5170
marcozecchini 0:9fca2b23d0ba 5171 MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
marcozecchini 0:9fca2b23d0ba 5172
marcozecchini 0:9fca2b23d0ba 5173 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 5174 if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
marcozecchini 0:9fca2b23d0ba 5175 {
marcozecchini 0:9fca2b23d0ba 5176 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE;
marcozecchini 0:9fca2b23d0ba 5177 ssl->renego_records_seen = 0;
marcozecchini 0:9fca2b23d0ba 5178 }
marcozecchini 0:9fca2b23d0ba 5179 #endif
marcozecchini 0:9fca2b23d0ba 5180
marcozecchini 0:9fca2b23d0ba 5181 /*
marcozecchini 0:9fca2b23d0ba 5182 * Free the previous session and switch in the current one
marcozecchini 0:9fca2b23d0ba 5183 */
marcozecchini 0:9fca2b23d0ba 5184 if( ssl->session )
marcozecchini 0:9fca2b23d0ba 5185 {
marcozecchini 0:9fca2b23d0ba 5186 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
marcozecchini 0:9fca2b23d0ba 5187 /* RFC 7366 3.1: keep the EtM state */
marcozecchini 0:9fca2b23d0ba 5188 ssl->session_negotiate->encrypt_then_mac =
marcozecchini 0:9fca2b23d0ba 5189 ssl->session->encrypt_then_mac;
marcozecchini 0:9fca2b23d0ba 5190 #endif
marcozecchini 0:9fca2b23d0ba 5191
marcozecchini 0:9fca2b23d0ba 5192 mbedtls_ssl_session_free( ssl->session );
marcozecchini 0:9fca2b23d0ba 5193 mbedtls_free( ssl->session );
marcozecchini 0:9fca2b23d0ba 5194 }
marcozecchini 0:9fca2b23d0ba 5195 ssl->session = ssl->session_negotiate;
marcozecchini 0:9fca2b23d0ba 5196 ssl->session_negotiate = NULL;
marcozecchini 0:9fca2b23d0ba 5197
marcozecchini 0:9fca2b23d0ba 5198 /*
marcozecchini 0:9fca2b23d0ba 5199 * Add cache entry
marcozecchini 0:9fca2b23d0ba 5200 */
marcozecchini 0:9fca2b23d0ba 5201 if( ssl->conf->f_set_cache != NULL &&
marcozecchini 0:9fca2b23d0ba 5202 ssl->session->id_len != 0 &&
marcozecchini 0:9fca2b23d0ba 5203 resume == 0 )
marcozecchini 0:9fca2b23d0ba 5204 {
marcozecchini 0:9fca2b23d0ba 5205 if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 )
marcozecchini 0:9fca2b23d0ba 5206 MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) );
marcozecchini 0:9fca2b23d0ba 5207 }
marcozecchini 0:9fca2b23d0ba 5208
marcozecchini 0:9fca2b23d0ba 5209 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 5210 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
marcozecchini 0:9fca2b23d0ba 5211 ssl->handshake->flight != NULL )
marcozecchini 0:9fca2b23d0ba 5212 {
marcozecchini 0:9fca2b23d0ba 5213 /* Cancel handshake timer */
marcozecchini 0:9fca2b23d0ba 5214 ssl_set_timer( ssl, 0 );
marcozecchini 0:9fca2b23d0ba 5215
marcozecchini 0:9fca2b23d0ba 5216 /* Keep last flight around in case we need to resend it:
marcozecchini 0:9fca2b23d0ba 5217 * we need the handshake and transform structures for that */
marcozecchini 0:9fca2b23d0ba 5218 MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) );
marcozecchini 0:9fca2b23d0ba 5219 }
marcozecchini 0:9fca2b23d0ba 5220 else
marcozecchini 0:9fca2b23d0ba 5221 #endif
marcozecchini 0:9fca2b23d0ba 5222 ssl_handshake_wrapup_free_hs_transform( ssl );
marcozecchini 0:9fca2b23d0ba 5223
marcozecchini 0:9fca2b23d0ba 5224 ssl->state++;
marcozecchini 0:9fca2b23d0ba 5225
marcozecchini 0:9fca2b23d0ba 5226 MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
marcozecchini 0:9fca2b23d0ba 5227 }
marcozecchini 0:9fca2b23d0ba 5228
marcozecchini 0:9fca2b23d0ba 5229 int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 5230 {
marcozecchini 0:9fca2b23d0ba 5231 int ret, hash_len;
marcozecchini 0:9fca2b23d0ba 5232
marcozecchini 0:9fca2b23d0ba 5233 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
marcozecchini 0:9fca2b23d0ba 5234
marcozecchini 0:9fca2b23d0ba 5235 /*
marcozecchini 0:9fca2b23d0ba 5236 * Set the out_msg pointer to the correct location based on IV length
marcozecchini 0:9fca2b23d0ba 5237 */
marcozecchini 0:9fca2b23d0ba 5238 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 5239 {
marcozecchini 0:9fca2b23d0ba 5240 ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen -
marcozecchini 0:9fca2b23d0ba 5241 ssl->transform_negotiate->fixed_ivlen;
marcozecchini 0:9fca2b23d0ba 5242 }
marcozecchini 0:9fca2b23d0ba 5243 else
marcozecchini 0:9fca2b23d0ba 5244 ssl->out_msg = ssl->out_iv;
marcozecchini 0:9fca2b23d0ba 5245
marcozecchini 0:9fca2b23d0ba 5246 ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
marcozecchini 0:9fca2b23d0ba 5247
marcozecchini 0:9fca2b23d0ba 5248 /*
marcozecchini 0:9fca2b23d0ba 5249 * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
marcozecchini 0:9fca2b23d0ba 5250 * may define some other value. Currently (early 2016), no defined
marcozecchini 0:9fca2b23d0ba 5251 * ciphersuite does this (and this is unlikely to change as activity has
marcozecchini 0:9fca2b23d0ba 5252 * moved to TLS 1.3 now) so we can keep the hardcoded 12 here.
marcozecchini 0:9fca2b23d0ba 5253 */
marcozecchini 0:9fca2b23d0ba 5254 hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12;
marcozecchini 0:9fca2b23d0ba 5255
marcozecchini 0:9fca2b23d0ba 5256 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 5257 ssl->verify_data_len = hash_len;
marcozecchini 0:9fca2b23d0ba 5258 memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
marcozecchini 0:9fca2b23d0ba 5259 #endif
marcozecchini 0:9fca2b23d0ba 5260
marcozecchini 0:9fca2b23d0ba 5261 ssl->out_msglen = 4 + hash_len;
marcozecchini 0:9fca2b23d0ba 5262 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
marcozecchini 0:9fca2b23d0ba 5263 ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED;
marcozecchini 0:9fca2b23d0ba 5264
marcozecchini 0:9fca2b23d0ba 5265 /*
marcozecchini 0:9fca2b23d0ba 5266 * In case of session resuming, invert the client and server
marcozecchini 0:9fca2b23d0ba 5267 * ChangeCipherSpec messages order.
marcozecchini 0:9fca2b23d0ba 5268 */
marcozecchini 0:9fca2b23d0ba 5269 if( ssl->handshake->resume != 0 )
marcozecchini 0:9fca2b23d0ba 5270 {
marcozecchini 0:9fca2b23d0ba 5271 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 5272 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 5273 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
marcozecchini 0:9fca2b23d0ba 5274 #endif
marcozecchini 0:9fca2b23d0ba 5275 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 5276 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 5277 ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
marcozecchini 0:9fca2b23d0ba 5278 #endif
marcozecchini 0:9fca2b23d0ba 5279 }
marcozecchini 0:9fca2b23d0ba 5280 else
marcozecchini 0:9fca2b23d0ba 5281 ssl->state++;
marcozecchini 0:9fca2b23d0ba 5282
marcozecchini 0:9fca2b23d0ba 5283 /*
marcozecchini 0:9fca2b23d0ba 5284 * Switch to our negotiated transform and session parameters for outbound
marcozecchini 0:9fca2b23d0ba 5285 * data.
marcozecchini 0:9fca2b23d0ba 5286 */
marcozecchini 0:9fca2b23d0ba 5287 MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
marcozecchini 0:9fca2b23d0ba 5288
marcozecchini 0:9fca2b23d0ba 5289 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 5290 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 5291 {
marcozecchini 0:9fca2b23d0ba 5292 unsigned char i;
marcozecchini 0:9fca2b23d0ba 5293
marcozecchini 0:9fca2b23d0ba 5294 /* Remember current epoch settings for resending */
marcozecchini 0:9fca2b23d0ba 5295 ssl->handshake->alt_transform_out = ssl->transform_out;
marcozecchini 0:9fca2b23d0ba 5296 memcpy( ssl->handshake->alt_out_ctr, ssl->out_ctr, 8 );
marcozecchini 0:9fca2b23d0ba 5297
marcozecchini 0:9fca2b23d0ba 5298 /* Set sequence_number to zero */
marcozecchini 0:9fca2b23d0ba 5299 memset( ssl->out_ctr + 2, 0, 6 );
marcozecchini 0:9fca2b23d0ba 5300
marcozecchini 0:9fca2b23d0ba 5301 /* Increment epoch */
marcozecchini 0:9fca2b23d0ba 5302 for( i = 2; i > 0; i-- )
marcozecchini 0:9fca2b23d0ba 5303 if( ++ssl->out_ctr[i - 1] != 0 )
marcozecchini 0:9fca2b23d0ba 5304 break;
marcozecchini 0:9fca2b23d0ba 5305
marcozecchini 0:9fca2b23d0ba 5306 /* The loop goes to its end iff the counter is wrapping */
marcozecchini 0:9fca2b23d0ba 5307 if( i == 0 )
marcozecchini 0:9fca2b23d0ba 5308 {
marcozecchini 0:9fca2b23d0ba 5309 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
marcozecchini 0:9fca2b23d0ba 5310 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
marcozecchini 0:9fca2b23d0ba 5311 }
marcozecchini 0:9fca2b23d0ba 5312 }
marcozecchini 0:9fca2b23d0ba 5313 else
marcozecchini 0:9fca2b23d0ba 5314 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 5315 memset( ssl->out_ctr, 0, 8 );
marcozecchini 0:9fca2b23d0ba 5316
marcozecchini 0:9fca2b23d0ba 5317 ssl->transform_out = ssl->transform_negotiate;
marcozecchini 0:9fca2b23d0ba 5318 ssl->session_out = ssl->session_negotiate;
marcozecchini 0:9fca2b23d0ba 5319
marcozecchini 0:9fca2b23d0ba 5320 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 5321 if( mbedtls_ssl_hw_record_activate != NULL )
marcozecchini 0:9fca2b23d0ba 5322 {
marcozecchini 0:9fca2b23d0ba 5323 if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 5324 {
marcozecchini 0:9fca2b23d0ba 5325 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
marcozecchini 0:9fca2b23d0ba 5326 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
marcozecchini 0:9fca2b23d0ba 5327 }
marcozecchini 0:9fca2b23d0ba 5328 }
marcozecchini 0:9fca2b23d0ba 5329 #endif
marcozecchini 0:9fca2b23d0ba 5330
marcozecchini 0:9fca2b23d0ba 5331 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 5332 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 5333 mbedtls_ssl_send_flight_completed( ssl );
marcozecchini 0:9fca2b23d0ba 5334 #endif
marcozecchini 0:9fca2b23d0ba 5335
marcozecchini 0:9fca2b23d0ba 5336 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 5337 {
marcozecchini 0:9fca2b23d0ba 5338 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
marcozecchini 0:9fca2b23d0ba 5339 return( ret );
marcozecchini 0:9fca2b23d0ba 5340 }
marcozecchini 0:9fca2b23d0ba 5341
marcozecchini 0:9fca2b23d0ba 5342 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
marcozecchini 0:9fca2b23d0ba 5343
marcozecchini 0:9fca2b23d0ba 5344 return( 0 );
marcozecchini 0:9fca2b23d0ba 5345 }
marcozecchini 0:9fca2b23d0ba 5346
marcozecchini 0:9fca2b23d0ba 5347 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 5348 #define SSL_MAX_HASH_LEN 36
marcozecchini 0:9fca2b23d0ba 5349 #else
marcozecchini 0:9fca2b23d0ba 5350 #define SSL_MAX_HASH_LEN 12
marcozecchini 0:9fca2b23d0ba 5351 #endif
marcozecchini 0:9fca2b23d0ba 5352
marcozecchini 0:9fca2b23d0ba 5353 int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 5354 {
marcozecchini 0:9fca2b23d0ba 5355 int ret;
marcozecchini 0:9fca2b23d0ba 5356 unsigned int hash_len;
marcozecchini 0:9fca2b23d0ba 5357 unsigned char buf[SSL_MAX_HASH_LEN];
marcozecchini 0:9fca2b23d0ba 5358
marcozecchini 0:9fca2b23d0ba 5359 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
marcozecchini 0:9fca2b23d0ba 5360
marcozecchini 0:9fca2b23d0ba 5361 ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
marcozecchini 0:9fca2b23d0ba 5362
marcozecchini 0:9fca2b23d0ba 5363 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 5364 {
marcozecchini 0:9fca2b23d0ba 5365 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
marcozecchini 0:9fca2b23d0ba 5366 return( ret );
marcozecchini 0:9fca2b23d0ba 5367 }
marcozecchini 0:9fca2b23d0ba 5368
marcozecchini 0:9fca2b23d0ba 5369 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
marcozecchini 0:9fca2b23d0ba 5370 {
marcozecchini 0:9fca2b23d0ba 5371 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
marcozecchini 0:9fca2b23d0ba 5372 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 5373 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 5374 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 5375 }
marcozecchini 0:9fca2b23d0ba 5376
marcozecchini 0:9fca2b23d0ba 5377 /* There is currently no ciphersuite using another length with TLS 1.2 */
marcozecchini 0:9fca2b23d0ba 5378 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 5379 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 5380 hash_len = 36;
marcozecchini 0:9fca2b23d0ba 5381 else
marcozecchini 0:9fca2b23d0ba 5382 #endif
marcozecchini 0:9fca2b23d0ba 5383 hash_len = 12;
marcozecchini 0:9fca2b23d0ba 5384
marcozecchini 0:9fca2b23d0ba 5385 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
marcozecchini 0:9fca2b23d0ba 5386 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
marcozecchini 0:9fca2b23d0ba 5387 {
marcozecchini 0:9fca2b23d0ba 5388 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
marcozecchini 0:9fca2b23d0ba 5389 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 5390 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
marcozecchini 0:9fca2b23d0ba 5391 return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
marcozecchini 0:9fca2b23d0ba 5392 }
marcozecchini 0:9fca2b23d0ba 5393
marcozecchini 0:9fca2b23d0ba 5394 if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
marcozecchini 0:9fca2b23d0ba 5395 buf, hash_len ) != 0 )
marcozecchini 0:9fca2b23d0ba 5396 {
marcozecchini 0:9fca2b23d0ba 5397 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
marcozecchini 0:9fca2b23d0ba 5398 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 5399 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
marcozecchini 0:9fca2b23d0ba 5400 return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
marcozecchini 0:9fca2b23d0ba 5401 }
marcozecchini 0:9fca2b23d0ba 5402
marcozecchini 0:9fca2b23d0ba 5403 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 5404 ssl->verify_data_len = hash_len;
marcozecchini 0:9fca2b23d0ba 5405 memcpy( ssl->peer_verify_data, buf, hash_len );
marcozecchini 0:9fca2b23d0ba 5406 #endif
marcozecchini 0:9fca2b23d0ba 5407
marcozecchini 0:9fca2b23d0ba 5408 if( ssl->handshake->resume != 0 )
marcozecchini 0:9fca2b23d0ba 5409 {
marcozecchini 0:9fca2b23d0ba 5410 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 5411 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 5412 ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
marcozecchini 0:9fca2b23d0ba 5413 #endif
marcozecchini 0:9fca2b23d0ba 5414 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 5415 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 5416 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
marcozecchini 0:9fca2b23d0ba 5417 #endif
marcozecchini 0:9fca2b23d0ba 5418 }
marcozecchini 0:9fca2b23d0ba 5419 else
marcozecchini 0:9fca2b23d0ba 5420 ssl->state++;
marcozecchini 0:9fca2b23d0ba 5421
marcozecchini 0:9fca2b23d0ba 5422 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 5423 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 5424 mbedtls_ssl_recv_flight_completed( ssl );
marcozecchini 0:9fca2b23d0ba 5425 #endif
marcozecchini 0:9fca2b23d0ba 5426
marcozecchini 0:9fca2b23d0ba 5427 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) );
marcozecchini 0:9fca2b23d0ba 5428
marcozecchini 0:9fca2b23d0ba 5429 return( 0 );
marcozecchini 0:9fca2b23d0ba 5430 }
marcozecchini 0:9fca2b23d0ba 5431
marcozecchini 0:9fca2b23d0ba 5432 static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
marcozecchini 0:9fca2b23d0ba 5433 {
marcozecchini 0:9fca2b23d0ba 5434 memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) );
marcozecchini 0:9fca2b23d0ba 5435
marcozecchini 0:9fca2b23d0ba 5436 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
marcozecchini 0:9fca2b23d0ba 5437 defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 5438 mbedtls_md5_init( &handshake->fin_md5 );
marcozecchini 0:9fca2b23d0ba 5439 mbedtls_sha1_init( &handshake->fin_sha1 );
marcozecchini 0:9fca2b23d0ba 5440 mbedtls_md5_starts( &handshake->fin_md5 );
marcozecchini 0:9fca2b23d0ba 5441 mbedtls_sha1_starts( &handshake->fin_sha1 );
marcozecchini 0:9fca2b23d0ba 5442 #endif
marcozecchini 0:9fca2b23d0ba 5443 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 5444 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 5445 mbedtls_sha256_init( &handshake->fin_sha256 );
marcozecchini 0:9fca2b23d0ba 5446 mbedtls_sha256_starts( &handshake->fin_sha256, 0 );
marcozecchini 0:9fca2b23d0ba 5447 #endif
marcozecchini 0:9fca2b23d0ba 5448 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 5449 mbedtls_sha512_init( &handshake->fin_sha512 );
marcozecchini 0:9fca2b23d0ba 5450 mbedtls_sha512_starts( &handshake->fin_sha512, 1 );
marcozecchini 0:9fca2b23d0ba 5451 #endif
marcozecchini 0:9fca2b23d0ba 5452 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 5453
marcozecchini 0:9fca2b23d0ba 5454 handshake->update_checksum = ssl_update_checksum_start;
marcozecchini 0:9fca2b23d0ba 5455
marcozecchini 0:9fca2b23d0ba 5456 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
marcozecchini 0:9fca2b23d0ba 5457 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
marcozecchini 0:9fca2b23d0ba 5458 mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs );
marcozecchini 0:9fca2b23d0ba 5459 #endif
marcozecchini 0:9fca2b23d0ba 5460
marcozecchini 0:9fca2b23d0ba 5461 #if defined(MBEDTLS_DHM_C)
marcozecchini 0:9fca2b23d0ba 5462 mbedtls_dhm_init( &handshake->dhm_ctx );
marcozecchini 0:9fca2b23d0ba 5463 #endif
marcozecchini 0:9fca2b23d0ba 5464 #if defined(MBEDTLS_ECDH_C)
marcozecchini 0:9fca2b23d0ba 5465 mbedtls_ecdh_init( &handshake->ecdh_ctx );
marcozecchini 0:9fca2b23d0ba 5466 #endif
marcozecchini 0:9fca2b23d0ba 5467 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
marcozecchini 0:9fca2b23d0ba 5468 mbedtls_ecjpake_init( &handshake->ecjpake_ctx );
marcozecchini 0:9fca2b23d0ba 5469 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 5470 handshake->ecjpake_cache = NULL;
marcozecchini 0:9fca2b23d0ba 5471 handshake->ecjpake_cache_len = 0;
marcozecchini 0:9fca2b23d0ba 5472 #endif
marcozecchini 0:9fca2b23d0ba 5473 #endif
marcozecchini 0:9fca2b23d0ba 5474
marcozecchini 0:9fca2b23d0ba 5475 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
marcozecchini 0:9fca2b23d0ba 5476 handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
marcozecchini 0:9fca2b23d0ba 5477 #endif
marcozecchini 0:9fca2b23d0ba 5478 }
marcozecchini 0:9fca2b23d0ba 5479
marcozecchini 0:9fca2b23d0ba 5480 static void ssl_transform_init( mbedtls_ssl_transform *transform )
marcozecchini 0:9fca2b23d0ba 5481 {
marcozecchini 0:9fca2b23d0ba 5482 memset( transform, 0, sizeof(mbedtls_ssl_transform) );
marcozecchini 0:9fca2b23d0ba 5483
marcozecchini 0:9fca2b23d0ba 5484 mbedtls_cipher_init( &transform->cipher_ctx_enc );
marcozecchini 0:9fca2b23d0ba 5485 mbedtls_cipher_init( &transform->cipher_ctx_dec );
marcozecchini 0:9fca2b23d0ba 5486
marcozecchini 0:9fca2b23d0ba 5487 mbedtls_md_init( &transform->md_ctx_enc );
marcozecchini 0:9fca2b23d0ba 5488 mbedtls_md_init( &transform->md_ctx_dec );
marcozecchini 0:9fca2b23d0ba 5489 }
marcozecchini 0:9fca2b23d0ba 5490
marcozecchini 0:9fca2b23d0ba 5491 void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
marcozecchini 0:9fca2b23d0ba 5492 {
marcozecchini 0:9fca2b23d0ba 5493 memset( session, 0, sizeof(mbedtls_ssl_session) );
marcozecchini 0:9fca2b23d0ba 5494 }
marcozecchini 0:9fca2b23d0ba 5495
marcozecchini 0:9fca2b23d0ba 5496 static int ssl_handshake_init( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 5497 {
marcozecchini 0:9fca2b23d0ba 5498 /* Clear old handshake information if present */
marcozecchini 0:9fca2b23d0ba 5499 if( ssl->transform_negotiate )
marcozecchini 0:9fca2b23d0ba 5500 mbedtls_ssl_transform_free( ssl->transform_negotiate );
marcozecchini 0:9fca2b23d0ba 5501 if( ssl->session_negotiate )
marcozecchini 0:9fca2b23d0ba 5502 mbedtls_ssl_session_free( ssl->session_negotiate );
marcozecchini 0:9fca2b23d0ba 5503 if( ssl->handshake )
marcozecchini 0:9fca2b23d0ba 5504 mbedtls_ssl_handshake_free( ssl->handshake );
marcozecchini 0:9fca2b23d0ba 5505
marcozecchini 0:9fca2b23d0ba 5506 /*
marcozecchini 0:9fca2b23d0ba 5507 * Either the pointers are now NULL or cleared properly and can be freed.
marcozecchini 0:9fca2b23d0ba 5508 * Now allocate missing structures.
marcozecchini 0:9fca2b23d0ba 5509 */
marcozecchini 0:9fca2b23d0ba 5510 if( ssl->transform_negotiate == NULL )
marcozecchini 0:9fca2b23d0ba 5511 {
marcozecchini 0:9fca2b23d0ba 5512 ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) );
marcozecchini 0:9fca2b23d0ba 5513 }
marcozecchini 0:9fca2b23d0ba 5514
marcozecchini 0:9fca2b23d0ba 5515 if( ssl->session_negotiate == NULL )
marcozecchini 0:9fca2b23d0ba 5516 {
marcozecchini 0:9fca2b23d0ba 5517 ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) );
marcozecchini 0:9fca2b23d0ba 5518 }
marcozecchini 0:9fca2b23d0ba 5519
marcozecchini 0:9fca2b23d0ba 5520 if( ssl->handshake == NULL )
marcozecchini 0:9fca2b23d0ba 5521 {
marcozecchini 0:9fca2b23d0ba 5522 ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
marcozecchini 0:9fca2b23d0ba 5523 }
marcozecchini 0:9fca2b23d0ba 5524
marcozecchini 0:9fca2b23d0ba 5525 /* All pointers should exist and can be directly freed without issue */
marcozecchini 0:9fca2b23d0ba 5526 if( ssl->handshake == NULL ||
marcozecchini 0:9fca2b23d0ba 5527 ssl->transform_negotiate == NULL ||
marcozecchini 0:9fca2b23d0ba 5528 ssl->session_negotiate == NULL )
marcozecchini 0:9fca2b23d0ba 5529 {
marcozecchini 0:9fca2b23d0ba 5530 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc() of ssl sub-contexts failed" ) );
marcozecchini 0:9fca2b23d0ba 5531
marcozecchini 0:9fca2b23d0ba 5532 mbedtls_free( ssl->handshake );
marcozecchini 0:9fca2b23d0ba 5533 mbedtls_free( ssl->transform_negotiate );
marcozecchini 0:9fca2b23d0ba 5534 mbedtls_free( ssl->session_negotiate );
marcozecchini 0:9fca2b23d0ba 5535
marcozecchini 0:9fca2b23d0ba 5536 ssl->handshake = NULL;
marcozecchini 0:9fca2b23d0ba 5537 ssl->transform_negotiate = NULL;
marcozecchini 0:9fca2b23d0ba 5538 ssl->session_negotiate = NULL;
marcozecchini 0:9fca2b23d0ba 5539
marcozecchini 0:9fca2b23d0ba 5540 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 5541 }
marcozecchini 0:9fca2b23d0ba 5542
marcozecchini 0:9fca2b23d0ba 5543 /* Initialize structures */
marcozecchini 0:9fca2b23d0ba 5544 mbedtls_ssl_session_init( ssl->session_negotiate );
marcozecchini 0:9fca2b23d0ba 5545 ssl_transform_init( ssl->transform_negotiate );
marcozecchini 0:9fca2b23d0ba 5546 ssl_handshake_params_init( ssl->handshake );
marcozecchini 0:9fca2b23d0ba 5547
marcozecchini 0:9fca2b23d0ba 5548 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 5549 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 5550 {
marcozecchini 0:9fca2b23d0ba 5551 ssl->handshake->alt_transform_out = ssl->transform_out;
marcozecchini 0:9fca2b23d0ba 5552
marcozecchini 0:9fca2b23d0ba 5553 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 5554 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
marcozecchini 0:9fca2b23d0ba 5555 else
marcozecchini 0:9fca2b23d0ba 5556 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
marcozecchini 0:9fca2b23d0ba 5557
marcozecchini 0:9fca2b23d0ba 5558 ssl_set_timer( ssl, 0 );
marcozecchini 0:9fca2b23d0ba 5559 }
marcozecchini 0:9fca2b23d0ba 5560 #endif
marcozecchini 0:9fca2b23d0ba 5561
marcozecchini 0:9fca2b23d0ba 5562 return( 0 );
marcozecchini 0:9fca2b23d0ba 5563 }
marcozecchini 0:9fca2b23d0ba 5564
marcozecchini 0:9fca2b23d0ba 5565 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 5566 /* Dummy cookie callbacks for defaults */
marcozecchini 0:9fca2b23d0ba 5567 static int ssl_cookie_write_dummy( void *ctx,
marcozecchini 0:9fca2b23d0ba 5568 unsigned char **p, unsigned char *end,
marcozecchini 0:9fca2b23d0ba 5569 const unsigned char *cli_id, size_t cli_id_len )
marcozecchini 0:9fca2b23d0ba 5570 {
marcozecchini 0:9fca2b23d0ba 5571 ((void) ctx);
marcozecchini 0:9fca2b23d0ba 5572 ((void) p);
marcozecchini 0:9fca2b23d0ba 5573 ((void) end);
marcozecchini 0:9fca2b23d0ba 5574 ((void) cli_id);
marcozecchini 0:9fca2b23d0ba 5575 ((void) cli_id_len);
marcozecchini 0:9fca2b23d0ba 5576
marcozecchini 0:9fca2b23d0ba 5577 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
marcozecchini 0:9fca2b23d0ba 5578 }
marcozecchini 0:9fca2b23d0ba 5579
marcozecchini 0:9fca2b23d0ba 5580 static int ssl_cookie_check_dummy( void *ctx,
marcozecchini 0:9fca2b23d0ba 5581 const unsigned char *cookie, size_t cookie_len,
marcozecchini 0:9fca2b23d0ba 5582 const unsigned char *cli_id, size_t cli_id_len )
marcozecchini 0:9fca2b23d0ba 5583 {
marcozecchini 0:9fca2b23d0ba 5584 ((void) ctx);
marcozecchini 0:9fca2b23d0ba 5585 ((void) cookie);
marcozecchini 0:9fca2b23d0ba 5586 ((void) cookie_len);
marcozecchini 0:9fca2b23d0ba 5587 ((void) cli_id);
marcozecchini 0:9fca2b23d0ba 5588 ((void) cli_id_len);
marcozecchini 0:9fca2b23d0ba 5589
marcozecchini 0:9fca2b23d0ba 5590 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
marcozecchini 0:9fca2b23d0ba 5591 }
marcozecchini 0:9fca2b23d0ba 5592 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 5593
marcozecchini 0:9fca2b23d0ba 5594 /*
marcozecchini 0:9fca2b23d0ba 5595 * Initialize an SSL context
marcozecchini 0:9fca2b23d0ba 5596 */
marcozecchini 0:9fca2b23d0ba 5597 void mbedtls_ssl_init( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 5598 {
marcozecchini 0:9fca2b23d0ba 5599 memset( ssl, 0, sizeof( mbedtls_ssl_context ) );
marcozecchini 0:9fca2b23d0ba 5600 }
marcozecchini 0:9fca2b23d0ba 5601
marcozecchini 0:9fca2b23d0ba 5602 /*
marcozecchini 0:9fca2b23d0ba 5603 * Setup an SSL context
marcozecchini 0:9fca2b23d0ba 5604 */
marcozecchini 0:9fca2b23d0ba 5605 int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 5606 const mbedtls_ssl_config *conf )
marcozecchini 0:9fca2b23d0ba 5607 {
marcozecchini 0:9fca2b23d0ba 5608 int ret;
marcozecchini 0:9fca2b23d0ba 5609 const size_t len = MBEDTLS_SSL_BUFFER_LEN;
marcozecchini 0:9fca2b23d0ba 5610
marcozecchini 0:9fca2b23d0ba 5611 ssl->conf = conf;
marcozecchini 0:9fca2b23d0ba 5612
marcozecchini 0:9fca2b23d0ba 5613 /*
marcozecchini 0:9fca2b23d0ba 5614 * Prepare base structures
marcozecchini 0:9fca2b23d0ba 5615 */
marcozecchini 0:9fca2b23d0ba 5616 if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL ||
marcozecchini 0:9fca2b23d0ba 5617 ( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 5618 {
marcozecchini 0:9fca2b23d0ba 5619 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) );
marcozecchini 0:9fca2b23d0ba 5620 mbedtls_free( ssl->in_buf );
marcozecchini 0:9fca2b23d0ba 5621 ssl->in_buf = NULL;
marcozecchini 0:9fca2b23d0ba 5622 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 5623 }
marcozecchini 0:9fca2b23d0ba 5624
marcozecchini 0:9fca2b23d0ba 5625 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 5626 if( conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 5627 {
marcozecchini 0:9fca2b23d0ba 5628 ssl->out_hdr = ssl->out_buf;
marcozecchini 0:9fca2b23d0ba 5629 ssl->out_ctr = ssl->out_buf + 3;
marcozecchini 0:9fca2b23d0ba 5630 ssl->out_len = ssl->out_buf + 11;
marcozecchini 0:9fca2b23d0ba 5631 ssl->out_iv = ssl->out_buf + 13;
marcozecchini 0:9fca2b23d0ba 5632 ssl->out_msg = ssl->out_buf + 13;
marcozecchini 0:9fca2b23d0ba 5633
marcozecchini 0:9fca2b23d0ba 5634 ssl->in_hdr = ssl->in_buf;
marcozecchini 0:9fca2b23d0ba 5635 ssl->in_ctr = ssl->in_buf + 3;
marcozecchini 0:9fca2b23d0ba 5636 ssl->in_len = ssl->in_buf + 11;
marcozecchini 0:9fca2b23d0ba 5637 ssl->in_iv = ssl->in_buf + 13;
marcozecchini 0:9fca2b23d0ba 5638 ssl->in_msg = ssl->in_buf + 13;
marcozecchini 0:9fca2b23d0ba 5639 }
marcozecchini 0:9fca2b23d0ba 5640 else
marcozecchini 0:9fca2b23d0ba 5641 #endif
marcozecchini 0:9fca2b23d0ba 5642 {
marcozecchini 0:9fca2b23d0ba 5643 ssl->out_ctr = ssl->out_buf;
marcozecchini 0:9fca2b23d0ba 5644 ssl->out_hdr = ssl->out_buf + 8;
marcozecchini 0:9fca2b23d0ba 5645 ssl->out_len = ssl->out_buf + 11;
marcozecchini 0:9fca2b23d0ba 5646 ssl->out_iv = ssl->out_buf + 13;
marcozecchini 0:9fca2b23d0ba 5647 ssl->out_msg = ssl->out_buf + 13;
marcozecchini 0:9fca2b23d0ba 5648
marcozecchini 0:9fca2b23d0ba 5649 ssl->in_ctr = ssl->in_buf;
marcozecchini 0:9fca2b23d0ba 5650 ssl->in_hdr = ssl->in_buf + 8;
marcozecchini 0:9fca2b23d0ba 5651 ssl->in_len = ssl->in_buf + 11;
marcozecchini 0:9fca2b23d0ba 5652 ssl->in_iv = ssl->in_buf + 13;
marcozecchini 0:9fca2b23d0ba 5653 ssl->in_msg = ssl->in_buf + 13;
marcozecchini 0:9fca2b23d0ba 5654 }
marcozecchini 0:9fca2b23d0ba 5655
marcozecchini 0:9fca2b23d0ba 5656 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 5657 return( ret );
marcozecchini 0:9fca2b23d0ba 5658
marcozecchini 0:9fca2b23d0ba 5659 return( 0 );
marcozecchini 0:9fca2b23d0ba 5660 }
marcozecchini 0:9fca2b23d0ba 5661
marcozecchini 0:9fca2b23d0ba 5662 /*
marcozecchini 0:9fca2b23d0ba 5663 * Reset an initialized and used SSL context for re-use while retaining
marcozecchini 0:9fca2b23d0ba 5664 * all application-set variables, function pointers and data.
marcozecchini 0:9fca2b23d0ba 5665 *
marcozecchini 0:9fca2b23d0ba 5666 * If partial is non-zero, keep data in the input buffer and client ID.
marcozecchini 0:9fca2b23d0ba 5667 * (Use when a DTLS client reconnects from the same port.)
marcozecchini 0:9fca2b23d0ba 5668 */
marcozecchini 0:9fca2b23d0ba 5669 static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
marcozecchini 0:9fca2b23d0ba 5670 {
marcozecchini 0:9fca2b23d0ba 5671 int ret;
marcozecchini 0:9fca2b23d0ba 5672
marcozecchini 0:9fca2b23d0ba 5673 ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
marcozecchini 0:9fca2b23d0ba 5674
marcozecchini 0:9fca2b23d0ba 5675 /* Cancel any possibly running timer */
marcozecchini 0:9fca2b23d0ba 5676 ssl_set_timer( ssl, 0 );
marcozecchini 0:9fca2b23d0ba 5677
marcozecchini 0:9fca2b23d0ba 5678 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 5679 ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
marcozecchini 0:9fca2b23d0ba 5680 ssl->renego_records_seen = 0;
marcozecchini 0:9fca2b23d0ba 5681
marcozecchini 0:9fca2b23d0ba 5682 ssl->verify_data_len = 0;
marcozecchini 0:9fca2b23d0ba 5683 memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN );
marcozecchini 0:9fca2b23d0ba 5684 memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN );
marcozecchini 0:9fca2b23d0ba 5685 #endif
marcozecchini 0:9fca2b23d0ba 5686 ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
marcozecchini 0:9fca2b23d0ba 5687
marcozecchini 0:9fca2b23d0ba 5688 ssl->in_offt = NULL;
marcozecchini 0:9fca2b23d0ba 5689
marcozecchini 0:9fca2b23d0ba 5690 ssl->in_msg = ssl->in_buf + 13;
marcozecchini 0:9fca2b23d0ba 5691 ssl->in_msgtype = 0;
marcozecchini 0:9fca2b23d0ba 5692 ssl->in_msglen = 0;
marcozecchini 0:9fca2b23d0ba 5693 if( partial == 0 )
marcozecchini 0:9fca2b23d0ba 5694 ssl->in_left = 0;
marcozecchini 0:9fca2b23d0ba 5695 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 5696 ssl->next_record_offset = 0;
marcozecchini 0:9fca2b23d0ba 5697 ssl->in_epoch = 0;
marcozecchini 0:9fca2b23d0ba 5698 #endif
marcozecchini 0:9fca2b23d0ba 5699 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
marcozecchini 0:9fca2b23d0ba 5700 ssl_dtls_replay_reset( ssl );
marcozecchini 0:9fca2b23d0ba 5701 #endif
marcozecchini 0:9fca2b23d0ba 5702
marcozecchini 0:9fca2b23d0ba 5703 ssl->in_hslen = 0;
marcozecchini 0:9fca2b23d0ba 5704 ssl->nb_zero = 0;
marcozecchini 0:9fca2b23d0ba 5705
marcozecchini 0:9fca2b23d0ba 5706 ssl->keep_current_message = 0;
marcozecchini 0:9fca2b23d0ba 5707
marcozecchini 0:9fca2b23d0ba 5708 ssl->out_msg = ssl->out_buf + 13;
marcozecchini 0:9fca2b23d0ba 5709 ssl->out_msgtype = 0;
marcozecchini 0:9fca2b23d0ba 5710 ssl->out_msglen = 0;
marcozecchini 0:9fca2b23d0ba 5711 ssl->out_left = 0;
marcozecchini 0:9fca2b23d0ba 5712 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
marcozecchini 0:9fca2b23d0ba 5713 if( ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED )
marcozecchini 0:9fca2b23d0ba 5714 ssl->split_done = 0;
marcozecchini 0:9fca2b23d0ba 5715 #endif
marcozecchini 0:9fca2b23d0ba 5716
marcozecchini 0:9fca2b23d0ba 5717 ssl->transform_in = NULL;
marcozecchini 0:9fca2b23d0ba 5718 ssl->transform_out = NULL;
marcozecchini 0:9fca2b23d0ba 5719
marcozecchini 0:9fca2b23d0ba 5720 memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
marcozecchini 0:9fca2b23d0ba 5721 if( partial == 0 )
marcozecchini 0:9fca2b23d0ba 5722 memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
marcozecchini 0:9fca2b23d0ba 5723
marcozecchini 0:9fca2b23d0ba 5724 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 5725 if( mbedtls_ssl_hw_record_reset != NULL )
marcozecchini 0:9fca2b23d0ba 5726 {
marcozecchini 0:9fca2b23d0ba 5727 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_reset()" ) );
marcozecchini 0:9fca2b23d0ba 5728 if( ( ret = mbedtls_ssl_hw_record_reset( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 5729 {
marcozecchini 0:9fca2b23d0ba 5730 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_reset", ret );
marcozecchini 0:9fca2b23d0ba 5731 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
marcozecchini 0:9fca2b23d0ba 5732 }
marcozecchini 0:9fca2b23d0ba 5733 }
marcozecchini 0:9fca2b23d0ba 5734 #endif
marcozecchini 0:9fca2b23d0ba 5735
marcozecchini 0:9fca2b23d0ba 5736 if( ssl->transform )
marcozecchini 0:9fca2b23d0ba 5737 {
marcozecchini 0:9fca2b23d0ba 5738 mbedtls_ssl_transform_free( ssl->transform );
marcozecchini 0:9fca2b23d0ba 5739 mbedtls_free( ssl->transform );
marcozecchini 0:9fca2b23d0ba 5740 ssl->transform = NULL;
marcozecchini 0:9fca2b23d0ba 5741 }
marcozecchini 0:9fca2b23d0ba 5742
marcozecchini 0:9fca2b23d0ba 5743 if( ssl->session )
marcozecchini 0:9fca2b23d0ba 5744 {
marcozecchini 0:9fca2b23d0ba 5745 mbedtls_ssl_session_free( ssl->session );
marcozecchini 0:9fca2b23d0ba 5746 mbedtls_free( ssl->session );
marcozecchini 0:9fca2b23d0ba 5747 ssl->session = NULL;
marcozecchini 0:9fca2b23d0ba 5748 }
marcozecchini 0:9fca2b23d0ba 5749
marcozecchini 0:9fca2b23d0ba 5750 #if defined(MBEDTLS_SSL_ALPN)
marcozecchini 0:9fca2b23d0ba 5751 ssl->alpn_chosen = NULL;
marcozecchini 0:9fca2b23d0ba 5752 #endif
marcozecchini 0:9fca2b23d0ba 5753
marcozecchini 0:9fca2b23d0ba 5754 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 5755 if( partial == 0 )
marcozecchini 0:9fca2b23d0ba 5756 {
marcozecchini 0:9fca2b23d0ba 5757 mbedtls_free( ssl->cli_id );
marcozecchini 0:9fca2b23d0ba 5758 ssl->cli_id = NULL;
marcozecchini 0:9fca2b23d0ba 5759 ssl->cli_id_len = 0;
marcozecchini 0:9fca2b23d0ba 5760 }
marcozecchini 0:9fca2b23d0ba 5761 #endif
marcozecchini 0:9fca2b23d0ba 5762
marcozecchini 0:9fca2b23d0ba 5763 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 5764 return( ret );
marcozecchini 0:9fca2b23d0ba 5765
marcozecchini 0:9fca2b23d0ba 5766 return( 0 );
marcozecchini 0:9fca2b23d0ba 5767 }
marcozecchini 0:9fca2b23d0ba 5768
marcozecchini 0:9fca2b23d0ba 5769 /*
marcozecchini 0:9fca2b23d0ba 5770 * Reset an initialized and used SSL context for re-use while retaining
marcozecchini 0:9fca2b23d0ba 5771 * all application-set variables, function pointers and data.
marcozecchini 0:9fca2b23d0ba 5772 */
marcozecchini 0:9fca2b23d0ba 5773 int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 5774 {
marcozecchini 0:9fca2b23d0ba 5775 return( ssl_session_reset_int( ssl, 0 ) );
marcozecchini 0:9fca2b23d0ba 5776 }
marcozecchini 0:9fca2b23d0ba 5777
marcozecchini 0:9fca2b23d0ba 5778 /*
marcozecchini 0:9fca2b23d0ba 5779 * SSL set accessors
marcozecchini 0:9fca2b23d0ba 5780 */
marcozecchini 0:9fca2b23d0ba 5781 void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint )
marcozecchini 0:9fca2b23d0ba 5782 {
marcozecchini 0:9fca2b23d0ba 5783 conf->endpoint = endpoint;
marcozecchini 0:9fca2b23d0ba 5784 }
marcozecchini 0:9fca2b23d0ba 5785
marcozecchini 0:9fca2b23d0ba 5786 void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport )
marcozecchini 0:9fca2b23d0ba 5787 {
marcozecchini 0:9fca2b23d0ba 5788 conf->transport = transport;
marcozecchini 0:9fca2b23d0ba 5789 }
marcozecchini 0:9fca2b23d0ba 5790
marcozecchini 0:9fca2b23d0ba 5791 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
marcozecchini 0:9fca2b23d0ba 5792 void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode )
marcozecchini 0:9fca2b23d0ba 5793 {
marcozecchini 0:9fca2b23d0ba 5794 conf->anti_replay = mode;
marcozecchini 0:9fca2b23d0ba 5795 }
marcozecchini 0:9fca2b23d0ba 5796 #endif
marcozecchini 0:9fca2b23d0ba 5797
marcozecchini 0:9fca2b23d0ba 5798 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
marcozecchini 0:9fca2b23d0ba 5799 void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit )
marcozecchini 0:9fca2b23d0ba 5800 {
marcozecchini 0:9fca2b23d0ba 5801 conf->badmac_limit = limit;
marcozecchini 0:9fca2b23d0ba 5802 }
marcozecchini 0:9fca2b23d0ba 5803 #endif
marcozecchini 0:9fca2b23d0ba 5804
marcozecchini 0:9fca2b23d0ba 5805 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 5806 void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max )
marcozecchini 0:9fca2b23d0ba 5807 {
marcozecchini 0:9fca2b23d0ba 5808 conf->hs_timeout_min = min;
marcozecchini 0:9fca2b23d0ba 5809 conf->hs_timeout_max = max;
marcozecchini 0:9fca2b23d0ba 5810 }
marcozecchini 0:9fca2b23d0ba 5811 #endif
marcozecchini 0:9fca2b23d0ba 5812
marcozecchini 0:9fca2b23d0ba 5813 void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode )
marcozecchini 0:9fca2b23d0ba 5814 {
marcozecchini 0:9fca2b23d0ba 5815 conf->authmode = authmode;
marcozecchini 0:9fca2b23d0ba 5816 }
marcozecchini 0:9fca2b23d0ba 5817
marcozecchini 0:9fca2b23d0ba 5818 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 5819 void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5820 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
marcozecchini 0:9fca2b23d0ba 5821 void *p_vrfy )
marcozecchini 0:9fca2b23d0ba 5822 {
marcozecchini 0:9fca2b23d0ba 5823 conf->f_vrfy = f_vrfy;
marcozecchini 0:9fca2b23d0ba 5824 conf->p_vrfy = p_vrfy;
marcozecchini 0:9fca2b23d0ba 5825 }
marcozecchini 0:9fca2b23d0ba 5826 #endif /* MBEDTLS_X509_CRT_PARSE_C */
marcozecchini 0:9fca2b23d0ba 5827
marcozecchini 0:9fca2b23d0ba 5828 void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5829 int (*f_rng)(void *, unsigned char *, size_t),
marcozecchini 0:9fca2b23d0ba 5830 void *p_rng )
marcozecchini 0:9fca2b23d0ba 5831 {
marcozecchini 0:9fca2b23d0ba 5832 conf->f_rng = f_rng;
marcozecchini 0:9fca2b23d0ba 5833 conf->p_rng = p_rng;
marcozecchini 0:9fca2b23d0ba 5834 }
marcozecchini 0:9fca2b23d0ba 5835
marcozecchini 0:9fca2b23d0ba 5836 void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5837 void (*f_dbg)(void *, int, const char *, int, const char *),
marcozecchini 0:9fca2b23d0ba 5838 void *p_dbg )
marcozecchini 0:9fca2b23d0ba 5839 {
marcozecchini 0:9fca2b23d0ba 5840 conf->f_dbg = f_dbg;
marcozecchini 0:9fca2b23d0ba 5841 conf->p_dbg = p_dbg;
marcozecchini 0:9fca2b23d0ba 5842 }
marcozecchini 0:9fca2b23d0ba 5843
marcozecchini 0:9fca2b23d0ba 5844 void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 5845 void *p_bio,
marcozecchini 0:9fca2b23d0ba 5846 mbedtls_ssl_send_t *f_send,
marcozecchini 0:9fca2b23d0ba 5847 mbedtls_ssl_recv_t *f_recv,
marcozecchini 0:9fca2b23d0ba 5848 mbedtls_ssl_recv_timeout_t *f_recv_timeout )
marcozecchini 0:9fca2b23d0ba 5849 {
marcozecchini 0:9fca2b23d0ba 5850 ssl->p_bio = p_bio;
marcozecchini 0:9fca2b23d0ba 5851 ssl->f_send = f_send;
marcozecchini 0:9fca2b23d0ba 5852 ssl->f_recv = f_recv;
marcozecchini 0:9fca2b23d0ba 5853 ssl->f_recv_timeout = f_recv_timeout;
marcozecchini 0:9fca2b23d0ba 5854 }
marcozecchini 0:9fca2b23d0ba 5855
marcozecchini 0:9fca2b23d0ba 5856 void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout )
marcozecchini 0:9fca2b23d0ba 5857 {
marcozecchini 0:9fca2b23d0ba 5858 conf->read_timeout = timeout;
marcozecchini 0:9fca2b23d0ba 5859 }
marcozecchini 0:9fca2b23d0ba 5860
marcozecchini 0:9fca2b23d0ba 5861 void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 5862 void *p_timer,
marcozecchini 0:9fca2b23d0ba 5863 mbedtls_ssl_set_timer_t *f_set_timer,
marcozecchini 0:9fca2b23d0ba 5864 mbedtls_ssl_get_timer_t *f_get_timer )
marcozecchini 0:9fca2b23d0ba 5865 {
marcozecchini 0:9fca2b23d0ba 5866 ssl->p_timer = p_timer;
marcozecchini 0:9fca2b23d0ba 5867 ssl->f_set_timer = f_set_timer;
marcozecchini 0:9fca2b23d0ba 5868 ssl->f_get_timer = f_get_timer;
marcozecchini 0:9fca2b23d0ba 5869
marcozecchini 0:9fca2b23d0ba 5870 /* Make sure we start with no timer running */
marcozecchini 0:9fca2b23d0ba 5871 ssl_set_timer( ssl, 0 );
marcozecchini 0:9fca2b23d0ba 5872 }
marcozecchini 0:9fca2b23d0ba 5873
marcozecchini 0:9fca2b23d0ba 5874 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 5875 void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5876 void *p_cache,
marcozecchini 0:9fca2b23d0ba 5877 int (*f_get_cache)(void *, mbedtls_ssl_session *),
marcozecchini 0:9fca2b23d0ba 5878 int (*f_set_cache)(void *, const mbedtls_ssl_session *) )
marcozecchini 0:9fca2b23d0ba 5879 {
marcozecchini 0:9fca2b23d0ba 5880 conf->p_cache = p_cache;
marcozecchini 0:9fca2b23d0ba 5881 conf->f_get_cache = f_get_cache;
marcozecchini 0:9fca2b23d0ba 5882 conf->f_set_cache = f_set_cache;
marcozecchini 0:9fca2b23d0ba 5883 }
marcozecchini 0:9fca2b23d0ba 5884 #endif /* MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 5885
marcozecchini 0:9fca2b23d0ba 5886 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 5887 int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session )
marcozecchini 0:9fca2b23d0ba 5888 {
marcozecchini 0:9fca2b23d0ba 5889 int ret;
marcozecchini 0:9fca2b23d0ba 5890
marcozecchini 0:9fca2b23d0ba 5891 if( ssl == NULL ||
marcozecchini 0:9fca2b23d0ba 5892 session == NULL ||
marcozecchini 0:9fca2b23d0ba 5893 ssl->session_negotiate == NULL ||
marcozecchini 0:9fca2b23d0ba 5894 ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 5895 {
marcozecchini 0:9fca2b23d0ba 5896 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 5897 }
marcozecchini 0:9fca2b23d0ba 5898
marcozecchini 0:9fca2b23d0ba 5899 if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 5900 return( ret );
marcozecchini 0:9fca2b23d0ba 5901
marcozecchini 0:9fca2b23d0ba 5902 ssl->handshake->resume = 1;
marcozecchini 0:9fca2b23d0ba 5903
marcozecchini 0:9fca2b23d0ba 5904 return( 0 );
marcozecchini 0:9fca2b23d0ba 5905 }
marcozecchini 0:9fca2b23d0ba 5906 #endif /* MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 5907
marcozecchini 0:9fca2b23d0ba 5908 void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5909 const int *ciphersuites )
marcozecchini 0:9fca2b23d0ba 5910 {
marcozecchini 0:9fca2b23d0ba 5911 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites;
marcozecchini 0:9fca2b23d0ba 5912 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites;
marcozecchini 0:9fca2b23d0ba 5913 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites;
marcozecchini 0:9fca2b23d0ba 5914 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites;
marcozecchini 0:9fca2b23d0ba 5915 }
marcozecchini 0:9fca2b23d0ba 5916
marcozecchini 0:9fca2b23d0ba 5917 void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5918 const int *ciphersuites,
marcozecchini 0:9fca2b23d0ba 5919 int major, int minor )
marcozecchini 0:9fca2b23d0ba 5920 {
marcozecchini 0:9fca2b23d0ba 5921 if( major != MBEDTLS_SSL_MAJOR_VERSION_3 )
marcozecchini 0:9fca2b23d0ba 5922 return;
marcozecchini 0:9fca2b23d0ba 5923
marcozecchini 0:9fca2b23d0ba 5924 if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 )
marcozecchini 0:9fca2b23d0ba 5925 return;
marcozecchini 0:9fca2b23d0ba 5926
marcozecchini 0:9fca2b23d0ba 5927 conf->ciphersuite_list[minor] = ciphersuites;
marcozecchini 0:9fca2b23d0ba 5928 }
marcozecchini 0:9fca2b23d0ba 5929
marcozecchini 0:9fca2b23d0ba 5930 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 5931 void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5932 const mbedtls_x509_crt_profile *profile )
marcozecchini 0:9fca2b23d0ba 5933 {
marcozecchini 0:9fca2b23d0ba 5934 conf->cert_profile = profile;
marcozecchini 0:9fca2b23d0ba 5935 }
marcozecchini 0:9fca2b23d0ba 5936
marcozecchini 0:9fca2b23d0ba 5937 /* Append a new keycert entry to a (possibly empty) list */
marcozecchini 0:9fca2b23d0ba 5938 static int ssl_append_key_cert( mbedtls_ssl_key_cert **head,
marcozecchini 0:9fca2b23d0ba 5939 mbedtls_x509_crt *cert,
marcozecchini 0:9fca2b23d0ba 5940 mbedtls_pk_context *key )
marcozecchini 0:9fca2b23d0ba 5941 {
marcozecchini 0:9fca2b23d0ba 5942 mbedtls_ssl_key_cert *new;
marcozecchini 0:9fca2b23d0ba 5943
marcozecchini 0:9fca2b23d0ba 5944 new = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) );
marcozecchini 0:9fca2b23d0ba 5945 if( new == NULL )
marcozecchini 0:9fca2b23d0ba 5946 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 5947
marcozecchini 0:9fca2b23d0ba 5948 new->cert = cert;
marcozecchini 0:9fca2b23d0ba 5949 new->key = key;
marcozecchini 0:9fca2b23d0ba 5950 new->next = NULL;
marcozecchini 0:9fca2b23d0ba 5951
marcozecchini 0:9fca2b23d0ba 5952 /* Update head is the list was null, else add to the end */
marcozecchini 0:9fca2b23d0ba 5953 if( *head == NULL )
marcozecchini 0:9fca2b23d0ba 5954 {
marcozecchini 0:9fca2b23d0ba 5955 *head = new;
marcozecchini 0:9fca2b23d0ba 5956 }
marcozecchini 0:9fca2b23d0ba 5957 else
marcozecchini 0:9fca2b23d0ba 5958 {
marcozecchini 0:9fca2b23d0ba 5959 mbedtls_ssl_key_cert *cur = *head;
marcozecchini 0:9fca2b23d0ba 5960 while( cur->next != NULL )
marcozecchini 0:9fca2b23d0ba 5961 cur = cur->next;
marcozecchini 0:9fca2b23d0ba 5962 cur->next = new;
marcozecchini 0:9fca2b23d0ba 5963 }
marcozecchini 0:9fca2b23d0ba 5964
marcozecchini 0:9fca2b23d0ba 5965 return( 0 );
marcozecchini 0:9fca2b23d0ba 5966 }
marcozecchini 0:9fca2b23d0ba 5967
marcozecchini 0:9fca2b23d0ba 5968 int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5969 mbedtls_x509_crt *own_cert,
marcozecchini 0:9fca2b23d0ba 5970 mbedtls_pk_context *pk_key )
marcozecchini 0:9fca2b23d0ba 5971 {
marcozecchini 0:9fca2b23d0ba 5972 return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) );
marcozecchini 0:9fca2b23d0ba 5973 }
marcozecchini 0:9fca2b23d0ba 5974
marcozecchini 0:9fca2b23d0ba 5975 void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 5976 mbedtls_x509_crt *ca_chain,
marcozecchini 0:9fca2b23d0ba 5977 mbedtls_x509_crl *ca_crl )
marcozecchini 0:9fca2b23d0ba 5978 {
marcozecchini 0:9fca2b23d0ba 5979 conf->ca_chain = ca_chain;
marcozecchini 0:9fca2b23d0ba 5980 conf->ca_crl = ca_crl;
marcozecchini 0:9fca2b23d0ba 5981 }
marcozecchini 0:9fca2b23d0ba 5982 #endif /* MBEDTLS_X509_CRT_PARSE_C */
marcozecchini 0:9fca2b23d0ba 5983
marcozecchini 0:9fca2b23d0ba 5984 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
marcozecchini 0:9fca2b23d0ba 5985 int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 5986 mbedtls_x509_crt *own_cert,
marcozecchini 0:9fca2b23d0ba 5987 mbedtls_pk_context *pk_key )
marcozecchini 0:9fca2b23d0ba 5988 {
marcozecchini 0:9fca2b23d0ba 5989 return( ssl_append_key_cert( &ssl->handshake->sni_key_cert,
marcozecchini 0:9fca2b23d0ba 5990 own_cert, pk_key ) );
marcozecchini 0:9fca2b23d0ba 5991 }
marcozecchini 0:9fca2b23d0ba 5992
marcozecchini 0:9fca2b23d0ba 5993 void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 5994 mbedtls_x509_crt *ca_chain,
marcozecchini 0:9fca2b23d0ba 5995 mbedtls_x509_crl *ca_crl )
marcozecchini 0:9fca2b23d0ba 5996 {
marcozecchini 0:9fca2b23d0ba 5997 ssl->handshake->sni_ca_chain = ca_chain;
marcozecchini 0:9fca2b23d0ba 5998 ssl->handshake->sni_ca_crl = ca_crl;
marcozecchini 0:9fca2b23d0ba 5999 }
marcozecchini 0:9fca2b23d0ba 6000
marcozecchini 0:9fca2b23d0ba 6001 void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 6002 int authmode )
marcozecchini 0:9fca2b23d0ba 6003 {
marcozecchini 0:9fca2b23d0ba 6004 ssl->handshake->sni_authmode = authmode;
marcozecchini 0:9fca2b23d0ba 6005 }
marcozecchini 0:9fca2b23d0ba 6006 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
marcozecchini 0:9fca2b23d0ba 6007
marcozecchini 0:9fca2b23d0ba 6008 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
marcozecchini 0:9fca2b23d0ba 6009 /*
marcozecchini 0:9fca2b23d0ba 6010 * Set EC J-PAKE password for current handshake
marcozecchini 0:9fca2b23d0ba 6011 */
marcozecchini 0:9fca2b23d0ba 6012 int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 6013 const unsigned char *pw,
marcozecchini 0:9fca2b23d0ba 6014 size_t pw_len )
marcozecchini 0:9fca2b23d0ba 6015 {
marcozecchini 0:9fca2b23d0ba 6016 mbedtls_ecjpake_role role;
marcozecchini 0:9fca2b23d0ba 6017
marcozecchini 0:9fca2b23d0ba 6018 if( ssl->handshake == NULL || ssl->conf == NULL )
marcozecchini 0:9fca2b23d0ba 6019 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6020
marcozecchini 0:9fca2b23d0ba 6021 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 6022 role = MBEDTLS_ECJPAKE_SERVER;
marcozecchini 0:9fca2b23d0ba 6023 else
marcozecchini 0:9fca2b23d0ba 6024 role = MBEDTLS_ECJPAKE_CLIENT;
marcozecchini 0:9fca2b23d0ba 6025
marcozecchini 0:9fca2b23d0ba 6026 return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx,
marcozecchini 0:9fca2b23d0ba 6027 role,
marcozecchini 0:9fca2b23d0ba 6028 MBEDTLS_MD_SHA256,
marcozecchini 0:9fca2b23d0ba 6029 MBEDTLS_ECP_DP_SECP256R1,
marcozecchini 0:9fca2b23d0ba 6030 pw, pw_len ) );
marcozecchini 0:9fca2b23d0ba 6031 }
marcozecchini 0:9fca2b23d0ba 6032 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
marcozecchini 0:9fca2b23d0ba 6033
marcozecchini 0:9fca2b23d0ba 6034 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
marcozecchini 0:9fca2b23d0ba 6035 int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6036 const unsigned char *psk, size_t psk_len,
marcozecchini 0:9fca2b23d0ba 6037 const unsigned char *psk_identity, size_t psk_identity_len )
marcozecchini 0:9fca2b23d0ba 6038 {
marcozecchini 0:9fca2b23d0ba 6039 if( psk == NULL || psk_identity == NULL )
marcozecchini 0:9fca2b23d0ba 6040 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6041
marcozecchini 0:9fca2b23d0ba 6042 if( psk_len > MBEDTLS_PSK_MAX_LEN )
marcozecchini 0:9fca2b23d0ba 6043 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6044
marcozecchini 0:9fca2b23d0ba 6045 /* Identity len will be encoded on two bytes */
marcozecchini 0:9fca2b23d0ba 6046 if( ( psk_identity_len >> 16 ) != 0 ||
marcozecchini 0:9fca2b23d0ba 6047 psk_identity_len > MBEDTLS_SSL_MAX_CONTENT_LEN )
marcozecchini 0:9fca2b23d0ba 6048 {
marcozecchini 0:9fca2b23d0ba 6049 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6050 }
marcozecchini 0:9fca2b23d0ba 6051
marcozecchini 0:9fca2b23d0ba 6052 if( conf->psk != NULL || conf->psk_identity != NULL )
marcozecchini 0:9fca2b23d0ba 6053 {
marcozecchini 0:9fca2b23d0ba 6054 mbedtls_free( conf->psk );
marcozecchini 0:9fca2b23d0ba 6055 mbedtls_free( conf->psk_identity );
marcozecchini 0:9fca2b23d0ba 6056 conf->psk = NULL;
marcozecchini 0:9fca2b23d0ba 6057 conf->psk_identity = NULL;
marcozecchini 0:9fca2b23d0ba 6058 }
marcozecchini 0:9fca2b23d0ba 6059
marcozecchini 0:9fca2b23d0ba 6060 if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ||
marcozecchini 0:9fca2b23d0ba 6061 ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 6062 {
marcozecchini 0:9fca2b23d0ba 6063 mbedtls_free( conf->psk );
marcozecchini 0:9fca2b23d0ba 6064 mbedtls_free( conf->psk_identity );
marcozecchini 0:9fca2b23d0ba 6065 conf->psk = NULL;
marcozecchini 0:9fca2b23d0ba 6066 conf->psk_identity = NULL;
marcozecchini 0:9fca2b23d0ba 6067 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 6068 }
marcozecchini 0:9fca2b23d0ba 6069
marcozecchini 0:9fca2b23d0ba 6070 conf->psk_len = psk_len;
marcozecchini 0:9fca2b23d0ba 6071 conf->psk_identity_len = psk_identity_len;
marcozecchini 0:9fca2b23d0ba 6072
marcozecchini 0:9fca2b23d0ba 6073 memcpy( conf->psk, psk, conf->psk_len );
marcozecchini 0:9fca2b23d0ba 6074 memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len );
marcozecchini 0:9fca2b23d0ba 6075
marcozecchini 0:9fca2b23d0ba 6076 return( 0 );
marcozecchini 0:9fca2b23d0ba 6077 }
marcozecchini 0:9fca2b23d0ba 6078
marcozecchini 0:9fca2b23d0ba 6079 int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 6080 const unsigned char *psk, size_t psk_len )
marcozecchini 0:9fca2b23d0ba 6081 {
marcozecchini 0:9fca2b23d0ba 6082 if( psk == NULL || ssl->handshake == NULL )
marcozecchini 0:9fca2b23d0ba 6083 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6084
marcozecchini 0:9fca2b23d0ba 6085 if( psk_len > MBEDTLS_PSK_MAX_LEN )
marcozecchini 0:9fca2b23d0ba 6086 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6087
marcozecchini 0:9fca2b23d0ba 6088 if( ssl->handshake->psk != NULL )
marcozecchini 0:9fca2b23d0ba 6089 mbedtls_free( ssl->handshake->psk );
marcozecchini 0:9fca2b23d0ba 6090
marcozecchini 0:9fca2b23d0ba 6091 if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
marcozecchini 0:9fca2b23d0ba 6092 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 6093
marcozecchini 0:9fca2b23d0ba 6094 ssl->handshake->psk_len = psk_len;
marcozecchini 0:9fca2b23d0ba 6095 memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len );
marcozecchini 0:9fca2b23d0ba 6096
marcozecchini 0:9fca2b23d0ba 6097 return( 0 );
marcozecchini 0:9fca2b23d0ba 6098 }
marcozecchini 0:9fca2b23d0ba 6099
marcozecchini 0:9fca2b23d0ba 6100 void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6101 int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
marcozecchini 0:9fca2b23d0ba 6102 size_t),
marcozecchini 0:9fca2b23d0ba 6103 void *p_psk )
marcozecchini 0:9fca2b23d0ba 6104 {
marcozecchini 0:9fca2b23d0ba 6105 conf->f_psk = f_psk;
marcozecchini 0:9fca2b23d0ba 6106 conf->p_psk = p_psk;
marcozecchini 0:9fca2b23d0ba 6107 }
marcozecchini 0:9fca2b23d0ba 6108 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
marcozecchini 0:9fca2b23d0ba 6109
marcozecchini 0:9fca2b23d0ba 6110 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 6111 int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G )
marcozecchini 0:9fca2b23d0ba 6112 {
marcozecchini 0:9fca2b23d0ba 6113 int ret;
marcozecchini 0:9fca2b23d0ba 6114
marcozecchini 0:9fca2b23d0ba 6115 if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 ||
marcozecchini 0:9fca2b23d0ba 6116 ( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6117 {
marcozecchini 0:9fca2b23d0ba 6118 mbedtls_mpi_free( &conf->dhm_P );
marcozecchini 0:9fca2b23d0ba 6119 mbedtls_mpi_free( &conf->dhm_G );
marcozecchini 0:9fca2b23d0ba 6120 return( ret );
marcozecchini 0:9fca2b23d0ba 6121 }
marcozecchini 0:9fca2b23d0ba 6122
marcozecchini 0:9fca2b23d0ba 6123 return( 0 );
marcozecchini 0:9fca2b23d0ba 6124 }
marcozecchini 0:9fca2b23d0ba 6125
marcozecchini 0:9fca2b23d0ba 6126 int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx )
marcozecchini 0:9fca2b23d0ba 6127 {
marcozecchini 0:9fca2b23d0ba 6128 int ret;
marcozecchini 0:9fca2b23d0ba 6129
marcozecchini 0:9fca2b23d0ba 6130 if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
marcozecchini 0:9fca2b23d0ba 6131 ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6132 {
marcozecchini 0:9fca2b23d0ba 6133 mbedtls_mpi_free( &conf->dhm_P );
marcozecchini 0:9fca2b23d0ba 6134 mbedtls_mpi_free( &conf->dhm_G );
marcozecchini 0:9fca2b23d0ba 6135 return( ret );
marcozecchini 0:9fca2b23d0ba 6136 }
marcozecchini 0:9fca2b23d0ba 6137
marcozecchini 0:9fca2b23d0ba 6138 return( 0 );
marcozecchini 0:9fca2b23d0ba 6139 }
marcozecchini 0:9fca2b23d0ba 6140 #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 6141
marcozecchini 0:9fca2b23d0ba 6142 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 6143 /*
marcozecchini 0:9fca2b23d0ba 6144 * Set the minimum length for Diffie-Hellman parameters
marcozecchini 0:9fca2b23d0ba 6145 */
marcozecchini 0:9fca2b23d0ba 6146 void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6147 unsigned int bitlen )
marcozecchini 0:9fca2b23d0ba 6148 {
marcozecchini 0:9fca2b23d0ba 6149 conf->dhm_min_bitlen = bitlen;
marcozecchini 0:9fca2b23d0ba 6150 }
marcozecchini 0:9fca2b23d0ba 6151 #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 6152
marcozecchini 0:9fca2b23d0ba 6153 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
marcozecchini 0:9fca2b23d0ba 6154 /*
marcozecchini 0:9fca2b23d0ba 6155 * Set allowed/preferred hashes for handshake signatures
marcozecchini 0:9fca2b23d0ba 6156 */
marcozecchini 0:9fca2b23d0ba 6157 void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6158 const int *hashes )
marcozecchini 0:9fca2b23d0ba 6159 {
marcozecchini 0:9fca2b23d0ba 6160 conf->sig_hashes = hashes;
marcozecchini 0:9fca2b23d0ba 6161 }
marcozecchini 0:9fca2b23d0ba 6162 #endif
marcozecchini 0:9fca2b23d0ba 6163
marcozecchini 0:9fca2b23d0ba 6164 #if defined(MBEDTLS_ECP_C)
marcozecchini 0:9fca2b23d0ba 6165 /*
marcozecchini 0:9fca2b23d0ba 6166 * Set the allowed elliptic curves
marcozecchini 0:9fca2b23d0ba 6167 */
marcozecchini 0:9fca2b23d0ba 6168 void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6169 const mbedtls_ecp_group_id *curve_list )
marcozecchini 0:9fca2b23d0ba 6170 {
marcozecchini 0:9fca2b23d0ba 6171 conf->curve_list = curve_list;
marcozecchini 0:9fca2b23d0ba 6172 }
marcozecchini 0:9fca2b23d0ba 6173 #endif
marcozecchini 0:9fca2b23d0ba 6174
marcozecchini 0:9fca2b23d0ba 6175 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 6176 int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname )
marcozecchini 0:9fca2b23d0ba 6177 {
marcozecchini 0:9fca2b23d0ba 6178 size_t hostname_len;
marcozecchini 0:9fca2b23d0ba 6179
marcozecchini 0:9fca2b23d0ba 6180 if( hostname == NULL )
marcozecchini 0:9fca2b23d0ba 6181 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6182
marcozecchini 0:9fca2b23d0ba 6183 hostname_len = strlen( hostname );
marcozecchini 0:9fca2b23d0ba 6184
marcozecchini 0:9fca2b23d0ba 6185 if( hostname_len + 1 == 0 )
marcozecchini 0:9fca2b23d0ba 6186 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6187
marcozecchini 0:9fca2b23d0ba 6188 if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN )
marcozecchini 0:9fca2b23d0ba 6189 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6190
marcozecchini 0:9fca2b23d0ba 6191 ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 );
marcozecchini 0:9fca2b23d0ba 6192
marcozecchini 0:9fca2b23d0ba 6193 if( ssl->hostname == NULL )
marcozecchini 0:9fca2b23d0ba 6194 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 6195
marcozecchini 0:9fca2b23d0ba 6196 memcpy( ssl->hostname, hostname, hostname_len );
marcozecchini 0:9fca2b23d0ba 6197
marcozecchini 0:9fca2b23d0ba 6198 ssl->hostname[hostname_len] = '\0';
marcozecchini 0:9fca2b23d0ba 6199
marcozecchini 0:9fca2b23d0ba 6200 return( 0 );
marcozecchini 0:9fca2b23d0ba 6201 }
marcozecchini 0:9fca2b23d0ba 6202 #endif
marcozecchini 0:9fca2b23d0ba 6203
marcozecchini 0:9fca2b23d0ba 6204 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
marcozecchini 0:9fca2b23d0ba 6205 void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6206 int (*f_sni)(void *, mbedtls_ssl_context *,
marcozecchini 0:9fca2b23d0ba 6207 const unsigned char *, size_t),
marcozecchini 0:9fca2b23d0ba 6208 void *p_sni )
marcozecchini 0:9fca2b23d0ba 6209 {
marcozecchini 0:9fca2b23d0ba 6210 conf->f_sni = f_sni;
marcozecchini 0:9fca2b23d0ba 6211 conf->p_sni = p_sni;
marcozecchini 0:9fca2b23d0ba 6212 }
marcozecchini 0:9fca2b23d0ba 6213 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
marcozecchini 0:9fca2b23d0ba 6214
marcozecchini 0:9fca2b23d0ba 6215 #if defined(MBEDTLS_SSL_ALPN)
marcozecchini 0:9fca2b23d0ba 6216 int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos )
marcozecchini 0:9fca2b23d0ba 6217 {
marcozecchini 0:9fca2b23d0ba 6218 size_t cur_len, tot_len;
marcozecchini 0:9fca2b23d0ba 6219 const char **p;
marcozecchini 0:9fca2b23d0ba 6220
marcozecchini 0:9fca2b23d0ba 6221 /*
marcozecchini 0:9fca2b23d0ba 6222 * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings
marcozecchini 0:9fca2b23d0ba 6223 * MUST NOT be truncated."
marcozecchini 0:9fca2b23d0ba 6224 * We check lengths now rather than later.
marcozecchini 0:9fca2b23d0ba 6225 */
marcozecchini 0:9fca2b23d0ba 6226 tot_len = 0;
marcozecchini 0:9fca2b23d0ba 6227 for( p = protos; *p != NULL; p++ )
marcozecchini 0:9fca2b23d0ba 6228 {
marcozecchini 0:9fca2b23d0ba 6229 cur_len = strlen( *p );
marcozecchini 0:9fca2b23d0ba 6230 tot_len += cur_len;
marcozecchini 0:9fca2b23d0ba 6231
marcozecchini 0:9fca2b23d0ba 6232 if( cur_len == 0 || cur_len > 255 || tot_len > 65535 )
marcozecchini 0:9fca2b23d0ba 6233 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6234 }
marcozecchini 0:9fca2b23d0ba 6235
marcozecchini 0:9fca2b23d0ba 6236 conf->alpn_list = protos;
marcozecchini 0:9fca2b23d0ba 6237
marcozecchini 0:9fca2b23d0ba 6238 return( 0 );
marcozecchini 0:9fca2b23d0ba 6239 }
marcozecchini 0:9fca2b23d0ba 6240
marcozecchini 0:9fca2b23d0ba 6241 const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6242 {
marcozecchini 0:9fca2b23d0ba 6243 return( ssl->alpn_chosen );
marcozecchini 0:9fca2b23d0ba 6244 }
marcozecchini 0:9fca2b23d0ba 6245 #endif /* MBEDTLS_SSL_ALPN */
marcozecchini 0:9fca2b23d0ba 6246
marcozecchini 0:9fca2b23d0ba 6247 void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
marcozecchini 0:9fca2b23d0ba 6248 {
marcozecchini 0:9fca2b23d0ba 6249 conf->max_major_ver = major;
marcozecchini 0:9fca2b23d0ba 6250 conf->max_minor_ver = minor;
marcozecchini 0:9fca2b23d0ba 6251 }
marcozecchini 0:9fca2b23d0ba 6252
marcozecchini 0:9fca2b23d0ba 6253 void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor )
marcozecchini 0:9fca2b23d0ba 6254 {
marcozecchini 0:9fca2b23d0ba 6255 conf->min_major_ver = major;
marcozecchini 0:9fca2b23d0ba 6256 conf->min_minor_ver = minor;
marcozecchini 0:9fca2b23d0ba 6257 }
marcozecchini 0:9fca2b23d0ba 6258
marcozecchini 0:9fca2b23d0ba 6259 #if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 6260 void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback )
marcozecchini 0:9fca2b23d0ba 6261 {
marcozecchini 0:9fca2b23d0ba 6262 conf->fallback = fallback;
marcozecchini 0:9fca2b23d0ba 6263 }
marcozecchini 0:9fca2b23d0ba 6264 #endif
marcozecchini 0:9fca2b23d0ba 6265
marcozecchini 0:9fca2b23d0ba 6266 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 6267 void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6268 char cert_req_ca_list )
marcozecchini 0:9fca2b23d0ba 6269 {
marcozecchini 0:9fca2b23d0ba 6270 conf->cert_req_ca_list = cert_req_ca_list;
marcozecchini 0:9fca2b23d0ba 6271 }
marcozecchini 0:9fca2b23d0ba 6272 #endif
marcozecchini 0:9fca2b23d0ba 6273
marcozecchini 0:9fca2b23d0ba 6274 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
marcozecchini 0:9fca2b23d0ba 6275 void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm )
marcozecchini 0:9fca2b23d0ba 6276 {
marcozecchini 0:9fca2b23d0ba 6277 conf->encrypt_then_mac = etm;
marcozecchini 0:9fca2b23d0ba 6278 }
marcozecchini 0:9fca2b23d0ba 6279 #endif
marcozecchini 0:9fca2b23d0ba 6280
marcozecchini 0:9fca2b23d0ba 6281 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
marcozecchini 0:9fca2b23d0ba 6282 void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems )
marcozecchini 0:9fca2b23d0ba 6283 {
marcozecchini 0:9fca2b23d0ba 6284 conf->extended_ms = ems;
marcozecchini 0:9fca2b23d0ba 6285 }
marcozecchini 0:9fca2b23d0ba 6286 #endif
marcozecchini 0:9fca2b23d0ba 6287
marcozecchini 0:9fca2b23d0ba 6288 #if defined(MBEDTLS_ARC4_C)
marcozecchini 0:9fca2b23d0ba 6289 void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 )
marcozecchini 0:9fca2b23d0ba 6290 {
marcozecchini 0:9fca2b23d0ba 6291 conf->arc4_disabled = arc4;
marcozecchini 0:9fca2b23d0ba 6292 }
marcozecchini 0:9fca2b23d0ba 6293 #endif
marcozecchini 0:9fca2b23d0ba 6294
marcozecchini 0:9fca2b23d0ba 6295 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
marcozecchini 0:9fca2b23d0ba 6296 int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code )
marcozecchini 0:9fca2b23d0ba 6297 {
marcozecchini 0:9fca2b23d0ba 6298 if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ||
marcozecchini 0:9fca2b23d0ba 6299 mfl_code_to_length[mfl_code] > MBEDTLS_SSL_MAX_CONTENT_LEN )
marcozecchini 0:9fca2b23d0ba 6300 {
marcozecchini 0:9fca2b23d0ba 6301 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6302 }
marcozecchini 0:9fca2b23d0ba 6303
marcozecchini 0:9fca2b23d0ba 6304 conf->mfl_code = mfl_code;
marcozecchini 0:9fca2b23d0ba 6305
marcozecchini 0:9fca2b23d0ba 6306 return( 0 );
marcozecchini 0:9fca2b23d0ba 6307 }
marcozecchini 0:9fca2b23d0ba 6308 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
marcozecchini 0:9fca2b23d0ba 6309
marcozecchini 0:9fca2b23d0ba 6310 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
marcozecchini 0:9fca2b23d0ba 6311 void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate )
marcozecchini 0:9fca2b23d0ba 6312 {
marcozecchini 0:9fca2b23d0ba 6313 conf->trunc_hmac = truncate;
marcozecchini 0:9fca2b23d0ba 6314 }
marcozecchini 0:9fca2b23d0ba 6315 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
marcozecchini 0:9fca2b23d0ba 6316
marcozecchini 0:9fca2b23d0ba 6317 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
marcozecchini 0:9fca2b23d0ba 6318 void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split )
marcozecchini 0:9fca2b23d0ba 6319 {
marcozecchini 0:9fca2b23d0ba 6320 conf->cbc_record_splitting = split;
marcozecchini 0:9fca2b23d0ba 6321 }
marcozecchini 0:9fca2b23d0ba 6322 #endif
marcozecchini 0:9fca2b23d0ba 6323
marcozecchini 0:9fca2b23d0ba 6324 void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy )
marcozecchini 0:9fca2b23d0ba 6325 {
marcozecchini 0:9fca2b23d0ba 6326 conf->allow_legacy_renegotiation = allow_legacy;
marcozecchini 0:9fca2b23d0ba 6327 }
marcozecchini 0:9fca2b23d0ba 6328
marcozecchini 0:9fca2b23d0ba 6329 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 6330 void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation )
marcozecchini 0:9fca2b23d0ba 6331 {
marcozecchini 0:9fca2b23d0ba 6332 conf->disable_renegotiation = renegotiation;
marcozecchini 0:9fca2b23d0ba 6333 }
marcozecchini 0:9fca2b23d0ba 6334
marcozecchini 0:9fca2b23d0ba 6335 void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records )
marcozecchini 0:9fca2b23d0ba 6336 {
marcozecchini 0:9fca2b23d0ba 6337 conf->renego_max_records = max_records;
marcozecchini 0:9fca2b23d0ba 6338 }
marcozecchini 0:9fca2b23d0ba 6339
marcozecchini 0:9fca2b23d0ba 6340 void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6341 const unsigned char period[8] )
marcozecchini 0:9fca2b23d0ba 6342 {
marcozecchini 0:9fca2b23d0ba 6343 memcpy( conf->renego_period, period, 8 );
marcozecchini 0:9fca2b23d0ba 6344 }
marcozecchini 0:9fca2b23d0ba 6345 #endif /* MBEDTLS_SSL_RENEGOTIATION */
marcozecchini 0:9fca2b23d0ba 6346
marcozecchini 0:9fca2b23d0ba 6347 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
marcozecchini 0:9fca2b23d0ba 6348 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 6349 void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets )
marcozecchini 0:9fca2b23d0ba 6350 {
marcozecchini 0:9fca2b23d0ba 6351 conf->session_tickets = use_tickets;
marcozecchini 0:9fca2b23d0ba 6352 }
marcozecchini 0:9fca2b23d0ba 6353 #endif
marcozecchini 0:9fca2b23d0ba 6354
marcozecchini 0:9fca2b23d0ba 6355 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 6356 void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6357 mbedtls_ssl_ticket_write_t *f_ticket_write,
marcozecchini 0:9fca2b23d0ba 6358 mbedtls_ssl_ticket_parse_t *f_ticket_parse,
marcozecchini 0:9fca2b23d0ba 6359 void *p_ticket )
marcozecchini 0:9fca2b23d0ba 6360 {
marcozecchini 0:9fca2b23d0ba 6361 conf->f_ticket_write = f_ticket_write;
marcozecchini 0:9fca2b23d0ba 6362 conf->f_ticket_parse = f_ticket_parse;
marcozecchini 0:9fca2b23d0ba 6363 conf->p_ticket = p_ticket;
marcozecchini 0:9fca2b23d0ba 6364 }
marcozecchini 0:9fca2b23d0ba 6365 #endif
marcozecchini 0:9fca2b23d0ba 6366 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
marcozecchini 0:9fca2b23d0ba 6367
marcozecchini 0:9fca2b23d0ba 6368 #if defined(MBEDTLS_SSL_EXPORT_KEYS)
marcozecchini 0:9fca2b23d0ba 6369 void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 6370 mbedtls_ssl_export_keys_t *f_export_keys,
marcozecchini 0:9fca2b23d0ba 6371 void *p_export_keys )
marcozecchini 0:9fca2b23d0ba 6372 {
marcozecchini 0:9fca2b23d0ba 6373 conf->f_export_keys = f_export_keys;
marcozecchini 0:9fca2b23d0ba 6374 conf->p_export_keys = p_export_keys;
marcozecchini 0:9fca2b23d0ba 6375 }
marcozecchini 0:9fca2b23d0ba 6376 #endif
marcozecchini 0:9fca2b23d0ba 6377
marcozecchini 0:9fca2b23d0ba 6378 /*
marcozecchini 0:9fca2b23d0ba 6379 * SSL get accessors
marcozecchini 0:9fca2b23d0ba 6380 */
marcozecchini 0:9fca2b23d0ba 6381 size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6382 {
marcozecchini 0:9fca2b23d0ba 6383 return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
marcozecchini 0:9fca2b23d0ba 6384 }
marcozecchini 0:9fca2b23d0ba 6385
marcozecchini 0:9fca2b23d0ba 6386 uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6387 {
marcozecchini 0:9fca2b23d0ba 6388 if( ssl->session != NULL )
marcozecchini 0:9fca2b23d0ba 6389 return( ssl->session->verify_result );
marcozecchini 0:9fca2b23d0ba 6390
marcozecchini 0:9fca2b23d0ba 6391 if( ssl->session_negotiate != NULL )
marcozecchini 0:9fca2b23d0ba 6392 return( ssl->session_negotiate->verify_result );
marcozecchini 0:9fca2b23d0ba 6393
marcozecchini 0:9fca2b23d0ba 6394 return( 0xFFFFFFFF );
marcozecchini 0:9fca2b23d0ba 6395 }
marcozecchini 0:9fca2b23d0ba 6396
marcozecchini 0:9fca2b23d0ba 6397 const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6398 {
marcozecchini 0:9fca2b23d0ba 6399 if( ssl == NULL || ssl->session == NULL )
marcozecchini 0:9fca2b23d0ba 6400 return( NULL );
marcozecchini 0:9fca2b23d0ba 6401
marcozecchini 0:9fca2b23d0ba 6402 return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite );
marcozecchini 0:9fca2b23d0ba 6403 }
marcozecchini 0:9fca2b23d0ba 6404
marcozecchini 0:9fca2b23d0ba 6405 const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6406 {
marcozecchini 0:9fca2b23d0ba 6407 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 6408 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 6409 {
marcozecchini 0:9fca2b23d0ba 6410 switch( ssl->minor_ver )
marcozecchini 0:9fca2b23d0ba 6411 {
marcozecchini 0:9fca2b23d0ba 6412 case MBEDTLS_SSL_MINOR_VERSION_2:
marcozecchini 0:9fca2b23d0ba 6413 return( "DTLSv1.0" );
marcozecchini 0:9fca2b23d0ba 6414
marcozecchini 0:9fca2b23d0ba 6415 case MBEDTLS_SSL_MINOR_VERSION_3:
marcozecchini 0:9fca2b23d0ba 6416 return( "DTLSv1.2" );
marcozecchini 0:9fca2b23d0ba 6417
marcozecchini 0:9fca2b23d0ba 6418 default:
marcozecchini 0:9fca2b23d0ba 6419 return( "unknown (DTLS)" );
marcozecchini 0:9fca2b23d0ba 6420 }
marcozecchini 0:9fca2b23d0ba 6421 }
marcozecchini 0:9fca2b23d0ba 6422 #endif
marcozecchini 0:9fca2b23d0ba 6423
marcozecchini 0:9fca2b23d0ba 6424 switch( ssl->minor_ver )
marcozecchini 0:9fca2b23d0ba 6425 {
marcozecchini 0:9fca2b23d0ba 6426 case MBEDTLS_SSL_MINOR_VERSION_0:
marcozecchini 0:9fca2b23d0ba 6427 return( "SSLv3.0" );
marcozecchini 0:9fca2b23d0ba 6428
marcozecchini 0:9fca2b23d0ba 6429 case MBEDTLS_SSL_MINOR_VERSION_1:
marcozecchini 0:9fca2b23d0ba 6430 return( "TLSv1.0" );
marcozecchini 0:9fca2b23d0ba 6431
marcozecchini 0:9fca2b23d0ba 6432 case MBEDTLS_SSL_MINOR_VERSION_2:
marcozecchini 0:9fca2b23d0ba 6433 return( "TLSv1.1" );
marcozecchini 0:9fca2b23d0ba 6434
marcozecchini 0:9fca2b23d0ba 6435 case MBEDTLS_SSL_MINOR_VERSION_3:
marcozecchini 0:9fca2b23d0ba 6436 return( "TLSv1.2" );
marcozecchini 0:9fca2b23d0ba 6437
marcozecchini 0:9fca2b23d0ba 6438 default:
marcozecchini 0:9fca2b23d0ba 6439 return( "unknown" );
marcozecchini 0:9fca2b23d0ba 6440 }
marcozecchini 0:9fca2b23d0ba 6441 }
marcozecchini 0:9fca2b23d0ba 6442
marcozecchini 0:9fca2b23d0ba 6443 int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6444 {
marcozecchini 0:9fca2b23d0ba 6445 size_t transform_expansion;
marcozecchini 0:9fca2b23d0ba 6446 const mbedtls_ssl_transform *transform = ssl->transform_out;
marcozecchini 0:9fca2b23d0ba 6447
marcozecchini 0:9fca2b23d0ba 6448 #if defined(MBEDTLS_ZLIB_SUPPORT)
marcozecchini 0:9fca2b23d0ba 6449 if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
marcozecchini 0:9fca2b23d0ba 6450 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
marcozecchini 0:9fca2b23d0ba 6451 #endif
marcozecchini 0:9fca2b23d0ba 6452
marcozecchini 0:9fca2b23d0ba 6453 if( transform == NULL )
marcozecchini 0:9fca2b23d0ba 6454 return( (int) mbedtls_ssl_hdr_len( ssl ) );
marcozecchini 0:9fca2b23d0ba 6455
marcozecchini 0:9fca2b23d0ba 6456 switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
marcozecchini 0:9fca2b23d0ba 6457 {
marcozecchini 0:9fca2b23d0ba 6458 case MBEDTLS_MODE_GCM:
marcozecchini 0:9fca2b23d0ba 6459 case MBEDTLS_MODE_CCM:
marcozecchini 0:9fca2b23d0ba 6460 case MBEDTLS_MODE_STREAM:
marcozecchini 0:9fca2b23d0ba 6461 transform_expansion = transform->minlen;
marcozecchini 0:9fca2b23d0ba 6462 break;
marcozecchini 0:9fca2b23d0ba 6463
marcozecchini 0:9fca2b23d0ba 6464 case MBEDTLS_MODE_CBC:
marcozecchini 0:9fca2b23d0ba 6465 transform_expansion = transform->maclen
marcozecchini 0:9fca2b23d0ba 6466 + mbedtls_cipher_get_block_size( &transform->cipher_ctx_enc );
marcozecchini 0:9fca2b23d0ba 6467 break;
marcozecchini 0:9fca2b23d0ba 6468
marcozecchini 0:9fca2b23d0ba 6469 default:
marcozecchini 0:9fca2b23d0ba 6470 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 6471 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 6472 }
marcozecchini 0:9fca2b23d0ba 6473
marcozecchini 0:9fca2b23d0ba 6474 return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) );
marcozecchini 0:9fca2b23d0ba 6475 }
marcozecchini 0:9fca2b23d0ba 6476
marcozecchini 0:9fca2b23d0ba 6477 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
marcozecchini 0:9fca2b23d0ba 6478 size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6479 {
marcozecchini 0:9fca2b23d0ba 6480 size_t max_len;
marcozecchini 0:9fca2b23d0ba 6481
marcozecchini 0:9fca2b23d0ba 6482 /*
marcozecchini 0:9fca2b23d0ba 6483 * Assume mfl_code is correct since it was checked when set
marcozecchini 0:9fca2b23d0ba 6484 */
marcozecchini 0:9fca2b23d0ba 6485 max_len = mfl_code_to_length[ssl->conf->mfl_code];
marcozecchini 0:9fca2b23d0ba 6486
marcozecchini 0:9fca2b23d0ba 6487 /*
marcozecchini 0:9fca2b23d0ba 6488 * Check if a smaller max length was negotiated
marcozecchini 0:9fca2b23d0ba 6489 */
marcozecchini 0:9fca2b23d0ba 6490 if( ssl->session_out != NULL &&
marcozecchini 0:9fca2b23d0ba 6491 mfl_code_to_length[ssl->session_out->mfl_code] < max_len )
marcozecchini 0:9fca2b23d0ba 6492 {
marcozecchini 0:9fca2b23d0ba 6493 max_len = mfl_code_to_length[ssl->session_out->mfl_code];
marcozecchini 0:9fca2b23d0ba 6494 }
marcozecchini 0:9fca2b23d0ba 6495
marcozecchini 0:9fca2b23d0ba 6496 return max_len;
marcozecchini 0:9fca2b23d0ba 6497 }
marcozecchini 0:9fca2b23d0ba 6498 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
marcozecchini 0:9fca2b23d0ba 6499
marcozecchini 0:9fca2b23d0ba 6500 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 6501 const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6502 {
marcozecchini 0:9fca2b23d0ba 6503 if( ssl == NULL || ssl->session == NULL )
marcozecchini 0:9fca2b23d0ba 6504 return( NULL );
marcozecchini 0:9fca2b23d0ba 6505
marcozecchini 0:9fca2b23d0ba 6506 return( ssl->session->peer_cert );
marcozecchini 0:9fca2b23d0ba 6507 }
marcozecchini 0:9fca2b23d0ba 6508 #endif /* MBEDTLS_X509_CRT_PARSE_C */
marcozecchini 0:9fca2b23d0ba 6509
marcozecchini 0:9fca2b23d0ba 6510 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 6511 int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst )
marcozecchini 0:9fca2b23d0ba 6512 {
marcozecchini 0:9fca2b23d0ba 6513 if( ssl == NULL ||
marcozecchini 0:9fca2b23d0ba 6514 dst == NULL ||
marcozecchini 0:9fca2b23d0ba 6515 ssl->session == NULL ||
marcozecchini 0:9fca2b23d0ba 6516 ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 6517 {
marcozecchini 0:9fca2b23d0ba 6518 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6519 }
marcozecchini 0:9fca2b23d0ba 6520
marcozecchini 0:9fca2b23d0ba 6521 return( ssl_session_copy( dst, ssl->session ) );
marcozecchini 0:9fca2b23d0ba 6522 }
marcozecchini 0:9fca2b23d0ba 6523 #endif /* MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 6524
marcozecchini 0:9fca2b23d0ba 6525 /*
marcozecchini 0:9fca2b23d0ba 6526 * Perform a single step of the SSL handshake
marcozecchini 0:9fca2b23d0ba 6527 */
marcozecchini 0:9fca2b23d0ba 6528 int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6529 {
marcozecchini 0:9fca2b23d0ba 6530 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
marcozecchini 0:9fca2b23d0ba 6531
marcozecchini 0:9fca2b23d0ba 6532 if( ssl == NULL || ssl->conf == NULL )
marcozecchini 0:9fca2b23d0ba 6533 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6534
marcozecchini 0:9fca2b23d0ba 6535 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 6536 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 6537 ret = mbedtls_ssl_handshake_client_step( ssl );
marcozecchini 0:9fca2b23d0ba 6538 #endif
marcozecchini 0:9fca2b23d0ba 6539 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 6540 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 6541 ret = mbedtls_ssl_handshake_server_step( ssl );
marcozecchini 0:9fca2b23d0ba 6542 #endif
marcozecchini 0:9fca2b23d0ba 6543
marcozecchini 0:9fca2b23d0ba 6544 return( ret );
marcozecchini 0:9fca2b23d0ba 6545 }
marcozecchini 0:9fca2b23d0ba 6546
marcozecchini 0:9fca2b23d0ba 6547 /*
marcozecchini 0:9fca2b23d0ba 6548 * Perform the SSL handshake
marcozecchini 0:9fca2b23d0ba 6549 */
marcozecchini 0:9fca2b23d0ba 6550 int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6551 {
marcozecchini 0:9fca2b23d0ba 6552 int ret = 0;
marcozecchini 0:9fca2b23d0ba 6553
marcozecchini 0:9fca2b23d0ba 6554 if( ssl == NULL || ssl->conf == NULL )
marcozecchini 0:9fca2b23d0ba 6555 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6556
marcozecchini 0:9fca2b23d0ba 6557 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
marcozecchini 0:9fca2b23d0ba 6558
marcozecchini 0:9fca2b23d0ba 6559 while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 6560 {
marcozecchini 0:9fca2b23d0ba 6561 ret = mbedtls_ssl_handshake_step( ssl );
marcozecchini 0:9fca2b23d0ba 6562
marcozecchini 0:9fca2b23d0ba 6563 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 6564 break;
marcozecchini 0:9fca2b23d0ba 6565 }
marcozecchini 0:9fca2b23d0ba 6566
marcozecchini 0:9fca2b23d0ba 6567 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= handshake" ) );
marcozecchini 0:9fca2b23d0ba 6568
marcozecchini 0:9fca2b23d0ba 6569 return( ret );
marcozecchini 0:9fca2b23d0ba 6570 }
marcozecchini 0:9fca2b23d0ba 6571
marcozecchini 0:9fca2b23d0ba 6572 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 6573 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 6574 /*
marcozecchini 0:9fca2b23d0ba 6575 * Write HelloRequest to request renegotiation on server
marcozecchini 0:9fca2b23d0ba 6576 */
marcozecchini 0:9fca2b23d0ba 6577 static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6578 {
marcozecchini 0:9fca2b23d0ba 6579 int ret;
marcozecchini 0:9fca2b23d0ba 6580
marcozecchini 0:9fca2b23d0ba 6581 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) );
marcozecchini 0:9fca2b23d0ba 6582
marcozecchini 0:9fca2b23d0ba 6583 ssl->out_msglen = 4;
marcozecchini 0:9fca2b23d0ba 6584 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
marcozecchini 0:9fca2b23d0ba 6585 ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST;
marcozecchini 0:9fca2b23d0ba 6586
marcozecchini 0:9fca2b23d0ba 6587 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6588 {
marcozecchini 0:9fca2b23d0ba 6589 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
marcozecchini 0:9fca2b23d0ba 6590 return( ret );
marcozecchini 0:9fca2b23d0ba 6591 }
marcozecchini 0:9fca2b23d0ba 6592
marcozecchini 0:9fca2b23d0ba 6593 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello request" ) );
marcozecchini 0:9fca2b23d0ba 6594
marcozecchini 0:9fca2b23d0ba 6595 return( 0 );
marcozecchini 0:9fca2b23d0ba 6596 }
marcozecchini 0:9fca2b23d0ba 6597 #endif /* MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 6598
marcozecchini 0:9fca2b23d0ba 6599 /*
marcozecchini 0:9fca2b23d0ba 6600 * Actually renegotiate current connection, triggered by either:
marcozecchini 0:9fca2b23d0ba 6601 * - any side: calling mbedtls_ssl_renegotiate(),
marcozecchini 0:9fca2b23d0ba 6602 * - client: receiving a HelloRequest during mbedtls_ssl_read(),
marcozecchini 0:9fca2b23d0ba 6603 * - server: receiving any handshake message on server during mbedtls_ssl_read() after
marcozecchini 0:9fca2b23d0ba 6604 * the initial handshake is completed.
marcozecchini 0:9fca2b23d0ba 6605 * If the handshake doesn't complete due to waiting for I/O, it will continue
marcozecchini 0:9fca2b23d0ba 6606 * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
marcozecchini 0:9fca2b23d0ba 6607 */
marcozecchini 0:9fca2b23d0ba 6608 static int ssl_start_renegotiation( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6609 {
marcozecchini 0:9fca2b23d0ba 6610 int ret;
marcozecchini 0:9fca2b23d0ba 6611
marcozecchini 0:9fca2b23d0ba 6612 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
marcozecchini 0:9fca2b23d0ba 6613
marcozecchini 0:9fca2b23d0ba 6614 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6615 return( ret );
marcozecchini 0:9fca2b23d0ba 6616
marcozecchini 0:9fca2b23d0ba 6617 /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and
marcozecchini 0:9fca2b23d0ba 6618 * the ServerHello will have message_seq = 1" */
marcozecchini 0:9fca2b23d0ba 6619 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 6620 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
marcozecchini 0:9fca2b23d0ba 6621 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
marcozecchini 0:9fca2b23d0ba 6622 {
marcozecchini 0:9fca2b23d0ba 6623 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 6624 ssl->handshake->out_msg_seq = 1;
marcozecchini 0:9fca2b23d0ba 6625 else
marcozecchini 0:9fca2b23d0ba 6626 ssl->handshake->in_msg_seq = 1;
marcozecchini 0:9fca2b23d0ba 6627 }
marcozecchini 0:9fca2b23d0ba 6628 #endif
marcozecchini 0:9fca2b23d0ba 6629
marcozecchini 0:9fca2b23d0ba 6630 ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
marcozecchini 0:9fca2b23d0ba 6631 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS;
marcozecchini 0:9fca2b23d0ba 6632
marcozecchini 0:9fca2b23d0ba 6633 if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6634 {
marcozecchini 0:9fca2b23d0ba 6635 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
marcozecchini 0:9fca2b23d0ba 6636 return( ret );
marcozecchini 0:9fca2b23d0ba 6637 }
marcozecchini 0:9fca2b23d0ba 6638
marcozecchini 0:9fca2b23d0ba 6639 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) );
marcozecchini 0:9fca2b23d0ba 6640
marcozecchini 0:9fca2b23d0ba 6641 return( 0 );
marcozecchini 0:9fca2b23d0ba 6642 }
marcozecchini 0:9fca2b23d0ba 6643
marcozecchini 0:9fca2b23d0ba 6644 /*
marcozecchini 0:9fca2b23d0ba 6645 * Renegotiate current connection on client,
marcozecchini 0:9fca2b23d0ba 6646 * or request renegotiation on server
marcozecchini 0:9fca2b23d0ba 6647 */
marcozecchini 0:9fca2b23d0ba 6648 int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6649 {
marcozecchini 0:9fca2b23d0ba 6650 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
marcozecchini 0:9fca2b23d0ba 6651
marcozecchini 0:9fca2b23d0ba 6652 if( ssl == NULL || ssl->conf == NULL )
marcozecchini 0:9fca2b23d0ba 6653 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6654
marcozecchini 0:9fca2b23d0ba 6655 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 6656 /* On server, just send the request */
marcozecchini 0:9fca2b23d0ba 6657 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 6658 {
marcozecchini 0:9fca2b23d0ba 6659 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 6660 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6661
marcozecchini 0:9fca2b23d0ba 6662 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
marcozecchini 0:9fca2b23d0ba 6663
marcozecchini 0:9fca2b23d0ba 6664 /* Did we already try/start sending HelloRequest? */
marcozecchini 0:9fca2b23d0ba 6665 if( ssl->out_left != 0 )
marcozecchini 0:9fca2b23d0ba 6666 return( mbedtls_ssl_flush_output( ssl ) );
marcozecchini 0:9fca2b23d0ba 6667
marcozecchini 0:9fca2b23d0ba 6668 return( ssl_write_hello_request( ssl ) );
marcozecchini 0:9fca2b23d0ba 6669 }
marcozecchini 0:9fca2b23d0ba 6670 #endif /* MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 6671
marcozecchini 0:9fca2b23d0ba 6672 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 6673 /*
marcozecchini 0:9fca2b23d0ba 6674 * On client, either start the renegotiation process or,
marcozecchini 0:9fca2b23d0ba 6675 * if already in progress, continue the handshake
marcozecchini 0:9fca2b23d0ba 6676 */
marcozecchini 0:9fca2b23d0ba 6677 if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
marcozecchini 0:9fca2b23d0ba 6678 {
marcozecchini 0:9fca2b23d0ba 6679 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 6680 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6681
marcozecchini 0:9fca2b23d0ba 6682 if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6683 {
marcozecchini 0:9fca2b23d0ba 6684 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
marcozecchini 0:9fca2b23d0ba 6685 return( ret );
marcozecchini 0:9fca2b23d0ba 6686 }
marcozecchini 0:9fca2b23d0ba 6687 }
marcozecchini 0:9fca2b23d0ba 6688 else
marcozecchini 0:9fca2b23d0ba 6689 {
marcozecchini 0:9fca2b23d0ba 6690 if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6691 {
marcozecchini 0:9fca2b23d0ba 6692 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
marcozecchini 0:9fca2b23d0ba 6693 return( ret );
marcozecchini 0:9fca2b23d0ba 6694 }
marcozecchini 0:9fca2b23d0ba 6695 }
marcozecchini 0:9fca2b23d0ba 6696 #endif /* MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 6697
marcozecchini 0:9fca2b23d0ba 6698 return( ret );
marcozecchini 0:9fca2b23d0ba 6699 }
marcozecchini 0:9fca2b23d0ba 6700
marcozecchini 0:9fca2b23d0ba 6701 /*
marcozecchini 0:9fca2b23d0ba 6702 * Check record counters and renegotiate if they're above the limit.
marcozecchini 0:9fca2b23d0ba 6703 */
marcozecchini 0:9fca2b23d0ba 6704 static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 6705 {
marcozecchini 0:9fca2b23d0ba 6706 size_t ep_len = ssl_ep_len( ssl );
marcozecchini 0:9fca2b23d0ba 6707 int in_ctr_cmp;
marcozecchini 0:9fca2b23d0ba 6708 int out_ctr_cmp;
marcozecchini 0:9fca2b23d0ba 6709
marcozecchini 0:9fca2b23d0ba 6710 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
marcozecchini 0:9fca2b23d0ba 6711 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
marcozecchini 0:9fca2b23d0ba 6712 ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
marcozecchini 0:9fca2b23d0ba 6713 {
marcozecchini 0:9fca2b23d0ba 6714 return( 0 );
marcozecchini 0:9fca2b23d0ba 6715 }
marcozecchini 0:9fca2b23d0ba 6716
marcozecchini 0:9fca2b23d0ba 6717 in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
marcozecchini 0:9fca2b23d0ba 6718 ssl->conf->renego_period + ep_len, 8 - ep_len );
marcozecchini 0:9fca2b23d0ba 6719 out_ctr_cmp = memcmp( ssl->out_ctr + ep_len,
marcozecchini 0:9fca2b23d0ba 6720 ssl->conf->renego_period + ep_len, 8 - ep_len );
marcozecchini 0:9fca2b23d0ba 6721
marcozecchini 0:9fca2b23d0ba 6722 if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
marcozecchini 0:9fca2b23d0ba 6723 {
marcozecchini 0:9fca2b23d0ba 6724 return( 0 );
marcozecchini 0:9fca2b23d0ba 6725 }
marcozecchini 0:9fca2b23d0ba 6726
marcozecchini 0:9fca2b23d0ba 6727 MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
marcozecchini 0:9fca2b23d0ba 6728 return( mbedtls_ssl_renegotiate( ssl ) );
marcozecchini 0:9fca2b23d0ba 6729 }
marcozecchini 0:9fca2b23d0ba 6730 #endif /* MBEDTLS_SSL_RENEGOTIATION */
marcozecchini 0:9fca2b23d0ba 6731
marcozecchini 0:9fca2b23d0ba 6732 /*
marcozecchini 0:9fca2b23d0ba 6733 * Receive application data decrypted from the SSL layer
marcozecchini 0:9fca2b23d0ba 6734 */
marcozecchini 0:9fca2b23d0ba 6735 int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
marcozecchini 0:9fca2b23d0ba 6736 {
marcozecchini 0:9fca2b23d0ba 6737 int ret;
marcozecchini 0:9fca2b23d0ba 6738 size_t n;
marcozecchini 0:9fca2b23d0ba 6739
marcozecchini 0:9fca2b23d0ba 6740 if( ssl == NULL || ssl->conf == NULL )
marcozecchini 0:9fca2b23d0ba 6741 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 6742
marcozecchini 0:9fca2b23d0ba 6743 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
marcozecchini 0:9fca2b23d0ba 6744
marcozecchini 0:9fca2b23d0ba 6745 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 6746 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 6747 {
marcozecchini 0:9fca2b23d0ba 6748 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6749 return( ret );
marcozecchini 0:9fca2b23d0ba 6750
marcozecchini 0:9fca2b23d0ba 6751 if( ssl->handshake != NULL &&
marcozecchini 0:9fca2b23d0ba 6752 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
marcozecchini 0:9fca2b23d0ba 6753 {
marcozecchini 0:9fca2b23d0ba 6754 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6755 return( ret );
marcozecchini 0:9fca2b23d0ba 6756 }
marcozecchini 0:9fca2b23d0ba 6757 }
marcozecchini 0:9fca2b23d0ba 6758 #endif
marcozecchini 0:9fca2b23d0ba 6759
marcozecchini 0:9fca2b23d0ba 6760 /*
marcozecchini 0:9fca2b23d0ba 6761 * Check if renegotiation is necessary and/or handshake is
marcozecchini 0:9fca2b23d0ba 6762 * in process. If yes, perform/continue, and fall through
marcozecchini 0:9fca2b23d0ba 6763 * if an unexpected packet is received while the client
marcozecchini 0:9fca2b23d0ba 6764 * is waiting for the ServerHello.
marcozecchini 0:9fca2b23d0ba 6765 *
marcozecchini 0:9fca2b23d0ba 6766 * (There is no equivalent to the last condition on
marcozecchini 0:9fca2b23d0ba 6767 * the server-side as it is not treated as within
marcozecchini 0:9fca2b23d0ba 6768 * a handshake while waiting for the ClientHello
marcozecchini 0:9fca2b23d0ba 6769 * after a renegotiation request.)
marcozecchini 0:9fca2b23d0ba 6770 */
marcozecchini 0:9fca2b23d0ba 6771
marcozecchini 0:9fca2b23d0ba 6772 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 6773 ret = ssl_check_ctr_renegotiate( ssl );
marcozecchini 0:9fca2b23d0ba 6774 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
marcozecchini 0:9fca2b23d0ba 6775 ret != 0 )
marcozecchini 0:9fca2b23d0ba 6776 {
marcozecchini 0:9fca2b23d0ba 6777 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
marcozecchini 0:9fca2b23d0ba 6778 return( ret );
marcozecchini 0:9fca2b23d0ba 6779 }
marcozecchini 0:9fca2b23d0ba 6780 #endif
marcozecchini 0:9fca2b23d0ba 6781
marcozecchini 0:9fca2b23d0ba 6782 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 6783 {
marcozecchini 0:9fca2b23d0ba 6784 ret = mbedtls_ssl_handshake( ssl );
marcozecchini 0:9fca2b23d0ba 6785 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
marcozecchini 0:9fca2b23d0ba 6786 ret != 0 )
marcozecchini 0:9fca2b23d0ba 6787 {
marcozecchini 0:9fca2b23d0ba 6788 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
marcozecchini 0:9fca2b23d0ba 6789 return( ret );
marcozecchini 0:9fca2b23d0ba 6790 }
marcozecchini 0:9fca2b23d0ba 6791 }
marcozecchini 0:9fca2b23d0ba 6792
marcozecchini 0:9fca2b23d0ba 6793 /*
marcozecchini 0:9fca2b23d0ba 6794 * TODO
marcozecchini 0:9fca2b23d0ba 6795 *
marcozecchini 0:9fca2b23d0ba 6796 * The logic should be streamlined here:
marcozecchini 0:9fca2b23d0ba 6797 *
marcozecchini 0:9fca2b23d0ba 6798 * Instead of
marcozecchini 0:9fca2b23d0ba 6799 *
marcozecchini 0:9fca2b23d0ba 6800 * - Manually checking whether ssl->in_offt is NULL
marcozecchini 0:9fca2b23d0ba 6801 * - Fetching a new record if yes
marcozecchini 0:9fca2b23d0ba 6802 * - Setting ssl->in_offt if one finds an application record
marcozecchini 0:9fca2b23d0ba 6803 * - Resetting keep_current_message after handling the application data
marcozecchini 0:9fca2b23d0ba 6804 *
marcozecchini 0:9fca2b23d0ba 6805 * one should
marcozecchini 0:9fca2b23d0ba 6806 *
marcozecchini 0:9fca2b23d0ba 6807 * - Adapt read_record to set ssl->in_offt automatically
marcozecchini 0:9fca2b23d0ba 6808 * when a new application data record is processed.
marcozecchini 0:9fca2b23d0ba 6809 * - Always call mbedtls_ssl_read_record here.
marcozecchini 0:9fca2b23d0ba 6810 *
marcozecchini 0:9fca2b23d0ba 6811 * This way, the logic of ssl_read would be much clearer:
marcozecchini 0:9fca2b23d0ba 6812 *
marcozecchini 0:9fca2b23d0ba 6813 * (1) Always call record layer and see what kind of record is on
marcozecchini 0:9fca2b23d0ba 6814 * and have it ready for consumption (in particular, in_offt
marcozecchini 0:9fca2b23d0ba 6815 * properly set for application data records).
marcozecchini 0:9fca2b23d0ba 6816 * (2) If it's application data (either freshly fetched
marcozecchini 0:9fca2b23d0ba 6817 * or something already being partially processed),
marcozecchini 0:9fca2b23d0ba 6818 * serve the read request from it.
marcozecchini 0:9fca2b23d0ba 6819 * (3) If it's something different from application data,
marcozecchini 0:9fca2b23d0ba 6820 * handle it accordingly, e.g. potentially start a
marcozecchini 0:9fca2b23d0ba 6821 * renegotiation.
marcozecchini 0:9fca2b23d0ba 6822 *
marcozecchini 0:9fca2b23d0ba 6823 * This will also remove the need to manually reset
marcozecchini 0:9fca2b23d0ba 6824 * ssl->keep_current_message = 0 below.
marcozecchini 0:9fca2b23d0ba 6825 *
marcozecchini 0:9fca2b23d0ba 6826 */
marcozecchini 0:9fca2b23d0ba 6827
marcozecchini 0:9fca2b23d0ba 6828 if( ssl->in_offt == NULL )
marcozecchini 0:9fca2b23d0ba 6829 {
marcozecchini 0:9fca2b23d0ba 6830 /* Start timer if not already running */
marcozecchini 0:9fca2b23d0ba 6831 if( ssl->f_get_timer != NULL &&
marcozecchini 0:9fca2b23d0ba 6832 ssl->f_get_timer( ssl->p_timer ) == -1 )
marcozecchini 0:9fca2b23d0ba 6833 {
marcozecchini 0:9fca2b23d0ba 6834 ssl_set_timer( ssl, ssl->conf->read_timeout );
marcozecchini 0:9fca2b23d0ba 6835 }
marcozecchini 0:9fca2b23d0ba 6836
marcozecchini 0:9fca2b23d0ba 6837 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6838 {
marcozecchini 0:9fca2b23d0ba 6839 if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
marcozecchini 0:9fca2b23d0ba 6840 return( 0 );
marcozecchini 0:9fca2b23d0ba 6841
marcozecchini 0:9fca2b23d0ba 6842 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
marcozecchini 0:9fca2b23d0ba 6843 return( ret );
marcozecchini 0:9fca2b23d0ba 6844 }
marcozecchini 0:9fca2b23d0ba 6845
marcozecchini 0:9fca2b23d0ba 6846 if( ssl->in_msglen == 0 &&
marcozecchini 0:9fca2b23d0ba 6847 ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
marcozecchini 0:9fca2b23d0ba 6848 {
marcozecchini 0:9fca2b23d0ba 6849 /*
marcozecchini 0:9fca2b23d0ba 6850 * OpenSSL sends empty messages to randomize the IV
marcozecchini 0:9fca2b23d0ba 6851 */
marcozecchini 0:9fca2b23d0ba 6852 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6853 {
marcozecchini 0:9fca2b23d0ba 6854 if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
marcozecchini 0:9fca2b23d0ba 6855 return( 0 );
marcozecchini 0:9fca2b23d0ba 6856
marcozecchini 0:9fca2b23d0ba 6857 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
marcozecchini 0:9fca2b23d0ba 6858 return( ret );
marcozecchini 0:9fca2b23d0ba 6859 }
marcozecchini 0:9fca2b23d0ba 6860 }
marcozecchini 0:9fca2b23d0ba 6861
marcozecchini 0:9fca2b23d0ba 6862 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 6863 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
marcozecchini 0:9fca2b23d0ba 6864 {
marcozecchini 0:9fca2b23d0ba 6865 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
marcozecchini 0:9fca2b23d0ba 6866
marcozecchini 0:9fca2b23d0ba 6867 /*
marcozecchini 0:9fca2b23d0ba 6868 * - For client-side, expect SERVER_HELLO_REQUEST.
marcozecchini 0:9fca2b23d0ba 6869 * - For server-side, expect CLIENT_HELLO.
marcozecchini 0:9fca2b23d0ba 6870 * - Fail (TLS) or silently drop record (DTLS) in other cases.
marcozecchini 0:9fca2b23d0ba 6871 */
marcozecchini 0:9fca2b23d0ba 6872
marcozecchini 0:9fca2b23d0ba 6873 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 6874 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
marcozecchini 0:9fca2b23d0ba 6875 ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
marcozecchini 0:9fca2b23d0ba 6876 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
marcozecchini 0:9fca2b23d0ba 6877 {
marcozecchini 0:9fca2b23d0ba 6878 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
marcozecchini 0:9fca2b23d0ba 6879
marcozecchini 0:9fca2b23d0ba 6880 /* With DTLS, drop the packet (probably from last handshake) */
marcozecchini 0:9fca2b23d0ba 6881 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 6882 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 6883 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 6884 #endif
marcozecchini 0:9fca2b23d0ba 6885 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 6886 }
marcozecchini 0:9fca2b23d0ba 6887 #endif /* MBEDTLS_SSL_CLI_C */
marcozecchini 0:9fca2b23d0ba 6888
marcozecchini 0:9fca2b23d0ba 6889 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 6890 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 6891 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
marcozecchini 0:9fca2b23d0ba 6892 {
marcozecchini 0:9fca2b23d0ba 6893 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
marcozecchini 0:9fca2b23d0ba 6894
marcozecchini 0:9fca2b23d0ba 6895 /* With DTLS, drop the packet (probably from last handshake) */
marcozecchini 0:9fca2b23d0ba 6896 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 6897 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 6898 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 6899 #endif
marcozecchini 0:9fca2b23d0ba 6900 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 6901 }
marcozecchini 0:9fca2b23d0ba 6902 #endif /* MBEDTLS_SSL_SRV_C */
marcozecchini 0:9fca2b23d0ba 6903
marcozecchini 0:9fca2b23d0ba 6904 /* Determine whether renegotiation attempt should be accepted */
marcozecchini 0:9fca2b23d0ba 6905
marcozecchini 0:9fca2b23d0ba 6906 if( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
marcozecchini 0:9fca2b23d0ba 6907 ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
marcozecchini 0:9fca2b23d0ba 6908 ssl->conf->allow_legacy_renegotiation ==
marcozecchini 0:9fca2b23d0ba 6909 MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) )
marcozecchini 0:9fca2b23d0ba 6910 {
marcozecchini 0:9fca2b23d0ba 6911 /*
marcozecchini 0:9fca2b23d0ba 6912 * Refuse renegotiation
marcozecchini 0:9fca2b23d0ba 6913 */
marcozecchini 0:9fca2b23d0ba 6914
marcozecchini 0:9fca2b23d0ba 6915 MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
marcozecchini 0:9fca2b23d0ba 6916
marcozecchini 0:9fca2b23d0ba 6917 #if defined(MBEDTLS_SSL_PROTO_SSL3)
marcozecchini 0:9fca2b23d0ba 6918 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
marcozecchini 0:9fca2b23d0ba 6919 {
marcozecchini 0:9fca2b23d0ba 6920 /* SSLv3 does not have a "no_renegotiation" warning, so
marcozecchini 0:9fca2b23d0ba 6921 we send a fatal alert and abort the connection. */
marcozecchini 0:9fca2b23d0ba 6922 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
marcozecchini 0:9fca2b23d0ba 6923 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 6924 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 6925 }
marcozecchini 0:9fca2b23d0ba 6926 else
marcozecchini 0:9fca2b23d0ba 6927 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
marcozecchini 0:9fca2b23d0ba 6928 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
marcozecchini 0:9fca2b23d0ba 6929 defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 6930 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
marcozecchini 0:9fca2b23d0ba 6931 {
marcozecchini 0:9fca2b23d0ba 6932 if( ( ret = mbedtls_ssl_send_alert_message( ssl,
marcozecchini 0:9fca2b23d0ba 6933 MBEDTLS_SSL_ALERT_LEVEL_WARNING,
marcozecchini 0:9fca2b23d0ba 6934 MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 6935 {
marcozecchini 0:9fca2b23d0ba 6936 return( ret );
marcozecchini 0:9fca2b23d0ba 6937 }
marcozecchini 0:9fca2b23d0ba 6938 }
marcozecchini 0:9fca2b23d0ba 6939 else
marcozecchini 0:9fca2b23d0ba 6940 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
marcozecchini 0:9fca2b23d0ba 6941 MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 6942 {
marcozecchini 0:9fca2b23d0ba 6943 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
marcozecchini 0:9fca2b23d0ba 6944 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
marcozecchini 0:9fca2b23d0ba 6945 }
marcozecchini 0:9fca2b23d0ba 6946 }
marcozecchini 0:9fca2b23d0ba 6947 else
marcozecchini 0:9fca2b23d0ba 6948 {
marcozecchini 0:9fca2b23d0ba 6949 /*
marcozecchini 0:9fca2b23d0ba 6950 * Accept renegotiation request
marcozecchini 0:9fca2b23d0ba 6951 */
marcozecchini 0:9fca2b23d0ba 6952
marcozecchini 0:9fca2b23d0ba 6953 /* DTLS clients need to know renego is server-initiated */
marcozecchini 0:9fca2b23d0ba 6954 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 6955 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
marcozecchini 0:9fca2b23d0ba 6956 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 6957 {
marcozecchini 0:9fca2b23d0ba 6958 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
marcozecchini 0:9fca2b23d0ba 6959 }
marcozecchini 0:9fca2b23d0ba 6960 #endif
marcozecchini 0:9fca2b23d0ba 6961 ret = ssl_start_renegotiation( ssl );
marcozecchini 0:9fca2b23d0ba 6962 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
marcozecchini 0:9fca2b23d0ba 6963 ret != 0 )
marcozecchini 0:9fca2b23d0ba 6964 {
marcozecchini 0:9fca2b23d0ba 6965 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
marcozecchini 0:9fca2b23d0ba 6966 return( ret );
marcozecchini 0:9fca2b23d0ba 6967 }
marcozecchini 0:9fca2b23d0ba 6968 }
marcozecchini 0:9fca2b23d0ba 6969
marcozecchini 0:9fca2b23d0ba 6970 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 6971 }
marcozecchini 0:9fca2b23d0ba 6972 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
marcozecchini 0:9fca2b23d0ba 6973 {
marcozecchini 0:9fca2b23d0ba 6974 if( ssl->conf->renego_max_records >= 0 )
marcozecchini 0:9fca2b23d0ba 6975 {
marcozecchini 0:9fca2b23d0ba 6976 if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
marcozecchini 0:9fca2b23d0ba 6977 {
marcozecchini 0:9fca2b23d0ba 6978 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
marcozecchini 0:9fca2b23d0ba 6979 "but not honored by client" ) );
marcozecchini 0:9fca2b23d0ba 6980 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 6981 }
marcozecchini 0:9fca2b23d0ba 6982 }
marcozecchini 0:9fca2b23d0ba 6983 }
marcozecchini 0:9fca2b23d0ba 6984 #endif /* MBEDTLS_SSL_RENEGOTIATION */
marcozecchini 0:9fca2b23d0ba 6985
marcozecchini 0:9fca2b23d0ba 6986 /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
marcozecchini 0:9fca2b23d0ba 6987 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
marcozecchini 0:9fca2b23d0ba 6988 {
marcozecchini 0:9fca2b23d0ba 6989 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
marcozecchini 0:9fca2b23d0ba 6990 return( MBEDTLS_ERR_SSL_WANT_READ );
marcozecchini 0:9fca2b23d0ba 6991 }
marcozecchini 0:9fca2b23d0ba 6992
marcozecchini 0:9fca2b23d0ba 6993 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
marcozecchini 0:9fca2b23d0ba 6994 {
marcozecchini 0:9fca2b23d0ba 6995 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
marcozecchini 0:9fca2b23d0ba 6996 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
marcozecchini 0:9fca2b23d0ba 6997 }
marcozecchini 0:9fca2b23d0ba 6998
marcozecchini 0:9fca2b23d0ba 6999 ssl->in_offt = ssl->in_msg;
marcozecchini 0:9fca2b23d0ba 7000
marcozecchini 0:9fca2b23d0ba 7001 /* We're going to return something now, cancel timer,
marcozecchini 0:9fca2b23d0ba 7002 * except if handshake (renegotiation) is in progress */
marcozecchini 0:9fca2b23d0ba 7003 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 7004 ssl_set_timer( ssl, 0 );
marcozecchini 0:9fca2b23d0ba 7005
marcozecchini 0:9fca2b23d0ba 7006 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 7007 /* If we requested renego but received AppData, resend HelloRequest.
marcozecchini 0:9fca2b23d0ba 7008 * Do it now, after setting in_offt, to avoid taking this branch
marcozecchini 0:9fca2b23d0ba 7009 * again if ssl_write_hello_request() returns WANT_WRITE */
marcozecchini 0:9fca2b23d0ba 7010 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 7011 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
marcozecchini 0:9fca2b23d0ba 7012 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
marcozecchini 0:9fca2b23d0ba 7013 {
marcozecchini 0:9fca2b23d0ba 7014 if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 7015 {
marcozecchini 0:9fca2b23d0ba 7016 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
marcozecchini 0:9fca2b23d0ba 7017 return( ret );
marcozecchini 0:9fca2b23d0ba 7018 }
marcozecchini 0:9fca2b23d0ba 7019 }
marcozecchini 0:9fca2b23d0ba 7020 #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
marcozecchini 0:9fca2b23d0ba 7021 #endif /* MBEDTLS_SSL_PROTO_DTLS */
marcozecchini 0:9fca2b23d0ba 7022 }
marcozecchini 0:9fca2b23d0ba 7023
marcozecchini 0:9fca2b23d0ba 7024 n = ( len < ssl->in_msglen )
marcozecchini 0:9fca2b23d0ba 7025 ? len : ssl->in_msglen;
marcozecchini 0:9fca2b23d0ba 7026
marcozecchini 0:9fca2b23d0ba 7027 memcpy( buf, ssl->in_offt, n );
marcozecchini 0:9fca2b23d0ba 7028 ssl->in_msglen -= n;
marcozecchini 0:9fca2b23d0ba 7029
marcozecchini 0:9fca2b23d0ba 7030 if( ssl->in_msglen == 0 )
marcozecchini 0:9fca2b23d0ba 7031 {
marcozecchini 0:9fca2b23d0ba 7032 /* all bytes consumed */
marcozecchini 0:9fca2b23d0ba 7033 ssl->in_offt = NULL;
marcozecchini 0:9fca2b23d0ba 7034 ssl->keep_current_message = 0;
marcozecchini 0:9fca2b23d0ba 7035 }
marcozecchini 0:9fca2b23d0ba 7036 else
marcozecchini 0:9fca2b23d0ba 7037 {
marcozecchini 0:9fca2b23d0ba 7038 /* more data available */
marcozecchini 0:9fca2b23d0ba 7039 ssl->in_offt += n;
marcozecchini 0:9fca2b23d0ba 7040 }
marcozecchini 0:9fca2b23d0ba 7041
marcozecchini 0:9fca2b23d0ba 7042 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
marcozecchini 0:9fca2b23d0ba 7043
marcozecchini 0:9fca2b23d0ba 7044 return( (int) n );
marcozecchini 0:9fca2b23d0ba 7045 }
marcozecchini 0:9fca2b23d0ba 7046
marcozecchini 0:9fca2b23d0ba 7047 /*
marcozecchini 0:9fca2b23d0ba 7048 * Send application data to be encrypted by the SSL layer,
marcozecchini 0:9fca2b23d0ba 7049 * taking care of max fragment length and buffer size
marcozecchini 0:9fca2b23d0ba 7050 */
marcozecchini 0:9fca2b23d0ba 7051 static int ssl_write_real( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 7052 const unsigned char *buf, size_t len )
marcozecchini 0:9fca2b23d0ba 7053 {
marcozecchini 0:9fca2b23d0ba 7054 int ret;
marcozecchini 0:9fca2b23d0ba 7055 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
marcozecchini 0:9fca2b23d0ba 7056 size_t max_len = mbedtls_ssl_get_max_frag_len( ssl );
marcozecchini 0:9fca2b23d0ba 7057
marcozecchini 0:9fca2b23d0ba 7058 if( len > max_len )
marcozecchini 0:9fca2b23d0ba 7059 {
marcozecchini 0:9fca2b23d0ba 7060 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 7061 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 7062 {
marcozecchini 0:9fca2b23d0ba 7063 MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
marcozecchini 0:9fca2b23d0ba 7064 "maximum fragment length: %d > %d",
marcozecchini 0:9fca2b23d0ba 7065 len, max_len ) );
marcozecchini 0:9fca2b23d0ba 7066 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 7067 }
marcozecchini 0:9fca2b23d0ba 7068 else
marcozecchini 0:9fca2b23d0ba 7069 #endif
marcozecchini 0:9fca2b23d0ba 7070 len = max_len;
marcozecchini 0:9fca2b23d0ba 7071 }
marcozecchini 0:9fca2b23d0ba 7072 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
marcozecchini 0:9fca2b23d0ba 7073
marcozecchini 0:9fca2b23d0ba 7074 if( ssl->out_left != 0 )
marcozecchini 0:9fca2b23d0ba 7075 {
marcozecchini 0:9fca2b23d0ba 7076 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 7077 {
marcozecchini 0:9fca2b23d0ba 7078 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
marcozecchini 0:9fca2b23d0ba 7079 return( ret );
marcozecchini 0:9fca2b23d0ba 7080 }
marcozecchini 0:9fca2b23d0ba 7081 }
marcozecchini 0:9fca2b23d0ba 7082 else
marcozecchini 0:9fca2b23d0ba 7083 {
marcozecchini 0:9fca2b23d0ba 7084 ssl->out_msglen = len;
marcozecchini 0:9fca2b23d0ba 7085 ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
marcozecchini 0:9fca2b23d0ba 7086 memcpy( ssl->out_msg, buf, len );
marcozecchini 0:9fca2b23d0ba 7087
marcozecchini 0:9fca2b23d0ba 7088 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 7089 {
marcozecchini 0:9fca2b23d0ba 7090 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
marcozecchini 0:9fca2b23d0ba 7091 return( ret );
marcozecchini 0:9fca2b23d0ba 7092 }
marcozecchini 0:9fca2b23d0ba 7093 }
marcozecchini 0:9fca2b23d0ba 7094
marcozecchini 0:9fca2b23d0ba 7095 return( (int) len );
marcozecchini 0:9fca2b23d0ba 7096 }
marcozecchini 0:9fca2b23d0ba 7097
marcozecchini 0:9fca2b23d0ba 7098 /*
marcozecchini 0:9fca2b23d0ba 7099 * Write application data, doing 1/n-1 splitting if necessary.
marcozecchini 0:9fca2b23d0ba 7100 *
marcozecchini 0:9fca2b23d0ba 7101 * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
marcozecchini 0:9fca2b23d0ba 7102 * then the caller will call us again with the same arguments, so
marcozecchini 0:9fca2b23d0ba 7103 * remember wether we already did the split or not.
marcozecchini 0:9fca2b23d0ba 7104 */
marcozecchini 0:9fca2b23d0ba 7105 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
marcozecchini 0:9fca2b23d0ba 7106 static int ssl_write_split( mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 7107 const unsigned char *buf, size_t len )
marcozecchini 0:9fca2b23d0ba 7108 {
marcozecchini 0:9fca2b23d0ba 7109 int ret;
marcozecchini 0:9fca2b23d0ba 7110
marcozecchini 0:9fca2b23d0ba 7111 if( ssl->conf->cbc_record_splitting ==
marcozecchini 0:9fca2b23d0ba 7112 MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
marcozecchini 0:9fca2b23d0ba 7113 len <= 1 ||
marcozecchini 0:9fca2b23d0ba 7114 ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
marcozecchini 0:9fca2b23d0ba 7115 mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
marcozecchini 0:9fca2b23d0ba 7116 != MBEDTLS_MODE_CBC )
marcozecchini 0:9fca2b23d0ba 7117 {
marcozecchini 0:9fca2b23d0ba 7118 return( ssl_write_real( ssl, buf, len ) );
marcozecchini 0:9fca2b23d0ba 7119 }
marcozecchini 0:9fca2b23d0ba 7120
marcozecchini 0:9fca2b23d0ba 7121 if( ssl->split_done == 0 )
marcozecchini 0:9fca2b23d0ba 7122 {
marcozecchini 0:9fca2b23d0ba 7123 if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
marcozecchini 0:9fca2b23d0ba 7124 return( ret );
marcozecchini 0:9fca2b23d0ba 7125 ssl->split_done = 1;
marcozecchini 0:9fca2b23d0ba 7126 }
marcozecchini 0:9fca2b23d0ba 7127
marcozecchini 0:9fca2b23d0ba 7128 if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
marcozecchini 0:9fca2b23d0ba 7129 return( ret );
marcozecchini 0:9fca2b23d0ba 7130 ssl->split_done = 0;
marcozecchini 0:9fca2b23d0ba 7131
marcozecchini 0:9fca2b23d0ba 7132 return( ret + 1 );
marcozecchini 0:9fca2b23d0ba 7133 }
marcozecchini 0:9fca2b23d0ba 7134 #endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
marcozecchini 0:9fca2b23d0ba 7135
marcozecchini 0:9fca2b23d0ba 7136 /*
marcozecchini 0:9fca2b23d0ba 7137 * Write application data (public-facing wrapper)
marcozecchini 0:9fca2b23d0ba 7138 */
marcozecchini 0:9fca2b23d0ba 7139 int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
marcozecchini 0:9fca2b23d0ba 7140 {
marcozecchini 0:9fca2b23d0ba 7141 int ret;
marcozecchini 0:9fca2b23d0ba 7142
marcozecchini 0:9fca2b23d0ba 7143 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
marcozecchini 0:9fca2b23d0ba 7144
marcozecchini 0:9fca2b23d0ba 7145 if( ssl == NULL || ssl->conf == NULL )
marcozecchini 0:9fca2b23d0ba 7146 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 7147
marcozecchini 0:9fca2b23d0ba 7148 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 7149 if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 7150 {
marcozecchini 0:9fca2b23d0ba 7151 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
marcozecchini 0:9fca2b23d0ba 7152 return( ret );
marcozecchini 0:9fca2b23d0ba 7153 }
marcozecchini 0:9fca2b23d0ba 7154 #endif
marcozecchini 0:9fca2b23d0ba 7155
marcozecchini 0:9fca2b23d0ba 7156 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 7157 {
marcozecchini 0:9fca2b23d0ba 7158 if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 7159 {
marcozecchini 0:9fca2b23d0ba 7160 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
marcozecchini 0:9fca2b23d0ba 7161 return( ret );
marcozecchini 0:9fca2b23d0ba 7162 }
marcozecchini 0:9fca2b23d0ba 7163 }
marcozecchini 0:9fca2b23d0ba 7164
marcozecchini 0:9fca2b23d0ba 7165 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
marcozecchini 0:9fca2b23d0ba 7166 ret = ssl_write_split( ssl, buf, len );
marcozecchini 0:9fca2b23d0ba 7167 #else
marcozecchini 0:9fca2b23d0ba 7168 ret = ssl_write_real( ssl, buf, len );
marcozecchini 0:9fca2b23d0ba 7169 #endif
marcozecchini 0:9fca2b23d0ba 7170
marcozecchini 0:9fca2b23d0ba 7171 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
marcozecchini 0:9fca2b23d0ba 7172
marcozecchini 0:9fca2b23d0ba 7173 return( ret );
marcozecchini 0:9fca2b23d0ba 7174 }
marcozecchini 0:9fca2b23d0ba 7175
marcozecchini 0:9fca2b23d0ba 7176 /*
marcozecchini 0:9fca2b23d0ba 7177 * Notify the peer that the connection is being closed
marcozecchini 0:9fca2b23d0ba 7178 */
marcozecchini 0:9fca2b23d0ba 7179 int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 7180 {
marcozecchini 0:9fca2b23d0ba 7181 int ret;
marcozecchini 0:9fca2b23d0ba 7182
marcozecchini 0:9fca2b23d0ba 7183 if( ssl == NULL || ssl->conf == NULL )
marcozecchini 0:9fca2b23d0ba 7184 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 7185
marcozecchini 0:9fca2b23d0ba 7186 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
marcozecchini 0:9fca2b23d0ba 7187
marcozecchini 0:9fca2b23d0ba 7188 if( ssl->out_left != 0 )
marcozecchini 0:9fca2b23d0ba 7189 return( mbedtls_ssl_flush_output( ssl ) );
marcozecchini 0:9fca2b23d0ba 7190
marcozecchini 0:9fca2b23d0ba 7191 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
marcozecchini 0:9fca2b23d0ba 7192 {
marcozecchini 0:9fca2b23d0ba 7193 if( ( ret = mbedtls_ssl_send_alert_message( ssl,
marcozecchini 0:9fca2b23d0ba 7194 MBEDTLS_SSL_ALERT_LEVEL_WARNING,
marcozecchini 0:9fca2b23d0ba 7195 MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 7196 {
marcozecchini 0:9fca2b23d0ba 7197 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
marcozecchini 0:9fca2b23d0ba 7198 return( ret );
marcozecchini 0:9fca2b23d0ba 7199 }
marcozecchini 0:9fca2b23d0ba 7200 }
marcozecchini 0:9fca2b23d0ba 7201
marcozecchini 0:9fca2b23d0ba 7202 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
marcozecchini 0:9fca2b23d0ba 7203
marcozecchini 0:9fca2b23d0ba 7204 return( 0 );
marcozecchini 0:9fca2b23d0ba 7205 }
marcozecchini 0:9fca2b23d0ba 7206
marcozecchini 0:9fca2b23d0ba 7207 void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
marcozecchini 0:9fca2b23d0ba 7208 {
marcozecchini 0:9fca2b23d0ba 7209 if( transform == NULL )
marcozecchini 0:9fca2b23d0ba 7210 return;
marcozecchini 0:9fca2b23d0ba 7211
marcozecchini 0:9fca2b23d0ba 7212 #if defined(MBEDTLS_ZLIB_SUPPORT)
marcozecchini 0:9fca2b23d0ba 7213 deflateEnd( &transform->ctx_deflate );
marcozecchini 0:9fca2b23d0ba 7214 inflateEnd( &transform->ctx_inflate );
marcozecchini 0:9fca2b23d0ba 7215 #endif
marcozecchini 0:9fca2b23d0ba 7216
marcozecchini 0:9fca2b23d0ba 7217 mbedtls_cipher_free( &transform->cipher_ctx_enc );
marcozecchini 0:9fca2b23d0ba 7218 mbedtls_cipher_free( &transform->cipher_ctx_dec );
marcozecchini 0:9fca2b23d0ba 7219
marcozecchini 0:9fca2b23d0ba 7220 mbedtls_md_free( &transform->md_ctx_enc );
marcozecchini 0:9fca2b23d0ba 7221 mbedtls_md_free( &transform->md_ctx_dec );
marcozecchini 0:9fca2b23d0ba 7222
marcozecchini 0:9fca2b23d0ba 7223 mbedtls_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
marcozecchini 0:9fca2b23d0ba 7224 }
marcozecchini 0:9fca2b23d0ba 7225
marcozecchini 0:9fca2b23d0ba 7226 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 7227 static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
marcozecchini 0:9fca2b23d0ba 7228 {
marcozecchini 0:9fca2b23d0ba 7229 mbedtls_ssl_key_cert *cur = key_cert, *next;
marcozecchini 0:9fca2b23d0ba 7230
marcozecchini 0:9fca2b23d0ba 7231 while( cur != NULL )
marcozecchini 0:9fca2b23d0ba 7232 {
marcozecchini 0:9fca2b23d0ba 7233 next = cur->next;
marcozecchini 0:9fca2b23d0ba 7234 mbedtls_free( cur );
marcozecchini 0:9fca2b23d0ba 7235 cur = next;
marcozecchini 0:9fca2b23d0ba 7236 }
marcozecchini 0:9fca2b23d0ba 7237 }
marcozecchini 0:9fca2b23d0ba 7238 #endif /* MBEDTLS_X509_CRT_PARSE_C */
marcozecchini 0:9fca2b23d0ba 7239
marcozecchini 0:9fca2b23d0ba 7240 void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake )
marcozecchini 0:9fca2b23d0ba 7241 {
marcozecchini 0:9fca2b23d0ba 7242 if( handshake == NULL )
marcozecchini 0:9fca2b23d0ba 7243 return;
marcozecchini 0:9fca2b23d0ba 7244
marcozecchini 0:9fca2b23d0ba 7245 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
marcozecchini 0:9fca2b23d0ba 7246 defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 7247 mbedtls_md5_free( &handshake->fin_md5 );
marcozecchini 0:9fca2b23d0ba 7248 mbedtls_sha1_free( &handshake->fin_sha1 );
marcozecchini 0:9fca2b23d0ba 7249 #endif
marcozecchini 0:9fca2b23d0ba 7250 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 7251 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 7252 mbedtls_sha256_free( &handshake->fin_sha256 );
marcozecchini 0:9fca2b23d0ba 7253 #endif
marcozecchini 0:9fca2b23d0ba 7254 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 7255 mbedtls_sha512_free( &handshake->fin_sha512 );
marcozecchini 0:9fca2b23d0ba 7256 #endif
marcozecchini 0:9fca2b23d0ba 7257 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 7258
marcozecchini 0:9fca2b23d0ba 7259 #if defined(MBEDTLS_DHM_C)
marcozecchini 0:9fca2b23d0ba 7260 mbedtls_dhm_free( &handshake->dhm_ctx );
marcozecchini 0:9fca2b23d0ba 7261 #endif
marcozecchini 0:9fca2b23d0ba 7262 #if defined(MBEDTLS_ECDH_C)
marcozecchini 0:9fca2b23d0ba 7263 mbedtls_ecdh_free( &handshake->ecdh_ctx );
marcozecchini 0:9fca2b23d0ba 7264 #endif
marcozecchini 0:9fca2b23d0ba 7265 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
marcozecchini 0:9fca2b23d0ba 7266 mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
marcozecchini 0:9fca2b23d0ba 7267 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 7268 mbedtls_free( handshake->ecjpake_cache );
marcozecchini 0:9fca2b23d0ba 7269 handshake->ecjpake_cache = NULL;
marcozecchini 0:9fca2b23d0ba 7270 handshake->ecjpake_cache_len = 0;
marcozecchini 0:9fca2b23d0ba 7271 #endif
marcozecchini 0:9fca2b23d0ba 7272 #endif
marcozecchini 0:9fca2b23d0ba 7273
marcozecchini 0:9fca2b23d0ba 7274 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
marcozecchini 0:9fca2b23d0ba 7275 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
marcozecchini 0:9fca2b23d0ba 7276 /* explicit void pointer cast for buggy MS compiler */
marcozecchini 0:9fca2b23d0ba 7277 mbedtls_free( (void *) handshake->curves );
marcozecchini 0:9fca2b23d0ba 7278 #endif
marcozecchini 0:9fca2b23d0ba 7279
marcozecchini 0:9fca2b23d0ba 7280 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
marcozecchini 0:9fca2b23d0ba 7281 if( handshake->psk != NULL )
marcozecchini 0:9fca2b23d0ba 7282 {
marcozecchini 0:9fca2b23d0ba 7283 mbedtls_zeroize( handshake->psk, handshake->psk_len );
marcozecchini 0:9fca2b23d0ba 7284 mbedtls_free( handshake->psk );
marcozecchini 0:9fca2b23d0ba 7285 }
marcozecchini 0:9fca2b23d0ba 7286 #endif
marcozecchini 0:9fca2b23d0ba 7287
marcozecchini 0:9fca2b23d0ba 7288 #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
marcozecchini 0:9fca2b23d0ba 7289 defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
marcozecchini 0:9fca2b23d0ba 7290 /*
marcozecchini 0:9fca2b23d0ba 7291 * Free only the linked list wrapper, not the keys themselves
marcozecchini 0:9fca2b23d0ba 7292 * since the belong to the SNI callback
marcozecchini 0:9fca2b23d0ba 7293 */
marcozecchini 0:9fca2b23d0ba 7294 if( handshake->sni_key_cert != NULL )
marcozecchini 0:9fca2b23d0ba 7295 {
marcozecchini 0:9fca2b23d0ba 7296 mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
marcozecchini 0:9fca2b23d0ba 7297
marcozecchini 0:9fca2b23d0ba 7298 while( cur != NULL )
marcozecchini 0:9fca2b23d0ba 7299 {
marcozecchini 0:9fca2b23d0ba 7300 next = cur->next;
marcozecchini 0:9fca2b23d0ba 7301 mbedtls_free( cur );
marcozecchini 0:9fca2b23d0ba 7302 cur = next;
marcozecchini 0:9fca2b23d0ba 7303 }
marcozecchini 0:9fca2b23d0ba 7304 }
marcozecchini 0:9fca2b23d0ba 7305 #endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
marcozecchini 0:9fca2b23d0ba 7306
marcozecchini 0:9fca2b23d0ba 7307 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 7308 mbedtls_free( handshake->verify_cookie );
marcozecchini 0:9fca2b23d0ba 7309 mbedtls_free( handshake->hs_msg );
marcozecchini 0:9fca2b23d0ba 7310 ssl_flight_free( handshake->flight );
marcozecchini 0:9fca2b23d0ba 7311 #endif
marcozecchini 0:9fca2b23d0ba 7312
marcozecchini 0:9fca2b23d0ba 7313 mbedtls_zeroize( handshake, sizeof( mbedtls_ssl_handshake_params ) );
marcozecchini 0:9fca2b23d0ba 7314 }
marcozecchini 0:9fca2b23d0ba 7315
marcozecchini 0:9fca2b23d0ba 7316 void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
marcozecchini 0:9fca2b23d0ba 7317 {
marcozecchini 0:9fca2b23d0ba 7318 if( session == NULL )
marcozecchini 0:9fca2b23d0ba 7319 return;
marcozecchini 0:9fca2b23d0ba 7320
marcozecchini 0:9fca2b23d0ba 7321 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 7322 if( session->peer_cert != NULL )
marcozecchini 0:9fca2b23d0ba 7323 {
marcozecchini 0:9fca2b23d0ba 7324 mbedtls_x509_crt_free( session->peer_cert );
marcozecchini 0:9fca2b23d0ba 7325 mbedtls_free( session->peer_cert );
marcozecchini 0:9fca2b23d0ba 7326 }
marcozecchini 0:9fca2b23d0ba 7327 #endif
marcozecchini 0:9fca2b23d0ba 7328
marcozecchini 0:9fca2b23d0ba 7329 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 7330 mbedtls_free( session->ticket );
marcozecchini 0:9fca2b23d0ba 7331 #endif
marcozecchini 0:9fca2b23d0ba 7332
marcozecchini 0:9fca2b23d0ba 7333 mbedtls_zeroize( session, sizeof( mbedtls_ssl_session ) );
marcozecchini 0:9fca2b23d0ba 7334 }
marcozecchini 0:9fca2b23d0ba 7335
marcozecchini 0:9fca2b23d0ba 7336 /*
marcozecchini 0:9fca2b23d0ba 7337 * Free an SSL context
marcozecchini 0:9fca2b23d0ba 7338 */
marcozecchini 0:9fca2b23d0ba 7339 void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
marcozecchini 0:9fca2b23d0ba 7340 {
marcozecchini 0:9fca2b23d0ba 7341 if( ssl == NULL )
marcozecchini 0:9fca2b23d0ba 7342 return;
marcozecchini 0:9fca2b23d0ba 7343
marcozecchini 0:9fca2b23d0ba 7344 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) );
marcozecchini 0:9fca2b23d0ba 7345
marcozecchini 0:9fca2b23d0ba 7346 if( ssl->out_buf != NULL )
marcozecchini 0:9fca2b23d0ba 7347 {
marcozecchini 0:9fca2b23d0ba 7348 mbedtls_zeroize( ssl->out_buf, MBEDTLS_SSL_BUFFER_LEN );
marcozecchini 0:9fca2b23d0ba 7349 mbedtls_free( ssl->out_buf );
marcozecchini 0:9fca2b23d0ba 7350 }
marcozecchini 0:9fca2b23d0ba 7351
marcozecchini 0:9fca2b23d0ba 7352 if( ssl->in_buf != NULL )
marcozecchini 0:9fca2b23d0ba 7353 {
marcozecchini 0:9fca2b23d0ba 7354 mbedtls_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN );
marcozecchini 0:9fca2b23d0ba 7355 mbedtls_free( ssl->in_buf );
marcozecchini 0:9fca2b23d0ba 7356 }
marcozecchini 0:9fca2b23d0ba 7357
marcozecchini 0:9fca2b23d0ba 7358 #if defined(MBEDTLS_ZLIB_SUPPORT)
marcozecchini 0:9fca2b23d0ba 7359 if( ssl->compress_buf != NULL )
marcozecchini 0:9fca2b23d0ba 7360 {
marcozecchini 0:9fca2b23d0ba 7361 mbedtls_zeroize( ssl->compress_buf, MBEDTLS_SSL_BUFFER_LEN );
marcozecchini 0:9fca2b23d0ba 7362 mbedtls_free( ssl->compress_buf );
marcozecchini 0:9fca2b23d0ba 7363 }
marcozecchini 0:9fca2b23d0ba 7364 #endif
marcozecchini 0:9fca2b23d0ba 7365
marcozecchini 0:9fca2b23d0ba 7366 if( ssl->transform )
marcozecchini 0:9fca2b23d0ba 7367 {
marcozecchini 0:9fca2b23d0ba 7368 mbedtls_ssl_transform_free( ssl->transform );
marcozecchini 0:9fca2b23d0ba 7369 mbedtls_free( ssl->transform );
marcozecchini 0:9fca2b23d0ba 7370 }
marcozecchini 0:9fca2b23d0ba 7371
marcozecchini 0:9fca2b23d0ba 7372 if( ssl->handshake )
marcozecchini 0:9fca2b23d0ba 7373 {
marcozecchini 0:9fca2b23d0ba 7374 mbedtls_ssl_handshake_free( ssl->handshake );
marcozecchini 0:9fca2b23d0ba 7375 mbedtls_ssl_transform_free( ssl->transform_negotiate );
marcozecchini 0:9fca2b23d0ba 7376 mbedtls_ssl_session_free( ssl->session_negotiate );
marcozecchini 0:9fca2b23d0ba 7377
marcozecchini 0:9fca2b23d0ba 7378 mbedtls_free( ssl->handshake );
marcozecchini 0:9fca2b23d0ba 7379 mbedtls_free( ssl->transform_negotiate );
marcozecchini 0:9fca2b23d0ba 7380 mbedtls_free( ssl->session_negotiate );
marcozecchini 0:9fca2b23d0ba 7381 }
marcozecchini 0:9fca2b23d0ba 7382
marcozecchini 0:9fca2b23d0ba 7383 if( ssl->session )
marcozecchini 0:9fca2b23d0ba 7384 {
marcozecchini 0:9fca2b23d0ba 7385 mbedtls_ssl_session_free( ssl->session );
marcozecchini 0:9fca2b23d0ba 7386 mbedtls_free( ssl->session );
marcozecchini 0:9fca2b23d0ba 7387 }
marcozecchini 0:9fca2b23d0ba 7388
marcozecchini 0:9fca2b23d0ba 7389 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 7390 if( ssl->hostname != NULL )
marcozecchini 0:9fca2b23d0ba 7391 {
marcozecchini 0:9fca2b23d0ba 7392 mbedtls_zeroize( ssl->hostname, strlen( ssl->hostname ) );
marcozecchini 0:9fca2b23d0ba 7393 mbedtls_free( ssl->hostname );
marcozecchini 0:9fca2b23d0ba 7394 }
marcozecchini 0:9fca2b23d0ba 7395 #endif
marcozecchini 0:9fca2b23d0ba 7396
marcozecchini 0:9fca2b23d0ba 7397 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
marcozecchini 0:9fca2b23d0ba 7398 if( mbedtls_ssl_hw_record_finish != NULL )
marcozecchini 0:9fca2b23d0ba 7399 {
marcozecchini 0:9fca2b23d0ba 7400 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_finish()" ) );
marcozecchini 0:9fca2b23d0ba 7401 mbedtls_ssl_hw_record_finish( ssl );
marcozecchini 0:9fca2b23d0ba 7402 }
marcozecchini 0:9fca2b23d0ba 7403 #endif
marcozecchini 0:9fca2b23d0ba 7404
marcozecchini 0:9fca2b23d0ba 7405 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 7406 mbedtls_free( ssl->cli_id );
marcozecchini 0:9fca2b23d0ba 7407 #endif
marcozecchini 0:9fca2b23d0ba 7408
marcozecchini 0:9fca2b23d0ba 7409 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) );
marcozecchini 0:9fca2b23d0ba 7410
marcozecchini 0:9fca2b23d0ba 7411 /* Actually clear after last debug message */
marcozecchini 0:9fca2b23d0ba 7412 mbedtls_zeroize( ssl, sizeof( mbedtls_ssl_context ) );
marcozecchini 0:9fca2b23d0ba 7413 }
marcozecchini 0:9fca2b23d0ba 7414
marcozecchini 0:9fca2b23d0ba 7415 /*
marcozecchini 0:9fca2b23d0ba 7416 * Initialze mbedtls_ssl_config
marcozecchini 0:9fca2b23d0ba 7417 */
marcozecchini 0:9fca2b23d0ba 7418 void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
marcozecchini 0:9fca2b23d0ba 7419 {
marcozecchini 0:9fca2b23d0ba 7420 memset( conf, 0, sizeof( mbedtls_ssl_config ) );
marcozecchini 0:9fca2b23d0ba 7421 }
marcozecchini 0:9fca2b23d0ba 7422
marcozecchini 0:9fca2b23d0ba 7423 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
marcozecchini 0:9fca2b23d0ba 7424 static int ssl_preset_default_hashes[] = {
marcozecchini 0:9fca2b23d0ba 7425 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 7426 MBEDTLS_MD_SHA512,
marcozecchini 0:9fca2b23d0ba 7427 MBEDTLS_MD_SHA384,
marcozecchini 0:9fca2b23d0ba 7428 #endif
marcozecchini 0:9fca2b23d0ba 7429 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 7430 MBEDTLS_MD_SHA256,
marcozecchini 0:9fca2b23d0ba 7431 MBEDTLS_MD_SHA224,
marcozecchini 0:9fca2b23d0ba 7432 #endif
marcozecchini 0:9fca2b23d0ba 7433 #if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE)
marcozecchini 0:9fca2b23d0ba 7434 MBEDTLS_MD_SHA1,
marcozecchini 0:9fca2b23d0ba 7435 #endif
marcozecchini 0:9fca2b23d0ba 7436 MBEDTLS_MD_NONE
marcozecchini 0:9fca2b23d0ba 7437 };
marcozecchini 0:9fca2b23d0ba 7438 #endif
marcozecchini 0:9fca2b23d0ba 7439
marcozecchini 0:9fca2b23d0ba 7440 static int ssl_preset_suiteb_ciphersuites[] = {
marcozecchini 0:9fca2b23d0ba 7441 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
marcozecchini 0:9fca2b23d0ba 7442 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
marcozecchini 0:9fca2b23d0ba 7443 0
marcozecchini 0:9fca2b23d0ba 7444 };
marcozecchini 0:9fca2b23d0ba 7445
marcozecchini 0:9fca2b23d0ba 7446 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
marcozecchini 0:9fca2b23d0ba 7447 static int ssl_preset_suiteb_hashes[] = {
marcozecchini 0:9fca2b23d0ba 7448 MBEDTLS_MD_SHA256,
marcozecchini 0:9fca2b23d0ba 7449 MBEDTLS_MD_SHA384,
marcozecchini 0:9fca2b23d0ba 7450 MBEDTLS_MD_NONE
marcozecchini 0:9fca2b23d0ba 7451 };
marcozecchini 0:9fca2b23d0ba 7452 #endif
marcozecchini 0:9fca2b23d0ba 7453
marcozecchini 0:9fca2b23d0ba 7454 #if defined(MBEDTLS_ECP_C)
marcozecchini 0:9fca2b23d0ba 7455 static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = {
marcozecchini 0:9fca2b23d0ba 7456 MBEDTLS_ECP_DP_SECP256R1,
marcozecchini 0:9fca2b23d0ba 7457 MBEDTLS_ECP_DP_SECP384R1,
marcozecchini 0:9fca2b23d0ba 7458 MBEDTLS_ECP_DP_NONE
marcozecchini 0:9fca2b23d0ba 7459 };
marcozecchini 0:9fca2b23d0ba 7460 #endif
marcozecchini 0:9fca2b23d0ba 7461
marcozecchini 0:9fca2b23d0ba 7462 /*
marcozecchini 0:9fca2b23d0ba 7463 * Load default in mbedtls_ssl_config
marcozecchini 0:9fca2b23d0ba 7464 */
marcozecchini 0:9fca2b23d0ba 7465 int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
marcozecchini 0:9fca2b23d0ba 7466 int endpoint, int transport, int preset )
marcozecchini 0:9fca2b23d0ba 7467 {
marcozecchini 0:9fca2b23d0ba 7468 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 7469 int ret;
marcozecchini 0:9fca2b23d0ba 7470 #endif
marcozecchini 0:9fca2b23d0ba 7471
marcozecchini 0:9fca2b23d0ba 7472 /* Use the functions here so that they are covered in tests,
marcozecchini 0:9fca2b23d0ba 7473 * but otherwise access member directly for efficiency */
marcozecchini 0:9fca2b23d0ba 7474 mbedtls_ssl_conf_endpoint( conf, endpoint );
marcozecchini 0:9fca2b23d0ba 7475 mbedtls_ssl_conf_transport( conf, transport );
marcozecchini 0:9fca2b23d0ba 7476
marcozecchini 0:9fca2b23d0ba 7477 /*
marcozecchini 0:9fca2b23d0ba 7478 * Things that are common to all presets
marcozecchini 0:9fca2b23d0ba 7479 */
marcozecchini 0:9fca2b23d0ba 7480 #if defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 7481 if( endpoint == MBEDTLS_SSL_IS_CLIENT )
marcozecchini 0:9fca2b23d0ba 7482 {
marcozecchini 0:9fca2b23d0ba 7483 conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
marcozecchini 0:9fca2b23d0ba 7484 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
marcozecchini 0:9fca2b23d0ba 7485 conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
marcozecchini 0:9fca2b23d0ba 7486 #endif
marcozecchini 0:9fca2b23d0ba 7487 }
marcozecchini 0:9fca2b23d0ba 7488 #endif
marcozecchini 0:9fca2b23d0ba 7489
marcozecchini 0:9fca2b23d0ba 7490 #if defined(MBEDTLS_ARC4_C)
marcozecchini 0:9fca2b23d0ba 7491 conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED;
marcozecchini 0:9fca2b23d0ba 7492 #endif
marcozecchini 0:9fca2b23d0ba 7493
marcozecchini 0:9fca2b23d0ba 7494 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
marcozecchini 0:9fca2b23d0ba 7495 conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
marcozecchini 0:9fca2b23d0ba 7496 #endif
marcozecchini 0:9fca2b23d0ba 7497
marcozecchini 0:9fca2b23d0ba 7498 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
marcozecchini 0:9fca2b23d0ba 7499 conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
marcozecchini 0:9fca2b23d0ba 7500 #endif
marcozecchini 0:9fca2b23d0ba 7501
marcozecchini 0:9fca2b23d0ba 7502 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
marcozecchini 0:9fca2b23d0ba 7503 conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED;
marcozecchini 0:9fca2b23d0ba 7504 #endif
marcozecchini 0:9fca2b23d0ba 7505
marcozecchini 0:9fca2b23d0ba 7506 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 7507 conf->f_cookie_write = ssl_cookie_write_dummy;
marcozecchini 0:9fca2b23d0ba 7508 conf->f_cookie_check = ssl_cookie_check_dummy;
marcozecchini 0:9fca2b23d0ba 7509 #endif
marcozecchini 0:9fca2b23d0ba 7510
marcozecchini 0:9fca2b23d0ba 7511 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
marcozecchini 0:9fca2b23d0ba 7512 conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED;
marcozecchini 0:9fca2b23d0ba 7513 #endif
marcozecchini 0:9fca2b23d0ba 7514
marcozecchini 0:9fca2b23d0ba 7515 #if defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 7516 conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
marcozecchini 0:9fca2b23d0ba 7517 #endif
marcozecchini 0:9fca2b23d0ba 7518
marcozecchini 0:9fca2b23d0ba 7519 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 7520 conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
marcozecchini 0:9fca2b23d0ba 7521 conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
marcozecchini 0:9fca2b23d0ba 7522 #endif
marcozecchini 0:9fca2b23d0ba 7523
marcozecchini 0:9fca2b23d0ba 7524 #if defined(MBEDTLS_SSL_RENEGOTIATION)
marcozecchini 0:9fca2b23d0ba 7525 conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT;
marcozecchini 0:9fca2b23d0ba 7526 memset( conf->renego_period, 0x00, 2 );
marcozecchini 0:9fca2b23d0ba 7527 memset( conf->renego_period + 2, 0xFF, 6 );
marcozecchini 0:9fca2b23d0ba 7528 #endif
marcozecchini 0:9fca2b23d0ba 7529
marcozecchini 0:9fca2b23d0ba 7530 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
marcozecchini 0:9fca2b23d0ba 7531 if( endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 7532 {
marcozecchini 0:9fca2b23d0ba 7533 if( ( ret = mbedtls_ssl_conf_dh_param( conf,
marcozecchini 0:9fca2b23d0ba 7534 MBEDTLS_DHM_RFC5114_MODP_2048_P,
marcozecchini 0:9fca2b23d0ba 7535 MBEDTLS_DHM_RFC5114_MODP_2048_G ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 7536 {
marcozecchini 0:9fca2b23d0ba 7537 return( ret );
marcozecchini 0:9fca2b23d0ba 7538 }
marcozecchini 0:9fca2b23d0ba 7539 }
marcozecchini 0:9fca2b23d0ba 7540 #endif
marcozecchini 0:9fca2b23d0ba 7541
marcozecchini 0:9fca2b23d0ba 7542 /*
marcozecchini 0:9fca2b23d0ba 7543 * Preset-specific defaults
marcozecchini 0:9fca2b23d0ba 7544 */
marcozecchini 0:9fca2b23d0ba 7545 switch( preset )
marcozecchini 0:9fca2b23d0ba 7546 {
marcozecchini 0:9fca2b23d0ba 7547 /*
marcozecchini 0:9fca2b23d0ba 7548 * NSA Suite B
marcozecchini 0:9fca2b23d0ba 7549 */
marcozecchini 0:9fca2b23d0ba 7550 case MBEDTLS_SSL_PRESET_SUITEB:
marcozecchini 0:9fca2b23d0ba 7551 conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
marcozecchini 0:9fca2b23d0ba 7552 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
marcozecchini 0:9fca2b23d0ba 7553 conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
marcozecchini 0:9fca2b23d0ba 7554 conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
marcozecchini 0:9fca2b23d0ba 7555
marcozecchini 0:9fca2b23d0ba 7556 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
marcozecchini 0:9fca2b23d0ba 7557 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
marcozecchini 0:9fca2b23d0ba 7558 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
marcozecchini 0:9fca2b23d0ba 7559 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
marcozecchini 0:9fca2b23d0ba 7560 ssl_preset_suiteb_ciphersuites;
marcozecchini 0:9fca2b23d0ba 7561
marcozecchini 0:9fca2b23d0ba 7562 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 7563 conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
marcozecchini 0:9fca2b23d0ba 7564 #endif
marcozecchini 0:9fca2b23d0ba 7565
marcozecchini 0:9fca2b23d0ba 7566 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
marcozecchini 0:9fca2b23d0ba 7567 conf->sig_hashes = ssl_preset_suiteb_hashes;
marcozecchini 0:9fca2b23d0ba 7568 #endif
marcozecchini 0:9fca2b23d0ba 7569
marcozecchini 0:9fca2b23d0ba 7570 #if defined(MBEDTLS_ECP_C)
marcozecchini 0:9fca2b23d0ba 7571 conf->curve_list = ssl_preset_suiteb_curves;
marcozecchini 0:9fca2b23d0ba 7572 #endif
marcozecchini 0:9fca2b23d0ba 7573 break;
marcozecchini 0:9fca2b23d0ba 7574
marcozecchini 0:9fca2b23d0ba 7575 /*
marcozecchini 0:9fca2b23d0ba 7576 * Default
marcozecchini 0:9fca2b23d0ba 7577 */
marcozecchini 0:9fca2b23d0ba 7578 default:
marcozecchini 0:9fca2b23d0ba 7579 conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
marcozecchini 0:9fca2b23d0ba 7580 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS 1.0 */
marcozecchini 0:9fca2b23d0ba 7581 conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
marcozecchini 0:9fca2b23d0ba 7582 conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
marcozecchini 0:9fca2b23d0ba 7583
marcozecchini 0:9fca2b23d0ba 7584 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 7585 if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 7586 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
marcozecchini 0:9fca2b23d0ba 7587 #endif
marcozecchini 0:9fca2b23d0ba 7588
marcozecchini 0:9fca2b23d0ba 7589 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
marcozecchini 0:9fca2b23d0ba 7590 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
marcozecchini 0:9fca2b23d0ba 7591 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
marcozecchini 0:9fca2b23d0ba 7592 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
marcozecchini 0:9fca2b23d0ba 7593 mbedtls_ssl_list_ciphersuites();
marcozecchini 0:9fca2b23d0ba 7594
marcozecchini 0:9fca2b23d0ba 7595 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 7596 conf->cert_profile = &mbedtls_x509_crt_profile_default;
marcozecchini 0:9fca2b23d0ba 7597 #endif
marcozecchini 0:9fca2b23d0ba 7598
marcozecchini 0:9fca2b23d0ba 7599 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
marcozecchini 0:9fca2b23d0ba 7600 conf->sig_hashes = ssl_preset_default_hashes;
marcozecchini 0:9fca2b23d0ba 7601 #endif
marcozecchini 0:9fca2b23d0ba 7602
marcozecchini 0:9fca2b23d0ba 7603 #if defined(MBEDTLS_ECP_C)
marcozecchini 0:9fca2b23d0ba 7604 conf->curve_list = mbedtls_ecp_grp_id_list();
marcozecchini 0:9fca2b23d0ba 7605 #endif
marcozecchini 0:9fca2b23d0ba 7606
marcozecchini 0:9fca2b23d0ba 7607 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
marcozecchini 0:9fca2b23d0ba 7608 conf->dhm_min_bitlen = 1024;
marcozecchini 0:9fca2b23d0ba 7609 #endif
marcozecchini 0:9fca2b23d0ba 7610 }
marcozecchini 0:9fca2b23d0ba 7611
marcozecchini 0:9fca2b23d0ba 7612 return( 0 );
marcozecchini 0:9fca2b23d0ba 7613 }
marcozecchini 0:9fca2b23d0ba 7614
marcozecchini 0:9fca2b23d0ba 7615 /*
marcozecchini 0:9fca2b23d0ba 7616 * Free mbedtls_ssl_config
marcozecchini 0:9fca2b23d0ba 7617 */
marcozecchini 0:9fca2b23d0ba 7618 void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
marcozecchini 0:9fca2b23d0ba 7619 {
marcozecchini 0:9fca2b23d0ba 7620 #if defined(MBEDTLS_DHM_C)
marcozecchini 0:9fca2b23d0ba 7621 mbedtls_mpi_free( &conf->dhm_P );
marcozecchini 0:9fca2b23d0ba 7622 mbedtls_mpi_free( &conf->dhm_G );
marcozecchini 0:9fca2b23d0ba 7623 #endif
marcozecchini 0:9fca2b23d0ba 7624
marcozecchini 0:9fca2b23d0ba 7625 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
marcozecchini 0:9fca2b23d0ba 7626 if( conf->psk != NULL )
marcozecchini 0:9fca2b23d0ba 7627 {
marcozecchini 0:9fca2b23d0ba 7628 mbedtls_zeroize( conf->psk, conf->psk_len );
marcozecchini 0:9fca2b23d0ba 7629 mbedtls_zeroize( conf->psk_identity, conf->psk_identity_len );
marcozecchini 0:9fca2b23d0ba 7630 mbedtls_free( conf->psk );
marcozecchini 0:9fca2b23d0ba 7631 mbedtls_free( conf->psk_identity );
marcozecchini 0:9fca2b23d0ba 7632 conf->psk_len = 0;
marcozecchini 0:9fca2b23d0ba 7633 conf->psk_identity_len = 0;
marcozecchini 0:9fca2b23d0ba 7634 }
marcozecchini 0:9fca2b23d0ba 7635 #endif
marcozecchini 0:9fca2b23d0ba 7636
marcozecchini 0:9fca2b23d0ba 7637 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 7638 ssl_key_cert_free( conf->key_cert );
marcozecchini 0:9fca2b23d0ba 7639 #endif
marcozecchini 0:9fca2b23d0ba 7640
marcozecchini 0:9fca2b23d0ba 7641 mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) );
marcozecchini 0:9fca2b23d0ba 7642 }
marcozecchini 0:9fca2b23d0ba 7643
marcozecchini 0:9fca2b23d0ba 7644 #if defined(MBEDTLS_PK_C) && \
marcozecchini 0:9fca2b23d0ba 7645 ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) )
marcozecchini 0:9fca2b23d0ba 7646 /*
marcozecchini 0:9fca2b23d0ba 7647 * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
marcozecchini 0:9fca2b23d0ba 7648 */
marcozecchini 0:9fca2b23d0ba 7649 unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk )
marcozecchini 0:9fca2b23d0ba 7650 {
marcozecchini 0:9fca2b23d0ba 7651 #if defined(MBEDTLS_RSA_C)
marcozecchini 0:9fca2b23d0ba 7652 if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) )
marcozecchini 0:9fca2b23d0ba 7653 return( MBEDTLS_SSL_SIG_RSA );
marcozecchini 0:9fca2b23d0ba 7654 #endif
marcozecchini 0:9fca2b23d0ba 7655 #if defined(MBEDTLS_ECDSA_C)
marcozecchini 0:9fca2b23d0ba 7656 if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) )
marcozecchini 0:9fca2b23d0ba 7657 return( MBEDTLS_SSL_SIG_ECDSA );
marcozecchini 0:9fca2b23d0ba 7658 #endif
marcozecchini 0:9fca2b23d0ba 7659 return( MBEDTLS_SSL_SIG_ANON );
marcozecchini 0:9fca2b23d0ba 7660 }
marcozecchini 0:9fca2b23d0ba 7661
marcozecchini 0:9fca2b23d0ba 7662 unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type )
marcozecchini 0:9fca2b23d0ba 7663 {
marcozecchini 0:9fca2b23d0ba 7664 switch( type ) {
marcozecchini 0:9fca2b23d0ba 7665 case MBEDTLS_PK_RSA:
marcozecchini 0:9fca2b23d0ba 7666 return( MBEDTLS_SSL_SIG_RSA );
marcozecchini 0:9fca2b23d0ba 7667 case MBEDTLS_PK_ECDSA:
marcozecchini 0:9fca2b23d0ba 7668 case MBEDTLS_PK_ECKEY:
marcozecchini 0:9fca2b23d0ba 7669 return( MBEDTLS_SSL_SIG_ECDSA );
marcozecchini 0:9fca2b23d0ba 7670 default:
marcozecchini 0:9fca2b23d0ba 7671 return( MBEDTLS_SSL_SIG_ANON );
marcozecchini 0:9fca2b23d0ba 7672 }
marcozecchini 0:9fca2b23d0ba 7673 }
marcozecchini 0:9fca2b23d0ba 7674
marcozecchini 0:9fca2b23d0ba 7675 mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
marcozecchini 0:9fca2b23d0ba 7676 {
marcozecchini 0:9fca2b23d0ba 7677 switch( sig )
marcozecchini 0:9fca2b23d0ba 7678 {
marcozecchini 0:9fca2b23d0ba 7679 #if defined(MBEDTLS_RSA_C)
marcozecchini 0:9fca2b23d0ba 7680 case MBEDTLS_SSL_SIG_RSA:
marcozecchini 0:9fca2b23d0ba 7681 return( MBEDTLS_PK_RSA );
marcozecchini 0:9fca2b23d0ba 7682 #endif
marcozecchini 0:9fca2b23d0ba 7683 #if defined(MBEDTLS_ECDSA_C)
marcozecchini 0:9fca2b23d0ba 7684 case MBEDTLS_SSL_SIG_ECDSA:
marcozecchini 0:9fca2b23d0ba 7685 return( MBEDTLS_PK_ECDSA );
marcozecchini 0:9fca2b23d0ba 7686 #endif
marcozecchini 0:9fca2b23d0ba 7687 default:
marcozecchini 0:9fca2b23d0ba 7688 return( MBEDTLS_PK_NONE );
marcozecchini 0:9fca2b23d0ba 7689 }
marcozecchini 0:9fca2b23d0ba 7690 }
marcozecchini 0:9fca2b23d0ba 7691 #endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
marcozecchini 0:9fca2b23d0ba 7692
marcozecchini 0:9fca2b23d0ba 7693 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
marcozecchini 0:9fca2b23d0ba 7694 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
marcozecchini 0:9fca2b23d0ba 7695
marcozecchini 0:9fca2b23d0ba 7696 /* Find an entry in a signature-hash set matching a given hash algorithm. */
marcozecchini 0:9fca2b23d0ba 7697 mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
marcozecchini 0:9fca2b23d0ba 7698 mbedtls_pk_type_t sig_alg )
marcozecchini 0:9fca2b23d0ba 7699 {
marcozecchini 0:9fca2b23d0ba 7700 switch( sig_alg )
marcozecchini 0:9fca2b23d0ba 7701 {
marcozecchini 0:9fca2b23d0ba 7702 case MBEDTLS_PK_RSA:
marcozecchini 0:9fca2b23d0ba 7703 return( set->rsa );
marcozecchini 0:9fca2b23d0ba 7704 case MBEDTLS_PK_ECDSA:
marcozecchini 0:9fca2b23d0ba 7705 return( set->ecdsa );
marcozecchini 0:9fca2b23d0ba 7706 default:
marcozecchini 0:9fca2b23d0ba 7707 return( MBEDTLS_MD_NONE );
marcozecchini 0:9fca2b23d0ba 7708 }
marcozecchini 0:9fca2b23d0ba 7709 }
marcozecchini 0:9fca2b23d0ba 7710
marcozecchini 0:9fca2b23d0ba 7711 /* Add a signature-hash-pair to a signature-hash set */
marcozecchini 0:9fca2b23d0ba 7712 void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
marcozecchini 0:9fca2b23d0ba 7713 mbedtls_pk_type_t sig_alg,
marcozecchini 0:9fca2b23d0ba 7714 mbedtls_md_type_t md_alg )
marcozecchini 0:9fca2b23d0ba 7715 {
marcozecchini 0:9fca2b23d0ba 7716 switch( sig_alg )
marcozecchini 0:9fca2b23d0ba 7717 {
marcozecchini 0:9fca2b23d0ba 7718 case MBEDTLS_PK_RSA:
marcozecchini 0:9fca2b23d0ba 7719 if( set->rsa == MBEDTLS_MD_NONE )
marcozecchini 0:9fca2b23d0ba 7720 set->rsa = md_alg;
marcozecchini 0:9fca2b23d0ba 7721 break;
marcozecchini 0:9fca2b23d0ba 7722
marcozecchini 0:9fca2b23d0ba 7723 case MBEDTLS_PK_ECDSA:
marcozecchini 0:9fca2b23d0ba 7724 if( set->ecdsa == MBEDTLS_MD_NONE )
marcozecchini 0:9fca2b23d0ba 7725 set->ecdsa = md_alg;
marcozecchini 0:9fca2b23d0ba 7726 break;
marcozecchini 0:9fca2b23d0ba 7727
marcozecchini 0:9fca2b23d0ba 7728 default:
marcozecchini 0:9fca2b23d0ba 7729 break;
marcozecchini 0:9fca2b23d0ba 7730 }
marcozecchini 0:9fca2b23d0ba 7731 }
marcozecchini 0:9fca2b23d0ba 7732
marcozecchini 0:9fca2b23d0ba 7733 /* Allow exactly one hash algorithm for each signature. */
marcozecchini 0:9fca2b23d0ba 7734 void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
marcozecchini 0:9fca2b23d0ba 7735 mbedtls_md_type_t md_alg )
marcozecchini 0:9fca2b23d0ba 7736 {
marcozecchini 0:9fca2b23d0ba 7737 set->rsa = md_alg;
marcozecchini 0:9fca2b23d0ba 7738 set->ecdsa = md_alg;
marcozecchini 0:9fca2b23d0ba 7739 }
marcozecchini 0:9fca2b23d0ba 7740
marcozecchini 0:9fca2b23d0ba 7741 #endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
marcozecchini 0:9fca2b23d0ba 7742 MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
marcozecchini 0:9fca2b23d0ba 7743
marcozecchini 0:9fca2b23d0ba 7744 /*
marcozecchini 0:9fca2b23d0ba 7745 * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
marcozecchini 0:9fca2b23d0ba 7746 */
marcozecchini 0:9fca2b23d0ba 7747 mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash )
marcozecchini 0:9fca2b23d0ba 7748 {
marcozecchini 0:9fca2b23d0ba 7749 switch( hash )
marcozecchini 0:9fca2b23d0ba 7750 {
marcozecchini 0:9fca2b23d0ba 7751 #if defined(MBEDTLS_MD5_C)
marcozecchini 0:9fca2b23d0ba 7752 case MBEDTLS_SSL_HASH_MD5:
marcozecchini 0:9fca2b23d0ba 7753 return( MBEDTLS_MD_MD5 );
marcozecchini 0:9fca2b23d0ba 7754 #endif
marcozecchini 0:9fca2b23d0ba 7755 #if defined(MBEDTLS_SHA1_C)
marcozecchini 0:9fca2b23d0ba 7756 case MBEDTLS_SSL_HASH_SHA1:
marcozecchini 0:9fca2b23d0ba 7757 return( MBEDTLS_MD_SHA1 );
marcozecchini 0:9fca2b23d0ba 7758 #endif
marcozecchini 0:9fca2b23d0ba 7759 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 7760 case MBEDTLS_SSL_HASH_SHA224:
marcozecchini 0:9fca2b23d0ba 7761 return( MBEDTLS_MD_SHA224 );
marcozecchini 0:9fca2b23d0ba 7762 case MBEDTLS_SSL_HASH_SHA256:
marcozecchini 0:9fca2b23d0ba 7763 return( MBEDTLS_MD_SHA256 );
marcozecchini 0:9fca2b23d0ba 7764 #endif
marcozecchini 0:9fca2b23d0ba 7765 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 7766 case MBEDTLS_SSL_HASH_SHA384:
marcozecchini 0:9fca2b23d0ba 7767 return( MBEDTLS_MD_SHA384 );
marcozecchini 0:9fca2b23d0ba 7768 case MBEDTLS_SSL_HASH_SHA512:
marcozecchini 0:9fca2b23d0ba 7769 return( MBEDTLS_MD_SHA512 );
marcozecchini 0:9fca2b23d0ba 7770 #endif
marcozecchini 0:9fca2b23d0ba 7771 default:
marcozecchini 0:9fca2b23d0ba 7772 return( MBEDTLS_MD_NONE );
marcozecchini 0:9fca2b23d0ba 7773 }
marcozecchini 0:9fca2b23d0ba 7774 }
marcozecchini 0:9fca2b23d0ba 7775
marcozecchini 0:9fca2b23d0ba 7776 /*
marcozecchini 0:9fca2b23d0ba 7777 * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX
marcozecchini 0:9fca2b23d0ba 7778 */
marcozecchini 0:9fca2b23d0ba 7779 unsigned char mbedtls_ssl_hash_from_md_alg( int md )
marcozecchini 0:9fca2b23d0ba 7780 {
marcozecchini 0:9fca2b23d0ba 7781 switch( md )
marcozecchini 0:9fca2b23d0ba 7782 {
marcozecchini 0:9fca2b23d0ba 7783 #if defined(MBEDTLS_MD5_C)
marcozecchini 0:9fca2b23d0ba 7784 case MBEDTLS_MD_MD5:
marcozecchini 0:9fca2b23d0ba 7785 return( MBEDTLS_SSL_HASH_MD5 );
marcozecchini 0:9fca2b23d0ba 7786 #endif
marcozecchini 0:9fca2b23d0ba 7787 #if defined(MBEDTLS_SHA1_C)
marcozecchini 0:9fca2b23d0ba 7788 case MBEDTLS_MD_SHA1:
marcozecchini 0:9fca2b23d0ba 7789 return( MBEDTLS_SSL_HASH_SHA1 );
marcozecchini 0:9fca2b23d0ba 7790 #endif
marcozecchini 0:9fca2b23d0ba 7791 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 7792 case MBEDTLS_MD_SHA224:
marcozecchini 0:9fca2b23d0ba 7793 return( MBEDTLS_SSL_HASH_SHA224 );
marcozecchini 0:9fca2b23d0ba 7794 case MBEDTLS_MD_SHA256:
marcozecchini 0:9fca2b23d0ba 7795 return( MBEDTLS_SSL_HASH_SHA256 );
marcozecchini 0:9fca2b23d0ba 7796 #endif
marcozecchini 0:9fca2b23d0ba 7797 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 7798 case MBEDTLS_MD_SHA384:
marcozecchini 0:9fca2b23d0ba 7799 return( MBEDTLS_SSL_HASH_SHA384 );
marcozecchini 0:9fca2b23d0ba 7800 case MBEDTLS_MD_SHA512:
marcozecchini 0:9fca2b23d0ba 7801 return( MBEDTLS_SSL_HASH_SHA512 );
marcozecchini 0:9fca2b23d0ba 7802 #endif
marcozecchini 0:9fca2b23d0ba 7803 default:
marcozecchini 0:9fca2b23d0ba 7804 return( MBEDTLS_SSL_HASH_NONE );
marcozecchini 0:9fca2b23d0ba 7805 }
marcozecchini 0:9fca2b23d0ba 7806 }
marcozecchini 0:9fca2b23d0ba 7807
marcozecchini 0:9fca2b23d0ba 7808 #if defined(MBEDTLS_ECP_C)
marcozecchini 0:9fca2b23d0ba 7809 /*
marcozecchini 0:9fca2b23d0ba 7810 * Check if a curve proposed by the peer is in our list.
marcozecchini 0:9fca2b23d0ba 7811 * Return 0 if we're willing to use it, -1 otherwise.
marcozecchini 0:9fca2b23d0ba 7812 */
marcozecchini 0:9fca2b23d0ba 7813 int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id )
marcozecchini 0:9fca2b23d0ba 7814 {
marcozecchini 0:9fca2b23d0ba 7815 const mbedtls_ecp_group_id *gid;
marcozecchini 0:9fca2b23d0ba 7816
marcozecchini 0:9fca2b23d0ba 7817 if( ssl->conf->curve_list == NULL )
marcozecchini 0:9fca2b23d0ba 7818 return( -1 );
marcozecchini 0:9fca2b23d0ba 7819
marcozecchini 0:9fca2b23d0ba 7820 for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
marcozecchini 0:9fca2b23d0ba 7821 if( *gid == grp_id )
marcozecchini 0:9fca2b23d0ba 7822 return( 0 );
marcozecchini 0:9fca2b23d0ba 7823
marcozecchini 0:9fca2b23d0ba 7824 return( -1 );
marcozecchini 0:9fca2b23d0ba 7825 }
marcozecchini 0:9fca2b23d0ba 7826 #endif /* MBEDTLS_ECP_C */
marcozecchini 0:9fca2b23d0ba 7827
marcozecchini 0:9fca2b23d0ba 7828 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
marcozecchini 0:9fca2b23d0ba 7829 /*
marcozecchini 0:9fca2b23d0ba 7830 * Check if a hash proposed by the peer is in our list.
marcozecchini 0:9fca2b23d0ba 7831 * Return 0 if we're willing to use it, -1 otherwise.
marcozecchini 0:9fca2b23d0ba 7832 */
marcozecchini 0:9fca2b23d0ba 7833 int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
marcozecchini 0:9fca2b23d0ba 7834 mbedtls_md_type_t md )
marcozecchini 0:9fca2b23d0ba 7835 {
marcozecchini 0:9fca2b23d0ba 7836 const int *cur;
marcozecchini 0:9fca2b23d0ba 7837
marcozecchini 0:9fca2b23d0ba 7838 if( ssl->conf->sig_hashes == NULL )
marcozecchini 0:9fca2b23d0ba 7839 return( -1 );
marcozecchini 0:9fca2b23d0ba 7840
marcozecchini 0:9fca2b23d0ba 7841 for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
marcozecchini 0:9fca2b23d0ba 7842 if( *cur == (int) md )
marcozecchini 0:9fca2b23d0ba 7843 return( 0 );
marcozecchini 0:9fca2b23d0ba 7844
marcozecchini 0:9fca2b23d0ba 7845 return( -1 );
marcozecchini 0:9fca2b23d0ba 7846 }
marcozecchini 0:9fca2b23d0ba 7847 #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
marcozecchini 0:9fca2b23d0ba 7848
marcozecchini 0:9fca2b23d0ba 7849 #if defined(MBEDTLS_X509_CRT_PARSE_C)
marcozecchini 0:9fca2b23d0ba 7850 int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
marcozecchini 0:9fca2b23d0ba 7851 const mbedtls_ssl_ciphersuite_t *ciphersuite,
marcozecchini 0:9fca2b23d0ba 7852 int cert_endpoint,
marcozecchini 0:9fca2b23d0ba 7853 uint32_t *flags )
marcozecchini 0:9fca2b23d0ba 7854 {
marcozecchini 0:9fca2b23d0ba 7855 int ret = 0;
marcozecchini 0:9fca2b23d0ba 7856 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
marcozecchini 0:9fca2b23d0ba 7857 int usage = 0;
marcozecchini 0:9fca2b23d0ba 7858 #endif
marcozecchini 0:9fca2b23d0ba 7859 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
marcozecchini 0:9fca2b23d0ba 7860 const char *ext_oid;
marcozecchini 0:9fca2b23d0ba 7861 size_t ext_len;
marcozecchini 0:9fca2b23d0ba 7862 #endif
marcozecchini 0:9fca2b23d0ba 7863
marcozecchini 0:9fca2b23d0ba 7864 #if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \
marcozecchini 0:9fca2b23d0ba 7865 !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
marcozecchini 0:9fca2b23d0ba 7866 ((void) cert);
marcozecchini 0:9fca2b23d0ba 7867 ((void) cert_endpoint);
marcozecchini 0:9fca2b23d0ba 7868 ((void) flags);
marcozecchini 0:9fca2b23d0ba 7869 #endif
marcozecchini 0:9fca2b23d0ba 7870
marcozecchini 0:9fca2b23d0ba 7871 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
marcozecchini 0:9fca2b23d0ba 7872 if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 7873 {
marcozecchini 0:9fca2b23d0ba 7874 /* Server part of the key exchange */
marcozecchini 0:9fca2b23d0ba 7875 switch( ciphersuite->key_exchange )
marcozecchini 0:9fca2b23d0ba 7876 {
marcozecchini 0:9fca2b23d0ba 7877 case MBEDTLS_KEY_EXCHANGE_RSA:
marcozecchini 0:9fca2b23d0ba 7878 case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
marcozecchini 0:9fca2b23d0ba 7879 usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
marcozecchini 0:9fca2b23d0ba 7880 break;
marcozecchini 0:9fca2b23d0ba 7881
marcozecchini 0:9fca2b23d0ba 7882 case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
marcozecchini 0:9fca2b23d0ba 7883 case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
marcozecchini 0:9fca2b23d0ba 7884 case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
marcozecchini 0:9fca2b23d0ba 7885 usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
marcozecchini 0:9fca2b23d0ba 7886 break;
marcozecchini 0:9fca2b23d0ba 7887
marcozecchini 0:9fca2b23d0ba 7888 case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
marcozecchini 0:9fca2b23d0ba 7889 case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
marcozecchini 0:9fca2b23d0ba 7890 usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
marcozecchini 0:9fca2b23d0ba 7891 break;
marcozecchini 0:9fca2b23d0ba 7892
marcozecchini 0:9fca2b23d0ba 7893 /* Don't use default: we want warnings when adding new values */
marcozecchini 0:9fca2b23d0ba 7894 case MBEDTLS_KEY_EXCHANGE_NONE:
marcozecchini 0:9fca2b23d0ba 7895 case MBEDTLS_KEY_EXCHANGE_PSK:
marcozecchini 0:9fca2b23d0ba 7896 case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
marcozecchini 0:9fca2b23d0ba 7897 case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
marcozecchini 0:9fca2b23d0ba 7898 case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
marcozecchini 0:9fca2b23d0ba 7899 usage = 0;
marcozecchini 0:9fca2b23d0ba 7900 }
marcozecchini 0:9fca2b23d0ba 7901 }
marcozecchini 0:9fca2b23d0ba 7902 else
marcozecchini 0:9fca2b23d0ba 7903 {
marcozecchini 0:9fca2b23d0ba 7904 /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
marcozecchini 0:9fca2b23d0ba 7905 usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
marcozecchini 0:9fca2b23d0ba 7906 }
marcozecchini 0:9fca2b23d0ba 7907
marcozecchini 0:9fca2b23d0ba 7908 if( mbedtls_x509_crt_check_key_usage( cert, usage ) != 0 )
marcozecchini 0:9fca2b23d0ba 7909 {
marcozecchini 0:9fca2b23d0ba 7910 *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
marcozecchini 0:9fca2b23d0ba 7911 ret = -1;
marcozecchini 0:9fca2b23d0ba 7912 }
marcozecchini 0:9fca2b23d0ba 7913 #else
marcozecchini 0:9fca2b23d0ba 7914 ((void) ciphersuite);
marcozecchini 0:9fca2b23d0ba 7915 #endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
marcozecchini 0:9fca2b23d0ba 7916
marcozecchini 0:9fca2b23d0ba 7917 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
marcozecchini 0:9fca2b23d0ba 7918 if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
marcozecchini 0:9fca2b23d0ba 7919 {
marcozecchini 0:9fca2b23d0ba 7920 ext_oid = MBEDTLS_OID_SERVER_AUTH;
marcozecchini 0:9fca2b23d0ba 7921 ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH );
marcozecchini 0:9fca2b23d0ba 7922 }
marcozecchini 0:9fca2b23d0ba 7923 else
marcozecchini 0:9fca2b23d0ba 7924 {
marcozecchini 0:9fca2b23d0ba 7925 ext_oid = MBEDTLS_OID_CLIENT_AUTH;
marcozecchini 0:9fca2b23d0ba 7926 ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH );
marcozecchini 0:9fca2b23d0ba 7927 }
marcozecchini 0:9fca2b23d0ba 7928
marcozecchini 0:9fca2b23d0ba 7929 if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 )
marcozecchini 0:9fca2b23d0ba 7930 {
marcozecchini 0:9fca2b23d0ba 7931 *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
marcozecchini 0:9fca2b23d0ba 7932 ret = -1;
marcozecchini 0:9fca2b23d0ba 7933 }
marcozecchini 0:9fca2b23d0ba 7934 #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
marcozecchini 0:9fca2b23d0ba 7935
marcozecchini 0:9fca2b23d0ba 7936 return( ret );
marcozecchini 0:9fca2b23d0ba 7937 }
marcozecchini 0:9fca2b23d0ba 7938 #endif /* MBEDTLS_X509_CRT_PARSE_C */
marcozecchini 0:9fca2b23d0ba 7939
marcozecchini 0:9fca2b23d0ba 7940 /*
marcozecchini 0:9fca2b23d0ba 7941 * Convert version numbers to/from wire format
marcozecchini 0:9fca2b23d0ba 7942 * and, for DTLS, to/from TLS equivalent.
marcozecchini 0:9fca2b23d0ba 7943 *
marcozecchini 0:9fca2b23d0ba 7944 * For TLS this is the identity.
marcozecchini 0:9fca2b23d0ba 7945 * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
marcozecchini 0:9fca2b23d0ba 7946 * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1)
marcozecchini 0:9fca2b23d0ba 7947 * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
marcozecchini 0:9fca2b23d0ba 7948 */
marcozecchini 0:9fca2b23d0ba 7949 void mbedtls_ssl_write_version( int major, int minor, int transport,
marcozecchini 0:9fca2b23d0ba 7950 unsigned char ver[2] )
marcozecchini 0:9fca2b23d0ba 7951 {
marcozecchini 0:9fca2b23d0ba 7952 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 7953 if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 7954 {
marcozecchini 0:9fca2b23d0ba 7955 if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
marcozecchini 0:9fca2b23d0ba 7956 --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
marcozecchini 0:9fca2b23d0ba 7957
marcozecchini 0:9fca2b23d0ba 7958 ver[0] = (unsigned char)( 255 - ( major - 2 ) );
marcozecchini 0:9fca2b23d0ba 7959 ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
marcozecchini 0:9fca2b23d0ba 7960 }
marcozecchini 0:9fca2b23d0ba 7961 else
marcozecchini 0:9fca2b23d0ba 7962 #else
marcozecchini 0:9fca2b23d0ba 7963 ((void) transport);
marcozecchini 0:9fca2b23d0ba 7964 #endif
marcozecchini 0:9fca2b23d0ba 7965 {
marcozecchini 0:9fca2b23d0ba 7966 ver[0] = (unsigned char) major;
marcozecchini 0:9fca2b23d0ba 7967 ver[1] = (unsigned char) minor;
marcozecchini 0:9fca2b23d0ba 7968 }
marcozecchini 0:9fca2b23d0ba 7969 }
marcozecchini 0:9fca2b23d0ba 7970
marcozecchini 0:9fca2b23d0ba 7971 void mbedtls_ssl_read_version( int *major, int *minor, int transport,
marcozecchini 0:9fca2b23d0ba 7972 const unsigned char ver[2] )
marcozecchini 0:9fca2b23d0ba 7973 {
marcozecchini 0:9fca2b23d0ba 7974 #if defined(MBEDTLS_SSL_PROTO_DTLS)
marcozecchini 0:9fca2b23d0ba 7975 if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
marcozecchini 0:9fca2b23d0ba 7976 {
marcozecchini 0:9fca2b23d0ba 7977 *major = 255 - ver[0] + 2;
marcozecchini 0:9fca2b23d0ba 7978 *minor = 255 - ver[1] + 1;
marcozecchini 0:9fca2b23d0ba 7979
marcozecchini 0:9fca2b23d0ba 7980 if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
marcozecchini 0:9fca2b23d0ba 7981 ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
marcozecchini 0:9fca2b23d0ba 7982 }
marcozecchini 0:9fca2b23d0ba 7983 else
marcozecchini 0:9fca2b23d0ba 7984 #else
marcozecchini 0:9fca2b23d0ba 7985 ((void) transport);
marcozecchini 0:9fca2b23d0ba 7986 #endif
marcozecchini 0:9fca2b23d0ba 7987 {
marcozecchini 0:9fca2b23d0ba 7988 *major = ver[0];
marcozecchini 0:9fca2b23d0ba 7989 *minor = ver[1];
marcozecchini 0:9fca2b23d0ba 7990 }
marcozecchini 0:9fca2b23d0ba 7991 }
marcozecchini 0:9fca2b23d0ba 7992
marcozecchini 0:9fca2b23d0ba 7993 int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
marcozecchini 0:9fca2b23d0ba 7994 {
marcozecchini 0:9fca2b23d0ba 7995 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
marcozecchini 0:9fca2b23d0ba 7996 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
marcozecchini 0:9fca2b23d0ba 7997 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
marcozecchini 0:9fca2b23d0ba 7998
marcozecchini 0:9fca2b23d0ba 7999 switch( md )
marcozecchini 0:9fca2b23d0ba 8000 {
marcozecchini 0:9fca2b23d0ba 8001 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
marcozecchini 0:9fca2b23d0ba 8002 #if defined(MBEDTLS_MD5_C)
marcozecchini 0:9fca2b23d0ba 8003 case MBEDTLS_SSL_HASH_MD5:
marcozecchini 0:9fca2b23d0ba 8004 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
marcozecchini 0:9fca2b23d0ba 8005 #endif
marcozecchini 0:9fca2b23d0ba 8006 #if defined(MBEDTLS_SHA1_C)
marcozecchini 0:9fca2b23d0ba 8007 case MBEDTLS_SSL_HASH_SHA1:
marcozecchini 0:9fca2b23d0ba 8008 ssl->handshake->calc_verify = ssl_calc_verify_tls;
marcozecchini 0:9fca2b23d0ba 8009 break;
marcozecchini 0:9fca2b23d0ba 8010 #endif
marcozecchini 0:9fca2b23d0ba 8011 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
marcozecchini 0:9fca2b23d0ba 8012 #if defined(MBEDTLS_SHA512_C)
marcozecchini 0:9fca2b23d0ba 8013 case MBEDTLS_SSL_HASH_SHA384:
marcozecchini 0:9fca2b23d0ba 8014 ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
marcozecchini 0:9fca2b23d0ba 8015 break;
marcozecchini 0:9fca2b23d0ba 8016 #endif
marcozecchini 0:9fca2b23d0ba 8017 #if defined(MBEDTLS_SHA256_C)
marcozecchini 0:9fca2b23d0ba 8018 case MBEDTLS_SSL_HASH_SHA256:
marcozecchini 0:9fca2b23d0ba 8019 ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256;
marcozecchini 0:9fca2b23d0ba 8020 break;
marcozecchini 0:9fca2b23d0ba 8021 #endif
marcozecchini 0:9fca2b23d0ba 8022 default:
marcozecchini 0:9fca2b23d0ba 8023 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
marcozecchini 0:9fca2b23d0ba 8024 }
marcozecchini 0:9fca2b23d0ba 8025
marcozecchini 0:9fca2b23d0ba 8026 return 0;
marcozecchini 0:9fca2b23d0ba 8027 #else /* !MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 8028 (void) ssl;
marcozecchini 0:9fca2b23d0ba 8029 (void) md;
marcozecchini 0:9fca2b23d0ba 8030
marcozecchini 0:9fca2b23d0ba 8031 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
marcozecchini 0:9fca2b23d0ba 8032 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
marcozecchini 0:9fca2b23d0ba 8033 }
marcozecchini 0:9fca2b23d0ba 8034
marcozecchini 0:9fca2b23d0ba 8035 #endif /* MBEDTLS_SSL_TLS_C */