mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 17 23:23:45 2019 +0000
Revision:
0:5b88d5760320
Child:
1:9db0e321a9f4
mbed-os5 only for TYBLE16

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /*
kenjiArai 0:5b88d5760320 2 * SSLv3/TLSv1 shared functions
kenjiArai 0:5b88d5760320 3 *
kenjiArai 0:5b88d5760320 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
kenjiArai 0:5b88d5760320 5 * SPDX-License-Identifier: Apache-2.0
kenjiArai 0:5b88d5760320 6 *
kenjiArai 0:5b88d5760320 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kenjiArai 0:5b88d5760320 8 * not use this file except in compliance with the License.
kenjiArai 0:5b88d5760320 9 * You may obtain a copy of the License at
kenjiArai 0:5b88d5760320 10 *
kenjiArai 0:5b88d5760320 11 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 0:5b88d5760320 12 *
kenjiArai 0:5b88d5760320 13 * Unless required by applicable law or agreed to in writing, software
kenjiArai 0:5b88d5760320 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kenjiArai 0:5b88d5760320 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 0:5b88d5760320 16 * See the License for the specific language governing permissions and
kenjiArai 0:5b88d5760320 17 * limitations under the License.
kenjiArai 0:5b88d5760320 18 *
kenjiArai 0:5b88d5760320 19 * This file is part of mbed TLS (https://tls.mbed.org)
kenjiArai 0:5b88d5760320 20 */
kenjiArai 0:5b88d5760320 21 /*
kenjiArai 0:5b88d5760320 22 * The SSL 3.0 specification was drafted by Netscape in 1996,
kenjiArai 0:5b88d5760320 23 * and became an IETF standard in 1999.
kenjiArai 0:5b88d5760320 24 *
kenjiArai 0:5b88d5760320 25 * http://wp.netscape.com/eng/ssl3/
kenjiArai 0:5b88d5760320 26 * http://www.ietf.org/rfc/rfc2246.txt
kenjiArai 0:5b88d5760320 27 * http://www.ietf.org/rfc/rfc4346.txt
kenjiArai 0:5b88d5760320 28 */
kenjiArai 0:5b88d5760320 29
kenjiArai 0:5b88d5760320 30 #if !defined(MBEDTLS_CONFIG_FILE)
kenjiArai 0:5b88d5760320 31 #include "mbedtls/config.h"
kenjiArai 0:5b88d5760320 32 #else
kenjiArai 0:5b88d5760320 33 #include MBEDTLS_CONFIG_FILE
kenjiArai 0:5b88d5760320 34 #endif
kenjiArai 0:5b88d5760320 35
kenjiArai 0:5b88d5760320 36 #if defined(MBEDTLS_SSL_TLS_C)
kenjiArai 0:5b88d5760320 37
kenjiArai 0:5b88d5760320 38 #if defined(MBEDTLS_PLATFORM_C)
kenjiArai 0:5b88d5760320 39 #include "mbedtls/platform.h"
kenjiArai 0:5b88d5760320 40 #else
kenjiArai 0:5b88d5760320 41 #include <stdlib.h>
kenjiArai 0:5b88d5760320 42 #define mbedtls_calloc calloc
kenjiArai 0:5b88d5760320 43 #define mbedtls_free free
kenjiArai 0:5b88d5760320 44 #endif
kenjiArai 0:5b88d5760320 45
kenjiArai 0:5b88d5760320 46 #include "mbedtls/debug.h"
kenjiArai 0:5b88d5760320 47 #include "mbedtls/ssl.h"
kenjiArai 0:5b88d5760320 48 #include "mbedtls/ssl_internal.h"
kenjiArai 0:5b88d5760320 49 #include "mbedtls/platform_util.h"
kenjiArai 0:5b88d5760320 50
kenjiArai 0:5b88d5760320 51 #include <string.h>
kenjiArai 0:5b88d5760320 52
kenjiArai 0:5b88d5760320 53 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 54 #include "mbedtls/psa_util.h"
kenjiArai 0:5b88d5760320 55 #include "psa/crypto.h"
kenjiArai 0:5b88d5760320 56 #endif
kenjiArai 0:5b88d5760320 57
kenjiArai 0:5b88d5760320 58 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 59 #include "mbedtls/oid.h"
kenjiArai 0:5b88d5760320 60 #endif
kenjiArai 0:5b88d5760320 61
kenjiArai 0:5b88d5760320 62 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 63 #include "mbedtls/psa_util.h"
kenjiArai 0:5b88d5760320 64 #endif
kenjiArai 0:5b88d5760320 65
kenjiArai 0:5b88d5760320 66 static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 67 static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
kenjiArai 0:5b88d5760320 68
kenjiArai 0:5b88d5760320 69 /* Length of the "epoch" field in the record header */
kenjiArai 0:5b88d5760320 70 static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 71 {
kenjiArai 0:5b88d5760320 72 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 73 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 74 return( 2 );
kenjiArai 0:5b88d5760320 75 #else
kenjiArai 0:5b88d5760320 76 ((void) ssl);
kenjiArai 0:5b88d5760320 77 #endif
kenjiArai 0:5b88d5760320 78 return( 0 );
kenjiArai 0:5b88d5760320 79 }
kenjiArai 0:5b88d5760320 80
kenjiArai 0:5b88d5760320 81 /*
kenjiArai 0:5b88d5760320 82 * Start a timer.
kenjiArai 0:5b88d5760320 83 * Passing millisecs = 0 cancels a running timer.
kenjiArai 0:5b88d5760320 84 */
kenjiArai 0:5b88d5760320 85 static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
kenjiArai 0:5b88d5760320 86 {
kenjiArai 0:5b88d5760320 87 if( ssl->f_set_timer == NULL )
kenjiArai 0:5b88d5760320 88 return;
kenjiArai 0:5b88d5760320 89
kenjiArai 0:5b88d5760320 90 MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
kenjiArai 0:5b88d5760320 91 ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
kenjiArai 0:5b88d5760320 92 }
kenjiArai 0:5b88d5760320 93
kenjiArai 0:5b88d5760320 94 /*
kenjiArai 0:5b88d5760320 95 * Return -1 is timer is expired, 0 if it isn't.
kenjiArai 0:5b88d5760320 96 */
kenjiArai 0:5b88d5760320 97 static int ssl_check_timer( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 98 {
kenjiArai 0:5b88d5760320 99 if( ssl->f_get_timer == NULL )
kenjiArai 0:5b88d5760320 100 return( 0 );
kenjiArai 0:5b88d5760320 101
kenjiArai 0:5b88d5760320 102 if( ssl->f_get_timer( ssl->p_timer ) == 2 )
kenjiArai 0:5b88d5760320 103 {
kenjiArai 0:5b88d5760320 104 MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
kenjiArai 0:5b88d5760320 105 return( -1 );
kenjiArai 0:5b88d5760320 106 }
kenjiArai 0:5b88d5760320 107
kenjiArai 0:5b88d5760320 108 return( 0 );
kenjiArai 0:5b88d5760320 109 }
kenjiArai 0:5b88d5760320 110
kenjiArai 0:5b88d5760320 111 static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 112 mbedtls_ssl_transform *transform );
kenjiArai 0:5b88d5760320 113 static void ssl_update_in_pointers( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 114
kenjiArai 0:5b88d5760320 115 #define SSL_DONT_FORCE_FLUSH 0
kenjiArai 0:5b88d5760320 116 #define SSL_FORCE_FLUSH 1
kenjiArai 0:5b88d5760320 117
kenjiArai 0:5b88d5760320 118 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 119
kenjiArai 0:5b88d5760320 120 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 121 /* Top-level Connection ID API */
kenjiArai 0:5b88d5760320 122
kenjiArai 0:5b88d5760320 123 int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 124 size_t len,
kenjiArai 0:5b88d5760320 125 int ignore_other_cid )
kenjiArai 0:5b88d5760320 126 {
kenjiArai 0:5b88d5760320 127 if( len > MBEDTLS_SSL_CID_IN_LEN_MAX )
kenjiArai 0:5b88d5760320 128 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 129
kenjiArai 0:5b88d5760320 130 if( ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_FAIL &&
kenjiArai 0:5b88d5760320 131 ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE )
kenjiArai 0:5b88d5760320 132 {
kenjiArai 0:5b88d5760320 133 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 134 }
kenjiArai 0:5b88d5760320 135
kenjiArai 0:5b88d5760320 136 conf->ignore_unexpected_cid = ignore_other_cid;
kenjiArai 0:5b88d5760320 137 conf->cid_len = len;
kenjiArai 0:5b88d5760320 138 return( 0 );
kenjiArai 0:5b88d5760320 139 }
kenjiArai 0:5b88d5760320 140
kenjiArai 0:5b88d5760320 141 int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 142 int enable,
kenjiArai 0:5b88d5760320 143 unsigned char const *own_cid,
kenjiArai 0:5b88d5760320 144 size_t own_cid_len )
kenjiArai 0:5b88d5760320 145 {
kenjiArai 0:5b88d5760320 146 if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 147 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 148
kenjiArai 0:5b88d5760320 149 ssl->negotiate_cid = enable;
kenjiArai 0:5b88d5760320 150 if( enable == MBEDTLS_SSL_CID_DISABLED )
kenjiArai 0:5b88d5760320 151 {
kenjiArai 0:5b88d5760320 152 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Disable use of CID extension." ) );
kenjiArai 0:5b88d5760320 153 return( 0 );
kenjiArai 0:5b88d5760320 154 }
kenjiArai 0:5b88d5760320 155 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Enable use of CID extension." ) );
kenjiArai 0:5b88d5760320 156 MBEDTLS_SSL_DEBUG_BUF( 3, "Own CID", own_cid, own_cid_len );
kenjiArai 0:5b88d5760320 157
kenjiArai 0:5b88d5760320 158 if( own_cid_len != ssl->conf->cid_len )
kenjiArai 0:5b88d5760320 159 {
kenjiArai 0:5b88d5760320 160 MBEDTLS_SSL_DEBUG_MSG( 3, ( "CID length %u does not match CID length %u in config",
kenjiArai 0:5b88d5760320 161 (unsigned) own_cid_len,
kenjiArai 0:5b88d5760320 162 (unsigned) ssl->conf->cid_len ) );
kenjiArai 0:5b88d5760320 163 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 164 }
kenjiArai 0:5b88d5760320 165
kenjiArai 0:5b88d5760320 166 memcpy( ssl->own_cid, own_cid, own_cid_len );
kenjiArai 0:5b88d5760320 167 /* Truncation is not an issue here because
kenjiArai 0:5b88d5760320 168 * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */
kenjiArai 0:5b88d5760320 169 ssl->own_cid_len = (uint8_t) own_cid_len;
kenjiArai 0:5b88d5760320 170
kenjiArai 0:5b88d5760320 171 return( 0 );
kenjiArai 0:5b88d5760320 172 }
kenjiArai 0:5b88d5760320 173
kenjiArai 0:5b88d5760320 174 int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 175 int *enabled,
kenjiArai 0:5b88d5760320 176 unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ],
kenjiArai 0:5b88d5760320 177 size_t *peer_cid_len )
kenjiArai 0:5b88d5760320 178 {
kenjiArai 0:5b88d5760320 179 *enabled = MBEDTLS_SSL_CID_DISABLED;
kenjiArai 0:5b88d5760320 180
kenjiArai 0:5b88d5760320 181 if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
kenjiArai 0:5b88d5760320 182 ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 183 {
kenjiArai 0:5b88d5760320 184 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 185 }
kenjiArai 0:5b88d5760320 186
kenjiArai 0:5b88d5760320 187 /* We report MBEDTLS_SSL_CID_DISABLED in case the CID extensions
kenjiArai 0:5b88d5760320 188 * were used, but client and server requested the empty CID.
kenjiArai 0:5b88d5760320 189 * This is indistinguishable from not using the CID extension
kenjiArai 0:5b88d5760320 190 * in the first place. */
kenjiArai 0:5b88d5760320 191 if( ssl->transform_in->in_cid_len == 0 &&
kenjiArai 0:5b88d5760320 192 ssl->transform_in->out_cid_len == 0 )
kenjiArai 0:5b88d5760320 193 {
kenjiArai 0:5b88d5760320 194 return( 0 );
kenjiArai 0:5b88d5760320 195 }
kenjiArai 0:5b88d5760320 196
kenjiArai 0:5b88d5760320 197 if( peer_cid_len != NULL )
kenjiArai 0:5b88d5760320 198 {
kenjiArai 0:5b88d5760320 199 *peer_cid_len = ssl->transform_in->out_cid_len;
kenjiArai 0:5b88d5760320 200 if( peer_cid != NULL )
kenjiArai 0:5b88d5760320 201 {
kenjiArai 0:5b88d5760320 202 memcpy( peer_cid, ssl->transform_in->out_cid,
kenjiArai 0:5b88d5760320 203 ssl->transform_in->out_cid_len );
kenjiArai 0:5b88d5760320 204 }
kenjiArai 0:5b88d5760320 205 }
kenjiArai 0:5b88d5760320 206
kenjiArai 0:5b88d5760320 207 *enabled = MBEDTLS_SSL_CID_ENABLED;
kenjiArai 0:5b88d5760320 208
kenjiArai 0:5b88d5760320 209 return( 0 );
kenjiArai 0:5b88d5760320 210 }
kenjiArai 0:5b88d5760320 211 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 212
kenjiArai 0:5b88d5760320 213 /* Forward declarations for functions related to message buffering. */
kenjiArai 0:5b88d5760320 214 static void ssl_buffering_free( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 215 static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 216 uint8_t slot );
kenjiArai 0:5b88d5760320 217 static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 218 static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 219 static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 220 static int ssl_buffer_message( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 221 static int ssl_buffer_future_record( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 222 static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 223
kenjiArai 0:5b88d5760320 224 static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 225 static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
kenjiArai 0:5b88d5760320 226 {
kenjiArai 0:5b88d5760320 227 size_t mtu = ssl_get_current_mtu( ssl );
kenjiArai 0:5b88d5760320 228
kenjiArai 0:5b88d5760320 229 if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN )
kenjiArai 0:5b88d5760320 230 return( mtu );
kenjiArai 0:5b88d5760320 231
kenjiArai 0:5b88d5760320 232 return( MBEDTLS_SSL_OUT_BUFFER_LEN );
kenjiArai 0:5b88d5760320 233 }
kenjiArai 0:5b88d5760320 234
kenjiArai 0:5b88d5760320 235 static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
kenjiArai 0:5b88d5760320 236 {
kenjiArai 0:5b88d5760320 237 size_t const bytes_written = ssl->out_left;
kenjiArai 0:5b88d5760320 238 size_t const mtu = ssl_get_maximum_datagram_size( ssl );
kenjiArai 0:5b88d5760320 239
kenjiArai 0:5b88d5760320 240 /* Double-check that the write-index hasn't gone
kenjiArai 0:5b88d5760320 241 * past what we can transmit in a single datagram. */
kenjiArai 0:5b88d5760320 242 if( bytes_written > mtu )
kenjiArai 0:5b88d5760320 243 {
kenjiArai 0:5b88d5760320 244 /* Should never happen... */
kenjiArai 0:5b88d5760320 245 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 246 }
kenjiArai 0:5b88d5760320 247
kenjiArai 0:5b88d5760320 248 return( (int) ( mtu - bytes_written ) );
kenjiArai 0:5b88d5760320 249 }
kenjiArai 0:5b88d5760320 250
kenjiArai 0:5b88d5760320 251 static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
kenjiArai 0:5b88d5760320 252 {
kenjiArai 0:5b88d5760320 253 int ret;
kenjiArai 0:5b88d5760320 254 size_t remaining, expansion;
kenjiArai 0:5b88d5760320 255 size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
kenjiArai 0:5b88d5760320 256
kenjiArai 0:5b88d5760320 257 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
kenjiArai 0:5b88d5760320 258 const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
kenjiArai 0:5b88d5760320 259
kenjiArai 0:5b88d5760320 260 if( max_len > mfl )
kenjiArai 0:5b88d5760320 261 max_len = mfl;
kenjiArai 0:5b88d5760320 262
kenjiArai 0:5b88d5760320 263 /* By the standard (RFC 6066 Sect. 4), the MFL extension
kenjiArai 0:5b88d5760320 264 * only limits the maximum record payload size, so in theory
kenjiArai 0:5b88d5760320 265 * we would be allowed to pack multiple records of payload size
kenjiArai 0:5b88d5760320 266 * MFL into a single datagram. However, this would mean that there's
kenjiArai 0:5b88d5760320 267 * no way to explicitly communicate MTU restrictions to the peer.
kenjiArai 0:5b88d5760320 268 *
kenjiArai 0:5b88d5760320 269 * The following reduction of max_len makes sure that we never
kenjiArai 0:5b88d5760320 270 * write datagrams larger than MFL + Record Expansion Overhead.
kenjiArai 0:5b88d5760320 271 */
kenjiArai 0:5b88d5760320 272 if( max_len <= ssl->out_left )
kenjiArai 0:5b88d5760320 273 return( 0 );
kenjiArai 0:5b88d5760320 274
kenjiArai 0:5b88d5760320 275 max_len -= ssl->out_left;
kenjiArai 0:5b88d5760320 276 #endif
kenjiArai 0:5b88d5760320 277
kenjiArai 0:5b88d5760320 278 ret = ssl_get_remaining_space_in_datagram( ssl );
kenjiArai 0:5b88d5760320 279 if( ret < 0 )
kenjiArai 0:5b88d5760320 280 return( ret );
kenjiArai 0:5b88d5760320 281 remaining = (size_t) ret;
kenjiArai 0:5b88d5760320 282
kenjiArai 0:5b88d5760320 283 ret = mbedtls_ssl_get_record_expansion( ssl );
kenjiArai 0:5b88d5760320 284 if( ret < 0 )
kenjiArai 0:5b88d5760320 285 return( ret );
kenjiArai 0:5b88d5760320 286 expansion = (size_t) ret;
kenjiArai 0:5b88d5760320 287
kenjiArai 0:5b88d5760320 288 if( remaining <= expansion )
kenjiArai 0:5b88d5760320 289 return( 0 );
kenjiArai 0:5b88d5760320 290
kenjiArai 0:5b88d5760320 291 remaining -= expansion;
kenjiArai 0:5b88d5760320 292 if( remaining >= max_len )
kenjiArai 0:5b88d5760320 293 remaining = max_len;
kenjiArai 0:5b88d5760320 294
kenjiArai 0:5b88d5760320 295 return( (int) remaining );
kenjiArai 0:5b88d5760320 296 }
kenjiArai 0:5b88d5760320 297
kenjiArai 0:5b88d5760320 298 /*
kenjiArai 0:5b88d5760320 299 * Double the retransmit timeout value, within the allowed range,
kenjiArai 0:5b88d5760320 300 * returning -1 if the maximum value has already been reached.
kenjiArai 0:5b88d5760320 301 */
kenjiArai 0:5b88d5760320 302 static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 303 {
kenjiArai 0:5b88d5760320 304 uint32_t new_timeout;
kenjiArai 0:5b88d5760320 305
kenjiArai 0:5b88d5760320 306 if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
kenjiArai 0:5b88d5760320 307 return( -1 );
kenjiArai 0:5b88d5760320 308
kenjiArai 0:5b88d5760320 309 /* Implement the final paragraph of RFC 6347 section 4.1.1.1
kenjiArai 0:5b88d5760320 310 * in the following way: after the initial transmission and a first
kenjiArai 0:5b88d5760320 311 * retransmission, back off to a temporary estimated MTU of 508 bytes.
kenjiArai 0:5b88d5760320 312 * This value is guaranteed to be deliverable (if not guaranteed to be
kenjiArai 0:5b88d5760320 313 * delivered) of any compliant IPv4 (and IPv6) network, and should work
kenjiArai 0:5b88d5760320 314 * on most non-IP stacks too. */
kenjiArai 0:5b88d5760320 315 if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
kenjiArai 0:5b88d5760320 316 {
kenjiArai 0:5b88d5760320 317 ssl->handshake->mtu = 508;
kenjiArai 0:5b88d5760320 318 MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) );
kenjiArai 0:5b88d5760320 319 }
kenjiArai 0:5b88d5760320 320
kenjiArai 0:5b88d5760320 321 new_timeout = 2 * ssl->handshake->retransmit_timeout;
kenjiArai 0:5b88d5760320 322
kenjiArai 0:5b88d5760320 323 /* Avoid arithmetic overflow and range overflow */
kenjiArai 0:5b88d5760320 324 if( new_timeout < ssl->handshake->retransmit_timeout ||
kenjiArai 0:5b88d5760320 325 new_timeout > ssl->conf->hs_timeout_max )
kenjiArai 0:5b88d5760320 326 {
kenjiArai 0:5b88d5760320 327 new_timeout = ssl->conf->hs_timeout_max;
kenjiArai 0:5b88d5760320 328 }
kenjiArai 0:5b88d5760320 329
kenjiArai 0:5b88d5760320 330 ssl->handshake->retransmit_timeout = new_timeout;
kenjiArai 0:5b88d5760320 331 MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
kenjiArai 0:5b88d5760320 332 ssl->handshake->retransmit_timeout ) );
kenjiArai 0:5b88d5760320 333
kenjiArai 0:5b88d5760320 334 return( 0 );
kenjiArai 0:5b88d5760320 335 }
kenjiArai 0:5b88d5760320 336
kenjiArai 0:5b88d5760320 337 static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 338 {
kenjiArai 0:5b88d5760320 339 ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
kenjiArai 0:5b88d5760320 340 MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
kenjiArai 0:5b88d5760320 341 ssl->handshake->retransmit_timeout ) );
kenjiArai 0:5b88d5760320 342 }
kenjiArai 0:5b88d5760320 343 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 344
kenjiArai 0:5b88d5760320 345 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
kenjiArai 0:5b88d5760320 346 /*
kenjiArai 0:5b88d5760320 347 * Convert max_fragment_length codes to length.
kenjiArai 0:5b88d5760320 348 * RFC 6066 says:
kenjiArai 0:5b88d5760320 349 * enum{
kenjiArai 0:5b88d5760320 350 * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
kenjiArai 0:5b88d5760320 351 * } MaxFragmentLength;
kenjiArai 0:5b88d5760320 352 * and we add 0 -> extension unused
kenjiArai 0:5b88d5760320 353 */
kenjiArai 0:5b88d5760320 354 static unsigned int ssl_mfl_code_to_length( int mfl )
kenjiArai 0:5b88d5760320 355 {
kenjiArai 0:5b88d5760320 356 switch( mfl )
kenjiArai 0:5b88d5760320 357 {
kenjiArai 0:5b88d5760320 358 case MBEDTLS_SSL_MAX_FRAG_LEN_NONE:
kenjiArai 0:5b88d5760320 359 return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN );
kenjiArai 0:5b88d5760320 360 case MBEDTLS_SSL_MAX_FRAG_LEN_512:
kenjiArai 0:5b88d5760320 361 return 512;
kenjiArai 0:5b88d5760320 362 case MBEDTLS_SSL_MAX_FRAG_LEN_1024:
kenjiArai 0:5b88d5760320 363 return 1024;
kenjiArai 0:5b88d5760320 364 case MBEDTLS_SSL_MAX_FRAG_LEN_2048:
kenjiArai 0:5b88d5760320 365 return 2048;
kenjiArai 0:5b88d5760320 366 case MBEDTLS_SSL_MAX_FRAG_LEN_4096:
kenjiArai 0:5b88d5760320 367 return 4096;
kenjiArai 0:5b88d5760320 368 default:
kenjiArai 0:5b88d5760320 369 return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN );
kenjiArai 0:5b88d5760320 370 }
kenjiArai 0:5b88d5760320 371 }
kenjiArai 0:5b88d5760320 372 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
kenjiArai 0:5b88d5760320 373
kenjiArai 0:5b88d5760320 374 int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
kenjiArai 0:5b88d5760320 375 const mbedtls_ssl_session *src )
kenjiArai 0:5b88d5760320 376 {
kenjiArai 0:5b88d5760320 377 mbedtls_ssl_session_free( dst );
kenjiArai 0:5b88d5760320 378 memcpy( dst, src, sizeof( mbedtls_ssl_session ) );
kenjiArai 0:5b88d5760320 379
kenjiArai 0:5b88d5760320 380 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 381
kenjiArai 0:5b88d5760320 382 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 383 if( src->peer_cert != NULL )
kenjiArai 0:5b88d5760320 384 {
kenjiArai 0:5b88d5760320 385 int ret;
kenjiArai 0:5b88d5760320 386
kenjiArai 0:5b88d5760320 387 dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) );
kenjiArai 0:5b88d5760320 388 if( dst->peer_cert == NULL )
kenjiArai 0:5b88d5760320 389 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 390
kenjiArai 0:5b88d5760320 391 mbedtls_x509_crt_init( dst->peer_cert );
kenjiArai 0:5b88d5760320 392
kenjiArai 0:5b88d5760320 393 if( ( ret = mbedtls_x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p,
kenjiArai 0:5b88d5760320 394 src->peer_cert->raw.len ) ) != 0 )
kenjiArai 0:5b88d5760320 395 {
kenjiArai 0:5b88d5760320 396 mbedtls_free( dst->peer_cert );
kenjiArai 0:5b88d5760320 397 dst->peer_cert = NULL;
kenjiArai 0:5b88d5760320 398 return( ret );
kenjiArai 0:5b88d5760320 399 }
kenjiArai 0:5b88d5760320 400 }
kenjiArai 0:5b88d5760320 401 #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 402 if( src->peer_cert_digest != NULL )
kenjiArai 0:5b88d5760320 403 {
kenjiArai 0:5b88d5760320 404 dst->peer_cert_digest =
kenjiArai 0:5b88d5760320 405 mbedtls_calloc( 1, src->peer_cert_digest_len );
kenjiArai 0:5b88d5760320 406 if( dst->peer_cert_digest == NULL )
kenjiArai 0:5b88d5760320 407 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 408
kenjiArai 0:5b88d5760320 409 memcpy( dst->peer_cert_digest, src->peer_cert_digest,
kenjiArai 0:5b88d5760320 410 src->peer_cert_digest_len );
kenjiArai 0:5b88d5760320 411 dst->peer_cert_digest_type = src->peer_cert_digest_type;
kenjiArai 0:5b88d5760320 412 dst->peer_cert_digest_len = src->peer_cert_digest_len;
kenjiArai 0:5b88d5760320 413 }
kenjiArai 0:5b88d5760320 414 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 415
kenjiArai 0:5b88d5760320 416 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 417
kenjiArai 0:5b88d5760320 418 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 419 if( src->ticket != NULL )
kenjiArai 0:5b88d5760320 420 {
kenjiArai 0:5b88d5760320 421 dst->ticket = mbedtls_calloc( 1, src->ticket_len );
kenjiArai 0:5b88d5760320 422 if( dst->ticket == NULL )
kenjiArai 0:5b88d5760320 423 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 424
kenjiArai 0:5b88d5760320 425 memcpy( dst->ticket, src->ticket, src->ticket_len );
kenjiArai 0:5b88d5760320 426 }
kenjiArai 0:5b88d5760320 427 #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 428
kenjiArai 0:5b88d5760320 429 return( 0 );
kenjiArai 0:5b88d5760320 430 }
kenjiArai 0:5b88d5760320 431
kenjiArai 0:5b88d5760320 432 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 433 int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 434 const unsigned char *key_enc, const unsigned char *key_dec,
kenjiArai 0:5b88d5760320 435 size_t keylen,
kenjiArai 0:5b88d5760320 436 const unsigned char *iv_enc, const unsigned char *iv_dec,
kenjiArai 0:5b88d5760320 437 size_t ivlen,
kenjiArai 0:5b88d5760320 438 const unsigned char *mac_enc, const unsigned char *mac_dec,
kenjiArai 0:5b88d5760320 439 size_t maclen ) = NULL;
kenjiArai 0:5b88d5760320 440 int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
kenjiArai 0:5b88d5760320 441 int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
kenjiArai 0:5b88d5760320 442 int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
kenjiArai 0:5b88d5760320 443 int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
kenjiArai 0:5b88d5760320 444 int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
kenjiArai 0:5b88d5760320 445 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
kenjiArai 0:5b88d5760320 446
kenjiArai 0:5b88d5760320 447 /*
kenjiArai 0:5b88d5760320 448 * Key material generation
kenjiArai 0:5b88d5760320 449 */
kenjiArai 0:5b88d5760320 450 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 451 static int ssl3_prf( const unsigned char *secret, size_t slen,
kenjiArai 0:5b88d5760320 452 const char *label,
kenjiArai 0:5b88d5760320 453 const unsigned char *random, size_t rlen,
kenjiArai 0:5b88d5760320 454 unsigned char *dstbuf, size_t dlen )
kenjiArai 0:5b88d5760320 455 {
kenjiArai 0:5b88d5760320 456 int ret = 0;
kenjiArai 0:5b88d5760320 457 size_t i;
kenjiArai 0:5b88d5760320 458 mbedtls_md5_context md5;
kenjiArai 0:5b88d5760320 459 mbedtls_sha1_context sha1;
kenjiArai 0:5b88d5760320 460 unsigned char padding[16];
kenjiArai 0:5b88d5760320 461 unsigned char sha1sum[20];
kenjiArai 0:5b88d5760320 462 ((void)label);
kenjiArai 0:5b88d5760320 463
kenjiArai 0:5b88d5760320 464 mbedtls_md5_init( &md5 );
kenjiArai 0:5b88d5760320 465 mbedtls_sha1_init( &sha1 );
kenjiArai 0:5b88d5760320 466
kenjiArai 0:5b88d5760320 467 /*
kenjiArai 0:5b88d5760320 468 * SSLv3:
kenjiArai 0:5b88d5760320 469 * block =
kenjiArai 0:5b88d5760320 470 * MD5( secret + SHA1( 'A' + secret + random ) ) +
kenjiArai 0:5b88d5760320 471 * MD5( secret + SHA1( 'BB' + secret + random ) ) +
kenjiArai 0:5b88d5760320 472 * MD5( secret + SHA1( 'CCC' + secret + random ) ) +
kenjiArai 0:5b88d5760320 473 * ...
kenjiArai 0:5b88d5760320 474 */
kenjiArai 0:5b88d5760320 475 for( i = 0; i < dlen / 16; i++ )
kenjiArai 0:5b88d5760320 476 {
kenjiArai 0:5b88d5760320 477 memset( padding, (unsigned char) ('A' + i), 1 + i );
kenjiArai 0:5b88d5760320 478
kenjiArai 0:5b88d5760320 479 if( ( ret = mbedtls_sha1_starts_ret( &sha1 ) ) != 0 )
kenjiArai 0:5b88d5760320 480 goto exit;
kenjiArai 0:5b88d5760320 481 if( ( ret = mbedtls_sha1_update_ret( &sha1, padding, 1 + i ) ) != 0 )
kenjiArai 0:5b88d5760320 482 goto exit;
kenjiArai 0:5b88d5760320 483 if( ( ret = mbedtls_sha1_update_ret( &sha1, secret, slen ) ) != 0 )
kenjiArai 0:5b88d5760320 484 goto exit;
kenjiArai 0:5b88d5760320 485 if( ( ret = mbedtls_sha1_update_ret( &sha1, random, rlen ) ) != 0 )
kenjiArai 0:5b88d5760320 486 goto exit;
kenjiArai 0:5b88d5760320 487 if( ( ret = mbedtls_sha1_finish_ret( &sha1, sha1sum ) ) != 0 )
kenjiArai 0:5b88d5760320 488 goto exit;
kenjiArai 0:5b88d5760320 489
kenjiArai 0:5b88d5760320 490 if( ( ret = mbedtls_md5_starts_ret( &md5 ) ) != 0 )
kenjiArai 0:5b88d5760320 491 goto exit;
kenjiArai 0:5b88d5760320 492 if( ( ret = mbedtls_md5_update_ret( &md5, secret, slen ) ) != 0 )
kenjiArai 0:5b88d5760320 493 goto exit;
kenjiArai 0:5b88d5760320 494 if( ( ret = mbedtls_md5_update_ret( &md5, sha1sum, 20 ) ) != 0 )
kenjiArai 0:5b88d5760320 495 goto exit;
kenjiArai 0:5b88d5760320 496 if( ( ret = mbedtls_md5_finish_ret( &md5, dstbuf + i * 16 ) ) != 0 )
kenjiArai 0:5b88d5760320 497 goto exit;
kenjiArai 0:5b88d5760320 498 }
kenjiArai 0:5b88d5760320 499
kenjiArai 0:5b88d5760320 500 exit:
kenjiArai 0:5b88d5760320 501 mbedtls_md5_free( &md5 );
kenjiArai 0:5b88d5760320 502 mbedtls_sha1_free( &sha1 );
kenjiArai 0:5b88d5760320 503
kenjiArai 0:5b88d5760320 504 mbedtls_platform_zeroize( padding, sizeof( padding ) );
kenjiArai 0:5b88d5760320 505 mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
kenjiArai 0:5b88d5760320 506
kenjiArai 0:5b88d5760320 507 return( ret );
kenjiArai 0:5b88d5760320 508 }
kenjiArai 0:5b88d5760320 509 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 510
kenjiArai 0:5b88d5760320 511 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 512 static int tls1_prf( const unsigned char *secret, size_t slen,
kenjiArai 0:5b88d5760320 513 const char *label,
kenjiArai 0:5b88d5760320 514 const unsigned char *random, size_t rlen,
kenjiArai 0:5b88d5760320 515 unsigned char *dstbuf, size_t dlen )
kenjiArai 0:5b88d5760320 516 {
kenjiArai 0:5b88d5760320 517 size_t nb, hs;
kenjiArai 0:5b88d5760320 518 size_t i, j, k;
kenjiArai 0:5b88d5760320 519 const unsigned char *S1, *S2;
kenjiArai 0:5b88d5760320 520 unsigned char *tmp;
kenjiArai 0:5b88d5760320 521 size_t tmp_len = 0;
kenjiArai 0:5b88d5760320 522 unsigned char h_i[20];
kenjiArai 0:5b88d5760320 523 const mbedtls_md_info_t *md_info;
kenjiArai 0:5b88d5760320 524 mbedtls_md_context_t md_ctx;
kenjiArai 0:5b88d5760320 525 int ret;
kenjiArai 0:5b88d5760320 526
kenjiArai 0:5b88d5760320 527 mbedtls_md_init( &md_ctx );
kenjiArai 0:5b88d5760320 528
kenjiArai 0:5b88d5760320 529 tmp_len = 20 + strlen( label ) + rlen;
kenjiArai 0:5b88d5760320 530 tmp = mbedtls_calloc( 1, tmp_len );
kenjiArai 0:5b88d5760320 531 if( tmp == NULL )
kenjiArai 0:5b88d5760320 532 {
kenjiArai 0:5b88d5760320 533 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
kenjiArai 0:5b88d5760320 534 goto exit;
kenjiArai 0:5b88d5760320 535 }
kenjiArai 0:5b88d5760320 536
kenjiArai 0:5b88d5760320 537 hs = ( slen + 1 ) / 2;
kenjiArai 0:5b88d5760320 538 S1 = secret;
kenjiArai 0:5b88d5760320 539 S2 = secret + slen - hs;
kenjiArai 0:5b88d5760320 540
kenjiArai 0:5b88d5760320 541 nb = strlen( label );
kenjiArai 0:5b88d5760320 542 memcpy( tmp + 20, label, nb );
kenjiArai 0:5b88d5760320 543 memcpy( tmp + 20 + nb, random, rlen );
kenjiArai 0:5b88d5760320 544 nb += rlen;
kenjiArai 0:5b88d5760320 545
kenjiArai 0:5b88d5760320 546 /*
kenjiArai 0:5b88d5760320 547 * First compute P_md5(secret,label+random)[0..dlen]
kenjiArai 0:5b88d5760320 548 */
kenjiArai 0:5b88d5760320 549 if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL )
kenjiArai 0:5b88d5760320 550 {
kenjiArai 0:5b88d5760320 551 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
kenjiArai 0:5b88d5760320 552 goto exit;
kenjiArai 0:5b88d5760320 553 }
kenjiArai 0:5b88d5760320 554
kenjiArai 0:5b88d5760320 555 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 556 {
kenjiArai 0:5b88d5760320 557 goto exit;
kenjiArai 0:5b88d5760320 558 }
kenjiArai 0:5b88d5760320 559
kenjiArai 0:5b88d5760320 560 mbedtls_md_hmac_starts( &md_ctx, S1, hs );
kenjiArai 0:5b88d5760320 561 mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
kenjiArai 0:5b88d5760320 562 mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
kenjiArai 0:5b88d5760320 563
kenjiArai 0:5b88d5760320 564 for( i = 0; i < dlen; i += 16 )
kenjiArai 0:5b88d5760320 565 {
kenjiArai 0:5b88d5760320 566 mbedtls_md_hmac_reset ( &md_ctx );
kenjiArai 0:5b88d5760320 567 mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb );
kenjiArai 0:5b88d5760320 568 mbedtls_md_hmac_finish( &md_ctx, h_i );
kenjiArai 0:5b88d5760320 569
kenjiArai 0:5b88d5760320 570 mbedtls_md_hmac_reset ( &md_ctx );
kenjiArai 0:5b88d5760320 571 mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 );
kenjiArai 0:5b88d5760320 572 mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
kenjiArai 0:5b88d5760320 573
kenjiArai 0:5b88d5760320 574 k = ( i + 16 > dlen ) ? dlen % 16 : 16;
kenjiArai 0:5b88d5760320 575
kenjiArai 0:5b88d5760320 576 for( j = 0; j < k; j++ )
kenjiArai 0:5b88d5760320 577 dstbuf[i + j] = h_i[j];
kenjiArai 0:5b88d5760320 578 }
kenjiArai 0:5b88d5760320 579
kenjiArai 0:5b88d5760320 580 mbedtls_md_free( &md_ctx );
kenjiArai 0:5b88d5760320 581
kenjiArai 0:5b88d5760320 582 /*
kenjiArai 0:5b88d5760320 583 * XOR out with P_sha1(secret,label+random)[0..dlen]
kenjiArai 0:5b88d5760320 584 */
kenjiArai 0:5b88d5760320 585 if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL )
kenjiArai 0:5b88d5760320 586 {
kenjiArai 0:5b88d5760320 587 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
kenjiArai 0:5b88d5760320 588 goto exit;
kenjiArai 0:5b88d5760320 589 }
kenjiArai 0:5b88d5760320 590
kenjiArai 0:5b88d5760320 591 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 592 {
kenjiArai 0:5b88d5760320 593 goto exit;
kenjiArai 0:5b88d5760320 594 }
kenjiArai 0:5b88d5760320 595
kenjiArai 0:5b88d5760320 596 mbedtls_md_hmac_starts( &md_ctx, S2, hs );
kenjiArai 0:5b88d5760320 597 mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
kenjiArai 0:5b88d5760320 598 mbedtls_md_hmac_finish( &md_ctx, tmp );
kenjiArai 0:5b88d5760320 599
kenjiArai 0:5b88d5760320 600 for( i = 0; i < dlen; i += 20 )
kenjiArai 0:5b88d5760320 601 {
kenjiArai 0:5b88d5760320 602 mbedtls_md_hmac_reset ( &md_ctx );
kenjiArai 0:5b88d5760320 603 mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb );
kenjiArai 0:5b88d5760320 604 mbedtls_md_hmac_finish( &md_ctx, h_i );
kenjiArai 0:5b88d5760320 605
kenjiArai 0:5b88d5760320 606 mbedtls_md_hmac_reset ( &md_ctx );
kenjiArai 0:5b88d5760320 607 mbedtls_md_hmac_update( &md_ctx, tmp, 20 );
kenjiArai 0:5b88d5760320 608 mbedtls_md_hmac_finish( &md_ctx, tmp );
kenjiArai 0:5b88d5760320 609
kenjiArai 0:5b88d5760320 610 k = ( i + 20 > dlen ) ? dlen % 20 : 20;
kenjiArai 0:5b88d5760320 611
kenjiArai 0:5b88d5760320 612 for( j = 0; j < k; j++ )
kenjiArai 0:5b88d5760320 613 dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
kenjiArai 0:5b88d5760320 614 }
kenjiArai 0:5b88d5760320 615
kenjiArai 0:5b88d5760320 616 exit:
kenjiArai 0:5b88d5760320 617 mbedtls_md_free( &md_ctx );
kenjiArai 0:5b88d5760320 618
kenjiArai 0:5b88d5760320 619 mbedtls_platform_zeroize( tmp, tmp_len );
kenjiArai 0:5b88d5760320 620 mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
kenjiArai 0:5b88d5760320 621
kenjiArai 0:5b88d5760320 622 mbedtls_free( tmp );
kenjiArai 0:5b88d5760320 623 return( ret );
kenjiArai 0:5b88d5760320 624 }
kenjiArai 0:5b88d5760320 625 #endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
kenjiArai 0:5b88d5760320 626
kenjiArai 0:5b88d5760320 627 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 628 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 629 static int tls_prf_generic( mbedtls_md_type_t md_type,
kenjiArai 0:5b88d5760320 630 const unsigned char *secret, size_t slen,
kenjiArai 0:5b88d5760320 631 const char *label,
kenjiArai 0:5b88d5760320 632 const unsigned char *random, size_t rlen,
kenjiArai 0:5b88d5760320 633 unsigned char *dstbuf, size_t dlen )
kenjiArai 0:5b88d5760320 634 {
kenjiArai 0:5b88d5760320 635 psa_status_t status;
kenjiArai 0:5b88d5760320 636 psa_algorithm_t alg;
kenjiArai 0:5b88d5760320 637 psa_key_policy_t policy;
kenjiArai 0:5b88d5760320 638 psa_key_handle_t master_slot;
kenjiArai 0:5b88d5760320 639 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
kenjiArai 0:5b88d5760320 640
kenjiArai 0:5b88d5760320 641 if( ( status = psa_allocate_key( &master_slot ) ) != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 642 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 643
kenjiArai 0:5b88d5760320 644 if( md_type == MBEDTLS_MD_SHA384 )
kenjiArai 0:5b88d5760320 645 alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
kenjiArai 0:5b88d5760320 646 else
kenjiArai 0:5b88d5760320 647 alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
kenjiArai 0:5b88d5760320 648
kenjiArai 0:5b88d5760320 649 policy = psa_key_policy_init();
kenjiArai 0:5b88d5760320 650 psa_key_policy_set_usage( &policy,
kenjiArai 0:5b88d5760320 651 PSA_KEY_USAGE_DERIVE,
kenjiArai 0:5b88d5760320 652 alg );
kenjiArai 0:5b88d5760320 653 status = psa_set_key_policy( master_slot, &policy );
kenjiArai 0:5b88d5760320 654 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 655 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 656
kenjiArai 0:5b88d5760320 657 status = psa_import_key( master_slot, PSA_KEY_TYPE_DERIVE, secret, slen );
kenjiArai 0:5b88d5760320 658 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 659 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 660
kenjiArai 0:5b88d5760320 661 status = psa_key_derivation( &generator,
kenjiArai 0:5b88d5760320 662 master_slot, alg,
kenjiArai 0:5b88d5760320 663 random, rlen,
kenjiArai 0:5b88d5760320 664 (unsigned char const *) label,
kenjiArai 0:5b88d5760320 665 (size_t) strlen( label ),
kenjiArai 0:5b88d5760320 666 dlen );
kenjiArai 0:5b88d5760320 667 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 668 {
kenjiArai 0:5b88d5760320 669 psa_generator_abort( &generator );
kenjiArai 0:5b88d5760320 670 psa_destroy_key( master_slot );
kenjiArai 0:5b88d5760320 671 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 672 }
kenjiArai 0:5b88d5760320 673
kenjiArai 0:5b88d5760320 674 status = psa_generator_read( &generator, dstbuf, dlen );
kenjiArai 0:5b88d5760320 675 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 676 {
kenjiArai 0:5b88d5760320 677 psa_generator_abort( &generator );
kenjiArai 0:5b88d5760320 678 psa_destroy_key( master_slot );
kenjiArai 0:5b88d5760320 679 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 680 }
kenjiArai 0:5b88d5760320 681
kenjiArai 0:5b88d5760320 682 status = psa_generator_abort( &generator );
kenjiArai 0:5b88d5760320 683 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 684 {
kenjiArai 0:5b88d5760320 685 psa_destroy_key( master_slot );
kenjiArai 0:5b88d5760320 686 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 687 }
kenjiArai 0:5b88d5760320 688
kenjiArai 0:5b88d5760320 689 status = psa_destroy_key( master_slot );
kenjiArai 0:5b88d5760320 690 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 691 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 692
kenjiArai 0:5b88d5760320 693 return( 0 );
kenjiArai 0:5b88d5760320 694 }
kenjiArai 0:5b88d5760320 695
kenjiArai 0:5b88d5760320 696 #else /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 697
kenjiArai 0:5b88d5760320 698 static int tls_prf_generic( mbedtls_md_type_t md_type,
kenjiArai 0:5b88d5760320 699 const unsigned char *secret, size_t slen,
kenjiArai 0:5b88d5760320 700 const char *label,
kenjiArai 0:5b88d5760320 701 const unsigned char *random, size_t rlen,
kenjiArai 0:5b88d5760320 702 unsigned char *dstbuf, size_t dlen )
kenjiArai 0:5b88d5760320 703 {
kenjiArai 0:5b88d5760320 704 size_t nb;
kenjiArai 0:5b88d5760320 705 size_t i, j, k, md_len;
kenjiArai 0:5b88d5760320 706 unsigned char *tmp;
kenjiArai 0:5b88d5760320 707 size_t tmp_len = 0;
kenjiArai 0:5b88d5760320 708 unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
kenjiArai 0:5b88d5760320 709 const mbedtls_md_info_t *md_info;
kenjiArai 0:5b88d5760320 710 mbedtls_md_context_t md_ctx;
kenjiArai 0:5b88d5760320 711 int ret;
kenjiArai 0:5b88d5760320 712
kenjiArai 0:5b88d5760320 713 mbedtls_md_init( &md_ctx );
kenjiArai 0:5b88d5760320 714
kenjiArai 0:5b88d5760320 715 if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL )
kenjiArai 0:5b88d5760320 716 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 717
kenjiArai 0:5b88d5760320 718 md_len = mbedtls_md_get_size( md_info );
kenjiArai 0:5b88d5760320 719
kenjiArai 0:5b88d5760320 720 tmp_len = md_len + strlen( label ) + rlen;
kenjiArai 0:5b88d5760320 721 tmp = mbedtls_calloc( 1, tmp_len );
kenjiArai 0:5b88d5760320 722 if( tmp == NULL )
kenjiArai 0:5b88d5760320 723 {
kenjiArai 0:5b88d5760320 724 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
kenjiArai 0:5b88d5760320 725 goto exit;
kenjiArai 0:5b88d5760320 726 }
kenjiArai 0:5b88d5760320 727
kenjiArai 0:5b88d5760320 728 nb = strlen( label );
kenjiArai 0:5b88d5760320 729 memcpy( tmp + md_len, label, nb );
kenjiArai 0:5b88d5760320 730 memcpy( tmp + md_len + nb, random, rlen );
kenjiArai 0:5b88d5760320 731 nb += rlen;
kenjiArai 0:5b88d5760320 732
kenjiArai 0:5b88d5760320 733 /*
kenjiArai 0:5b88d5760320 734 * Compute P_<hash>(secret, label + random)[0..dlen]
kenjiArai 0:5b88d5760320 735 */
kenjiArai 0:5b88d5760320 736 if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 737 goto exit;
kenjiArai 0:5b88d5760320 738
kenjiArai 0:5b88d5760320 739 mbedtls_md_hmac_starts( &md_ctx, secret, slen );
kenjiArai 0:5b88d5760320 740 mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
kenjiArai 0:5b88d5760320 741 mbedtls_md_hmac_finish( &md_ctx, tmp );
kenjiArai 0:5b88d5760320 742
kenjiArai 0:5b88d5760320 743 for( i = 0; i < dlen; i += md_len )
kenjiArai 0:5b88d5760320 744 {
kenjiArai 0:5b88d5760320 745 mbedtls_md_hmac_reset ( &md_ctx );
kenjiArai 0:5b88d5760320 746 mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
kenjiArai 0:5b88d5760320 747 mbedtls_md_hmac_finish( &md_ctx, h_i );
kenjiArai 0:5b88d5760320 748
kenjiArai 0:5b88d5760320 749 mbedtls_md_hmac_reset ( &md_ctx );
kenjiArai 0:5b88d5760320 750 mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
kenjiArai 0:5b88d5760320 751 mbedtls_md_hmac_finish( &md_ctx, tmp );
kenjiArai 0:5b88d5760320 752
kenjiArai 0:5b88d5760320 753 k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
kenjiArai 0:5b88d5760320 754
kenjiArai 0:5b88d5760320 755 for( j = 0; j < k; j++ )
kenjiArai 0:5b88d5760320 756 dstbuf[i + j] = h_i[j];
kenjiArai 0:5b88d5760320 757 }
kenjiArai 0:5b88d5760320 758
kenjiArai 0:5b88d5760320 759 exit:
kenjiArai 0:5b88d5760320 760 mbedtls_md_free( &md_ctx );
kenjiArai 0:5b88d5760320 761
kenjiArai 0:5b88d5760320 762 mbedtls_platform_zeroize( tmp, tmp_len );
kenjiArai 0:5b88d5760320 763 mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
kenjiArai 0:5b88d5760320 764
kenjiArai 0:5b88d5760320 765 mbedtls_free( tmp );
kenjiArai 0:5b88d5760320 766
kenjiArai 0:5b88d5760320 767 return( ret );
kenjiArai 0:5b88d5760320 768 }
kenjiArai 0:5b88d5760320 769 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 770 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 771 static int tls_prf_sha256( const unsigned char *secret, size_t slen,
kenjiArai 0:5b88d5760320 772 const char *label,
kenjiArai 0:5b88d5760320 773 const unsigned char *random, size_t rlen,
kenjiArai 0:5b88d5760320 774 unsigned char *dstbuf, size_t dlen )
kenjiArai 0:5b88d5760320 775 {
kenjiArai 0:5b88d5760320 776 return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen,
kenjiArai 0:5b88d5760320 777 label, random, rlen, dstbuf, dlen ) );
kenjiArai 0:5b88d5760320 778 }
kenjiArai 0:5b88d5760320 779 #endif /* MBEDTLS_SHA256_C */
kenjiArai 0:5b88d5760320 780
kenjiArai 0:5b88d5760320 781 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 782 static int tls_prf_sha384( const unsigned char *secret, size_t slen,
kenjiArai 0:5b88d5760320 783 const char *label,
kenjiArai 0:5b88d5760320 784 const unsigned char *random, size_t rlen,
kenjiArai 0:5b88d5760320 785 unsigned char *dstbuf, size_t dlen )
kenjiArai 0:5b88d5760320 786 {
kenjiArai 0:5b88d5760320 787 return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen,
kenjiArai 0:5b88d5760320 788 label, random, rlen, dstbuf, dlen ) );
kenjiArai 0:5b88d5760320 789 }
kenjiArai 0:5b88d5760320 790 #endif /* MBEDTLS_SHA512_C */
kenjiArai 0:5b88d5760320 791 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 792
kenjiArai 0:5b88d5760320 793 static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t );
kenjiArai 0:5b88d5760320 794
kenjiArai 0:5b88d5760320 795 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 796 defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 797 static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t );
kenjiArai 0:5b88d5760320 798 #endif
kenjiArai 0:5b88d5760320 799
kenjiArai 0:5b88d5760320 800 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 801 static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * );
kenjiArai 0:5b88d5760320 802 static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int );
kenjiArai 0:5b88d5760320 803 #endif
kenjiArai 0:5b88d5760320 804
kenjiArai 0:5b88d5760320 805 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 806 static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * );
kenjiArai 0:5b88d5760320 807 static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int );
kenjiArai 0:5b88d5760320 808 #endif
kenjiArai 0:5b88d5760320 809
kenjiArai 0:5b88d5760320 810 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 811 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 812 static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
kenjiArai 0:5b88d5760320 813 static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * );
kenjiArai 0:5b88d5760320 814 static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
kenjiArai 0:5b88d5760320 815 #endif
kenjiArai 0:5b88d5760320 816
kenjiArai 0:5b88d5760320 817 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 818 static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t );
kenjiArai 0:5b88d5760320 819 static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * );
kenjiArai 0:5b88d5760320 820 static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
kenjiArai 0:5b88d5760320 821 #endif
kenjiArai 0:5b88d5760320 822 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 823
kenjiArai 0:5b88d5760320 824 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
kenjiArai 0:5b88d5760320 825 defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 826 static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
kenjiArai 0:5b88d5760320 827 {
kenjiArai 0:5b88d5760320 828 if( ssl->conf->f_psk != NULL )
kenjiArai 0:5b88d5760320 829 {
kenjiArai 0:5b88d5760320 830 /* If we've used a callback to select the PSK,
kenjiArai 0:5b88d5760320 831 * the static configuration is irrelevant. */
kenjiArai 0:5b88d5760320 832 if( ssl->handshake->psk_opaque != 0 )
kenjiArai 0:5b88d5760320 833 return( 1 );
kenjiArai 0:5b88d5760320 834
kenjiArai 0:5b88d5760320 835 return( 0 );
kenjiArai 0:5b88d5760320 836 }
kenjiArai 0:5b88d5760320 837
kenjiArai 0:5b88d5760320 838 if( ssl->conf->psk_opaque != 0 )
kenjiArai 0:5b88d5760320 839 return( 1 );
kenjiArai 0:5b88d5760320 840
kenjiArai 0:5b88d5760320 841 return( 0 );
kenjiArai 0:5b88d5760320 842 }
kenjiArai 0:5b88d5760320 843 #endif /* MBEDTLS_USE_PSA_CRYPTO &&
kenjiArai 0:5b88d5760320 844 MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
kenjiArai 0:5b88d5760320 845
kenjiArai 0:5b88d5760320 846 #if defined(MBEDTLS_SSL_EXPORT_KEYS)
kenjiArai 0:5b88d5760320 847 static mbedtls_tls_prf_types tls_prf_get_type( mbedtls_ssl_tls_prf_cb *tls_prf )
kenjiArai 0:5b88d5760320 848 {
kenjiArai 0:5b88d5760320 849 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 850 if( tls_prf == ssl3_prf )
kenjiArai 0:5b88d5760320 851 {
kenjiArai 0:5b88d5760320 852 return( MBEDTLS_SSL_TLS_PRF_SSL3 );
kenjiArai 0:5b88d5760320 853 }
kenjiArai 0:5b88d5760320 854 else
kenjiArai 0:5b88d5760320 855 #endif
kenjiArai 0:5b88d5760320 856 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 857 if( tls_prf == tls1_prf )
kenjiArai 0:5b88d5760320 858 {
kenjiArai 0:5b88d5760320 859 return( MBEDTLS_SSL_TLS_PRF_TLS1 );
kenjiArai 0:5b88d5760320 860 }
kenjiArai 0:5b88d5760320 861 else
kenjiArai 0:5b88d5760320 862 #endif
kenjiArai 0:5b88d5760320 863 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 864 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 865 if( tls_prf == tls_prf_sha384 )
kenjiArai 0:5b88d5760320 866 {
kenjiArai 0:5b88d5760320 867 return( MBEDTLS_SSL_TLS_PRF_SHA384 );
kenjiArai 0:5b88d5760320 868 }
kenjiArai 0:5b88d5760320 869 else
kenjiArai 0:5b88d5760320 870 #endif
kenjiArai 0:5b88d5760320 871 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 872 if( tls_prf == tls_prf_sha256 )
kenjiArai 0:5b88d5760320 873 {
kenjiArai 0:5b88d5760320 874 return( MBEDTLS_SSL_TLS_PRF_SHA256 );
kenjiArai 0:5b88d5760320 875 }
kenjiArai 0:5b88d5760320 876 else
kenjiArai 0:5b88d5760320 877 #endif
kenjiArai 0:5b88d5760320 878 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 879 return( MBEDTLS_SSL_TLS_PRF_NONE );
kenjiArai 0:5b88d5760320 880 }
kenjiArai 0:5b88d5760320 881 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
kenjiArai 0:5b88d5760320 882
kenjiArai 0:5b88d5760320 883 int mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf,
kenjiArai 0:5b88d5760320 884 const unsigned char *secret, size_t slen,
kenjiArai 0:5b88d5760320 885 const char *label,
kenjiArai 0:5b88d5760320 886 const unsigned char *random, size_t rlen,
kenjiArai 0:5b88d5760320 887 unsigned char *dstbuf, size_t dlen )
kenjiArai 0:5b88d5760320 888 {
kenjiArai 0:5b88d5760320 889 mbedtls_ssl_tls_prf_cb *tls_prf = NULL;
kenjiArai 0:5b88d5760320 890
kenjiArai 0:5b88d5760320 891 switch( prf )
kenjiArai 0:5b88d5760320 892 {
kenjiArai 0:5b88d5760320 893 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 894 case MBEDTLS_SSL_TLS_PRF_SSL3:
kenjiArai 0:5b88d5760320 895 tls_prf = ssl3_prf;
kenjiArai 0:5b88d5760320 896 break;
kenjiArai 0:5b88d5760320 897 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 898 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 899 case MBEDTLS_SSL_TLS_PRF_TLS1:
kenjiArai 0:5b88d5760320 900 tls_prf = tls1_prf;
kenjiArai 0:5b88d5760320 901 break;
kenjiArai 0:5b88d5760320 902 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
kenjiArai 0:5b88d5760320 903
kenjiArai 0:5b88d5760320 904 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 905 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 906 case MBEDTLS_SSL_TLS_PRF_SHA384:
kenjiArai 0:5b88d5760320 907 tls_prf = tls_prf_sha384;
kenjiArai 0:5b88d5760320 908 break;
kenjiArai 0:5b88d5760320 909 #endif /* MBEDTLS_SHA512_C */
kenjiArai 0:5b88d5760320 910 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 911 case MBEDTLS_SSL_TLS_PRF_SHA256:
kenjiArai 0:5b88d5760320 912 tls_prf = tls_prf_sha256;
kenjiArai 0:5b88d5760320 913 break;
kenjiArai 0:5b88d5760320 914 #endif /* MBEDTLS_SHA256_C */
kenjiArai 0:5b88d5760320 915 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 916 default:
kenjiArai 0:5b88d5760320 917 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
kenjiArai 0:5b88d5760320 918 }
kenjiArai 0:5b88d5760320 919
kenjiArai 0:5b88d5760320 920 return( tls_prf( secret, slen, label, random, rlen, dstbuf, dlen ) );
kenjiArai 0:5b88d5760320 921 }
kenjiArai 0:5b88d5760320 922
kenjiArai 0:5b88d5760320 923 int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 924 {
kenjiArai 0:5b88d5760320 925 int ret = 0;
kenjiArai 0:5b88d5760320 926 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 927 int psa_fallthrough;
kenjiArai 0:5b88d5760320 928 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 929 unsigned char tmp[64];
kenjiArai 0:5b88d5760320 930 unsigned char keyblk[256];
kenjiArai 0:5b88d5760320 931 unsigned char *key1;
kenjiArai 0:5b88d5760320 932 unsigned char *key2;
kenjiArai 0:5b88d5760320 933 unsigned char *mac_enc;
kenjiArai 0:5b88d5760320 934 unsigned char *mac_dec;
kenjiArai 0:5b88d5760320 935 size_t mac_key_len;
kenjiArai 0:5b88d5760320 936 size_t iv_copy_len;
kenjiArai 0:5b88d5760320 937 unsigned keylen;
kenjiArai 0:5b88d5760320 938 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
kenjiArai 0:5b88d5760320 939 const mbedtls_cipher_info_t *cipher_info;
kenjiArai 0:5b88d5760320 940 const mbedtls_md_info_t *md_info;
kenjiArai 0:5b88d5760320 941
kenjiArai 0:5b88d5760320 942 /* cf. RFC 5246, Section 8.1:
kenjiArai 0:5b88d5760320 943 * "The master secret is always exactly 48 bytes in length." */
kenjiArai 0:5b88d5760320 944 size_t const master_secret_len = 48;
kenjiArai 0:5b88d5760320 945
kenjiArai 0:5b88d5760320 946 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
kenjiArai 0:5b88d5760320 947 unsigned char session_hash[48];
kenjiArai 0:5b88d5760320 948 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
kenjiArai 0:5b88d5760320 949
kenjiArai 0:5b88d5760320 950 mbedtls_ssl_session *session = ssl->session_negotiate;
kenjiArai 0:5b88d5760320 951 mbedtls_ssl_transform *transform = ssl->transform_negotiate;
kenjiArai 0:5b88d5760320 952 mbedtls_ssl_handshake_params *handshake = ssl->handshake;
kenjiArai 0:5b88d5760320 953
kenjiArai 0:5b88d5760320 954 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
kenjiArai 0:5b88d5760320 955
kenjiArai 0:5b88d5760320 956 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
kenjiArai 0:5b88d5760320 957 defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
kenjiArai 0:5b88d5760320 958 transform->encrypt_then_mac = session->encrypt_then_mac;
kenjiArai 0:5b88d5760320 959 #endif
kenjiArai 0:5b88d5760320 960 transform->minor_ver = ssl->minor_ver;
kenjiArai 0:5b88d5760320 961
kenjiArai 0:5b88d5760320 962 ciphersuite_info = handshake->ciphersuite_info;
kenjiArai 0:5b88d5760320 963 cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
kenjiArai 0:5b88d5760320 964 if( cipher_info == NULL )
kenjiArai 0:5b88d5760320 965 {
kenjiArai 0:5b88d5760320 966 MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
kenjiArai 0:5b88d5760320 967 ciphersuite_info->cipher ) );
kenjiArai 0:5b88d5760320 968 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 969 }
kenjiArai 0:5b88d5760320 970
kenjiArai 0:5b88d5760320 971 md_info = mbedtls_md_info_from_type( ciphersuite_info->mac );
kenjiArai 0:5b88d5760320 972 if( md_info == NULL )
kenjiArai 0:5b88d5760320 973 {
kenjiArai 0:5b88d5760320 974 MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found",
kenjiArai 0:5b88d5760320 975 ciphersuite_info->mac ) );
kenjiArai 0:5b88d5760320 976 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 977 }
kenjiArai 0:5b88d5760320 978
kenjiArai 0:5b88d5760320 979 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 980 /* Copy own and peer's CID if the use of the CID
kenjiArai 0:5b88d5760320 981 * extension has been negotiated. */
kenjiArai 0:5b88d5760320 982 if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED )
kenjiArai 0:5b88d5760320 983 {
kenjiArai 0:5b88d5760320 984 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Copy CIDs into SSL transform" ) );
kenjiArai 0:5b88d5760320 985
kenjiArai 0:5b88d5760320 986 transform->in_cid_len = ssl->own_cid_len;
kenjiArai 0:5b88d5760320 987 memcpy( transform->in_cid, ssl->own_cid, ssl->own_cid_len );
kenjiArai 0:5b88d5760320 988 MBEDTLS_SSL_DEBUG_BUF( 3, "Incoming CID", transform->in_cid,
kenjiArai 0:5b88d5760320 989 transform->in_cid_len );
kenjiArai 0:5b88d5760320 990
kenjiArai 0:5b88d5760320 991 transform->out_cid_len = ssl->handshake->peer_cid_len;
kenjiArai 0:5b88d5760320 992 memcpy( transform->out_cid, ssl->handshake->peer_cid,
kenjiArai 0:5b88d5760320 993 ssl->handshake->peer_cid_len );
kenjiArai 0:5b88d5760320 994 MBEDTLS_SSL_DEBUG_BUF( 3, "Outgoing CID", transform->out_cid,
kenjiArai 0:5b88d5760320 995 transform->out_cid_len );
kenjiArai 0:5b88d5760320 996 }
kenjiArai 0:5b88d5760320 997 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 998
kenjiArai 0:5b88d5760320 999 /*
kenjiArai 0:5b88d5760320 1000 * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
kenjiArai 0:5b88d5760320 1001 */
kenjiArai 0:5b88d5760320 1002 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 1003 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 1004 {
kenjiArai 0:5b88d5760320 1005 handshake->tls_prf = ssl3_prf;
kenjiArai 0:5b88d5760320 1006 handshake->calc_verify = ssl_calc_verify_ssl;
kenjiArai 0:5b88d5760320 1007 handshake->calc_finished = ssl_calc_finished_ssl;
kenjiArai 0:5b88d5760320 1008 }
kenjiArai 0:5b88d5760320 1009 else
kenjiArai 0:5b88d5760320 1010 #endif
kenjiArai 0:5b88d5760320 1011 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 1012 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 1013 {
kenjiArai 0:5b88d5760320 1014 handshake->tls_prf = tls1_prf;
kenjiArai 0:5b88d5760320 1015 handshake->calc_verify = ssl_calc_verify_tls;
kenjiArai 0:5b88d5760320 1016 handshake->calc_finished = ssl_calc_finished_tls;
kenjiArai 0:5b88d5760320 1017 }
kenjiArai 0:5b88d5760320 1018 else
kenjiArai 0:5b88d5760320 1019 #endif
kenjiArai 0:5b88d5760320 1020 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 1021 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 1022 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
kenjiArai 0:5b88d5760320 1023 ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
kenjiArai 0:5b88d5760320 1024 {
kenjiArai 0:5b88d5760320 1025 handshake->tls_prf = tls_prf_sha384;
kenjiArai 0:5b88d5760320 1026 handshake->calc_verify = ssl_calc_verify_tls_sha384;
kenjiArai 0:5b88d5760320 1027 handshake->calc_finished = ssl_calc_finished_tls_sha384;
kenjiArai 0:5b88d5760320 1028 }
kenjiArai 0:5b88d5760320 1029 else
kenjiArai 0:5b88d5760320 1030 #endif
kenjiArai 0:5b88d5760320 1031 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 1032 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 1033 {
kenjiArai 0:5b88d5760320 1034 handshake->tls_prf = tls_prf_sha256;
kenjiArai 0:5b88d5760320 1035 handshake->calc_verify = ssl_calc_verify_tls_sha256;
kenjiArai 0:5b88d5760320 1036 handshake->calc_finished = ssl_calc_finished_tls_sha256;
kenjiArai 0:5b88d5760320 1037 }
kenjiArai 0:5b88d5760320 1038 else
kenjiArai 0:5b88d5760320 1039 #endif
kenjiArai 0:5b88d5760320 1040 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 1041 {
kenjiArai 0:5b88d5760320 1042 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 1043 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 1044 }
kenjiArai 0:5b88d5760320 1045
kenjiArai 0:5b88d5760320 1046 /*
kenjiArai 0:5b88d5760320 1047 * SSLv3:
kenjiArai 0:5b88d5760320 1048 * master =
kenjiArai 0:5b88d5760320 1049 * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) +
kenjiArai 0:5b88d5760320 1050 * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) +
kenjiArai 0:5b88d5760320 1051 * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
kenjiArai 0:5b88d5760320 1052 *
kenjiArai 0:5b88d5760320 1053 * TLSv1+:
kenjiArai 0:5b88d5760320 1054 * master = PRF( premaster, "master secret", randbytes )[0..47]
kenjiArai 0:5b88d5760320 1055 */
kenjiArai 0:5b88d5760320 1056 if( handshake->resume != 0 )
kenjiArai 0:5b88d5760320 1057 {
kenjiArai 0:5b88d5760320 1058 MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
kenjiArai 0:5b88d5760320 1059 }
kenjiArai 0:5b88d5760320 1060 else
kenjiArai 0:5b88d5760320 1061 {
kenjiArai 0:5b88d5760320 1062 /* The label for the KDF used for key expansion.
kenjiArai 0:5b88d5760320 1063 * This is either "master secret" or "extended master secret"
kenjiArai 0:5b88d5760320 1064 * depending on whether the Extended Master Secret extension
kenjiArai 0:5b88d5760320 1065 * is used. */
kenjiArai 0:5b88d5760320 1066 char const *lbl = "master secret";
kenjiArai 0:5b88d5760320 1067
kenjiArai 0:5b88d5760320 1068 /* The salt for the KDF used for key expansion.
kenjiArai 0:5b88d5760320 1069 * - If the Extended Master Secret extension is not used,
kenjiArai 0:5b88d5760320 1070 * this is ClientHello.Random + ServerHello.Random
kenjiArai 0:5b88d5760320 1071 * (see Sect. 8.1 in RFC 5246).
kenjiArai 0:5b88d5760320 1072 * - If the Extended Master Secret extension is used,
kenjiArai 0:5b88d5760320 1073 * this is the transcript of the handshake so far.
kenjiArai 0:5b88d5760320 1074 * (see Sect. 4 in RFC 7627). */
kenjiArai 0:5b88d5760320 1075 unsigned char const *salt = handshake->randbytes;
kenjiArai 0:5b88d5760320 1076 size_t salt_len = 64;
kenjiArai 0:5b88d5760320 1077
kenjiArai 0:5b88d5760320 1078 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
kenjiArai 0:5b88d5760320 1079 if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
kenjiArai 0:5b88d5760320 1080 {
kenjiArai 0:5b88d5760320 1081 MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) );
kenjiArai 0:5b88d5760320 1082
kenjiArai 0:5b88d5760320 1083 lbl = "extended master secret";
kenjiArai 0:5b88d5760320 1084 salt = session_hash;
kenjiArai 0:5b88d5760320 1085 ssl->handshake->calc_verify( ssl, session_hash );
kenjiArai 0:5b88d5760320 1086 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 1087 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 1088 {
kenjiArai 0:5b88d5760320 1089 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 1090 if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
kenjiArai 0:5b88d5760320 1091 {
kenjiArai 0:5b88d5760320 1092 salt_len = 48;
kenjiArai 0:5b88d5760320 1093 }
kenjiArai 0:5b88d5760320 1094 else
kenjiArai 0:5b88d5760320 1095 #endif /* MBEDTLS_SHA512_C */
kenjiArai 0:5b88d5760320 1096 salt_len = 32;
kenjiArai 0:5b88d5760320 1097 }
kenjiArai 0:5b88d5760320 1098 else
kenjiArai 0:5b88d5760320 1099 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 1100 salt_len = 36;
kenjiArai 0:5b88d5760320 1101
kenjiArai 0:5b88d5760320 1102 MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, salt_len );
kenjiArai 0:5b88d5760320 1103 }
kenjiArai 0:5b88d5760320 1104 #endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */
kenjiArai 0:5b88d5760320 1105
kenjiArai 0:5b88d5760320 1106 #if defined(MBEDTLS_USE_PSA_CRYPTO) && \
kenjiArai 0:5b88d5760320 1107 defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
kenjiArai 0:5b88d5760320 1108 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
kenjiArai 0:5b88d5760320 1109 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
kenjiArai 0:5b88d5760320 1110 ssl_use_opaque_psk( ssl ) == 1 )
kenjiArai 0:5b88d5760320 1111 {
kenjiArai 0:5b88d5760320 1112 /* Perform PSK-to-MS expansion in a single step. */
kenjiArai 0:5b88d5760320 1113 psa_status_t status;
kenjiArai 0:5b88d5760320 1114 psa_algorithm_t alg;
kenjiArai 0:5b88d5760320 1115 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
kenjiArai 0:5b88d5760320 1116 psa_key_handle_t psk;
kenjiArai 0:5b88d5760320 1117
kenjiArai 0:5b88d5760320 1118 MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PSK-to-MS expansion" ) );
kenjiArai 0:5b88d5760320 1119
kenjiArai 0:5b88d5760320 1120 psk = ssl->conf->psk_opaque;
kenjiArai 0:5b88d5760320 1121 if( ssl->handshake->psk_opaque != 0 )
kenjiArai 0:5b88d5760320 1122 psk = ssl->handshake->psk_opaque;
kenjiArai 0:5b88d5760320 1123
kenjiArai 0:5b88d5760320 1124 if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
kenjiArai 0:5b88d5760320 1125 alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
kenjiArai 0:5b88d5760320 1126 else
kenjiArai 0:5b88d5760320 1127 alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
kenjiArai 0:5b88d5760320 1128
kenjiArai 0:5b88d5760320 1129 status = psa_key_derivation( &generator, psk, alg,
kenjiArai 0:5b88d5760320 1130 salt, salt_len,
kenjiArai 0:5b88d5760320 1131 (unsigned char const *) lbl,
kenjiArai 0:5b88d5760320 1132 (size_t) strlen( lbl ),
kenjiArai 0:5b88d5760320 1133 master_secret_len );
kenjiArai 0:5b88d5760320 1134 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1135 {
kenjiArai 0:5b88d5760320 1136 psa_generator_abort( &generator );
kenjiArai 0:5b88d5760320 1137 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 1138 }
kenjiArai 0:5b88d5760320 1139
kenjiArai 0:5b88d5760320 1140 status = psa_generator_read( &generator, session->master,
kenjiArai 0:5b88d5760320 1141 master_secret_len );
kenjiArai 0:5b88d5760320 1142 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1143 {
kenjiArai 0:5b88d5760320 1144 psa_generator_abort( &generator );
kenjiArai 0:5b88d5760320 1145 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 1146 }
kenjiArai 0:5b88d5760320 1147
kenjiArai 0:5b88d5760320 1148 status = psa_generator_abort( &generator );
kenjiArai 0:5b88d5760320 1149 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1150 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 1151 }
kenjiArai 0:5b88d5760320 1152 else
kenjiArai 0:5b88d5760320 1153 #endif
kenjiArai 0:5b88d5760320 1154 {
kenjiArai 0:5b88d5760320 1155 ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
kenjiArai 0:5b88d5760320 1156 lbl, salt, salt_len,
kenjiArai 0:5b88d5760320 1157 session->master,
kenjiArai 0:5b88d5760320 1158 master_secret_len );
kenjiArai 0:5b88d5760320 1159 if( ret != 0 )
kenjiArai 0:5b88d5760320 1160 {
kenjiArai 0:5b88d5760320 1161 MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
kenjiArai 0:5b88d5760320 1162 return( ret );
kenjiArai 0:5b88d5760320 1163 }
kenjiArai 0:5b88d5760320 1164
kenjiArai 0:5b88d5760320 1165 MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret",
kenjiArai 0:5b88d5760320 1166 handshake->premaster,
kenjiArai 0:5b88d5760320 1167 handshake->pmslen );
kenjiArai 0:5b88d5760320 1168
kenjiArai 0:5b88d5760320 1169 mbedtls_platform_zeroize( handshake->premaster,
kenjiArai 0:5b88d5760320 1170 sizeof(handshake->premaster) );
kenjiArai 0:5b88d5760320 1171 }
kenjiArai 0:5b88d5760320 1172 }
kenjiArai 0:5b88d5760320 1173
kenjiArai 0:5b88d5760320 1174 /*
kenjiArai 0:5b88d5760320 1175 * Swap the client and server random values.
kenjiArai 0:5b88d5760320 1176 */
kenjiArai 0:5b88d5760320 1177 memcpy( tmp, handshake->randbytes, 64 );
kenjiArai 0:5b88d5760320 1178 memcpy( handshake->randbytes, tmp + 32, 32 );
kenjiArai 0:5b88d5760320 1179 memcpy( handshake->randbytes + 32, tmp, 32 );
kenjiArai 0:5b88d5760320 1180 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
kenjiArai 0:5b88d5760320 1181
kenjiArai 0:5b88d5760320 1182 /*
kenjiArai 0:5b88d5760320 1183 * SSLv3:
kenjiArai 0:5b88d5760320 1184 * key block =
kenjiArai 0:5b88d5760320 1185 * MD5( master + SHA1( 'A' + master + randbytes ) ) +
kenjiArai 0:5b88d5760320 1186 * MD5( master + SHA1( 'BB' + master + randbytes ) ) +
kenjiArai 0:5b88d5760320 1187 * MD5( master + SHA1( 'CCC' + master + randbytes ) ) +
kenjiArai 0:5b88d5760320 1188 * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
kenjiArai 0:5b88d5760320 1189 * ...
kenjiArai 0:5b88d5760320 1190 *
kenjiArai 0:5b88d5760320 1191 * TLSv1:
kenjiArai 0:5b88d5760320 1192 * key block = PRF( master, "key expansion", randbytes )
kenjiArai 0:5b88d5760320 1193 */
kenjiArai 0:5b88d5760320 1194 ret = handshake->tls_prf( session->master, 48, "key expansion",
kenjiArai 0:5b88d5760320 1195 handshake->randbytes, 64, keyblk, 256 );
kenjiArai 0:5b88d5760320 1196 if( ret != 0 )
kenjiArai 0:5b88d5760320 1197 {
kenjiArai 0:5b88d5760320 1198 MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
kenjiArai 0:5b88d5760320 1199 return( ret );
kenjiArai 0:5b88d5760320 1200 }
kenjiArai 0:5b88d5760320 1201
kenjiArai 0:5b88d5760320 1202 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
kenjiArai 0:5b88d5760320 1203 mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) );
kenjiArai 0:5b88d5760320 1204 MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 );
kenjiArai 0:5b88d5760320 1205 MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
kenjiArai 0:5b88d5760320 1206 MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
kenjiArai 0:5b88d5760320 1207
kenjiArai 0:5b88d5760320 1208 /*
kenjiArai 0:5b88d5760320 1209 * Determine the appropriate key, IV and MAC length.
kenjiArai 0:5b88d5760320 1210 */
kenjiArai 0:5b88d5760320 1211
kenjiArai 0:5b88d5760320 1212 keylen = cipher_info->key_bitlen / 8;
kenjiArai 0:5b88d5760320 1213
kenjiArai 0:5b88d5760320 1214 #if defined(MBEDTLS_GCM_C) || \
kenjiArai 0:5b88d5760320 1215 defined(MBEDTLS_CCM_C) || \
kenjiArai 0:5b88d5760320 1216 defined(MBEDTLS_CHACHAPOLY_C)
kenjiArai 0:5b88d5760320 1217 if( cipher_info->mode == MBEDTLS_MODE_GCM ||
kenjiArai 0:5b88d5760320 1218 cipher_info->mode == MBEDTLS_MODE_CCM ||
kenjiArai 0:5b88d5760320 1219 cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
kenjiArai 0:5b88d5760320 1220 {
kenjiArai 0:5b88d5760320 1221 size_t explicit_ivlen;
kenjiArai 0:5b88d5760320 1222
kenjiArai 0:5b88d5760320 1223 transform->maclen = 0;
kenjiArai 0:5b88d5760320 1224 mac_key_len = 0;
kenjiArai 0:5b88d5760320 1225 transform->taglen =
kenjiArai 0:5b88d5760320 1226 ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
kenjiArai 0:5b88d5760320 1227
kenjiArai 0:5b88d5760320 1228 /* All modes haves 96-bit IVs;
kenjiArai 0:5b88d5760320 1229 * GCM and CCM has 4 implicit and 8 explicit bytes
kenjiArai 0:5b88d5760320 1230 * ChachaPoly has all 12 bytes implicit
kenjiArai 0:5b88d5760320 1231 */
kenjiArai 0:5b88d5760320 1232 transform->ivlen = 12;
kenjiArai 0:5b88d5760320 1233 if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
kenjiArai 0:5b88d5760320 1234 transform->fixed_ivlen = 12;
kenjiArai 0:5b88d5760320 1235 else
kenjiArai 0:5b88d5760320 1236 transform->fixed_ivlen = 4;
kenjiArai 0:5b88d5760320 1237
kenjiArai 0:5b88d5760320 1238 /* Minimum length of encrypted record */
kenjiArai 0:5b88d5760320 1239 explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
kenjiArai 0:5b88d5760320 1240 transform->minlen = explicit_ivlen + transform->taglen;
kenjiArai 0:5b88d5760320 1241 }
kenjiArai 0:5b88d5760320 1242 else
kenjiArai 0:5b88d5760320 1243 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
kenjiArai 0:5b88d5760320 1244 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
kenjiArai 0:5b88d5760320 1245 if( cipher_info->mode == MBEDTLS_MODE_STREAM ||
kenjiArai 0:5b88d5760320 1246 cipher_info->mode == MBEDTLS_MODE_CBC )
kenjiArai 0:5b88d5760320 1247 {
kenjiArai 0:5b88d5760320 1248 /* Initialize HMAC contexts */
kenjiArai 0:5b88d5760320 1249 if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
kenjiArai 0:5b88d5760320 1250 ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 1251 {
kenjiArai 0:5b88d5760320 1252 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
kenjiArai 0:5b88d5760320 1253 goto end;
kenjiArai 0:5b88d5760320 1254 }
kenjiArai 0:5b88d5760320 1255
kenjiArai 0:5b88d5760320 1256 /* Get MAC length */
kenjiArai 0:5b88d5760320 1257 mac_key_len = mbedtls_md_get_size( md_info );
kenjiArai 0:5b88d5760320 1258 transform->maclen = mac_key_len;
kenjiArai 0:5b88d5760320 1259
kenjiArai 0:5b88d5760320 1260 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
kenjiArai 0:5b88d5760320 1261 /*
kenjiArai 0:5b88d5760320 1262 * If HMAC is to be truncated, we shall keep the leftmost bytes,
kenjiArai 0:5b88d5760320 1263 * (rfc 6066 page 13 or rfc 2104 section 4),
kenjiArai 0:5b88d5760320 1264 * so we only need to adjust the length here.
kenjiArai 0:5b88d5760320 1265 */
kenjiArai 0:5b88d5760320 1266 if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
kenjiArai 0:5b88d5760320 1267 {
kenjiArai 0:5b88d5760320 1268 transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
kenjiArai 0:5b88d5760320 1269
kenjiArai 0:5b88d5760320 1270 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
kenjiArai 0:5b88d5760320 1271 /* Fall back to old, non-compliant version of the truncated
kenjiArai 0:5b88d5760320 1272 * HMAC implementation which also truncates the key
kenjiArai 0:5b88d5760320 1273 * (Mbed TLS versions from 1.3 to 2.6.0) */
kenjiArai 0:5b88d5760320 1274 mac_key_len = transform->maclen;
kenjiArai 0:5b88d5760320 1275 #endif
kenjiArai 0:5b88d5760320 1276 }
kenjiArai 0:5b88d5760320 1277 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
kenjiArai 0:5b88d5760320 1278
kenjiArai 0:5b88d5760320 1279 /* IV length */
kenjiArai 0:5b88d5760320 1280 transform->ivlen = cipher_info->iv_size;
kenjiArai 0:5b88d5760320 1281
kenjiArai 0:5b88d5760320 1282 /* Minimum length */
kenjiArai 0:5b88d5760320 1283 if( cipher_info->mode == MBEDTLS_MODE_STREAM )
kenjiArai 0:5b88d5760320 1284 transform->minlen = transform->maclen;
kenjiArai 0:5b88d5760320 1285 else
kenjiArai 0:5b88d5760320 1286 {
kenjiArai 0:5b88d5760320 1287 /*
kenjiArai 0:5b88d5760320 1288 * GenericBlockCipher:
kenjiArai 0:5b88d5760320 1289 * 1. if EtM is in use: one block plus MAC
kenjiArai 0:5b88d5760320 1290 * otherwise: * first multiple of blocklen greater than maclen
kenjiArai 0:5b88d5760320 1291 * 2. IV except for SSL3 and TLS 1.0
kenjiArai 0:5b88d5760320 1292 */
kenjiArai 0:5b88d5760320 1293 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
kenjiArai 0:5b88d5760320 1294 if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
kenjiArai 0:5b88d5760320 1295 {
kenjiArai 0:5b88d5760320 1296 transform->minlen = transform->maclen
kenjiArai 0:5b88d5760320 1297 + cipher_info->block_size;
kenjiArai 0:5b88d5760320 1298 }
kenjiArai 0:5b88d5760320 1299 else
kenjiArai 0:5b88d5760320 1300 #endif
kenjiArai 0:5b88d5760320 1301 {
kenjiArai 0:5b88d5760320 1302 transform->minlen = transform->maclen
kenjiArai 0:5b88d5760320 1303 + cipher_info->block_size
kenjiArai 0:5b88d5760320 1304 - transform->maclen % cipher_info->block_size;
kenjiArai 0:5b88d5760320 1305 }
kenjiArai 0:5b88d5760320 1306
kenjiArai 0:5b88d5760320 1307 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
kenjiArai 0:5b88d5760320 1308 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
kenjiArai 0:5b88d5760320 1309 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 )
kenjiArai 0:5b88d5760320 1310 ; /* No need to adjust minlen */
kenjiArai 0:5b88d5760320 1311 else
kenjiArai 0:5b88d5760320 1312 #endif
kenjiArai 0:5b88d5760320 1313 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 1314 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
kenjiArai 0:5b88d5760320 1315 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 1316 {
kenjiArai 0:5b88d5760320 1317 transform->minlen += transform->ivlen;
kenjiArai 0:5b88d5760320 1318 }
kenjiArai 0:5b88d5760320 1319 else
kenjiArai 0:5b88d5760320 1320 #endif
kenjiArai 0:5b88d5760320 1321 {
kenjiArai 0:5b88d5760320 1322 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 1323 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
kenjiArai 0:5b88d5760320 1324 goto end;
kenjiArai 0:5b88d5760320 1325 }
kenjiArai 0:5b88d5760320 1326 }
kenjiArai 0:5b88d5760320 1327 }
kenjiArai 0:5b88d5760320 1328 else
kenjiArai 0:5b88d5760320 1329 #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
kenjiArai 0:5b88d5760320 1330 {
kenjiArai 0:5b88d5760320 1331 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 1332 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 1333 }
kenjiArai 0:5b88d5760320 1334
kenjiArai 0:5b88d5760320 1335 MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %u, minlen: %u, ivlen: %u, maclen: %u",
kenjiArai 0:5b88d5760320 1336 (unsigned) keylen,
kenjiArai 0:5b88d5760320 1337 (unsigned) transform->minlen,
kenjiArai 0:5b88d5760320 1338 (unsigned) transform->ivlen,
kenjiArai 0:5b88d5760320 1339 (unsigned) transform->maclen ) );
kenjiArai 0:5b88d5760320 1340
kenjiArai 0:5b88d5760320 1341 /*
kenjiArai 0:5b88d5760320 1342 * Finally setup the cipher contexts, IVs and MAC secrets.
kenjiArai 0:5b88d5760320 1343 */
kenjiArai 0:5b88d5760320 1344 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 1345 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 1346 {
kenjiArai 0:5b88d5760320 1347 key1 = keyblk + mac_key_len * 2;
kenjiArai 0:5b88d5760320 1348 key2 = keyblk + mac_key_len * 2 + keylen;
kenjiArai 0:5b88d5760320 1349
kenjiArai 0:5b88d5760320 1350 mac_enc = keyblk;
kenjiArai 0:5b88d5760320 1351 mac_dec = keyblk + mac_key_len;
kenjiArai 0:5b88d5760320 1352
kenjiArai 0:5b88d5760320 1353 /*
kenjiArai 0:5b88d5760320 1354 * This is not used in TLS v1.1.
kenjiArai 0:5b88d5760320 1355 */
kenjiArai 0:5b88d5760320 1356 iv_copy_len = ( transform->fixed_ivlen ) ?
kenjiArai 0:5b88d5760320 1357 transform->fixed_ivlen : transform->ivlen;
kenjiArai 0:5b88d5760320 1358 memcpy( transform->iv_enc, key2 + keylen, iv_copy_len );
kenjiArai 0:5b88d5760320 1359 memcpy( transform->iv_dec, key2 + keylen + iv_copy_len,
kenjiArai 0:5b88d5760320 1360 iv_copy_len );
kenjiArai 0:5b88d5760320 1361 }
kenjiArai 0:5b88d5760320 1362 else
kenjiArai 0:5b88d5760320 1363 #endif /* MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 1364 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 1365 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 1366 {
kenjiArai 0:5b88d5760320 1367 key1 = keyblk + mac_key_len * 2 + keylen;
kenjiArai 0:5b88d5760320 1368 key2 = keyblk + mac_key_len * 2;
kenjiArai 0:5b88d5760320 1369
kenjiArai 0:5b88d5760320 1370 mac_enc = keyblk + mac_key_len;
kenjiArai 0:5b88d5760320 1371 mac_dec = keyblk;
kenjiArai 0:5b88d5760320 1372
kenjiArai 0:5b88d5760320 1373 /*
kenjiArai 0:5b88d5760320 1374 * This is not used in TLS v1.1.
kenjiArai 0:5b88d5760320 1375 */
kenjiArai 0:5b88d5760320 1376 iv_copy_len = ( transform->fixed_ivlen ) ?
kenjiArai 0:5b88d5760320 1377 transform->fixed_ivlen : transform->ivlen;
kenjiArai 0:5b88d5760320 1378 memcpy( transform->iv_dec, key1 + keylen, iv_copy_len );
kenjiArai 0:5b88d5760320 1379 memcpy( transform->iv_enc, key1 + keylen + iv_copy_len,
kenjiArai 0:5b88d5760320 1380 iv_copy_len );
kenjiArai 0:5b88d5760320 1381 }
kenjiArai 0:5b88d5760320 1382 else
kenjiArai 0:5b88d5760320 1383 #endif /* MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 1384 {
kenjiArai 0:5b88d5760320 1385 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 1386 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
kenjiArai 0:5b88d5760320 1387 goto end;
kenjiArai 0:5b88d5760320 1388 }
kenjiArai 0:5b88d5760320 1389
kenjiArai 0:5b88d5760320 1390 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
kenjiArai 0:5b88d5760320 1391 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 1392 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 1393 {
kenjiArai 0:5b88d5760320 1394 if( mac_key_len > sizeof( transform->mac_enc ) )
kenjiArai 0:5b88d5760320 1395 {
kenjiArai 0:5b88d5760320 1396 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 1397 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
kenjiArai 0:5b88d5760320 1398 goto end;
kenjiArai 0:5b88d5760320 1399 }
kenjiArai 0:5b88d5760320 1400
kenjiArai 0:5b88d5760320 1401 memcpy( transform->mac_enc, mac_enc, mac_key_len );
kenjiArai 0:5b88d5760320 1402 memcpy( transform->mac_dec, mac_dec, mac_key_len );
kenjiArai 0:5b88d5760320 1403 }
kenjiArai 0:5b88d5760320 1404 else
kenjiArai 0:5b88d5760320 1405 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 1406 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 1407 defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 1408 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
kenjiArai 0:5b88d5760320 1409 {
kenjiArai 0:5b88d5760320 1410 /* For HMAC-based ciphersuites, initialize the HMAC transforms.
kenjiArai 0:5b88d5760320 1411 For AEAD-based ciphersuites, there is nothing to do here. */
kenjiArai 0:5b88d5760320 1412 if( mac_key_len != 0 )
kenjiArai 0:5b88d5760320 1413 {
kenjiArai 0:5b88d5760320 1414 mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len );
kenjiArai 0:5b88d5760320 1415 mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len );
kenjiArai 0:5b88d5760320 1416 }
kenjiArai 0:5b88d5760320 1417 }
kenjiArai 0:5b88d5760320 1418 else
kenjiArai 0:5b88d5760320 1419 #endif
kenjiArai 0:5b88d5760320 1420 {
kenjiArai 0:5b88d5760320 1421 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 1422 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
kenjiArai 0:5b88d5760320 1423 goto end;
kenjiArai 0:5b88d5760320 1424 }
kenjiArai 0:5b88d5760320 1425 #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
kenjiArai 0:5b88d5760320 1426
kenjiArai 0:5b88d5760320 1427 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 1428 if( mbedtls_ssl_hw_record_init != NULL )
kenjiArai 0:5b88d5760320 1429 {
kenjiArai 0:5b88d5760320 1430 int ret = 0;
kenjiArai 0:5b88d5760320 1431
kenjiArai 0:5b88d5760320 1432 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
kenjiArai 0:5b88d5760320 1433
kenjiArai 0:5b88d5760320 1434 if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, keylen,
kenjiArai 0:5b88d5760320 1435 transform->iv_enc, transform->iv_dec,
kenjiArai 0:5b88d5760320 1436 iv_copy_len,
kenjiArai 0:5b88d5760320 1437 mac_enc, mac_dec,
kenjiArai 0:5b88d5760320 1438 mac_key_len ) ) != 0 )
kenjiArai 0:5b88d5760320 1439 {
kenjiArai 0:5b88d5760320 1440 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
kenjiArai 0:5b88d5760320 1441 ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
kenjiArai 0:5b88d5760320 1442 goto end;
kenjiArai 0:5b88d5760320 1443 }
kenjiArai 0:5b88d5760320 1444 }
kenjiArai 0:5b88d5760320 1445 #else
kenjiArai 0:5b88d5760320 1446 ((void) mac_dec);
kenjiArai 0:5b88d5760320 1447 ((void) mac_enc);
kenjiArai 0:5b88d5760320 1448 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
kenjiArai 0:5b88d5760320 1449
kenjiArai 0:5b88d5760320 1450 #if defined(MBEDTLS_SSL_EXPORT_KEYS)
kenjiArai 0:5b88d5760320 1451 if( ssl->conf->f_export_keys != NULL )
kenjiArai 0:5b88d5760320 1452 {
kenjiArai 0:5b88d5760320 1453 ssl->conf->f_export_keys( ssl->conf->p_export_keys,
kenjiArai 0:5b88d5760320 1454 session->master, keyblk,
kenjiArai 0:5b88d5760320 1455 mac_key_len, keylen,
kenjiArai 0:5b88d5760320 1456 iv_copy_len );
kenjiArai 0:5b88d5760320 1457 }
kenjiArai 0:5b88d5760320 1458
kenjiArai 0:5b88d5760320 1459 if( ssl->conf->f_export_keys_ext != NULL )
kenjiArai 0:5b88d5760320 1460 {
kenjiArai 0:5b88d5760320 1461 ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys,
kenjiArai 0:5b88d5760320 1462 session->master, keyblk,
kenjiArai 0:5b88d5760320 1463 mac_key_len, keylen,
kenjiArai 0:5b88d5760320 1464 iv_copy_len,
kenjiArai 0:5b88d5760320 1465 handshake->randbytes + 32,
kenjiArai 0:5b88d5760320 1466 handshake->randbytes,
kenjiArai 0:5b88d5760320 1467 tls_prf_get_type( handshake->tls_prf ) );
kenjiArai 0:5b88d5760320 1468 }
kenjiArai 0:5b88d5760320 1469 #endif
kenjiArai 0:5b88d5760320 1470
kenjiArai 0:5b88d5760320 1471 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 1472
kenjiArai 0:5b88d5760320 1473 /* Only use PSA-based ciphers for TLS-1.2.
kenjiArai 0:5b88d5760320 1474 * That's relevant at least for TLS-1.0, where
kenjiArai 0:5b88d5760320 1475 * we assume that mbedtls_cipher_crypt() updates
kenjiArai 0:5b88d5760320 1476 * the structure field for the IV, which the PSA-based
kenjiArai 0:5b88d5760320 1477 * implementation currently doesn't. */
kenjiArai 0:5b88d5760320 1478 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 1479 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 1480 {
kenjiArai 0:5b88d5760320 1481 ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_enc,
kenjiArai 0:5b88d5760320 1482 cipher_info, transform->taglen );
kenjiArai 0:5b88d5760320 1483 if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
kenjiArai 0:5b88d5760320 1484 {
kenjiArai 0:5b88d5760320 1485 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
kenjiArai 0:5b88d5760320 1486 goto end;
kenjiArai 0:5b88d5760320 1487 }
kenjiArai 0:5b88d5760320 1488
kenjiArai 0:5b88d5760320 1489 if( ret == 0 )
kenjiArai 0:5b88d5760320 1490 {
kenjiArai 0:5b88d5760320 1491 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based encryption cipher context" ) );
kenjiArai 0:5b88d5760320 1492 psa_fallthrough = 0;
kenjiArai 0:5b88d5760320 1493 }
kenjiArai 0:5b88d5760320 1494 else
kenjiArai 0:5b88d5760320 1495 {
kenjiArai 0:5b88d5760320 1496 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record encryption - fall through to default setup." ) );
kenjiArai 0:5b88d5760320 1497 psa_fallthrough = 1;
kenjiArai 0:5b88d5760320 1498 }
kenjiArai 0:5b88d5760320 1499 }
kenjiArai 0:5b88d5760320 1500 else
kenjiArai 0:5b88d5760320 1501 psa_fallthrough = 1;
kenjiArai 0:5b88d5760320 1502 #else
kenjiArai 0:5b88d5760320 1503 psa_fallthrough = 1;
kenjiArai 0:5b88d5760320 1504 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 1505
kenjiArai 0:5b88d5760320 1506 if( psa_fallthrough == 1 )
kenjiArai 0:5b88d5760320 1507 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 1508 if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
kenjiArai 0:5b88d5760320 1509 cipher_info ) ) != 0 )
kenjiArai 0:5b88d5760320 1510 {
kenjiArai 0:5b88d5760320 1511 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
kenjiArai 0:5b88d5760320 1512 goto end;
kenjiArai 0:5b88d5760320 1513 }
kenjiArai 0:5b88d5760320 1514
kenjiArai 0:5b88d5760320 1515 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 1516 /* Only use PSA-based ciphers for TLS-1.2.
kenjiArai 0:5b88d5760320 1517 * That's relevant at least for TLS-1.0, where
kenjiArai 0:5b88d5760320 1518 * we assume that mbedtls_cipher_crypt() updates
kenjiArai 0:5b88d5760320 1519 * the structure field for the IV, which the PSA-based
kenjiArai 0:5b88d5760320 1520 * implementation currently doesn't. */
kenjiArai 0:5b88d5760320 1521 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 1522 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 1523 {
kenjiArai 0:5b88d5760320 1524 ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_dec,
kenjiArai 0:5b88d5760320 1525 cipher_info, transform->taglen );
kenjiArai 0:5b88d5760320 1526 if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
kenjiArai 0:5b88d5760320 1527 {
kenjiArai 0:5b88d5760320 1528 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
kenjiArai 0:5b88d5760320 1529 goto end;
kenjiArai 0:5b88d5760320 1530 }
kenjiArai 0:5b88d5760320 1531
kenjiArai 0:5b88d5760320 1532 if( ret == 0 )
kenjiArai 0:5b88d5760320 1533 {
kenjiArai 0:5b88d5760320 1534 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based decryption cipher context" ) );
kenjiArai 0:5b88d5760320 1535 psa_fallthrough = 0;
kenjiArai 0:5b88d5760320 1536 }
kenjiArai 0:5b88d5760320 1537 else
kenjiArai 0:5b88d5760320 1538 {
kenjiArai 0:5b88d5760320 1539 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record decryption - fall through to default setup." ) );
kenjiArai 0:5b88d5760320 1540 psa_fallthrough = 1;
kenjiArai 0:5b88d5760320 1541 }
kenjiArai 0:5b88d5760320 1542 }
kenjiArai 0:5b88d5760320 1543 else
kenjiArai 0:5b88d5760320 1544 psa_fallthrough = 1;
kenjiArai 0:5b88d5760320 1545 #else
kenjiArai 0:5b88d5760320 1546 psa_fallthrough = 1;
kenjiArai 0:5b88d5760320 1547 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 1548
kenjiArai 0:5b88d5760320 1549 if( psa_fallthrough == 1 )
kenjiArai 0:5b88d5760320 1550 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 1551 if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
kenjiArai 0:5b88d5760320 1552 cipher_info ) ) != 0 )
kenjiArai 0:5b88d5760320 1553 {
kenjiArai 0:5b88d5760320 1554 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
kenjiArai 0:5b88d5760320 1555 goto end;
kenjiArai 0:5b88d5760320 1556 }
kenjiArai 0:5b88d5760320 1557
kenjiArai 0:5b88d5760320 1558 if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
kenjiArai 0:5b88d5760320 1559 cipher_info->key_bitlen,
kenjiArai 0:5b88d5760320 1560 MBEDTLS_ENCRYPT ) ) != 0 )
kenjiArai 0:5b88d5760320 1561 {
kenjiArai 0:5b88d5760320 1562 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
kenjiArai 0:5b88d5760320 1563 goto end;
kenjiArai 0:5b88d5760320 1564 }
kenjiArai 0:5b88d5760320 1565
kenjiArai 0:5b88d5760320 1566 if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
kenjiArai 0:5b88d5760320 1567 cipher_info->key_bitlen,
kenjiArai 0:5b88d5760320 1568 MBEDTLS_DECRYPT ) ) != 0 )
kenjiArai 0:5b88d5760320 1569 {
kenjiArai 0:5b88d5760320 1570 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
kenjiArai 0:5b88d5760320 1571 goto end;
kenjiArai 0:5b88d5760320 1572 }
kenjiArai 0:5b88d5760320 1573
kenjiArai 0:5b88d5760320 1574 #if defined(MBEDTLS_CIPHER_MODE_CBC)
kenjiArai 0:5b88d5760320 1575 if( cipher_info->mode == MBEDTLS_MODE_CBC )
kenjiArai 0:5b88d5760320 1576 {
kenjiArai 0:5b88d5760320 1577 if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
kenjiArai 0:5b88d5760320 1578 MBEDTLS_PADDING_NONE ) ) != 0 )
kenjiArai 0:5b88d5760320 1579 {
kenjiArai 0:5b88d5760320 1580 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
kenjiArai 0:5b88d5760320 1581 goto end;
kenjiArai 0:5b88d5760320 1582 }
kenjiArai 0:5b88d5760320 1583
kenjiArai 0:5b88d5760320 1584 if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
kenjiArai 0:5b88d5760320 1585 MBEDTLS_PADDING_NONE ) ) != 0 )
kenjiArai 0:5b88d5760320 1586 {
kenjiArai 0:5b88d5760320 1587 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
kenjiArai 0:5b88d5760320 1588 goto end;
kenjiArai 0:5b88d5760320 1589 }
kenjiArai 0:5b88d5760320 1590 }
kenjiArai 0:5b88d5760320 1591 #endif /* MBEDTLS_CIPHER_MODE_CBC */
kenjiArai 0:5b88d5760320 1592
kenjiArai 0:5b88d5760320 1593
kenjiArai 0:5b88d5760320 1594 #if defined(MBEDTLS_ZLIB_SUPPORT)
kenjiArai 0:5b88d5760320 1595 // Initialize compression
kenjiArai 0:5b88d5760320 1596 //
kenjiArai 0:5b88d5760320 1597 if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
kenjiArai 0:5b88d5760320 1598 {
kenjiArai 0:5b88d5760320 1599 if( ssl->compress_buf == NULL )
kenjiArai 0:5b88d5760320 1600 {
kenjiArai 0:5b88d5760320 1601 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
kenjiArai 0:5b88d5760320 1602 ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
kenjiArai 0:5b88d5760320 1603 if( ssl->compress_buf == NULL )
kenjiArai 0:5b88d5760320 1604 {
kenjiArai 0:5b88d5760320 1605 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
kenjiArai 0:5b88d5760320 1606 MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
kenjiArai 0:5b88d5760320 1607 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
kenjiArai 0:5b88d5760320 1608 goto end;
kenjiArai 0:5b88d5760320 1609 }
kenjiArai 0:5b88d5760320 1610 }
kenjiArai 0:5b88d5760320 1611
kenjiArai 0:5b88d5760320 1612 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) );
kenjiArai 0:5b88d5760320 1613
kenjiArai 0:5b88d5760320 1614 memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) );
kenjiArai 0:5b88d5760320 1615 memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) );
kenjiArai 0:5b88d5760320 1616
kenjiArai 0:5b88d5760320 1617 if( deflateInit( &transform->ctx_deflate,
kenjiArai 0:5b88d5760320 1618 Z_DEFAULT_COMPRESSION ) != Z_OK ||
kenjiArai 0:5b88d5760320 1619 inflateInit( &transform->ctx_inflate ) != Z_OK )
kenjiArai 0:5b88d5760320 1620 {
kenjiArai 0:5b88d5760320 1621 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
kenjiArai 0:5b88d5760320 1622 ret = MBEDTLS_ERR_SSL_COMPRESSION_FAILED;
kenjiArai 0:5b88d5760320 1623 goto end;
kenjiArai 0:5b88d5760320 1624 }
kenjiArai 0:5b88d5760320 1625 }
kenjiArai 0:5b88d5760320 1626 #endif /* MBEDTLS_ZLIB_SUPPORT */
kenjiArai 0:5b88d5760320 1627
kenjiArai 0:5b88d5760320 1628 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
kenjiArai 0:5b88d5760320 1629 end:
kenjiArai 0:5b88d5760320 1630 mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
kenjiArai 0:5b88d5760320 1631 mbedtls_platform_zeroize( handshake->randbytes,
kenjiArai 0:5b88d5760320 1632 sizeof( handshake->randbytes ) );
kenjiArai 0:5b88d5760320 1633 return( ret );
kenjiArai 0:5b88d5760320 1634 }
kenjiArai 0:5b88d5760320 1635
kenjiArai 0:5b88d5760320 1636 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 1637 void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
kenjiArai 0:5b88d5760320 1638 {
kenjiArai 0:5b88d5760320 1639 mbedtls_md5_context md5;
kenjiArai 0:5b88d5760320 1640 mbedtls_sha1_context sha1;
kenjiArai 0:5b88d5760320 1641 unsigned char pad_1[48];
kenjiArai 0:5b88d5760320 1642 unsigned char pad_2[48];
kenjiArai 0:5b88d5760320 1643
kenjiArai 0:5b88d5760320 1644 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) );
kenjiArai 0:5b88d5760320 1645
kenjiArai 0:5b88d5760320 1646 mbedtls_md5_init( &md5 );
kenjiArai 0:5b88d5760320 1647 mbedtls_sha1_init( &sha1 );
kenjiArai 0:5b88d5760320 1648
kenjiArai 0:5b88d5760320 1649 mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
kenjiArai 0:5b88d5760320 1650 mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
kenjiArai 0:5b88d5760320 1651
kenjiArai 0:5b88d5760320 1652 memset( pad_1, 0x36, 48 );
kenjiArai 0:5b88d5760320 1653 memset( pad_2, 0x5C, 48 );
kenjiArai 0:5b88d5760320 1654
kenjiArai 0:5b88d5760320 1655 mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 );
kenjiArai 0:5b88d5760320 1656 mbedtls_md5_update_ret( &md5, pad_1, 48 );
kenjiArai 0:5b88d5760320 1657 mbedtls_md5_finish_ret( &md5, hash );
kenjiArai 0:5b88d5760320 1658
kenjiArai 0:5b88d5760320 1659 mbedtls_md5_starts_ret( &md5 );
kenjiArai 0:5b88d5760320 1660 mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 );
kenjiArai 0:5b88d5760320 1661 mbedtls_md5_update_ret( &md5, pad_2, 48 );
kenjiArai 0:5b88d5760320 1662 mbedtls_md5_update_ret( &md5, hash, 16 );
kenjiArai 0:5b88d5760320 1663 mbedtls_md5_finish_ret( &md5, hash );
kenjiArai 0:5b88d5760320 1664
kenjiArai 0:5b88d5760320 1665 mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 );
kenjiArai 0:5b88d5760320 1666 mbedtls_sha1_update_ret( &sha1, pad_1, 40 );
kenjiArai 0:5b88d5760320 1667 mbedtls_sha1_finish_ret( &sha1, hash + 16 );
kenjiArai 0:5b88d5760320 1668
kenjiArai 0:5b88d5760320 1669 mbedtls_sha1_starts_ret( &sha1 );
kenjiArai 0:5b88d5760320 1670 mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 );
kenjiArai 0:5b88d5760320 1671 mbedtls_sha1_update_ret( &sha1, pad_2, 40 );
kenjiArai 0:5b88d5760320 1672 mbedtls_sha1_update_ret( &sha1, hash + 16, 20 );
kenjiArai 0:5b88d5760320 1673 mbedtls_sha1_finish_ret( &sha1, hash + 16 );
kenjiArai 0:5b88d5760320 1674
kenjiArai 0:5b88d5760320 1675 MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
kenjiArai 0:5b88d5760320 1676 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
kenjiArai 0:5b88d5760320 1677
kenjiArai 0:5b88d5760320 1678 mbedtls_md5_free( &md5 );
kenjiArai 0:5b88d5760320 1679 mbedtls_sha1_free( &sha1 );
kenjiArai 0:5b88d5760320 1680
kenjiArai 0:5b88d5760320 1681 return;
kenjiArai 0:5b88d5760320 1682 }
kenjiArai 0:5b88d5760320 1683 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 1684
kenjiArai 0:5b88d5760320 1685 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 1686 void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
kenjiArai 0:5b88d5760320 1687 {
kenjiArai 0:5b88d5760320 1688 mbedtls_md5_context md5;
kenjiArai 0:5b88d5760320 1689 mbedtls_sha1_context sha1;
kenjiArai 0:5b88d5760320 1690
kenjiArai 0:5b88d5760320 1691 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) );
kenjiArai 0:5b88d5760320 1692
kenjiArai 0:5b88d5760320 1693 mbedtls_md5_init( &md5 );
kenjiArai 0:5b88d5760320 1694 mbedtls_sha1_init( &sha1 );
kenjiArai 0:5b88d5760320 1695
kenjiArai 0:5b88d5760320 1696 mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
kenjiArai 0:5b88d5760320 1697 mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
kenjiArai 0:5b88d5760320 1698
kenjiArai 0:5b88d5760320 1699 mbedtls_md5_finish_ret( &md5, hash );
kenjiArai 0:5b88d5760320 1700 mbedtls_sha1_finish_ret( &sha1, hash + 16 );
kenjiArai 0:5b88d5760320 1701
kenjiArai 0:5b88d5760320 1702 MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
kenjiArai 0:5b88d5760320 1703 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
kenjiArai 0:5b88d5760320 1704
kenjiArai 0:5b88d5760320 1705 mbedtls_md5_free( &md5 );
kenjiArai 0:5b88d5760320 1706 mbedtls_sha1_free( &sha1 );
kenjiArai 0:5b88d5760320 1707
kenjiArai 0:5b88d5760320 1708 return;
kenjiArai 0:5b88d5760320 1709 }
kenjiArai 0:5b88d5760320 1710 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
kenjiArai 0:5b88d5760320 1711
kenjiArai 0:5b88d5760320 1712 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 1713 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 1714 void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] )
kenjiArai 0:5b88d5760320 1715 {
kenjiArai 0:5b88d5760320 1716 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 1717 size_t hash_size;
kenjiArai 0:5b88d5760320 1718 psa_status_t status;
kenjiArai 0:5b88d5760320 1719 psa_hash_operation_t sha256_psa = psa_hash_operation_init();
kenjiArai 0:5b88d5760320 1720
kenjiArai 0:5b88d5760320 1721 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha256" ) );
kenjiArai 0:5b88d5760320 1722 status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
kenjiArai 0:5b88d5760320 1723 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1724 {
kenjiArai 0:5b88d5760320 1725 MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
kenjiArai 0:5b88d5760320 1726 return;
kenjiArai 0:5b88d5760320 1727 }
kenjiArai 0:5b88d5760320 1728
kenjiArai 0:5b88d5760320 1729 status = psa_hash_finish( &sha256_psa, hash, 32, &hash_size );
kenjiArai 0:5b88d5760320 1730 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1731 {
kenjiArai 0:5b88d5760320 1732 MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
kenjiArai 0:5b88d5760320 1733 return;
kenjiArai 0:5b88d5760320 1734 }
kenjiArai 0:5b88d5760320 1735 MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, 32 );
kenjiArai 0:5b88d5760320 1736 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
kenjiArai 0:5b88d5760320 1737 #else
kenjiArai 0:5b88d5760320 1738 mbedtls_sha256_context sha256;
kenjiArai 0:5b88d5760320 1739
kenjiArai 0:5b88d5760320 1740 mbedtls_sha256_init( &sha256 );
kenjiArai 0:5b88d5760320 1741
kenjiArai 0:5b88d5760320 1742 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
kenjiArai 0:5b88d5760320 1743
kenjiArai 0:5b88d5760320 1744 mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
kenjiArai 0:5b88d5760320 1745 mbedtls_sha256_finish_ret( &sha256, hash );
kenjiArai 0:5b88d5760320 1746
kenjiArai 0:5b88d5760320 1747 MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
kenjiArai 0:5b88d5760320 1748 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
kenjiArai 0:5b88d5760320 1749
kenjiArai 0:5b88d5760320 1750 mbedtls_sha256_free( &sha256 );
kenjiArai 0:5b88d5760320 1751 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 1752 return;
kenjiArai 0:5b88d5760320 1753 }
kenjiArai 0:5b88d5760320 1754 #endif /* MBEDTLS_SHA256_C */
kenjiArai 0:5b88d5760320 1755
kenjiArai 0:5b88d5760320 1756 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 1757 void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] )
kenjiArai 0:5b88d5760320 1758 {
kenjiArai 0:5b88d5760320 1759 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 1760 size_t hash_size;
kenjiArai 0:5b88d5760320 1761 psa_status_t status;
kenjiArai 0:5b88d5760320 1762 psa_hash_operation_t sha384_psa = psa_hash_operation_init();
kenjiArai 0:5b88d5760320 1763
kenjiArai 0:5b88d5760320 1764 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha384" ) );
kenjiArai 0:5b88d5760320 1765 status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
kenjiArai 0:5b88d5760320 1766 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1767 {
kenjiArai 0:5b88d5760320 1768 MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
kenjiArai 0:5b88d5760320 1769 return;
kenjiArai 0:5b88d5760320 1770 }
kenjiArai 0:5b88d5760320 1771
kenjiArai 0:5b88d5760320 1772 status = psa_hash_finish( &sha384_psa, hash, 48, &hash_size );
kenjiArai 0:5b88d5760320 1773 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1774 {
kenjiArai 0:5b88d5760320 1775 MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
kenjiArai 0:5b88d5760320 1776 return;
kenjiArai 0:5b88d5760320 1777 }
kenjiArai 0:5b88d5760320 1778 MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, 48 );
kenjiArai 0:5b88d5760320 1779 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
kenjiArai 0:5b88d5760320 1780 #else
kenjiArai 0:5b88d5760320 1781 mbedtls_sha512_context sha512;
kenjiArai 0:5b88d5760320 1782
kenjiArai 0:5b88d5760320 1783 mbedtls_sha512_init( &sha512 );
kenjiArai 0:5b88d5760320 1784
kenjiArai 0:5b88d5760320 1785 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
kenjiArai 0:5b88d5760320 1786
kenjiArai 0:5b88d5760320 1787 mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
kenjiArai 0:5b88d5760320 1788 mbedtls_sha512_finish_ret( &sha512, hash );
kenjiArai 0:5b88d5760320 1789
kenjiArai 0:5b88d5760320 1790 MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
kenjiArai 0:5b88d5760320 1791 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
kenjiArai 0:5b88d5760320 1792
kenjiArai 0:5b88d5760320 1793 mbedtls_sha512_free( &sha512 );
kenjiArai 0:5b88d5760320 1794 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 1795 return;
kenjiArai 0:5b88d5760320 1796 }
kenjiArai 0:5b88d5760320 1797 #endif /* MBEDTLS_SHA512_C */
kenjiArai 0:5b88d5760320 1798 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 1799
kenjiArai 0:5b88d5760320 1800 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
kenjiArai 0:5b88d5760320 1801 int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
kenjiArai 0:5b88d5760320 1802 {
kenjiArai 0:5b88d5760320 1803 unsigned char *p = ssl->handshake->premaster;
kenjiArai 0:5b88d5760320 1804 unsigned char *end = p + sizeof( ssl->handshake->premaster );
kenjiArai 0:5b88d5760320 1805 const unsigned char *psk = ssl->conf->psk;
kenjiArai 0:5b88d5760320 1806 size_t psk_len = ssl->conf->psk_len;
kenjiArai 0:5b88d5760320 1807
kenjiArai 0:5b88d5760320 1808 /* If the psk callback was called, use its result */
kenjiArai 0:5b88d5760320 1809 if( ssl->handshake->psk != NULL )
kenjiArai 0:5b88d5760320 1810 {
kenjiArai 0:5b88d5760320 1811 psk = ssl->handshake->psk;
kenjiArai 0:5b88d5760320 1812 psk_len = ssl->handshake->psk_len;
kenjiArai 0:5b88d5760320 1813 }
kenjiArai 0:5b88d5760320 1814
kenjiArai 0:5b88d5760320 1815 /*
kenjiArai 0:5b88d5760320 1816 * PMS = struct {
kenjiArai 0:5b88d5760320 1817 * opaque other_secret<0..2^16-1>;
kenjiArai 0:5b88d5760320 1818 * opaque psk<0..2^16-1>;
kenjiArai 0:5b88d5760320 1819 * };
kenjiArai 0:5b88d5760320 1820 * with "other_secret" depending on the particular key exchange
kenjiArai 0:5b88d5760320 1821 */
kenjiArai 0:5b88d5760320 1822 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
kenjiArai 0:5b88d5760320 1823 if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK )
kenjiArai 0:5b88d5760320 1824 {
kenjiArai 0:5b88d5760320 1825 if( end - p < 2 )
kenjiArai 0:5b88d5760320 1826 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 1827
kenjiArai 0:5b88d5760320 1828 *(p++) = (unsigned char)( psk_len >> 8 );
kenjiArai 0:5b88d5760320 1829 *(p++) = (unsigned char)( psk_len );
kenjiArai 0:5b88d5760320 1830
kenjiArai 0:5b88d5760320 1831 if( end < p || (size_t)( end - p ) < psk_len )
kenjiArai 0:5b88d5760320 1832 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 1833
kenjiArai 0:5b88d5760320 1834 memset( p, 0, psk_len );
kenjiArai 0:5b88d5760320 1835 p += psk_len;
kenjiArai 0:5b88d5760320 1836 }
kenjiArai 0:5b88d5760320 1837 else
kenjiArai 0:5b88d5760320 1838 #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
kenjiArai 0:5b88d5760320 1839 #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
kenjiArai 0:5b88d5760320 1840 if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
kenjiArai 0:5b88d5760320 1841 {
kenjiArai 0:5b88d5760320 1842 /*
kenjiArai 0:5b88d5760320 1843 * other_secret already set by the ClientKeyExchange message,
kenjiArai 0:5b88d5760320 1844 * and is 48 bytes long
kenjiArai 0:5b88d5760320 1845 */
kenjiArai 0:5b88d5760320 1846 if( end - p < 2 )
kenjiArai 0:5b88d5760320 1847 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 1848
kenjiArai 0:5b88d5760320 1849 *p++ = 0;
kenjiArai 0:5b88d5760320 1850 *p++ = 48;
kenjiArai 0:5b88d5760320 1851 p += 48;
kenjiArai 0:5b88d5760320 1852 }
kenjiArai 0:5b88d5760320 1853 else
kenjiArai 0:5b88d5760320 1854 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
kenjiArai 0:5b88d5760320 1855 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
kenjiArai 0:5b88d5760320 1856 if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
kenjiArai 0:5b88d5760320 1857 {
kenjiArai 0:5b88d5760320 1858 int ret;
kenjiArai 0:5b88d5760320 1859 size_t len;
kenjiArai 0:5b88d5760320 1860
kenjiArai 0:5b88d5760320 1861 /* Write length only when we know the actual value */
kenjiArai 0:5b88d5760320 1862 if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
kenjiArai 0:5b88d5760320 1863 p + 2, end - ( p + 2 ), &len,
kenjiArai 0:5b88d5760320 1864 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
kenjiArai 0:5b88d5760320 1865 {
kenjiArai 0:5b88d5760320 1866 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
kenjiArai 0:5b88d5760320 1867 return( ret );
kenjiArai 0:5b88d5760320 1868 }
kenjiArai 0:5b88d5760320 1869 *(p++) = (unsigned char)( len >> 8 );
kenjiArai 0:5b88d5760320 1870 *(p++) = (unsigned char)( len );
kenjiArai 0:5b88d5760320 1871 p += len;
kenjiArai 0:5b88d5760320 1872
kenjiArai 0:5b88d5760320 1873 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
kenjiArai 0:5b88d5760320 1874 }
kenjiArai 0:5b88d5760320 1875 else
kenjiArai 0:5b88d5760320 1876 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
kenjiArai 0:5b88d5760320 1877 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
kenjiArai 0:5b88d5760320 1878 if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
kenjiArai 0:5b88d5760320 1879 {
kenjiArai 0:5b88d5760320 1880 int ret;
kenjiArai 0:5b88d5760320 1881 size_t zlen;
kenjiArai 0:5b88d5760320 1882
kenjiArai 0:5b88d5760320 1883 if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
kenjiArai 0:5b88d5760320 1884 p + 2, end - ( p + 2 ),
kenjiArai 0:5b88d5760320 1885 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
kenjiArai 0:5b88d5760320 1886 {
kenjiArai 0:5b88d5760320 1887 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
kenjiArai 0:5b88d5760320 1888 return( ret );
kenjiArai 0:5b88d5760320 1889 }
kenjiArai 0:5b88d5760320 1890
kenjiArai 0:5b88d5760320 1891 *(p++) = (unsigned char)( zlen >> 8 );
kenjiArai 0:5b88d5760320 1892 *(p++) = (unsigned char)( zlen );
kenjiArai 0:5b88d5760320 1893 p += zlen;
kenjiArai 0:5b88d5760320 1894
kenjiArai 0:5b88d5760320 1895 MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
kenjiArai 0:5b88d5760320 1896 MBEDTLS_DEBUG_ECDH_Z );
kenjiArai 0:5b88d5760320 1897 }
kenjiArai 0:5b88d5760320 1898 else
kenjiArai 0:5b88d5760320 1899 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
kenjiArai 0:5b88d5760320 1900 {
kenjiArai 0:5b88d5760320 1901 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 1902 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 1903 }
kenjiArai 0:5b88d5760320 1904
kenjiArai 0:5b88d5760320 1905 /* opaque psk<0..2^16-1>; */
kenjiArai 0:5b88d5760320 1906 if( end - p < 2 )
kenjiArai 0:5b88d5760320 1907 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 1908
kenjiArai 0:5b88d5760320 1909 *(p++) = (unsigned char)( psk_len >> 8 );
kenjiArai 0:5b88d5760320 1910 *(p++) = (unsigned char)( psk_len );
kenjiArai 0:5b88d5760320 1911
kenjiArai 0:5b88d5760320 1912 if( end < p || (size_t)( end - p ) < psk_len )
kenjiArai 0:5b88d5760320 1913 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 1914
kenjiArai 0:5b88d5760320 1915 memcpy( p, psk, psk_len );
kenjiArai 0:5b88d5760320 1916 p += psk_len;
kenjiArai 0:5b88d5760320 1917
kenjiArai 0:5b88d5760320 1918 ssl->handshake->pmslen = p - ssl->handshake->premaster;
kenjiArai 0:5b88d5760320 1919
kenjiArai 0:5b88d5760320 1920 return( 0 );
kenjiArai 0:5b88d5760320 1921 }
kenjiArai 0:5b88d5760320 1922 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
kenjiArai 0:5b88d5760320 1923
kenjiArai 0:5b88d5760320 1924 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 1925 /*
kenjiArai 0:5b88d5760320 1926 * SSLv3.0 MAC functions
kenjiArai 0:5b88d5760320 1927 */
kenjiArai 0:5b88d5760320 1928 #define SSL_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */
kenjiArai 0:5b88d5760320 1929 static void ssl_mac( mbedtls_md_context_t *md_ctx,
kenjiArai 0:5b88d5760320 1930 const unsigned char *secret,
kenjiArai 0:5b88d5760320 1931 const unsigned char *buf, size_t len,
kenjiArai 0:5b88d5760320 1932 const unsigned char *ctr, int type,
kenjiArai 0:5b88d5760320 1933 unsigned char out[SSL_MAC_MAX_BYTES] )
kenjiArai 0:5b88d5760320 1934 {
kenjiArai 0:5b88d5760320 1935 unsigned char header[11];
kenjiArai 0:5b88d5760320 1936 unsigned char padding[48];
kenjiArai 0:5b88d5760320 1937 int padlen;
kenjiArai 0:5b88d5760320 1938 int md_size = mbedtls_md_get_size( md_ctx->md_info );
kenjiArai 0:5b88d5760320 1939 int md_type = mbedtls_md_get_type( md_ctx->md_info );
kenjiArai 0:5b88d5760320 1940
kenjiArai 0:5b88d5760320 1941 /* Only MD5 and SHA-1 supported */
kenjiArai 0:5b88d5760320 1942 if( md_type == MBEDTLS_MD_MD5 )
kenjiArai 0:5b88d5760320 1943 padlen = 48;
kenjiArai 0:5b88d5760320 1944 else
kenjiArai 0:5b88d5760320 1945 padlen = 40;
kenjiArai 0:5b88d5760320 1946
kenjiArai 0:5b88d5760320 1947 memcpy( header, ctr, 8 );
kenjiArai 0:5b88d5760320 1948 header[ 8] = (unsigned char) type;
kenjiArai 0:5b88d5760320 1949 header[ 9] = (unsigned char)( len >> 8 );
kenjiArai 0:5b88d5760320 1950 header[10] = (unsigned char)( len );
kenjiArai 0:5b88d5760320 1951
kenjiArai 0:5b88d5760320 1952 memset( padding, 0x36, padlen );
kenjiArai 0:5b88d5760320 1953 mbedtls_md_starts( md_ctx );
kenjiArai 0:5b88d5760320 1954 mbedtls_md_update( md_ctx, secret, md_size );
kenjiArai 0:5b88d5760320 1955 mbedtls_md_update( md_ctx, padding, padlen );
kenjiArai 0:5b88d5760320 1956 mbedtls_md_update( md_ctx, header, 11 );
kenjiArai 0:5b88d5760320 1957 mbedtls_md_update( md_ctx, buf, len );
kenjiArai 0:5b88d5760320 1958 mbedtls_md_finish( md_ctx, out );
kenjiArai 0:5b88d5760320 1959
kenjiArai 0:5b88d5760320 1960 memset( padding, 0x5C, padlen );
kenjiArai 0:5b88d5760320 1961 mbedtls_md_starts( md_ctx );
kenjiArai 0:5b88d5760320 1962 mbedtls_md_update( md_ctx, secret, md_size );
kenjiArai 0:5b88d5760320 1963 mbedtls_md_update( md_ctx, padding, padlen );
kenjiArai 0:5b88d5760320 1964 mbedtls_md_update( md_ctx, out, md_size );
kenjiArai 0:5b88d5760320 1965 mbedtls_md_finish( md_ctx, out );
kenjiArai 0:5b88d5760320 1966 }
kenjiArai 0:5b88d5760320 1967 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 1968
kenjiArai 0:5b88d5760320 1969 /* The function below is only used in the Lucky 13 counter-measure in
kenjiArai 0:5b88d5760320 1970 * mbedtls_ssl_decrypt_buf(). These are the defines that guard the call site. */
kenjiArai 0:5b88d5760320 1971 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) && \
kenjiArai 0:5b88d5760320 1972 ( defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 1973 defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 1974 defined(MBEDTLS_SSL_PROTO_TLS1_2) )
kenjiArai 0:5b88d5760320 1975 /* This function makes sure every byte in the memory region is accessed
kenjiArai 0:5b88d5760320 1976 * (in ascending addresses order) */
kenjiArai 0:5b88d5760320 1977 static void ssl_read_memory( unsigned char *p, size_t len )
kenjiArai 0:5b88d5760320 1978 {
kenjiArai 0:5b88d5760320 1979 unsigned char acc = 0;
kenjiArai 0:5b88d5760320 1980 volatile unsigned char force;
kenjiArai 0:5b88d5760320 1981
kenjiArai 0:5b88d5760320 1982 for( ; len != 0; p++, len-- )
kenjiArai 0:5b88d5760320 1983 acc ^= *p;
kenjiArai 0:5b88d5760320 1984
kenjiArai 0:5b88d5760320 1985 force = acc;
kenjiArai 0:5b88d5760320 1986 (void) force;
kenjiArai 0:5b88d5760320 1987 }
kenjiArai 0:5b88d5760320 1988 #endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */
kenjiArai 0:5b88d5760320 1989
kenjiArai 0:5b88d5760320 1990 /*
kenjiArai 0:5b88d5760320 1991 * Encryption/decryption functions
kenjiArai 0:5b88d5760320 1992 */
kenjiArai 0:5b88d5760320 1993
kenjiArai 0:5b88d5760320 1994 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 1995 /* This functions transforms a DTLS plaintext fragment and a record content
kenjiArai 0:5b88d5760320 1996 * type into an instance of the DTLSInnerPlaintext structure:
kenjiArai 0:5b88d5760320 1997 *
kenjiArai 0:5b88d5760320 1998 * struct {
kenjiArai 0:5b88d5760320 1999 * opaque content[DTLSPlaintext.length];
kenjiArai 0:5b88d5760320 2000 * ContentType real_type;
kenjiArai 0:5b88d5760320 2001 * uint8 zeros[length_of_padding];
kenjiArai 0:5b88d5760320 2002 * } DTLSInnerPlaintext;
kenjiArai 0:5b88d5760320 2003 *
kenjiArai 0:5b88d5760320 2004 * Input:
kenjiArai 0:5b88d5760320 2005 * - `content`: The beginning of the buffer holding the
kenjiArai 0:5b88d5760320 2006 * plaintext to be wrapped.
kenjiArai 0:5b88d5760320 2007 * - `*content_size`: The length of the plaintext in Bytes.
kenjiArai 0:5b88d5760320 2008 * - `max_len`: The number of Bytes available starting from
kenjiArai 0:5b88d5760320 2009 * `content`. This must be `>= *content_size`.
kenjiArai 0:5b88d5760320 2010 * - `rec_type`: The desired record content type.
kenjiArai 0:5b88d5760320 2011 *
kenjiArai 0:5b88d5760320 2012 * Output:
kenjiArai 0:5b88d5760320 2013 * - `content`: The beginning of the resulting DTLSInnerPlaintext structure.
kenjiArai 0:5b88d5760320 2014 * - `*content_size`: The length of the resulting DTLSInnerPlaintext structure.
kenjiArai 0:5b88d5760320 2015 *
kenjiArai 0:5b88d5760320 2016 * Returns:
kenjiArai 0:5b88d5760320 2017 * - `0` on success.
kenjiArai 0:5b88d5760320 2018 * - A negative error code if `max_len` didn't offer enough space
kenjiArai 0:5b88d5760320 2019 * for the expansion.
kenjiArai 0:5b88d5760320 2020 */
kenjiArai 0:5b88d5760320 2021 static int ssl_cid_build_inner_plaintext( unsigned char *content,
kenjiArai 0:5b88d5760320 2022 size_t *content_size,
kenjiArai 0:5b88d5760320 2023 size_t remaining,
kenjiArai 0:5b88d5760320 2024 uint8_t rec_type )
kenjiArai 0:5b88d5760320 2025 {
kenjiArai 0:5b88d5760320 2026 size_t len = *content_size;
kenjiArai 0:5b88d5760320 2027 size_t pad = ( MBEDTLS_SSL_CID_PADDING_GRANULARITY -
kenjiArai 0:5b88d5760320 2028 ( len + 1 ) % MBEDTLS_SSL_CID_PADDING_GRANULARITY ) %
kenjiArai 0:5b88d5760320 2029 MBEDTLS_SSL_CID_PADDING_GRANULARITY;
kenjiArai 0:5b88d5760320 2030
kenjiArai 0:5b88d5760320 2031 /* Write real content type */
kenjiArai 0:5b88d5760320 2032 if( remaining == 0 )
kenjiArai 0:5b88d5760320 2033 return( -1 );
kenjiArai 0:5b88d5760320 2034 content[ len ] = rec_type;
kenjiArai 0:5b88d5760320 2035 len++;
kenjiArai 0:5b88d5760320 2036 remaining--;
kenjiArai 0:5b88d5760320 2037
kenjiArai 0:5b88d5760320 2038 if( remaining < pad )
kenjiArai 0:5b88d5760320 2039 return( -1 );
kenjiArai 0:5b88d5760320 2040 memset( content + len, 0, pad );
kenjiArai 0:5b88d5760320 2041 len += pad;
kenjiArai 0:5b88d5760320 2042 remaining -= pad;
kenjiArai 0:5b88d5760320 2043
kenjiArai 0:5b88d5760320 2044 *content_size = len;
kenjiArai 0:5b88d5760320 2045 return( 0 );
kenjiArai 0:5b88d5760320 2046 }
kenjiArai 0:5b88d5760320 2047
kenjiArai 0:5b88d5760320 2048 /* This function parses a DTLSInnerPlaintext structure.
kenjiArai 0:5b88d5760320 2049 * See ssl_cid_build_inner_plaintext() for details. */
kenjiArai 0:5b88d5760320 2050 static int ssl_cid_parse_inner_plaintext( unsigned char const *content,
kenjiArai 0:5b88d5760320 2051 size_t *content_size,
kenjiArai 0:5b88d5760320 2052 uint8_t *rec_type )
kenjiArai 0:5b88d5760320 2053 {
kenjiArai 0:5b88d5760320 2054 size_t remaining = *content_size;
kenjiArai 0:5b88d5760320 2055
kenjiArai 0:5b88d5760320 2056 /* Determine length of padding by skipping zeroes from the back. */
kenjiArai 0:5b88d5760320 2057 do
kenjiArai 0:5b88d5760320 2058 {
kenjiArai 0:5b88d5760320 2059 if( remaining == 0 )
kenjiArai 0:5b88d5760320 2060 return( -1 );
kenjiArai 0:5b88d5760320 2061 remaining--;
kenjiArai 0:5b88d5760320 2062 } while( content[ remaining ] == 0 );
kenjiArai 0:5b88d5760320 2063
kenjiArai 0:5b88d5760320 2064 *content_size = remaining;
kenjiArai 0:5b88d5760320 2065 *rec_type = content[ remaining ];
kenjiArai 0:5b88d5760320 2066
kenjiArai 0:5b88d5760320 2067 return( 0 );
kenjiArai 0:5b88d5760320 2068 }
kenjiArai 0:5b88d5760320 2069 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 2070
kenjiArai 0:5b88d5760320 2071 /* `add_data` must have size 13 Bytes if the CID extension is disabled,
kenjiArai 0:5b88d5760320 2072 * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */
kenjiArai 0:5b88d5760320 2073 static void ssl_extract_add_data_from_record( unsigned char* add_data,
kenjiArai 0:5b88d5760320 2074 size_t *add_data_len,
kenjiArai 0:5b88d5760320 2075 mbedtls_record *rec )
kenjiArai 0:5b88d5760320 2076 {
kenjiArai 0:5b88d5760320 2077 /* Quoting RFC 5246 (TLS 1.2):
kenjiArai 0:5b88d5760320 2078 *
kenjiArai 0:5b88d5760320 2079 * additional_data = seq_num + TLSCompressed.type +
kenjiArai 0:5b88d5760320 2080 * TLSCompressed.version + TLSCompressed.length;
kenjiArai 0:5b88d5760320 2081 *
kenjiArai 0:5b88d5760320 2082 * For the CID extension, this is extended as follows
kenjiArai 0:5b88d5760320 2083 * (quoting draft-ietf-tls-dtls-connection-id-05,
kenjiArai 0:5b88d5760320 2084 * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05):
kenjiArai 0:5b88d5760320 2085 *
kenjiArai 0:5b88d5760320 2086 * additional_data = seq_num + DTLSPlaintext.type +
kenjiArai 0:5b88d5760320 2087 * DTLSPlaintext.version +
kenjiArai 0:5b88d5760320 2088 * cid +
kenjiArai 0:5b88d5760320 2089 * cid_length +
kenjiArai 0:5b88d5760320 2090 * length_of_DTLSInnerPlaintext;
kenjiArai 0:5b88d5760320 2091 */
kenjiArai 0:5b88d5760320 2092
kenjiArai 0:5b88d5760320 2093 memcpy( add_data, rec->ctr, sizeof( rec->ctr ) );
kenjiArai 0:5b88d5760320 2094 add_data[8] = rec->type;
kenjiArai 0:5b88d5760320 2095 memcpy( add_data + 9, rec->ver, sizeof( rec->ver ) );
kenjiArai 0:5b88d5760320 2096
kenjiArai 0:5b88d5760320 2097 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 2098 if( rec->cid_len != 0 )
kenjiArai 0:5b88d5760320 2099 {
kenjiArai 0:5b88d5760320 2100 memcpy( add_data + 11, rec->cid, rec->cid_len );
kenjiArai 0:5b88d5760320 2101 add_data[11 + rec->cid_len + 0] = rec->cid_len;
kenjiArai 0:5b88d5760320 2102 add_data[11 + rec->cid_len + 1] = ( rec->data_len >> 8 ) & 0xFF;
kenjiArai 0:5b88d5760320 2103 add_data[11 + rec->cid_len + 2] = ( rec->data_len >> 0 ) & 0xFF;
kenjiArai 0:5b88d5760320 2104 *add_data_len = 13 + 1 + rec->cid_len;
kenjiArai 0:5b88d5760320 2105 }
kenjiArai 0:5b88d5760320 2106 else
kenjiArai 0:5b88d5760320 2107 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 2108 {
kenjiArai 0:5b88d5760320 2109 add_data[11 + 0] = ( rec->data_len >> 8 ) & 0xFF;
kenjiArai 0:5b88d5760320 2110 add_data[11 + 1] = ( rec->data_len >> 0 ) & 0xFF;
kenjiArai 0:5b88d5760320 2111 *add_data_len = 13;
kenjiArai 0:5b88d5760320 2112 }
kenjiArai 0:5b88d5760320 2113 }
kenjiArai 0:5b88d5760320 2114
kenjiArai 0:5b88d5760320 2115 int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 2116 mbedtls_ssl_transform *transform,
kenjiArai 0:5b88d5760320 2117 mbedtls_record *rec,
kenjiArai 0:5b88d5760320 2118 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 2119 void *p_rng )
kenjiArai 0:5b88d5760320 2120 {
kenjiArai 0:5b88d5760320 2121 mbedtls_cipher_mode_t mode;
kenjiArai 0:5b88d5760320 2122 int auth_done = 0;
kenjiArai 0:5b88d5760320 2123 unsigned char * data;
kenjiArai 0:5b88d5760320 2124 unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ];
kenjiArai 0:5b88d5760320 2125 size_t add_data_len;
kenjiArai 0:5b88d5760320 2126 size_t post_avail;
kenjiArai 0:5b88d5760320 2127
kenjiArai 0:5b88d5760320 2128 /* The SSL context is only used for debugging purposes! */
kenjiArai 0:5b88d5760320 2129 #if !defined(MBEDTLS_DEBUG_C)
kenjiArai 0:5b88d5760320 2130 ((void) ssl);
kenjiArai 0:5b88d5760320 2131 #endif
kenjiArai 0:5b88d5760320 2132
kenjiArai 0:5b88d5760320 2133 /* The PRNG is used for dynamic IV generation that's used
kenjiArai 0:5b88d5760320 2134 * for CBC transformations in TLS 1.1 and TLS 1.2. */
kenjiArai 0:5b88d5760320 2135 #if !( defined(MBEDTLS_CIPHER_MODE_CBC) && \
kenjiArai 0:5b88d5760320 2136 ( defined(MBEDTLS_AES_C) || \
kenjiArai 0:5b88d5760320 2137 defined(MBEDTLS_ARIA_C) || \
kenjiArai 0:5b88d5760320 2138 defined(MBEDTLS_CAMELLIA_C) ) && \
kenjiArai 0:5b88d5760320 2139 ( defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) ) )
kenjiArai 0:5b88d5760320 2140 ((void) f_rng);
kenjiArai 0:5b88d5760320 2141 ((void) p_rng);
kenjiArai 0:5b88d5760320 2142 #endif
kenjiArai 0:5b88d5760320 2143
kenjiArai 0:5b88d5760320 2144 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
kenjiArai 0:5b88d5760320 2145
kenjiArai 0:5b88d5760320 2146 if( transform == NULL )
kenjiArai 0:5b88d5760320 2147 {
kenjiArai 0:5b88d5760320 2148 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) );
kenjiArai 0:5b88d5760320 2149 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2150 }
kenjiArai 0:5b88d5760320 2151 if( rec == NULL
kenjiArai 0:5b88d5760320 2152 || rec->buf == NULL
kenjiArai 0:5b88d5760320 2153 || rec->buf_len < rec->data_offset
kenjiArai 0:5b88d5760320 2154 || rec->buf_len - rec->data_offset < rec->data_len
kenjiArai 0:5b88d5760320 2155 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 2156 || rec->cid_len != 0
kenjiArai 0:5b88d5760320 2157 #endif
kenjiArai 0:5b88d5760320 2158 )
kenjiArai 0:5b88d5760320 2159 {
kenjiArai 0:5b88d5760320 2160 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) );
kenjiArai 0:5b88d5760320 2161 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2162 }
kenjiArai 0:5b88d5760320 2163
kenjiArai 0:5b88d5760320 2164 data = rec->buf + rec->data_offset;
kenjiArai 0:5b88d5760320 2165 post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
kenjiArai 0:5b88d5760320 2166 MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
kenjiArai 0:5b88d5760320 2167 data, rec->data_len );
kenjiArai 0:5b88d5760320 2168
kenjiArai 0:5b88d5760320 2169 mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc );
kenjiArai 0:5b88d5760320 2170
kenjiArai 0:5b88d5760320 2171 if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
kenjiArai 0:5b88d5760320 2172 {
kenjiArai 0:5b88d5760320 2173 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %u too large, maximum %d",
kenjiArai 0:5b88d5760320 2174 (unsigned) rec->data_len,
kenjiArai 0:5b88d5760320 2175 MBEDTLS_SSL_OUT_CONTENT_LEN ) );
kenjiArai 0:5b88d5760320 2176 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 2177 }
kenjiArai 0:5b88d5760320 2178
kenjiArai 0:5b88d5760320 2179 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 2180 /*
kenjiArai 0:5b88d5760320 2181 * Add CID information
kenjiArai 0:5b88d5760320 2182 */
kenjiArai 0:5b88d5760320 2183 rec->cid_len = transform->out_cid_len;
kenjiArai 0:5b88d5760320 2184 memcpy( rec->cid, transform->out_cid, transform->out_cid_len );
kenjiArai 0:5b88d5760320 2185 MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len );
kenjiArai 0:5b88d5760320 2186
kenjiArai 0:5b88d5760320 2187 if( rec->cid_len != 0 )
kenjiArai 0:5b88d5760320 2188 {
kenjiArai 0:5b88d5760320 2189 /*
kenjiArai 0:5b88d5760320 2190 * Wrap plaintext into DTLSInnerPlaintext structure.
kenjiArai 0:5b88d5760320 2191 * See ssl_cid_build_inner_plaintext() for more information.
kenjiArai 0:5b88d5760320 2192 *
kenjiArai 0:5b88d5760320 2193 * Note that this changes `rec->data_len`, and hence
kenjiArai 0:5b88d5760320 2194 * `post_avail` needs to be recalculated afterwards.
kenjiArai 0:5b88d5760320 2195 */
kenjiArai 0:5b88d5760320 2196 if( ssl_cid_build_inner_plaintext( data,
kenjiArai 0:5b88d5760320 2197 &rec->data_len,
kenjiArai 0:5b88d5760320 2198 post_avail,
kenjiArai 0:5b88d5760320 2199 rec->type ) != 0 )
kenjiArai 0:5b88d5760320 2200 {
kenjiArai 0:5b88d5760320 2201 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
kenjiArai 0:5b88d5760320 2202 }
kenjiArai 0:5b88d5760320 2203
kenjiArai 0:5b88d5760320 2204 rec->type = MBEDTLS_SSL_MSG_CID;
kenjiArai 0:5b88d5760320 2205 }
kenjiArai 0:5b88d5760320 2206 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 2207
kenjiArai 0:5b88d5760320 2208 post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
kenjiArai 0:5b88d5760320 2209
kenjiArai 0:5b88d5760320 2210 /*
kenjiArai 0:5b88d5760320 2211 * Add MAC before if needed
kenjiArai 0:5b88d5760320 2212 */
kenjiArai 0:5b88d5760320 2213 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
kenjiArai 0:5b88d5760320 2214 if( mode == MBEDTLS_MODE_STREAM ||
kenjiArai 0:5b88d5760320 2215 ( mode == MBEDTLS_MODE_CBC
kenjiArai 0:5b88d5760320 2216 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
kenjiArai 0:5b88d5760320 2217 && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
kenjiArai 0:5b88d5760320 2218 #endif
kenjiArai 0:5b88d5760320 2219 ) )
kenjiArai 0:5b88d5760320 2220 {
kenjiArai 0:5b88d5760320 2221 if( post_avail < transform->maclen )
kenjiArai 0:5b88d5760320 2222 {
kenjiArai 0:5b88d5760320 2223 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
kenjiArai 0:5b88d5760320 2224 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
kenjiArai 0:5b88d5760320 2225 }
kenjiArai 0:5b88d5760320 2226
kenjiArai 0:5b88d5760320 2227 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 2228 if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 2229 {
kenjiArai 0:5b88d5760320 2230 unsigned char mac[SSL_MAC_MAX_BYTES];
kenjiArai 0:5b88d5760320 2231 ssl_mac( &transform->md_ctx_enc, transform->mac_enc,
kenjiArai 0:5b88d5760320 2232 data, rec->data_len, rec->ctr, rec->type, mac );
kenjiArai 0:5b88d5760320 2233 memcpy( data + rec->data_len, mac, transform->maclen );
kenjiArai 0:5b88d5760320 2234 }
kenjiArai 0:5b88d5760320 2235 else
kenjiArai 0:5b88d5760320 2236 #endif
kenjiArai 0:5b88d5760320 2237 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 2238 defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 2239 if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
kenjiArai 0:5b88d5760320 2240 {
kenjiArai 0:5b88d5760320 2241 unsigned char mac[MBEDTLS_SSL_MAC_ADD];
kenjiArai 0:5b88d5760320 2242
kenjiArai 0:5b88d5760320 2243 ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
kenjiArai 0:5b88d5760320 2244
kenjiArai 0:5b88d5760320 2245 mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
kenjiArai 0:5b88d5760320 2246 add_data_len );
kenjiArai 0:5b88d5760320 2247 mbedtls_md_hmac_update( &transform->md_ctx_enc,
kenjiArai 0:5b88d5760320 2248 data, rec->data_len );
kenjiArai 0:5b88d5760320 2249 mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
kenjiArai 0:5b88d5760320 2250 mbedtls_md_hmac_reset( &transform->md_ctx_enc );
kenjiArai 0:5b88d5760320 2251
kenjiArai 0:5b88d5760320 2252 memcpy( data + rec->data_len, mac, transform->maclen );
kenjiArai 0:5b88d5760320 2253 }
kenjiArai 0:5b88d5760320 2254 else
kenjiArai 0:5b88d5760320 2255 #endif
kenjiArai 0:5b88d5760320 2256 {
kenjiArai 0:5b88d5760320 2257 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2258 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2259 }
kenjiArai 0:5b88d5760320 2260
kenjiArai 0:5b88d5760320 2261 MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len,
kenjiArai 0:5b88d5760320 2262 transform->maclen );
kenjiArai 0:5b88d5760320 2263
kenjiArai 0:5b88d5760320 2264 rec->data_len += transform->maclen;
kenjiArai 0:5b88d5760320 2265 post_avail -= transform->maclen;
kenjiArai 0:5b88d5760320 2266 auth_done++;
kenjiArai 0:5b88d5760320 2267 }
kenjiArai 0:5b88d5760320 2268 #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
kenjiArai 0:5b88d5760320 2269
kenjiArai 0:5b88d5760320 2270 /*
kenjiArai 0:5b88d5760320 2271 * Encrypt
kenjiArai 0:5b88d5760320 2272 */
kenjiArai 0:5b88d5760320 2273 #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
kenjiArai 0:5b88d5760320 2274 if( mode == MBEDTLS_MODE_STREAM )
kenjiArai 0:5b88d5760320 2275 {
kenjiArai 0:5b88d5760320 2276 int ret;
kenjiArai 0:5b88d5760320 2277 size_t olen;
kenjiArai 0:5b88d5760320 2278 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
kenjiArai 0:5b88d5760320 2279 "including %d bytes of padding",
kenjiArai 0:5b88d5760320 2280 rec->data_len, 0 ) );
kenjiArai 0:5b88d5760320 2281
kenjiArai 0:5b88d5760320 2282 if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
kenjiArai 0:5b88d5760320 2283 transform->iv_enc, transform->ivlen,
kenjiArai 0:5b88d5760320 2284 data, rec->data_len,
kenjiArai 0:5b88d5760320 2285 data, &olen ) ) != 0 )
kenjiArai 0:5b88d5760320 2286 {
kenjiArai 0:5b88d5760320 2287 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
kenjiArai 0:5b88d5760320 2288 return( ret );
kenjiArai 0:5b88d5760320 2289 }
kenjiArai 0:5b88d5760320 2290
kenjiArai 0:5b88d5760320 2291 if( rec->data_len != olen )
kenjiArai 0:5b88d5760320 2292 {
kenjiArai 0:5b88d5760320 2293 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2294 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2295 }
kenjiArai 0:5b88d5760320 2296 }
kenjiArai 0:5b88d5760320 2297 else
kenjiArai 0:5b88d5760320 2298 #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
kenjiArai 0:5b88d5760320 2299
kenjiArai 0:5b88d5760320 2300 #if defined(MBEDTLS_GCM_C) || \
kenjiArai 0:5b88d5760320 2301 defined(MBEDTLS_CCM_C) || \
kenjiArai 0:5b88d5760320 2302 defined(MBEDTLS_CHACHAPOLY_C)
kenjiArai 0:5b88d5760320 2303 if( mode == MBEDTLS_MODE_GCM ||
kenjiArai 0:5b88d5760320 2304 mode == MBEDTLS_MODE_CCM ||
kenjiArai 0:5b88d5760320 2305 mode == MBEDTLS_MODE_CHACHAPOLY )
kenjiArai 0:5b88d5760320 2306 {
kenjiArai 0:5b88d5760320 2307 int ret;
kenjiArai 0:5b88d5760320 2308 unsigned char iv[12];
kenjiArai 0:5b88d5760320 2309 size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen;
kenjiArai 0:5b88d5760320 2310
kenjiArai 0:5b88d5760320 2311 /* Check that there's space for both the authentication tag
kenjiArai 0:5b88d5760320 2312 * and the explicit IV before and after the record content. */
kenjiArai 0:5b88d5760320 2313 if( post_avail < transform->taglen ||
kenjiArai 0:5b88d5760320 2314 rec->data_offset < explicit_iv_len )
kenjiArai 0:5b88d5760320 2315 {
kenjiArai 0:5b88d5760320 2316 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
kenjiArai 0:5b88d5760320 2317 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
kenjiArai 0:5b88d5760320 2318 }
kenjiArai 0:5b88d5760320 2319
kenjiArai 0:5b88d5760320 2320 /*
kenjiArai 0:5b88d5760320 2321 * Generate IV
kenjiArai 0:5b88d5760320 2322 */
kenjiArai 0:5b88d5760320 2323 if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
kenjiArai 0:5b88d5760320 2324 {
kenjiArai 0:5b88d5760320 2325 /* GCM and CCM: fixed || explicit (=seqnum) */
kenjiArai 0:5b88d5760320 2326 memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
kenjiArai 0:5b88d5760320 2327 memcpy( iv + transform->fixed_ivlen, rec->ctr,
kenjiArai 0:5b88d5760320 2328 explicit_iv_len );
kenjiArai 0:5b88d5760320 2329 /* Prefix record content with explicit IV. */
kenjiArai 0:5b88d5760320 2330 memcpy( data - explicit_iv_len, rec->ctr, explicit_iv_len );
kenjiArai 0:5b88d5760320 2331 }
kenjiArai 0:5b88d5760320 2332 else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
kenjiArai 0:5b88d5760320 2333 {
kenjiArai 0:5b88d5760320 2334 /* ChachaPoly: fixed XOR sequence number */
kenjiArai 0:5b88d5760320 2335 unsigned char i;
kenjiArai 0:5b88d5760320 2336
kenjiArai 0:5b88d5760320 2337 memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
kenjiArai 0:5b88d5760320 2338
kenjiArai 0:5b88d5760320 2339 for( i = 0; i < 8; i++ )
kenjiArai 0:5b88d5760320 2340 iv[i+4] ^= rec->ctr[i];
kenjiArai 0:5b88d5760320 2341 }
kenjiArai 0:5b88d5760320 2342 else
kenjiArai 0:5b88d5760320 2343 {
kenjiArai 0:5b88d5760320 2344 /* Reminder if we ever add an AEAD mode with a different size */
kenjiArai 0:5b88d5760320 2345 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2346 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2347 }
kenjiArai 0:5b88d5760320 2348
kenjiArai 0:5b88d5760320 2349 ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
kenjiArai 0:5b88d5760320 2350
kenjiArai 0:5b88d5760320 2351 MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
kenjiArai 0:5b88d5760320 2352 iv, transform->ivlen );
kenjiArai 0:5b88d5760320 2353 MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)",
kenjiArai 0:5b88d5760320 2354 data - explicit_iv_len, explicit_iv_len );
kenjiArai 0:5b88d5760320 2355 MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
kenjiArai 0:5b88d5760320 2356 add_data, add_data_len );
kenjiArai 0:5b88d5760320 2357 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
kenjiArai 0:5b88d5760320 2358 "including 0 bytes of padding",
kenjiArai 0:5b88d5760320 2359 rec->data_len ) );
kenjiArai 0:5b88d5760320 2360
kenjiArai 0:5b88d5760320 2361 /*
kenjiArai 0:5b88d5760320 2362 * Encrypt and authenticate
kenjiArai 0:5b88d5760320 2363 */
kenjiArai 0:5b88d5760320 2364
kenjiArai 0:5b88d5760320 2365 if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc,
kenjiArai 0:5b88d5760320 2366 iv, transform->ivlen,
kenjiArai 0:5b88d5760320 2367 add_data, add_data_len, /* add data */
kenjiArai 0:5b88d5760320 2368 data, rec->data_len, /* source */
kenjiArai 0:5b88d5760320 2369 data, &rec->data_len, /* destination */
kenjiArai 0:5b88d5760320 2370 data + rec->data_len, transform->taglen ) ) != 0 )
kenjiArai 0:5b88d5760320 2371 {
kenjiArai 0:5b88d5760320 2372 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
kenjiArai 0:5b88d5760320 2373 return( ret );
kenjiArai 0:5b88d5760320 2374 }
kenjiArai 0:5b88d5760320 2375
kenjiArai 0:5b88d5760320 2376 MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag",
kenjiArai 0:5b88d5760320 2377 data + rec->data_len, transform->taglen );
kenjiArai 0:5b88d5760320 2378
kenjiArai 0:5b88d5760320 2379 rec->data_len += transform->taglen + explicit_iv_len;
kenjiArai 0:5b88d5760320 2380 rec->data_offset -= explicit_iv_len;
kenjiArai 0:5b88d5760320 2381 post_avail -= transform->taglen;
kenjiArai 0:5b88d5760320 2382 auth_done++;
kenjiArai 0:5b88d5760320 2383 }
kenjiArai 0:5b88d5760320 2384 else
kenjiArai 0:5b88d5760320 2385 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
kenjiArai 0:5b88d5760320 2386 #if defined(MBEDTLS_CIPHER_MODE_CBC) && \
kenjiArai 0:5b88d5760320 2387 ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
kenjiArai 0:5b88d5760320 2388 if( mode == MBEDTLS_MODE_CBC )
kenjiArai 0:5b88d5760320 2389 {
kenjiArai 0:5b88d5760320 2390 int ret;
kenjiArai 0:5b88d5760320 2391 size_t padlen, i;
kenjiArai 0:5b88d5760320 2392 size_t olen;
kenjiArai 0:5b88d5760320 2393
kenjiArai 0:5b88d5760320 2394 /* Currently we're always using minimal padding
kenjiArai 0:5b88d5760320 2395 * (up to 255 bytes would be allowed). */
kenjiArai 0:5b88d5760320 2396 padlen = transform->ivlen - ( rec->data_len + 1 ) % transform->ivlen;
kenjiArai 0:5b88d5760320 2397 if( padlen == transform->ivlen )
kenjiArai 0:5b88d5760320 2398 padlen = 0;
kenjiArai 0:5b88d5760320 2399
kenjiArai 0:5b88d5760320 2400 /* Check there's enough space in the buffer for the padding. */
kenjiArai 0:5b88d5760320 2401 if( post_avail < padlen + 1 )
kenjiArai 0:5b88d5760320 2402 {
kenjiArai 0:5b88d5760320 2403 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
kenjiArai 0:5b88d5760320 2404 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
kenjiArai 0:5b88d5760320 2405 }
kenjiArai 0:5b88d5760320 2406
kenjiArai 0:5b88d5760320 2407 for( i = 0; i <= padlen; i++ )
kenjiArai 0:5b88d5760320 2408 data[rec->data_len + i] = (unsigned char) padlen;
kenjiArai 0:5b88d5760320 2409
kenjiArai 0:5b88d5760320 2410 rec->data_len += padlen + 1;
kenjiArai 0:5b88d5760320 2411 post_avail -= padlen + 1;
kenjiArai 0:5b88d5760320 2412
kenjiArai 0:5b88d5760320 2413 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 2414 /*
kenjiArai 0:5b88d5760320 2415 * Prepend per-record IV for block cipher in TLS v1.1 and up as per
kenjiArai 0:5b88d5760320 2416 * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
kenjiArai 0:5b88d5760320 2417 */
kenjiArai 0:5b88d5760320 2418 if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
kenjiArai 0:5b88d5760320 2419 {
kenjiArai 0:5b88d5760320 2420 if( f_rng == NULL )
kenjiArai 0:5b88d5760320 2421 {
kenjiArai 0:5b88d5760320 2422 MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) );
kenjiArai 0:5b88d5760320 2423 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2424 }
kenjiArai 0:5b88d5760320 2425
kenjiArai 0:5b88d5760320 2426 if( rec->data_offset < transform->ivlen )
kenjiArai 0:5b88d5760320 2427 {
kenjiArai 0:5b88d5760320 2428 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
kenjiArai 0:5b88d5760320 2429 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
kenjiArai 0:5b88d5760320 2430 }
kenjiArai 0:5b88d5760320 2431
kenjiArai 0:5b88d5760320 2432 /*
kenjiArai 0:5b88d5760320 2433 * Generate IV
kenjiArai 0:5b88d5760320 2434 */
kenjiArai 0:5b88d5760320 2435 ret = f_rng( p_rng, transform->iv_enc, transform->ivlen );
kenjiArai 0:5b88d5760320 2436 if( ret != 0 )
kenjiArai 0:5b88d5760320 2437 return( ret );
kenjiArai 0:5b88d5760320 2438
kenjiArai 0:5b88d5760320 2439 memcpy( data - transform->ivlen, transform->iv_enc,
kenjiArai 0:5b88d5760320 2440 transform->ivlen );
kenjiArai 0:5b88d5760320 2441
kenjiArai 0:5b88d5760320 2442 }
kenjiArai 0:5b88d5760320 2443 #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 2444
kenjiArai 0:5b88d5760320 2445 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
kenjiArai 0:5b88d5760320 2446 "including %d bytes of IV and %d bytes of padding",
kenjiArai 0:5b88d5760320 2447 rec->data_len, transform->ivlen,
kenjiArai 0:5b88d5760320 2448 padlen + 1 ) );
kenjiArai 0:5b88d5760320 2449
kenjiArai 0:5b88d5760320 2450 if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
kenjiArai 0:5b88d5760320 2451 transform->iv_enc,
kenjiArai 0:5b88d5760320 2452 transform->ivlen,
kenjiArai 0:5b88d5760320 2453 data, rec->data_len,
kenjiArai 0:5b88d5760320 2454 data, &olen ) ) != 0 )
kenjiArai 0:5b88d5760320 2455 {
kenjiArai 0:5b88d5760320 2456 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
kenjiArai 0:5b88d5760320 2457 return( ret );
kenjiArai 0:5b88d5760320 2458 }
kenjiArai 0:5b88d5760320 2459
kenjiArai 0:5b88d5760320 2460 if( rec->data_len != olen )
kenjiArai 0:5b88d5760320 2461 {
kenjiArai 0:5b88d5760320 2462 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2463 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2464 }
kenjiArai 0:5b88d5760320 2465
kenjiArai 0:5b88d5760320 2466 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
kenjiArai 0:5b88d5760320 2467 if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
kenjiArai 0:5b88d5760320 2468 {
kenjiArai 0:5b88d5760320 2469 /*
kenjiArai 0:5b88d5760320 2470 * Save IV in SSL3 and TLS1
kenjiArai 0:5b88d5760320 2471 */
kenjiArai 0:5b88d5760320 2472 memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv,
kenjiArai 0:5b88d5760320 2473 transform->ivlen );
kenjiArai 0:5b88d5760320 2474 }
kenjiArai 0:5b88d5760320 2475 else
kenjiArai 0:5b88d5760320 2476 #endif
kenjiArai 0:5b88d5760320 2477 {
kenjiArai 0:5b88d5760320 2478 data -= transform->ivlen;
kenjiArai 0:5b88d5760320 2479 rec->data_offset -= transform->ivlen;
kenjiArai 0:5b88d5760320 2480 rec->data_len += transform->ivlen;
kenjiArai 0:5b88d5760320 2481 }
kenjiArai 0:5b88d5760320 2482
kenjiArai 0:5b88d5760320 2483 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
kenjiArai 0:5b88d5760320 2484 if( auth_done == 0 )
kenjiArai 0:5b88d5760320 2485 {
kenjiArai 0:5b88d5760320 2486 unsigned char mac[MBEDTLS_SSL_MAC_ADD];
kenjiArai 0:5b88d5760320 2487
kenjiArai 0:5b88d5760320 2488 /*
kenjiArai 0:5b88d5760320 2489 * MAC(MAC_write_key, seq_num +
kenjiArai 0:5b88d5760320 2490 * TLSCipherText.type +
kenjiArai 0:5b88d5760320 2491 * TLSCipherText.version +
kenjiArai 0:5b88d5760320 2492 * length_of( (IV +) ENC(...) ) +
kenjiArai 0:5b88d5760320 2493 * IV + // except for TLS 1.0
kenjiArai 0:5b88d5760320 2494 * ENC(content + padding + padding_length));
kenjiArai 0:5b88d5760320 2495 */
kenjiArai 0:5b88d5760320 2496
kenjiArai 0:5b88d5760320 2497 if( post_avail < transform->maclen)
kenjiArai 0:5b88d5760320 2498 {
kenjiArai 0:5b88d5760320 2499 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
kenjiArai 0:5b88d5760320 2500 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
kenjiArai 0:5b88d5760320 2501 }
kenjiArai 0:5b88d5760320 2502
kenjiArai 0:5b88d5760320 2503 ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
kenjiArai 0:5b88d5760320 2504
kenjiArai 0:5b88d5760320 2505 MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
kenjiArai 0:5b88d5760320 2506 MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
kenjiArai 0:5b88d5760320 2507 add_data_len );
kenjiArai 0:5b88d5760320 2508
kenjiArai 0:5b88d5760320 2509 mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
kenjiArai 0:5b88d5760320 2510 add_data_len );
kenjiArai 0:5b88d5760320 2511 mbedtls_md_hmac_update( &transform->md_ctx_enc,
kenjiArai 0:5b88d5760320 2512 data, rec->data_len );
kenjiArai 0:5b88d5760320 2513 mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
kenjiArai 0:5b88d5760320 2514 mbedtls_md_hmac_reset( &transform->md_ctx_enc );
kenjiArai 0:5b88d5760320 2515
kenjiArai 0:5b88d5760320 2516 memcpy( data + rec->data_len, mac, transform->maclen );
kenjiArai 0:5b88d5760320 2517
kenjiArai 0:5b88d5760320 2518 rec->data_len += transform->maclen;
kenjiArai 0:5b88d5760320 2519 post_avail -= transform->maclen;
kenjiArai 0:5b88d5760320 2520 auth_done++;
kenjiArai 0:5b88d5760320 2521 }
kenjiArai 0:5b88d5760320 2522 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
kenjiArai 0:5b88d5760320 2523 }
kenjiArai 0:5b88d5760320 2524 else
kenjiArai 0:5b88d5760320 2525 #endif /* MBEDTLS_CIPHER_MODE_CBC &&
kenjiArai 0:5b88d5760320 2526 ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
kenjiArai 0:5b88d5760320 2527 {
kenjiArai 0:5b88d5760320 2528 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2529 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2530 }
kenjiArai 0:5b88d5760320 2531
kenjiArai 0:5b88d5760320 2532 /* Make extra sure authentication was performed, exactly once */
kenjiArai 0:5b88d5760320 2533 if( auth_done != 1 )
kenjiArai 0:5b88d5760320 2534 {
kenjiArai 0:5b88d5760320 2535 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2536 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2537 }
kenjiArai 0:5b88d5760320 2538
kenjiArai 0:5b88d5760320 2539 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
kenjiArai 0:5b88d5760320 2540
kenjiArai 0:5b88d5760320 2541 return( 0 );
kenjiArai 0:5b88d5760320 2542 }
kenjiArai 0:5b88d5760320 2543
kenjiArai 0:5b88d5760320 2544 int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 2545 mbedtls_ssl_transform *transform,
kenjiArai 0:5b88d5760320 2546 mbedtls_record *rec )
kenjiArai 0:5b88d5760320 2547 {
kenjiArai 0:5b88d5760320 2548 size_t olen;
kenjiArai 0:5b88d5760320 2549 mbedtls_cipher_mode_t mode;
kenjiArai 0:5b88d5760320 2550 int ret, auth_done = 0;
kenjiArai 0:5b88d5760320 2551 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
kenjiArai 0:5b88d5760320 2552 size_t padlen = 0, correct = 1;
kenjiArai 0:5b88d5760320 2553 #endif
kenjiArai 0:5b88d5760320 2554 unsigned char* data;
kenjiArai 0:5b88d5760320 2555 unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ];
kenjiArai 0:5b88d5760320 2556 size_t add_data_len;
kenjiArai 0:5b88d5760320 2557
kenjiArai 0:5b88d5760320 2558 #if !defined(MBEDTLS_DEBUG_C)
kenjiArai 0:5b88d5760320 2559 ((void) ssl);
kenjiArai 0:5b88d5760320 2560 #endif
kenjiArai 0:5b88d5760320 2561
kenjiArai 0:5b88d5760320 2562 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
kenjiArai 0:5b88d5760320 2563 if( transform == NULL )
kenjiArai 0:5b88d5760320 2564 {
kenjiArai 0:5b88d5760320 2565 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to decrypt_buf" ) );
kenjiArai 0:5b88d5760320 2566 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2567 }
kenjiArai 0:5b88d5760320 2568 if( rec == NULL ||
kenjiArai 0:5b88d5760320 2569 rec->buf == NULL ||
kenjiArai 0:5b88d5760320 2570 rec->buf_len < rec->data_offset ||
kenjiArai 0:5b88d5760320 2571 rec->buf_len - rec->data_offset < rec->data_len )
kenjiArai 0:5b88d5760320 2572 {
kenjiArai 0:5b88d5760320 2573 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to decrypt_buf" ) );
kenjiArai 0:5b88d5760320 2574 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2575 }
kenjiArai 0:5b88d5760320 2576
kenjiArai 0:5b88d5760320 2577 data = rec->buf + rec->data_offset;
kenjiArai 0:5b88d5760320 2578 mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec );
kenjiArai 0:5b88d5760320 2579
kenjiArai 0:5b88d5760320 2580 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 2581 /*
kenjiArai 0:5b88d5760320 2582 * Match record's CID with incoming CID.
kenjiArai 0:5b88d5760320 2583 */
kenjiArai 0:5b88d5760320 2584 if( rec->cid_len != transform->in_cid_len ||
kenjiArai 0:5b88d5760320 2585 memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 )
kenjiArai 0:5b88d5760320 2586 {
kenjiArai 0:5b88d5760320 2587 return( MBEDTLS_ERR_SSL_UNEXPECTED_CID );
kenjiArai 0:5b88d5760320 2588 }
kenjiArai 0:5b88d5760320 2589 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 2590
kenjiArai 0:5b88d5760320 2591 #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
kenjiArai 0:5b88d5760320 2592 if( mode == MBEDTLS_MODE_STREAM )
kenjiArai 0:5b88d5760320 2593 {
kenjiArai 0:5b88d5760320 2594 padlen = 0;
kenjiArai 0:5b88d5760320 2595 if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
kenjiArai 0:5b88d5760320 2596 transform->iv_dec,
kenjiArai 0:5b88d5760320 2597 transform->ivlen,
kenjiArai 0:5b88d5760320 2598 data, rec->data_len,
kenjiArai 0:5b88d5760320 2599 data, &olen ) ) != 0 )
kenjiArai 0:5b88d5760320 2600 {
kenjiArai 0:5b88d5760320 2601 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
kenjiArai 0:5b88d5760320 2602 return( ret );
kenjiArai 0:5b88d5760320 2603 }
kenjiArai 0:5b88d5760320 2604
kenjiArai 0:5b88d5760320 2605 if( rec->data_len != olen )
kenjiArai 0:5b88d5760320 2606 {
kenjiArai 0:5b88d5760320 2607 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2608 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2609 }
kenjiArai 0:5b88d5760320 2610 }
kenjiArai 0:5b88d5760320 2611 else
kenjiArai 0:5b88d5760320 2612 #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
kenjiArai 0:5b88d5760320 2613 #if defined(MBEDTLS_GCM_C) || \
kenjiArai 0:5b88d5760320 2614 defined(MBEDTLS_CCM_C) || \
kenjiArai 0:5b88d5760320 2615 defined(MBEDTLS_CHACHAPOLY_C)
kenjiArai 0:5b88d5760320 2616 if( mode == MBEDTLS_MODE_GCM ||
kenjiArai 0:5b88d5760320 2617 mode == MBEDTLS_MODE_CCM ||
kenjiArai 0:5b88d5760320 2618 mode == MBEDTLS_MODE_CHACHAPOLY )
kenjiArai 0:5b88d5760320 2619 {
kenjiArai 0:5b88d5760320 2620 unsigned char iv[12];
kenjiArai 0:5b88d5760320 2621 size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen;
kenjiArai 0:5b88d5760320 2622
kenjiArai 0:5b88d5760320 2623 /*
kenjiArai 0:5b88d5760320 2624 * Compute and update sizes
kenjiArai 0:5b88d5760320 2625 */
kenjiArai 0:5b88d5760320 2626 if( rec->data_len < explicit_iv_len + transform->taglen )
kenjiArai 0:5b88d5760320 2627 {
kenjiArai 0:5b88d5760320 2628 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) "
kenjiArai 0:5b88d5760320 2629 "+ taglen (%d)", rec->data_len,
kenjiArai 0:5b88d5760320 2630 explicit_iv_len, transform->taglen ) );
kenjiArai 0:5b88d5760320 2631 return( MBEDTLS_ERR_SSL_INVALID_MAC );
kenjiArai 0:5b88d5760320 2632 }
kenjiArai 0:5b88d5760320 2633
kenjiArai 0:5b88d5760320 2634 /*
kenjiArai 0:5b88d5760320 2635 * Prepare IV
kenjiArai 0:5b88d5760320 2636 */
kenjiArai 0:5b88d5760320 2637 if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
kenjiArai 0:5b88d5760320 2638 {
kenjiArai 0:5b88d5760320 2639 /* GCM and CCM: fixed || explicit (transmitted) */
kenjiArai 0:5b88d5760320 2640 memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
kenjiArai 0:5b88d5760320 2641 memcpy( iv + transform->fixed_ivlen, data, 8 );
kenjiArai 0:5b88d5760320 2642
kenjiArai 0:5b88d5760320 2643 }
kenjiArai 0:5b88d5760320 2644 else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
kenjiArai 0:5b88d5760320 2645 {
kenjiArai 0:5b88d5760320 2646 /* ChachaPoly: fixed XOR sequence number */
kenjiArai 0:5b88d5760320 2647 unsigned char i;
kenjiArai 0:5b88d5760320 2648
kenjiArai 0:5b88d5760320 2649 memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
kenjiArai 0:5b88d5760320 2650
kenjiArai 0:5b88d5760320 2651 for( i = 0; i < 8; i++ )
kenjiArai 0:5b88d5760320 2652 iv[i+4] ^= rec->ctr[i];
kenjiArai 0:5b88d5760320 2653 }
kenjiArai 0:5b88d5760320 2654 else
kenjiArai 0:5b88d5760320 2655 {
kenjiArai 0:5b88d5760320 2656 /* Reminder if we ever add an AEAD mode with a different size */
kenjiArai 0:5b88d5760320 2657 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2658 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2659 }
kenjiArai 0:5b88d5760320 2660
kenjiArai 0:5b88d5760320 2661 data += explicit_iv_len;
kenjiArai 0:5b88d5760320 2662 rec->data_offset += explicit_iv_len;
kenjiArai 0:5b88d5760320 2663 rec->data_len -= explicit_iv_len + transform->taglen;
kenjiArai 0:5b88d5760320 2664
kenjiArai 0:5b88d5760320 2665 ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
kenjiArai 0:5b88d5760320 2666 MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
kenjiArai 0:5b88d5760320 2667 add_data, add_data_len );
kenjiArai 0:5b88d5760320 2668
kenjiArai 0:5b88d5760320 2669 memcpy( transform->iv_dec + transform->fixed_ivlen,
kenjiArai 0:5b88d5760320 2670 data - explicit_iv_len, explicit_iv_len );
kenjiArai 0:5b88d5760320 2671
kenjiArai 0:5b88d5760320 2672 MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
kenjiArai 0:5b88d5760320 2673 MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", data + rec->data_len,
kenjiArai 0:5b88d5760320 2674 transform->taglen );
kenjiArai 0:5b88d5760320 2675
kenjiArai 0:5b88d5760320 2676
kenjiArai 0:5b88d5760320 2677 /*
kenjiArai 0:5b88d5760320 2678 * Decrypt and authenticate
kenjiArai 0:5b88d5760320 2679 */
kenjiArai 0:5b88d5760320 2680 if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx_dec,
kenjiArai 0:5b88d5760320 2681 iv, transform->ivlen,
kenjiArai 0:5b88d5760320 2682 add_data, add_data_len,
kenjiArai 0:5b88d5760320 2683 data, rec->data_len,
kenjiArai 0:5b88d5760320 2684 data, &olen,
kenjiArai 0:5b88d5760320 2685 data + rec->data_len,
kenjiArai 0:5b88d5760320 2686 transform->taglen ) ) != 0 )
kenjiArai 0:5b88d5760320 2687 {
kenjiArai 0:5b88d5760320 2688 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
kenjiArai 0:5b88d5760320 2689
kenjiArai 0:5b88d5760320 2690 if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
kenjiArai 0:5b88d5760320 2691 return( MBEDTLS_ERR_SSL_INVALID_MAC );
kenjiArai 0:5b88d5760320 2692
kenjiArai 0:5b88d5760320 2693 return( ret );
kenjiArai 0:5b88d5760320 2694 }
kenjiArai 0:5b88d5760320 2695 auth_done++;
kenjiArai 0:5b88d5760320 2696
kenjiArai 0:5b88d5760320 2697 if( olen != rec->data_len )
kenjiArai 0:5b88d5760320 2698 {
kenjiArai 0:5b88d5760320 2699 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2700 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2701 }
kenjiArai 0:5b88d5760320 2702 }
kenjiArai 0:5b88d5760320 2703 else
kenjiArai 0:5b88d5760320 2704 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
kenjiArai 0:5b88d5760320 2705 #if defined(MBEDTLS_CIPHER_MODE_CBC) && \
kenjiArai 0:5b88d5760320 2706 ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
kenjiArai 0:5b88d5760320 2707 if( mode == MBEDTLS_MODE_CBC )
kenjiArai 0:5b88d5760320 2708 {
kenjiArai 0:5b88d5760320 2709 size_t minlen = 0;
kenjiArai 0:5b88d5760320 2710
kenjiArai 0:5b88d5760320 2711 /*
kenjiArai 0:5b88d5760320 2712 * Check immediate ciphertext sanity
kenjiArai 0:5b88d5760320 2713 */
kenjiArai 0:5b88d5760320 2714 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 2715 if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
kenjiArai 0:5b88d5760320 2716 {
kenjiArai 0:5b88d5760320 2717 /* The ciphertext is prefixed with the CBC IV. */
kenjiArai 0:5b88d5760320 2718 minlen += transform->ivlen;
kenjiArai 0:5b88d5760320 2719 }
kenjiArai 0:5b88d5760320 2720 #endif
kenjiArai 0:5b88d5760320 2721
kenjiArai 0:5b88d5760320 2722 /* Size considerations:
kenjiArai 0:5b88d5760320 2723 *
kenjiArai 0:5b88d5760320 2724 * - The CBC cipher text must not be empty and hence
kenjiArai 0:5b88d5760320 2725 * at least of size transform->ivlen.
kenjiArai 0:5b88d5760320 2726 *
kenjiArai 0:5b88d5760320 2727 * Together with the potential IV-prefix, this explains
kenjiArai 0:5b88d5760320 2728 * the first of the two checks below.
kenjiArai 0:5b88d5760320 2729 *
kenjiArai 0:5b88d5760320 2730 * - The record must contain a MAC, either in plain or
kenjiArai 0:5b88d5760320 2731 * encrypted, depending on whether Encrypt-then-MAC
kenjiArai 0:5b88d5760320 2732 * is used or not.
kenjiArai 0:5b88d5760320 2733 * - If it is, the message contains the IV-prefix,
kenjiArai 0:5b88d5760320 2734 * the CBC ciphertext, and the MAC.
kenjiArai 0:5b88d5760320 2735 * - If it is not, the padded plaintext, and hence
kenjiArai 0:5b88d5760320 2736 * the CBC ciphertext, has at least length maclen + 1
kenjiArai 0:5b88d5760320 2737 * because there is at least the padding length byte.
kenjiArai 0:5b88d5760320 2738 *
kenjiArai 0:5b88d5760320 2739 * As the CBC ciphertext is not empty, both cases give the
kenjiArai 0:5b88d5760320 2740 * lower bound minlen + maclen + 1 on the record size, which
kenjiArai 0:5b88d5760320 2741 * we test for in the second check below.
kenjiArai 0:5b88d5760320 2742 */
kenjiArai 0:5b88d5760320 2743 if( rec->data_len < minlen + transform->ivlen ||
kenjiArai 0:5b88d5760320 2744 rec->data_len < minlen + transform->maclen + 1 )
kenjiArai 0:5b88d5760320 2745 {
kenjiArai 0:5b88d5760320 2746 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) "
kenjiArai 0:5b88d5760320 2747 "+ 1 ) ( + expl IV )", rec->data_len,
kenjiArai 0:5b88d5760320 2748 transform->ivlen,
kenjiArai 0:5b88d5760320 2749 transform->maclen ) );
kenjiArai 0:5b88d5760320 2750 return( MBEDTLS_ERR_SSL_INVALID_MAC );
kenjiArai 0:5b88d5760320 2751 }
kenjiArai 0:5b88d5760320 2752
kenjiArai 0:5b88d5760320 2753 /*
kenjiArai 0:5b88d5760320 2754 * Authenticate before decrypt if enabled
kenjiArai 0:5b88d5760320 2755 */
kenjiArai 0:5b88d5760320 2756 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
kenjiArai 0:5b88d5760320 2757 if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
kenjiArai 0:5b88d5760320 2758 {
kenjiArai 0:5b88d5760320 2759 unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
kenjiArai 0:5b88d5760320 2760
kenjiArai 0:5b88d5760320 2761 MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
kenjiArai 0:5b88d5760320 2762
kenjiArai 0:5b88d5760320 2763 /* Safe due to the check data_len >= minlen + maclen + 1 above. */
kenjiArai 0:5b88d5760320 2764 rec->data_len -= transform->maclen;
kenjiArai 0:5b88d5760320 2765
kenjiArai 0:5b88d5760320 2766 ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
kenjiArai 0:5b88d5760320 2767
kenjiArai 0:5b88d5760320 2768 MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
kenjiArai 0:5b88d5760320 2769 add_data_len );
kenjiArai 0:5b88d5760320 2770 mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
kenjiArai 0:5b88d5760320 2771 add_data_len );
kenjiArai 0:5b88d5760320 2772 mbedtls_md_hmac_update( &transform->md_ctx_dec,
kenjiArai 0:5b88d5760320 2773 data, rec->data_len );
kenjiArai 0:5b88d5760320 2774 mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
kenjiArai 0:5b88d5760320 2775 mbedtls_md_hmac_reset( &transform->md_ctx_dec );
kenjiArai 0:5b88d5760320 2776
kenjiArai 0:5b88d5760320 2777 MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len,
kenjiArai 0:5b88d5760320 2778 transform->maclen );
kenjiArai 0:5b88d5760320 2779 MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
kenjiArai 0:5b88d5760320 2780 transform->maclen );
kenjiArai 0:5b88d5760320 2781
kenjiArai 0:5b88d5760320 2782 if( mbedtls_ssl_safer_memcmp( data + rec->data_len, mac_expect,
kenjiArai 0:5b88d5760320 2783 transform->maclen ) != 0 )
kenjiArai 0:5b88d5760320 2784 {
kenjiArai 0:5b88d5760320 2785 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
kenjiArai 0:5b88d5760320 2786 return( MBEDTLS_ERR_SSL_INVALID_MAC );
kenjiArai 0:5b88d5760320 2787 }
kenjiArai 0:5b88d5760320 2788 auth_done++;
kenjiArai 0:5b88d5760320 2789 }
kenjiArai 0:5b88d5760320 2790 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
kenjiArai 0:5b88d5760320 2791
kenjiArai 0:5b88d5760320 2792 /*
kenjiArai 0:5b88d5760320 2793 * Check length sanity
kenjiArai 0:5b88d5760320 2794 */
kenjiArai 0:5b88d5760320 2795 if( rec->data_len % transform->ivlen != 0 )
kenjiArai 0:5b88d5760320 2796 {
kenjiArai 0:5b88d5760320 2797 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
kenjiArai 0:5b88d5760320 2798 rec->data_len, transform->ivlen ) );
kenjiArai 0:5b88d5760320 2799 return( MBEDTLS_ERR_SSL_INVALID_MAC );
kenjiArai 0:5b88d5760320 2800 }
kenjiArai 0:5b88d5760320 2801
kenjiArai 0:5b88d5760320 2802 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 2803 /*
kenjiArai 0:5b88d5760320 2804 * Initialize for prepended IV for block cipher in TLS v1.1 and up
kenjiArai 0:5b88d5760320 2805 */
kenjiArai 0:5b88d5760320 2806 if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
kenjiArai 0:5b88d5760320 2807 {
kenjiArai 0:5b88d5760320 2808 /* This is safe because data_len >= minlen + maclen + 1 initially,
kenjiArai 0:5b88d5760320 2809 * and at this point we have at most subtracted maclen (note that
kenjiArai 0:5b88d5760320 2810 * minlen == transform->ivlen here). */
kenjiArai 0:5b88d5760320 2811 memcpy( transform->iv_dec, data, transform->ivlen );
kenjiArai 0:5b88d5760320 2812
kenjiArai 0:5b88d5760320 2813 data += transform->ivlen;
kenjiArai 0:5b88d5760320 2814 rec->data_offset += transform->ivlen;
kenjiArai 0:5b88d5760320 2815 rec->data_len -= transform->ivlen;
kenjiArai 0:5b88d5760320 2816 }
kenjiArai 0:5b88d5760320 2817 #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 2818
kenjiArai 0:5b88d5760320 2819 if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
kenjiArai 0:5b88d5760320 2820 transform->iv_dec, transform->ivlen,
kenjiArai 0:5b88d5760320 2821 data, rec->data_len, data, &olen ) ) != 0 )
kenjiArai 0:5b88d5760320 2822 {
kenjiArai 0:5b88d5760320 2823 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
kenjiArai 0:5b88d5760320 2824 return( ret );
kenjiArai 0:5b88d5760320 2825 }
kenjiArai 0:5b88d5760320 2826
kenjiArai 0:5b88d5760320 2827 if( rec->data_len != olen )
kenjiArai 0:5b88d5760320 2828 {
kenjiArai 0:5b88d5760320 2829 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2830 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2831 }
kenjiArai 0:5b88d5760320 2832
kenjiArai 0:5b88d5760320 2833 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
kenjiArai 0:5b88d5760320 2834 if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
kenjiArai 0:5b88d5760320 2835 {
kenjiArai 0:5b88d5760320 2836 /*
kenjiArai 0:5b88d5760320 2837 * Save IV in SSL3 and TLS1
kenjiArai 0:5b88d5760320 2838 */
kenjiArai 0:5b88d5760320 2839 memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv,
kenjiArai 0:5b88d5760320 2840 transform->ivlen );
kenjiArai 0:5b88d5760320 2841 }
kenjiArai 0:5b88d5760320 2842 #endif
kenjiArai 0:5b88d5760320 2843
kenjiArai 0:5b88d5760320 2844 /* Safe since data_len >= minlen + maclen + 1, so after having
kenjiArai 0:5b88d5760320 2845 * subtracted at most minlen and maclen up to this point,
kenjiArai 0:5b88d5760320 2846 * data_len > 0. */
kenjiArai 0:5b88d5760320 2847 padlen = data[rec->data_len - 1];
kenjiArai 0:5b88d5760320 2848
kenjiArai 0:5b88d5760320 2849 if( auth_done == 1 )
kenjiArai 0:5b88d5760320 2850 {
kenjiArai 0:5b88d5760320 2851 correct *= ( rec->data_len >= padlen + 1 );
kenjiArai 0:5b88d5760320 2852 padlen *= ( rec->data_len >= padlen + 1 );
kenjiArai 0:5b88d5760320 2853 }
kenjiArai 0:5b88d5760320 2854 else
kenjiArai 0:5b88d5760320 2855 {
kenjiArai 0:5b88d5760320 2856 #if defined(MBEDTLS_SSL_DEBUG_ALL)
kenjiArai 0:5b88d5760320 2857 if( rec->data_len < transform->maclen + padlen + 1 )
kenjiArai 0:5b88d5760320 2858 {
kenjiArai 0:5b88d5760320 2859 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
kenjiArai 0:5b88d5760320 2860 rec->data_len,
kenjiArai 0:5b88d5760320 2861 transform->maclen,
kenjiArai 0:5b88d5760320 2862 padlen + 1 ) );
kenjiArai 0:5b88d5760320 2863 }
kenjiArai 0:5b88d5760320 2864 #endif
kenjiArai 0:5b88d5760320 2865
kenjiArai 0:5b88d5760320 2866 correct *= ( rec->data_len >= transform->maclen + padlen + 1 );
kenjiArai 0:5b88d5760320 2867 padlen *= ( rec->data_len >= transform->maclen + padlen + 1 );
kenjiArai 0:5b88d5760320 2868 }
kenjiArai 0:5b88d5760320 2869
kenjiArai 0:5b88d5760320 2870 padlen++;
kenjiArai 0:5b88d5760320 2871
kenjiArai 0:5b88d5760320 2872 /* Regardless of the validity of the padding,
kenjiArai 0:5b88d5760320 2873 * we have data_len >= padlen here. */
kenjiArai 0:5b88d5760320 2874
kenjiArai 0:5b88d5760320 2875 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 2876 if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 2877 {
kenjiArai 0:5b88d5760320 2878 if( padlen > transform->ivlen )
kenjiArai 0:5b88d5760320 2879 {
kenjiArai 0:5b88d5760320 2880 #if defined(MBEDTLS_SSL_DEBUG_ALL)
kenjiArai 0:5b88d5760320 2881 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
kenjiArai 0:5b88d5760320 2882 "should be no more than %d",
kenjiArai 0:5b88d5760320 2883 padlen, transform->ivlen ) );
kenjiArai 0:5b88d5760320 2884 #endif
kenjiArai 0:5b88d5760320 2885 correct = 0;
kenjiArai 0:5b88d5760320 2886 }
kenjiArai 0:5b88d5760320 2887 }
kenjiArai 0:5b88d5760320 2888 else
kenjiArai 0:5b88d5760320 2889 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 2890 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 2891 defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 2892 if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 2893 {
kenjiArai 0:5b88d5760320 2894 /* The padding check involves a series of up to 256
kenjiArai 0:5b88d5760320 2895 * consecutive memory reads at the end of the record
kenjiArai 0:5b88d5760320 2896 * plaintext buffer. In order to hide the length and
kenjiArai 0:5b88d5760320 2897 * validity of the padding, always perform exactly
kenjiArai 0:5b88d5760320 2898 * `min(256,plaintext_len)` reads (but take into account
kenjiArai 0:5b88d5760320 2899 * only the last `padlen` bytes for the padding check). */
kenjiArai 0:5b88d5760320 2900 size_t pad_count = 0;
kenjiArai 0:5b88d5760320 2901 size_t real_count = 0;
kenjiArai 0:5b88d5760320 2902 volatile unsigned char* const check = data;
kenjiArai 0:5b88d5760320 2903
kenjiArai 0:5b88d5760320 2904 /* Index of first padding byte; it has been ensured above
kenjiArai 0:5b88d5760320 2905 * that the subtraction is safe. */
kenjiArai 0:5b88d5760320 2906 size_t const padding_idx = rec->data_len - padlen;
kenjiArai 0:5b88d5760320 2907 size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
kenjiArai 0:5b88d5760320 2908 size_t const start_idx = rec->data_len - num_checks;
kenjiArai 0:5b88d5760320 2909 size_t idx;
kenjiArai 0:5b88d5760320 2910
kenjiArai 0:5b88d5760320 2911 for( idx = start_idx; idx < rec->data_len; idx++ )
kenjiArai 0:5b88d5760320 2912 {
kenjiArai 0:5b88d5760320 2913 real_count |= ( idx >= padding_idx );
kenjiArai 0:5b88d5760320 2914 pad_count += real_count * ( check[idx] == padlen - 1 );
kenjiArai 0:5b88d5760320 2915 }
kenjiArai 0:5b88d5760320 2916 correct &= ( pad_count == padlen );
kenjiArai 0:5b88d5760320 2917
kenjiArai 0:5b88d5760320 2918 #if defined(MBEDTLS_SSL_DEBUG_ALL)
kenjiArai 0:5b88d5760320 2919 if( padlen > 0 && correct == 0 )
kenjiArai 0:5b88d5760320 2920 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
kenjiArai 0:5b88d5760320 2921 #endif
kenjiArai 0:5b88d5760320 2922 padlen &= correct * 0x1FF;
kenjiArai 0:5b88d5760320 2923 }
kenjiArai 0:5b88d5760320 2924 else
kenjiArai 0:5b88d5760320 2925 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
kenjiArai 0:5b88d5760320 2926 MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 2927 {
kenjiArai 0:5b88d5760320 2928 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2929 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2930 }
kenjiArai 0:5b88d5760320 2931
kenjiArai 0:5b88d5760320 2932 /* If the padding was found to be invalid, padlen == 0
kenjiArai 0:5b88d5760320 2933 * and the subtraction is safe. If the padding was found valid,
kenjiArai 0:5b88d5760320 2934 * padlen hasn't been changed and the previous assertion
kenjiArai 0:5b88d5760320 2935 * data_len >= padlen still holds. */
kenjiArai 0:5b88d5760320 2936 rec->data_len -= padlen;
kenjiArai 0:5b88d5760320 2937 }
kenjiArai 0:5b88d5760320 2938 else
kenjiArai 0:5b88d5760320 2939 #endif /* MBEDTLS_CIPHER_MODE_CBC &&
kenjiArai 0:5b88d5760320 2940 ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
kenjiArai 0:5b88d5760320 2941 {
kenjiArai 0:5b88d5760320 2942 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 2943 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 2944 }
kenjiArai 0:5b88d5760320 2945
kenjiArai 0:5b88d5760320 2946 #if defined(MBEDTLS_SSL_DEBUG_ALL)
kenjiArai 0:5b88d5760320 2947 MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
kenjiArai 0:5b88d5760320 2948 data, rec->data_len );
kenjiArai 0:5b88d5760320 2949 #endif
kenjiArai 0:5b88d5760320 2950
kenjiArai 0:5b88d5760320 2951 /*
kenjiArai 0:5b88d5760320 2952 * Authenticate if not done yet.
kenjiArai 0:5b88d5760320 2953 * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
kenjiArai 0:5b88d5760320 2954 */
kenjiArai 0:5b88d5760320 2955 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
kenjiArai 0:5b88d5760320 2956 if( auth_done == 0 )
kenjiArai 0:5b88d5760320 2957 {
kenjiArai 0:5b88d5760320 2958 unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
kenjiArai 0:5b88d5760320 2959
kenjiArai 0:5b88d5760320 2960 /* If the initial value of padlen was such that
kenjiArai 0:5b88d5760320 2961 * data_len < maclen + padlen + 1, then padlen
kenjiArai 0:5b88d5760320 2962 * got reset to 1, and the initial check
kenjiArai 0:5b88d5760320 2963 * data_len >= minlen + maclen + 1
kenjiArai 0:5b88d5760320 2964 * guarantees that at this point we still
kenjiArai 0:5b88d5760320 2965 * have at least data_len >= maclen.
kenjiArai 0:5b88d5760320 2966 *
kenjiArai 0:5b88d5760320 2967 * If the initial value of padlen was such that
kenjiArai 0:5b88d5760320 2968 * data_len >= maclen + padlen + 1, then we have
kenjiArai 0:5b88d5760320 2969 * subtracted either padlen + 1 (if the padding was correct)
kenjiArai 0:5b88d5760320 2970 * or 0 (if the padding was incorrect) since then,
kenjiArai 0:5b88d5760320 2971 * hence data_len >= maclen in any case.
kenjiArai 0:5b88d5760320 2972 */
kenjiArai 0:5b88d5760320 2973 rec->data_len -= transform->maclen;
kenjiArai 0:5b88d5760320 2974
kenjiArai 0:5b88d5760320 2975 ssl_extract_add_data_from_record( add_data, &add_data_len, rec );
kenjiArai 0:5b88d5760320 2976
kenjiArai 0:5b88d5760320 2977 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 2978 if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 2979 {
kenjiArai 0:5b88d5760320 2980 ssl_mac( &transform->md_ctx_dec,
kenjiArai 0:5b88d5760320 2981 transform->mac_dec,
kenjiArai 0:5b88d5760320 2982 data, rec->data_len,
kenjiArai 0:5b88d5760320 2983 rec->ctr, rec->type,
kenjiArai 0:5b88d5760320 2984 mac_expect );
kenjiArai 0:5b88d5760320 2985 }
kenjiArai 0:5b88d5760320 2986 else
kenjiArai 0:5b88d5760320 2987 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 2988 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 2989 defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 2990 if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 2991 {
kenjiArai 0:5b88d5760320 2992 /*
kenjiArai 0:5b88d5760320 2993 * Process MAC and always update for padlen afterwards to make
kenjiArai 0:5b88d5760320 2994 * total time independent of padlen.
kenjiArai 0:5b88d5760320 2995 *
kenjiArai 0:5b88d5760320 2996 * Known timing attacks:
kenjiArai 0:5b88d5760320 2997 * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
kenjiArai 0:5b88d5760320 2998 *
kenjiArai 0:5b88d5760320 2999 * To compensate for different timings for the MAC calculation
kenjiArai 0:5b88d5760320 3000 * depending on how much padding was removed (which is determined
kenjiArai 0:5b88d5760320 3001 * by padlen), process extra_run more blocks through the hash
kenjiArai 0:5b88d5760320 3002 * function.
kenjiArai 0:5b88d5760320 3003 *
kenjiArai 0:5b88d5760320 3004 * The formula in the paper is
kenjiArai 0:5b88d5760320 3005 * extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 )
kenjiArai 0:5b88d5760320 3006 * where L1 is the size of the header plus the decrypted message
kenjiArai 0:5b88d5760320 3007 * plus CBC padding and L2 is the size of the header plus the
kenjiArai 0:5b88d5760320 3008 * decrypted message. This is for an underlying hash function
kenjiArai 0:5b88d5760320 3009 * with 64-byte blocks.
kenjiArai 0:5b88d5760320 3010 * We use ( (Lx+8) / 64 ) to handle 'negative Lx' values
kenjiArai 0:5b88d5760320 3011 * correctly. We round down instead of up, so -56 is the correct
kenjiArai 0:5b88d5760320 3012 * value for our calculations instead of -55.
kenjiArai 0:5b88d5760320 3013 *
kenjiArai 0:5b88d5760320 3014 * Repeat the formula rather than defining a block_size variable.
kenjiArai 0:5b88d5760320 3015 * This avoids requiring division by a variable at runtime
kenjiArai 0:5b88d5760320 3016 * (which would be marginally less efficient and would require
kenjiArai 0:5b88d5760320 3017 * linking an extra division function in some builds).
kenjiArai 0:5b88d5760320 3018 */
kenjiArai 0:5b88d5760320 3019 size_t j, extra_run = 0;
kenjiArai 0:5b88d5760320 3020 unsigned char tmp[MBEDTLS_MD_MAX_BLOCK_SIZE];
kenjiArai 0:5b88d5760320 3021
kenjiArai 0:5b88d5760320 3022 /*
kenjiArai 0:5b88d5760320 3023 * The next two sizes are the minimum and maximum values of
kenjiArai 0:5b88d5760320 3024 * in_msglen over all padlen values.
kenjiArai 0:5b88d5760320 3025 *
kenjiArai 0:5b88d5760320 3026 * They're independent of padlen, since we previously did
kenjiArai 0:5b88d5760320 3027 * in_msglen -= padlen.
kenjiArai 0:5b88d5760320 3028 *
kenjiArai 0:5b88d5760320 3029 * Note that max_len + maclen is never more than the buffer
kenjiArai 0:5b88d5760320 3030 * length, as we previously did in_msglen -= maclen too.
kenjiArai 0:5b88d5760320 3031 */
kenjiArai 0:5b88d5760320 3032 const size_t max_len = rec->data_len + padlen;
kenjiArai 0:5b88d5760320 3033 const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
kenjiArai 0:5b88d5760320 3034
kenjiArai 0:5b88d5760320 3035 memset( tmp, 0, sizeof( tmp ) );
kenjiArai 0:5b88d5760320 3036
kenjiArai 0:5b88d5760320 3037 switch( mbedtls_md_get_type( transform->md_ctx_dec.md_info ) )
kenjiArai 0:5b88d5760320 3038 {
kenjiArai 0:5b88d5760320 3039 #if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \
kenjiArai 0:5b88d5760320 3040 defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 3041 case MBEDTLS_MD_MD5:
kenjiArai 0:5b88d5760320 3042 case MBEDTLS_MD_SHA1:
kenjiArai 0:5b88d5760320 3043 case MBEDTLS_MD_SHA256:
kenjiArai 0:5b88d5760320 3044 /* 8 bytes of message size, 64-byte compression blocks */
kenjiArai 0:5b88d5760320 3045 extra_run =
kenjiArai 0:5b88d5760320 3046 ( add_data_len + rec->data_len + padlen + 8 ) / 64 -
kenjiArai 0:5b88d5760320 3047 ( add_data_len + rec->data_len + 8 ) / 64;
kenjiArai 0:5b88d5760320 3048 break;
kenjiArai 0:5b88d5760320 3049 #endif
kenjiArai 0:5b88d5760320 3050 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 3051 case MBEDTLS_MD_SHA384:
kenjiArai 0:5b88d5760320 3052 /* 16 bytes of message size, 128-byte compression blocks */
kenjiArai 0:5b88d5760320 3053 extra_run =
kenjiArai 0:5b88d5760320 3054 ( add_data_len + rec->data_len + padlen + 16 ) / 128 -
kenjiArai 0:5b88d5760320 3055 ( add_data_len + rec->data_len + 16 ) / 128;
kenjiArai 0:5b88d5760320 3056 break;
kenjiArai 0:5b88d5760320 3057 #endif
kenjiArai 0:5b88d5760320 3058 default:
kenjiArai 0:5b88d5760320 3059 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 3060 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3061 }
kenjiArai 0:5b88d5760320 3062
kenjiArai 0:5b88d5760320 3063 extra_run &= correct * 0xFF;
kenjiArai 0:5b88d5760320 3064
kenjiArai 0:5b88d5760320 3065 mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
kenjiArai 0:5b88d5760320 3066 add_data_len );
kenjiArai 0:5b88d5760320 3067 mbedtls_md_hmac_update( &transform->md_ctx_dec, data,
kenjiArai 0:5b88d5760320 3068 rec->data_len );
kenjiArai 0:5b88d5760320 3069 /* Make sure we access everything even when padlen > 0. This
kenjiArai 0:5b88d5760320 3070 * makes the synchronisation requirements for just-in-time
kenjiArai 0:5b88d5760320 3071 * Prime+Probe attacks much tighter and hopefully impractical. */
kenjiArai 0:5b88d5760320 3072 ssl_read_memory( data + rec->data_len, padlen );
kenjiArai 0:5b88d5760320 3073 mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
kenjiArai 0:5b88d5760320 3074
kenjiArai 0:5b88d5760320 3075 /* Call mbedtls_md_process at least once due to cache attacks
kenjiArai 0:5b88d5760320 3076 * that observe whether md_process() was called of not */
kenjiArai 0:5b88d5760320 3077 for( j = 0; j < extra_run + 1; j++ )
kenjiArai 0:5b88d5760320 3078 mbedtls_md_process( &transform->md_ctx_dec, tmp );
kenjiArai 0:5b88d5760320 3079
kenjiArai 0:5b88d5760320 3080 mbedtls_md_hmac_reset( &transform->md_ctx_dec );
kenjiArai 0:5b88d5760320 3081
kenjiArai 0:5b88d5760320 3082 /* Make sure we access all the memory that could contain the MAC,
kenjiArai 0:5b88d5760320 3083 * before we check it in the next code block. This makes the
kenjiArai 0:5b88d5760320 3084 * synchronisation requirements for just-in-time Prime+Probe
kenjiArai 0:5b88d5760320 3085 * attacks much tighter and hopefully impractical. */
kenjiArai 0:5b88d5760320 3086 ssl_read_memory( data + min_len,
kenjiArai 0:5b88d5760320 3087 max_len - min_len + transform->maclen );
kenjiArai 0:5b88d5760320 3088 }
kenjiArai 0:5b88d5760320 3089 else
kenjiArai 0:5b88d5760320 3090 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
kenjiArai 0:5b88d5760320 3091 MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 3092 {
kenjiArai 0:5b88d5760320 3093 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 3094 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3095 }
kenjiArai 0:5b88d5760320 3096
kenjiArai 0:5b88d5760320 3097 #if defined(MBEDTLS_SSL_DEBUG_ALL)
kenjiArai 0:5b88d5760320 3098 MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen );
kenjiArai 0:5b88d5760320 3099 MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len, transform->maclen );
kenjiArai 0:5b88d5760320 3100 #endif
kenjiArai 0:5b88d5760320 3101
kenjiArai 0:5b88d5760320 3102 if( mbedtls_ssl_safer_memcmp( data + rec->data_len, mac_expect,
kenjiArai 0:5b88d5760320 3103 transform->maclen ) != 0 )
kenjiArai 0:5b88d5760320 3104 {
kenjiArai 0:5b88d5760320 3105 #if defined(MBEDTLS_SSL_DEBUG_ALL)
kenjiArai 0:5b88d5760320 3106 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
kenjiArai 0:5b88d5760320 3107 #endif
kenjiArai 0:5b88d5760320 3108 correct = 0;
kenjiArai 0:5b88d5760320 3109 }
kenjiArai 0:5b88d5760320 3110 auth_done++;
kenjiArai 0:5b88d5760320 3111 }
kenjiArai 0:5b88d5760320 3112
kenjiArai 0:5b88d5760320 3113 /*
kenjiArai 0:5b88d5760320 3114 * Finally check the correct flag
kenjiArai 0:5b88d5760320 3115 */
kenjiArai 0:5b88d5760320 3116 if( correct == 0 )
kenjiArai 0:5b88d5760320 3117 return( MBEDTLS_ERR_SSL_INVALID_MAC );
kenjiArai 0:5b88d5760320 3118 #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
kenjiArai 0:5b88d5760320 3119
kenjiArai 0:5b88d5760320 3120 /* Make extra sure authentication was performed, exactly once */
kenjiArai 0:5b88d5760320 3121 if( auth_done != 1 )
kenjiArai 0:5b88d5760320 3122 {
kenjiArai 0:5b88d5760320 3123 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 3124 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3125 }
kenjiArai 0:5b88d5760320 3126
kenjiArai 0:5b88d5760320 3127 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 3128 if( rec->cid_len != 0 )
kenjiArai 0:5b88d5760320 3129 {
kenjiArai 0:5b88d5760320 3130 ret = ssl_cid_parse_inner_plaintext( data, &rec->data_len,
kenjiArai 0:5b88d5760320 3131 &rec->type );
kenjiArai 0:5b88d5760320 3132 if( ret != 0 )
kenjiArai 0:5b88d5760320 3133 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 3134 }
kenjiArai 0:5b88d5760320 3135 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 3136
kenjiArai 0:5b88d5760320 3137 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
kenjiArai 0:5b88d5760320 3138
kenjiArai 0:5b88d5760320 3139 return( 0 );
kenjiArai 0:5b88d5760320 3140 }
kenjiArai 0:5b88d5760320 3141
kenjiArai 0:5b88d5760320 3142 #undef MAC_NONE
kenjiArai 0:5b88d5760320 3143 #undef MAC_PLAINTEXT
kenjiArai 0:5b88d5760320 3144 #undef MAC_CIPHERTEXT
kenjiArai 0:5b88d5760320 3145
kenjiArai 0:5b88d5760320 3146 #if defined(MBEDTLS_ZLIB_SUPPORT)
kenjiArai 0:5b88d5760320 3147 /*
kenjiArai 0:5b88d5760320 3148 * Compression/decompression functions
kenjiArai 0:5b88d5760320 3149 */
kenjiArai 0:5b88d5760320 3150 static int ssl_compress_buf( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3151 {
kenjiArai 0:5b88d5760320 3152 int ret;
kenjiArai 0:5b88d5760320 3153 unsigned char *msg_post = ssl->out_msg;
kenjiArai 0:5b88d5760320 3154 ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
kenjiArai 0:5b88d5760320 3155 size_t len_pre = ssl->out_msglen;
kenjiArai 0:5b88d5760320 3156 unsigned char *msg_pre = ssl->compress_buf;
kenjiArai 0:5b88d5760320 3157
kenjiArai 0:5b88d5760320 3158 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
kenjiArai 0:5b88d5760320 3159
kenjiArai 0:5b88d5760320 3160 if( len_pre == 0 )
kenjiArai 0:5b88d5760320 3161 return( 0 );
kenjiArai 0:5b88d5760320 3162
kenjiArai 0:5b88d5760320 3163 memcpy( msg_pre, ssl->out_msg, len_pre );
kenjiArai 0:5b88d5760320 3164
kenjiArai 0:5b88d5760320 3165 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ",
kenjiArai 0:5b88d5760320 3166 ssl->out_msglen ) );
kenjiArai 0:5b88d5760320 3167
kenjiArai 0:5b88d5760320 3168 MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
kenjiArai 0:5b88d5760320 3169 ssl->out_msg, ssl->out_msglen );
kenjiArai 0:5b88d5760320 3170
kenjiArai 0:5b88d5760320 3171 ssl->transform_out->ctx_deflate.next_in = msg_pre;
kenjiArai 0:5b88d5760320 3172 ssl->transform_out->ctx_deflate.avail_in = len_pre;
kenjiArai 0:5b88d5760320 3173 ssl->transform_out->ctx_deflate.next_out = msg_post;
kenjiArai 0:5b88d5760320 3174 ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written;
kenjiArai 0:5b88d5760320 3175
kenjiArai 0:5b88d5760320 3176 ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
kenjiArai 0:5b88d5760320 3177 if( ret != Z_OK )
kenjiArai 0:5b88d5760320 3178 {
kenjiArai 0:5b88d5760320 3179 MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
kenjiArai 0:5b88d5760320 3180 return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
kenjiArai 0:5b88d5760320 3181 }
kenjiArai 0:5b88d5760320 3182
kenjiArai 0:5b88d5760320 3183 ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN -
kenjiArai 0:5b88d5760320 3184 ssl->transform_out->ctx_deflate.avail_out - bytes_written;
kenjiArai 0:5b88d5760320 3185
kenjiArai 0:5b88d5760320 3186 MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
kenjiArai 0:5b88d5760320 3187 ssl->out_msglen ) );
kenjiArai 0:5b88d5760320 3188
kenjiArai 0:5b88d5760320 3189 MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
kenjiArai 0:5b88d5760320 3190 ssl->out_msg, ssl->out_msglen );
kenjiArai 0:5b88d5760320 3191
kenjiArai 0:5b88d5760320 3192 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
kenjiArai 0:5b88d5760320 3193
kenjiArai 0:5b88d5760320 3194 return( 0 );
kenjiArai 0:5b88d5760320 3195 }
kenjiArai 0:5b88d5760320 3196
kenjiArai 0:5b88d5760320 3197 static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3198 {
kenjiArai 0:5b88d5760320 3199 int ret;
kenjiArai 0:5b88d5760320 3200 unsigned char *msg_post = ssl->in_msg;
kenjiArai 0:5b88d5760320 3201 ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
kenjiArai 0:5b88d5760320 3202 size_t len_pre = ssl->in_msglen;
kenjiArai 0:5b88d5760320 3203 unsigned char *msg_pre = ssl->compress_buf;
kenjiArai 0:5b88d5760320 3204
kenjiArai 0:5b88d5760320 3205 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
kenjiArai 0:5b88d5760320 3206
kenjiArai 0:5b88d5760320 3207 if( len_pre == 0 )
kenjiArai 0:5b88d5760320 3208 return( 0 );
kenjiArai 0:5b88d5760320 3209
kenjiArai 0:5b88d5760320 3210 memcpy( msg_pre, ssl->in_msg, len_pre );
kenjiArai 0:5b88d5760320 3211
kenjiArai 0:5b88d5760320 3212 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ",
kenjiArai 0:5b88d5760320 3213 ssl->in_msglen ) );
kenjiArai 0:5b88d5760320 3214
kenjiArai 0:5b88d5760320 3215 MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
kenjiArai 0:5b88d5760320 3216 ssl->in_msg, ssl->in_msglen );
kenjiArai 0:5b88d5760320 3217
kenjiArai 0:5b88d5760320 3218 ssl->transform_in->ctx_inflate.next_in = msg_pre;
kenjiArai 0:5b88d5760320 3219 ssl->transform_in->ctx_inflate.avail_in = len_pre;
kenjiArai 0:5b88d5760320 3220 ssl->transform_in->ctx_inflate.next_out = msg_post;
kenjiArai 0:5b88d5760320 3221 ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN -
kenjiArai 0:5b88d5760320 3222 header_bytes;
kenjiArai 0:5b88d5760320 3223
kenjiArai 0:5b88d5760320 3224 ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
kenjiArai 0:5b88d5760320 3225 if( ret != Z_OK )
kenjiArai 0:5b88d5760320 3226 {
kenjiArai 0:5b88d5760320 3227 MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
kenjiArai 0:5b88d5760320 3228 return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
kenjiArai 0:5b88d5760320 3229 }
kenjiArai 0:5b88d5760320 3230
kenjiArai 0:5b88d5760320 3231 ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN -
kenjiArai 0:5b88d5760320 3232 ssl->transform_in->ctx_inflate.avail_out - header_bytes;
kenjiArai 0:5b88d5760320 3233
kenjiArai 0:5b88d5760320 3234 MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
kenjiArai 0:5b88d5760320 3235 ssl->in_msglen ) );
kenjiArai 0:5b88d5760320 3236
kenjiArai 0:5b88d5760320 3237 MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
kenjiArai 0:5b88d5760320 3238 ssl->in_msg, ssl->in_msglen );
kenjiArai 0:5b88d5760320 3239
kenjiArai 0:5b88d5760320 3240 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
kenjiArai 0:5b88d5760320 3241
kenjiArai 0:5b88d5760320 3242 return( 0 );
kenjiArai 0:5b88d5760320 3243 }
kenjiArai 0:5b88d5760320 3244 #endif /* MBEDTLS_ZLIB_SUPPORT */
kenjiArai 0:5b88d5760320 3245
kenjiArai 0:5b88d5760320 3246 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 3247 static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 3248
kenjiArai 0:5b88d5760320 3249 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 3250 static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3251 {
kenjiArai 0:5b88d5760320 3252 /* If renegotiation is not enforced, retransmit until we would reach max
kenjiArai 0:5b88d5760320 3253 * timeout if we were using the usual handshake doubling scheme */
kenjiArai 0:5b88d5760320 3254 if( ssl->conf->renego_max_records < 0 )
kenjiArai 0:5b88d5760320 3255 {
kenjiArai 0:5b88d5760320 3256 uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
kenjiArai 0:5b88d5760320 3257 unsigned char doublings = 1;
kenjiArai 0:5b88d5760320 3258
kenjiArai 0:5b88d5760320 3259 while( ratio != 0 )
kenjiArai 0:5b88d5760320 3260 {
kenjiArai 0:5b88d5760320 3261 ++doublings;
kenjiArai 0:5b88d5760320 3262 ratio >>= 1;
kenjiArai 0:5b88d5760320 3263 }
kenjiArai 0:5b88d5760320 3264
kenjiArai 0:5b88d5760320 3265 if( ++ssl->renego_records_seen > doublings )
kenjiArai 0:5b88d5760320 3266 {
kenjiArai 0:5b88d5760320 3267 MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) );
kenjiArai 0:5b88d5760320 3268 return( 0 );
kenjiArai 0:5b88d5760320 3269 }
kenjiArai 0:5b88d5760320 3270 }
kenjiArai 0:5b88d5760320 3271
kenjiArai 0:5b88d5760320 3272 return( ssl_write_hello_request( ssl ) );
kenjiArai 0:5b88d5760320 3273 }
kenjiArai 0:5b88d5760320 3274 #endif
kenjiArai 0:5b88d5760320 3275 #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
kenjiArai 0:5b88d5760320 3276
kenjiArai 0:5b88d5760320 3277 /*
kenjiArai 0:5b88d5760320 3278 * Fill the input message buffer by appending data to it.
kenjiArai 0:5b88d5760320 3279 * The amount of data already fetched is in ssl->in_left.
kenjiArai 0:5b88d5760320 3280 *
kenjiArai 0:5b88d5760320 3281 * If we return 0, is it guaranteed that (at least) nb_want bytes are
kenjiArai 0:5b88d5760320 3282 * available (from this read and/or a previous one). Otherwise, an error code
kenjiArai 0:5b88d5760320 3283 * is returned (possibly EOF or WANT_READ).
kenjiArai 0:5b88d5760320 3284 *
kenjiArai 0:5b88d5760320 3285 * With stream transport (TLS) on success ssl->in_left == nb_want, but
kenjiArai 0:5b88d5760320 3286 * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
kenjiArai 0:5b88d5760320 3287 * since we always read a whole datagram at once.
kenjiArai 0:5b88d5760320 3288 *
kenjiArai 0:5b88d5760320 3289 * For DTLS, it is up to the caller to set ssl->next_record_offset when
kenjiArai 0:5b88d5760320 3290 * they're done reading a record.
kenjiArai 0:5b88d5760320 3291 */
kenjiArai 0:5b88d5760320 3292 int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
kenjiArai 0:5b88d5760320 3293 {
kenjiArai 0:5b88d5760320 3294 int ret;
kenjiArai 0:5b88d5760320 3295 size_t len;
kenjiArai 0:5b88d5760320 3296
kenjiArai 0:5b88d5760320 3297 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
kenjiArai 0:5b88d5760320 3298
kenjiArai 0:5b88d5760320 3299 if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
kenjiArai 0:5b88d5760320 3300 {
kenjiArai 0:5b88d5760320 3301 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
kenjiArai 0:5b88d5760320 3302 "or mbedtls_ssl_set_bio()" ) );
kenjiArai 0:5b88d5760320 3303 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 3304 }
kenjiArai 0:5b88d5760320 3305
kenjiArai 0:5b88d5760320 3306 if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) )
kenjiArai 0:5b88d5760320 3307 {
kenjiArai 0:5b88d5760320 3308 MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
kenjiArai 0:5b88d5760320 3309 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 3310 }
kenjiArai 0:5b88d5760320 3311
kenjiArai 0:5b88d5760320 3312 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 3313 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 3314 {
kenjiArai 0:5b88d5760320 3315 uint32_t timeout;
kenjiArai 0:5b88d5760320 3316
kenjiArai 0:5b88d5760320 3317 /* Just to be sure */
kenjiArai 0:5b88d5760320 3318 if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
kenjiArai 0:5b88d5760320 3319 {
kenjiArai 0:5b88d5760320 3320 MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
kenjiArai 0:5b88d5760320 3321 "mbedtls_ssl_set_timer_cb() for DTLS" ) );
kenjiArai 0:5b88d5760320 3322 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 3323 }
kenjiArai 0:5b88d5760320 3324
kenjiArai 0:5b88d5760320 3325 /*
kenjiArai 0:5b88d5760320 3326 * The point is, we need to always read a full datagram at once, so we
kenjiArai 0:5b88d5760320 3327 * sometimes read more then requested, and handle the additional data.
kenjiArai 0:5b88d5760320 3328 * It could be the rest of the current record (while fetching the
kenjiArai 0:5b88d5760320 3329 * header) and/or some other records in the same datagram.
kenjiArai 0:5b88d5760320 3330 */
kenjiArai 0:5b88d5760320 3331
kenjiArai 0:5b88d5760320 3332 /*
kenjiArai 0:5b88d5760320 3333 * Move to the next record in the already read datagram if applicable
kenjiArai 0:5b88d5760320 3334 */
kenjiArai 0:5b88d5760320 3335 if( ssl->next_record_offset != 0 )
kenjiArai 0:5b88d5760320 3336 {
kenjiArai 0:5b88d5760320 3337 if( ssl->in_left < ssl->next_record_offset )
kenjiArai 0:5b88d5760320 3338 {
kenjiArai 0:5b88d5760320 3339 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 3340 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3341 }
kenjiArai 0:5b88d5760320 3342
kenjiArai 0:5b88d5760320 3343 ssl->in_left -= ssl->next_record_offset;
kenjiArai 0:5b88d5760320 3344
kenjiArai 0:5b88d5760320 3345 if( ssl->in_left != 0 )
kenjiArai 0:5b88d5760320 3346 {
kenjiArai 0:5b88d5760320 3347 MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d",
kenjiArai 0:5b88d5760320 3348 ssl->next_record_offset ) );
kenjiArai 0:5b88d5760320 3349 memmove( ssl->in_hdr,
kenjiArai 0:5b88d5760320 3350 ssl->in_hdr + ssl->next_record_offset,
kenjiArai 0:5b88d5760320 3351 ssl->in_left );
kenjiArai 0:5b88d5760320 3352 }
kenjiArai 0:5b88d5760320 3353
kenjiArai 0:5b88d5760320 3354 ssl->next_record_offset = 0;
kenjiArai 0:5b88d5760320 3355 }
kenjiArai 0:5b88d5760320 3356
kenjiArai 0:5b88d5760320 3357 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
kenjiArai 0:5b88d5760320 3358 ssl->in_left, nb_want ) );
kenjiArai 0:5b88d5760320 3359
kenjiArai 0:5b88d5760320 3360 /*
kenjiArai 0:5b88d5760320 3361 * Done if we already have enough data.
kenjiArai 0:5b88d5760320 3362 */
kenjiArai 0:5b88d5760320 3363 if( nb_want <= ssl->in_left)
kenjiArai 0:5b88d5760320 3364 {
kenjiArai 0:5b88d5760320 3365 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
kenjiArai 0:5b88d5760320 3366 return( 0 );
kenjiArai 0:5b88d5760320 3367 }
kenjiArai 0:5b88d5760320 3368
kenjiArai 0:5b88d5760320 3369 /*
kenjiArai 0:5b88d5760320 3370 * A record can't be split across datagrams. If we need to read but
kenjiArai 0:5b88d5760320 3371 * are not at the beginning of a new record, the caller did something
kenjiArai 0:5b88d5760320 3372 * wrong.
kenjiArai 0:5b88d5760320 3373 */
kenjiArai 0:5b88d5760320 3374 if( ssl->in_left != 0 )
kenjiArai 0:5b88d5760320 3375 {
kenjiArai 0:5b88d5760320 3376 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 3377 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3378 }
kenjiArai 0:5b88d5760320 3379
kenjiArai 0:5b88d5760320 3380 /*
kenjiArai 0:5b88d5760320 3381 * Don't even try to read if time's out already.
kenjiArai 0:5b88d5760320 3382 * This avoids by-passing the timer when repeatedly receiving messages
kenjiArai 0:5b88d5760320 3383 * that will end up being dropped.
kenjiArai 0:5b88d5760320 3384 */
kenjiArai 0:5b88d5760320 3385 if( ssl_check_timer( ssl ) != 0 )
kenjiArai 0:5b88d5760320 3386 {
kenjiArai 0:5b88d5760320 3387 MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) );
kenjiArai 0:5b88d5760320 3388 ret = MBEDTLS_ERR_SSL_TIMEOUT;
kenjiArai 0:5b88d5760320 3389 }
kenjiArai 0:5b88d5760320 3390 else
kenjiArai 0:5b88d5760320 3391 {
kenjiArai 0:5b88d5760320 3392 len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
kenjiArai 0:5b88d5760320 3393
kenjiArai 0:5b88d5760320 3394 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 3395 timeout = ssl->handshake->retransmit_timeout;
kenjiArai 0:5b88d5760320 3396 else
kenjiArai 0:5b88d5760320 3397 timeout = ssl->conf->read_timeout;
kenjiArai 0:5b88d5760320 3398
kenjiArai 0:5b88d5760320 3399 MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
kenjiArai 0:5b88d5760320 3400
kenjiArai 0:5b88d5760320 3401 if( ssl->f_recv_timeout != NULL )
kenjiArai 0:5b88d5760320 3402 ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
kenjiArai 0:5b88d5760320 3403 timeout );
kenjiArai 0:5b88d5760320 3404 else
kenjiArai 0:5b88d5760320 3405 ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
kenjiArai 0:5b88d5760320 3406
kenjiArai 0:5b88d5760320 3407 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
kenjiArai 0:5b88d5760320 3408
kenjiArai 0:5b88d5760320 3409 if( ret == 0 )
kenjiArai 0:5b88d5760320 3410 return( MBEDTLS_ERR_SSL_CONN_EOF );
kenjiArai 0:5b88d5760320 3411 }
kenjiArai 0:5b88d5760320 3412
kenjiArai 0:5b88d5760320 3413 if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
kenjiArai 0:5b88d5760320 3414 {
kenjiArai 0:5b88d5760320 3415 MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
kenjiArai 0:5b88d5760320 3416 ssl_set_timer( ssl, 0 );
kenjiArai 0:5b88d5760320 3417
kenjiArai 0:5b88d5760320 3418 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 3419 {
kenjiArai 0:5b88d5760320 3420 if( ssl_double_retransmit_timeout( ssl ) != 0 )
kenjiArai 0:5b88d5760320 3421 {
kenjiArai 0:5b88d5760320 3422 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
kenjiArai 0:5b88d5760320 3423 return( MBEDTLS_ERR_SSL_TIMEOUT );
kenjiArai 0:5b88d5760320 3424 }
kenjiArai 0:5b88d5760320 3425
kenjiArai 0:5b88d5760320 3426 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 3427 {
kenjiArai 0:5b88d5760320 3428 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
kenjiArai 0:5b88d5760320 3429 return( ret );
kenjiArai 0:5b88d5760320 3430 }
kenjiArai 0:5b88d5760320 3431
kenjiArai 0:5b88d5760320 3432 return( MBEDTLS_ERR_SSL_WANT_READ );
kenjiArai 0:5b88d5760320 3433 }
kenjiArai 0:5b88d5760320 3434 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 3435 else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
kenjiArai 0:5b88d5760320 3436 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
kenjiArai 0:5b88d5760320 3437 {
kenjiArai 0:5b88d5760320 3438 if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 3439 {
kenjiArai 0:5b88d5760320 3440 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
kenjiArai 0:5b88d5760320 3441 return( ret );
kenjiArai 0:5b88d5760320 3442 }
kenjiArai 0:5b88d5760320 3443
kenjiArai 0:5b88d5760320 3444 return( MBEDTLS_ERR_SSL_WANT_READ );
kenjiArai 0:5b88d5760320 3445 }
kenjiArai 0:5b88d5760320 3446 #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
kenjiArai 0:5b88d5760320 3447 }
kenjiArai 0:5b88d5760320 3448
kenjiArai 0:5b88d5760320 3449 if( ret < 0 )
kenjiArai 0:5b88d5760320 3450 return( ret );
kenjiArai 0:5b88d5760320 3451
kenjiArai 0:5b88d5760320 3452 ssl->in_left = ret;
kenjiArai 0:5b88d5760320 3453 }
kenjiArai 0:5b88d5760320 3454 else
kenjiArai 0:5b88d5760320 3455 #endif
kenjiArai 0:5b88d5760320 3456 {
kenjiArai 0:5b88d5760320 3457 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
kenjiArai 0:5b88d5760320 3458 ssl->in_left, nb_want ) );
kenjiArai 0:5b88d5760320 3459
kenjiArai 0:5b88d5760320 3460 while( ssl->in_left < nb_want )
kenjiArai 0:5b88d5760320 3461 {
kenjiArai 0:5b88d5760320 3462 len = nb_want - ssl->in_left;
kenjiArai 0:5b88d5760320 3463
kenjiArai 0:5b88d5760320 3464 if( ssl_check_timer( ssl ) != 0 )
kenjiArai 0:5b88d5760320 3465 ret = MBEDTLS_ERR_SSL_TIMEOUT;
kenjiArai 0:5b88d5760320 3466 else
kenjiArai 0:5b88d5760320 3467 {
kenjiArai 0:5b88d5760320 3468 if( ssl->f_recv_timeout != NULL )
kenjiArai 0:5b88d5760320 3469 {
kenjiArai 0:5b88d5760320 3470 ret = ssl->f_recv_timeout( ssl->p_bio,
kenjiArai 0:5b88d5760320 3471 ssl->in_hdr + ssl->in_left, len,
kenjiArai 0:5b88d5760320 3472 ssl->conf->read_timeout );
kenjiArai 0:5b88d5760320 3473 }
kenjiArai 0:5b88d5760320 3474 else
kenjiArai 0:5b88d5760320 3475 {
kenjiArai 0:5b88d5760320 3476 ret = ssl->f_recv( ssl->p_bio,
kenjiArai 0:5b88d5760320 3477 ssl->in_hdr + ssl->in_left, len );
kenjiArai 0:5b88d5760320 3478 }
kenjiArai 0:5b88d5760320 3479 }
kenjiArai 0:5b88d5760320 3480
kenjiArai 0:5b88d5760320 3481 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
kenjiArai 0:5b88d5760320 3482 ssl->in_left, nb_want ) );
kenjiArai 0:5b88d5760320 3483 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
kenjiArai 0:5b88d5760320 3484
kenjiArai 0:5b88d5760320 3485 if( ret == 0 )
kenjiArai 0:5b88d5760320 3486 return( MBEDTLS_ERR_SSL_CONN_EOF );
kenjiArai 0:5b88d5760320 3487
kenjiArai 0:5b88d5760320 3488 if( ret < 0 )
kenjiArai 0:5b88d5760320 3489 return( ret );
kenjiArai 0:5b88d5760320 3490
kenjiArai 0:5b88d5760320 3491 if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
kenjiArai 0:5b88d5760320 3492 {
kenjiArai 0:5b88d5760320 3493 MBEDTLS_SSL_DEBUG_MSG( 1,
kenjiArai 0:5b88d5760320 3494 ( "f_recv returned %d bytes but only %lu were requested",
kenjiArai 0:5b88d5760320 3495 ret, (unsigned long)len ) );
kenjiArai 0:5b88d5760320 3496 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3497 }
kenjiArai 0:5b88d5760320 3498
kenjiArai 0:5b88d5760320 3499 ssl->in_left += ret;
kenjiArai 0:5b88d5760320 3500 }
kenjiArai 0:5b88d5760320 3501 }
kenjiArai 0:5b88d5760320 3502
kenjiArai 0:5b88d5760320 3503 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
kenjiArai 0:5b88d5760320 3504
kenjiArai 0:5b88d5760320 3505 return( 0 );
kenjiArai 0:5b88d5760320 3506 }
kenjiArai 0:5b88d5760320 3507
kenjiArai 0:5b88d5760320 3508 /*
kenjiArai 0:5b88d5760320 3509 * Flush any data not yet written
kenjiArai 0:5b88d5760320 3510 */
kenjiArai 0:5b88d5760320 3511 int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3512 {
kenjiArai 0:5b88d5760320 3513 int ret;
kenjiArai 0:5b88d5760320 3514 unsigned char *buf;
kenjiArai 0:5b88d5760320 3515
kenjiArai 0:5b88d5760320 3516 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
kenjiArai 0:5b88d5760320 3517
kenjiArai 0:5b88d5760320 3518 if( ssl->f_send == NULL )
kenjiArai 0:5b88d5760320 3519 {
kenjiArai 0:5b88d5760320 3520 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
kenjiArai 0:5b88d5760320 3521 "or mbedtls_ssl_set_bio()" ) );
kenjiArai 0:5b88d5760320 3522 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 3523 }
kenjiArai 0:5b88d5760320 3524
kenjiArai 0:5b88d5760320 3525 /* Avoid incrementing counter if data is flushed */
kenjiArai 0:5b88d5760320 3526 if( ssl->out_left == 0 )
kenjiArai 0:5b88d5760320 3527 {
kenjiArai 0:5b88d5760320 3528 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
kenjiArai 0:5b88d5760320 3529 return( 0 );
kenjiArai 0:5b88d5760320 3530 }
kenjiArai 0:5b88d5760320 3531
kenjiArai 0:5b88d5760320 3532 while( ssl->out_left > 0 )
kenjiArai 0:5b88d5760320 3533 {
kenjiArai 0:5b88d5760320 3534 MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
kenjiArai 0:5b88d5760320 3535 mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
kenjiArai 0:5b88d5760320 3536
kenjiArai 0:5b88d5760320 3537 buf = ssl->out_hdr - ssl->out_left;
kenjiArai 0:5b88d5760320 3538 ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
kenjiArai 0:5b88d5760320 3539
kenjiArai 0:5b88d5760320 3540 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
kenjiArai 0:5b88d5760320 3541
kenjiArai 0:5b88d5760320 3542 if( ret <= 0 )
kenjiArai 0:5b88d5760320 3543 return( ret );
kenjiArai 0:5b88d5760320 3544
kenjiArai 0:5b88d5760320 3545 if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
kenjiArai 0:5b88d5760320 3546 {
kenjiArai 0:5b88d5760320 3547 MBEDTLS_SSL_DEBUG_MSG( 1,
kenjiArai 0:5b88d5760320 3548 ( "f_send returned %d bytes but only %lu bytes were sent",
kenjiArai 0:5b88d5760320 3549 ret, (unsigned long)ssl->out_left ) );
kenjiArai 0:5b88d5760320 3550 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3551 }
kenjiArai 0:5b88d5760320 3552
kenjiArai 0:5b88d5760320 3553 ssl->out_left -= ret;
kenjiArai 0:5b88d5760320 3554 }
kenjiArai 0:5b88d5760320 3555
kenjiArai 0:5b88d5760320 3556 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 3557 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 3558 {
kenjiArai 0:5b88d5760320 3559 ssl->out_hdr = ssl->out_buf;
kenjiArai 0:5b88d5760320 3560 }
kenjiArai 0:5b88d5760320 3561 else
kenjiArai 0:5b88d5760320 3562 #endif
kenjiArai 0:5b88d5760320 3563 {
kenjiArai 0:5b88d5760320 3564 ssl->out_hdr = ssl->out_buf + 8;
kenjiArai 0:5b88d5760320 3565 }
kenjiArai 0:5b88d5760320 3566 ssl_update_out_pointers( ssl, ssl->transform_out );
kenjiArai 0:5b88d5760320 3567
kenjiArai 0:5b88d5760320 3568 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
kenjiArai 0:5b88d5760320 3569
kenjiArai 0:5b88d5760320 3570 return( 0 );
kenjiArai 0:5b88d5760320 3571 }
kenjiArai 0:5b88d5760320 3572
kenjiArai 0:5b88d5760320 3573 /*
kenjiArai 0:5b88d5760320 3574 * Functions to handle the DTLS retransmission state machine
kenjiArai 0:5b88d5760320 3575 */
kenjiArai 0:5b88d5760320 3576 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 3577 /*
kenjiArai 0:5b88d5760320 3578 * Append current handshake message to current outgoing flight
kenjiArai 0:5b88d5760320 3579 */
kenjiArai 0:5b88d5760320 3580 static int ssl_flight_append( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3581 {
kenjiArai 0:5b88d5760320 3582 mbedtls_ssl_flight_item *msg;
kenjiArai 0:5b88d5760320 3583 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
kenjiArai 0:5b88d5760320 3584 MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
kenjiArai 0:5b88d5760320 3585 ssl->out_msg, ssl->out_msglen );
kenjiArai 0:5b88d5760320 3586
kenjiArai 0:5b88d5760320 3587 /* Allocate space for current message */
kenjiArai 0:5b88d5760320 3588 if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
kenjiArai 0:5b88d5760320 3589 {
kenjiArai 0:5b88d5760320 3590 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed",
kenjiArai 0:5b88d5760320 3591 sizeof( mbedtls_ssl_flight_item ) ) );
kenjiArai 0:5b88d5760320 3592 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 3593 }
kenjiArai 0:5b88d5760320 3594
kenjiArai 0:5b88d5760320 3595 if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
kenjiArai 0:5b88d5760320 3596 {
kenjiArai 0:5b88d5760320 3597 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) );
kenjiArai 0:5b88d5760320 3598 mbedtls_free( msg );
kenjiArai 0:5b88d5760320 3599 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 3600 }
kenjiArai 0:5b88d5760320 3601
kenjiArai 0:5b88d5760320 3602 /* Copy current handshake message with headers */
kenjiArai 0:5b88d5760320 3603 memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
kenjiArai 0:5b88d5760320 3604 msg->len = ssl->out_msglen;
kenjiArai 0:5b88d5760320 3605 msg->type = ssl->out_msgtype;
kenjiArai 0:5b88d5760320 3606 msg->next = NULL;
kenjiArai 0:5b88d5760320 3607
kenjiArai 0:5b88d5760320 3608 /* Append to the current flight */
kenjiArai 0:5b88d5760320 3609 if( ssl->handshake->flight == NULL )
kenjiArai 0:5b88d5760320 3610 ssl->handshake->flight = msg;
kenjiArai 0:5b88d5760320 3611 else
kenjiArai 0:5b88d5760320 3612 {
kenjiArai 0:5b88d5760320 3613 mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
kenjiArai 0:5b88d5760320 3614 while( cur->next != NULL )
kenjiArai 0:5b88d5760320 3615 cur = cur->next;
kenjiArai 0:5b88d5760320 3616 cur->next = msg;
kenjiArai 0:5b88d5760320 3617 }
kenjiArai 0:5b88d5760320 3618
kenjiArai 0:5b88d5760320 3619 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
kenjiArai 0:5b88d5760320 3620 return( 0 );
kenjiArai 0:5b88d5760320 3621 }
kenjiArai 0:5b88d5760320 3622
kenjiArai 0:5b88d5760320 3623 /*
kenjiArai 0:5b88d5760320 3624 * Free the current flight of handshake messages
kenjiArai 0:5b88d5760320 3625 */
kenjiArai 0:5b88d5760320 3626 static void ssl_flight_free( mbedtls_ssl_flight_item *flight )
kenjiArai 0:5b88d5760320 3627 {
kenjiArai 0:5b88d5760320 3628 mbedtls_ssl_flight_item *cur = flight;
kenjiArai 0:5b88d5760320 3629 mbedtls_ssl_flight_item *next;
kenjiArai 0:5b88d5760320 3630
kenjiArai 0:5b88d5760320 3631 while( cur != NULL )
kenjiArai 0:5b88d5760320 3632 {
kenjiArai 0:5b88d5760320 3633 next = cur->next;
kenjiArai 0:5b88d5760320 3634
kenjiArai 0:5b88d5760320 3635 mbedtls_free( cur->p );
kenjiArai 0:5b88d5760320 3636 mbedtls_free( cur );
kenjiArai 0:5b88d5760320 3637
kenjiArai 0:5b88d5760320 3638 cur = next;
kenjiArai 0:5b88d5760320 3639 }
kenjiArai 0:5b88d5760320 3640 }
kenjiArai 0:5b88d5760320 3641
kenjiArai 0:5b88d5760320 3642 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
kenjiArai 0:5b88d5760320 3643 static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 3644 #endif
kenjiArai 0:5b88d5760320 3645
kenjiArai 0:5b88d5760320 3646 /*
kenjiArai 0:5b88d5760320 3647 * Swap transform_out and out_ctr with the alternative ones
kenjiArai 0:5b88d5760320 3648 */
kenjiArai 0:5b88d5760320 3649 static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3650 {
kenjiArai 0:5b88d5760320 3651 mbedtls_ssl_transform *tmp_transform;
kenjiArai 0:5b88d5760320 3652 unsigned char tmp_out_ctr[8];
kenjiArai 0:5b88d5760320 3653
kenjiArai 0:5b88d5760320 3654 if( ssl->transform_out == ssl->handshake->alt_transform_out )
kenjiArai 0:5b88d5760320 3655 {
kenjiArai 0:5b88d5760320 3656 MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
kenjiArai 0:5b88d5760320 3657 return;
kenjiArai 0:5b88d5760320 3658 }
kenjiArai 0:5b88d5760320 3659
kenjiArai 0:5b88d5760320 3660 MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
kenjiArai 0:5b88d5760320 3661
kenjiArai 0:5b88d5760320 3662 /* Swap transforms */
kenjiArai 0:5b88d5760320 3663 tmp_transform = ssl->transform_out;
kenjiArai 0:5b88d5760320 3664 ssl->transform_out = ssl->handshake->alt_transform_out;
kenjiArai 0:5b88d5760320 3665 ssl->handshake->alt_transform_out = tmp_transform;
kenjiArai 0:5b88d5760320 3666
kenjiArai 0:5b88d5760320 3667 /* Swap epoch + sequence_number */
kenjiArai 0:5b88d5760320 3668 memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
kenjiArai 0:5b88d5760320 3669 memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
kenjiArai 0:5b88d5760320 3670 memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
kenjiArai 0:5b88d5760320 3671
kenjiArai 0:5b88d5760320 3672 /* Adjust to the newly activated transform */
kenjiArai 0:5b88d5760320 3673 ssl_update_out_pointers( ssl, ssl->transform_out );
kenjiArai 0:5b88d5760320 3674
kenjiArai 0:5b88d5760320 3675 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 3676 if( mbedtls_ssl_hw_record_activate != NULL )
kenjiArai 0:5b88d5760320 3677 {
kenjiArai 0:5b88d5760320 3678 if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
kenjiArai 0:5b88d5760320 3679 {
kenjiArai 0:5b88d5760320 3680 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
kenjiArai 0:5b88d5760320 3681 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 3682 }
kenjiArai 0:5b88d5760320 3683 }
kenjiArai 0:5b88d5760320 3684 #endif
kenjiArai 0:5b88d5760320 3685 }
kenjiArai 0:5b88d5760320 3686
kenjiArai 0:5b88d5760320 3687 /*
kenjiArai 0:5b88d5760320 3688 * Retransmit the current flight of messages.
kenjiArai 0:5b88d5760320 3689 */
kenjiArai 0:5b88d5760320 3690 int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3691 {
kenjiArai 0:5b88d5760320 3692 int ret = 0;
kenjiArai 0:5b88d5760320 3693
kenjiArai 0:5b88d5760320 3694 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
kenjiArai 0:5b88d5760320 3695
kenjiArai 0:5b88d5760320 3696 ret = mbedtls_ssl_flight_transmit( ssl );
kenjiArai 0:5b88d5760320 3697
kenjiArai 0:5b88d5760320 3698 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
kenjiArai 0:5b88d5760320 3699
kenjiArai 0:5b88d5760320 3700 return( ret );
kenjiArai 0:5b88d5760320 3701 }
kenjiArai 0:5b88d5760320 3702
kenjiArai 0:5b88d5760320 3703 /*
kenjiArai 0:5b88d5760320 3704 * Transmit or retransmit the current flight of messages.
kenjiArai 0:5b88d5760320 3705 *
kenjiArai 0:5b88d5760320 3706 * Need to remember the current message in case flush_output returns
kenjiArai 0:5b88d5760320 3707 * WANT_WRITE, causing us to exit this function and come back later.
kenjiArai 0:5b88d5760320 3708 * This function must be called until state is no longer SENDING.
kenjiArai 0:5b88d5760320 3709 */
kenjiArai 0:5b88d5760320 3710 int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3711 {
kenjiArai 0:5b88d5760320 3712 int ret;
kenjiArai 0:5b88d5760320 3713 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
kenjiArai 0:5b88d5760320 3714
kenjiArai 0:5b88d5760320 3715 if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
kenjiArai 0:5b88d5760320 3716 {
kenjiArai 0:5b88d5760320 3717 MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) );
kenjiArai 0:5b88d5760320 3718
kenjiArai 0:5b88d5760320 3719 ssl->handshake->cur_msg = ssl->handshake->flight;
kenjiArai 0:5b88d5760320 3720 ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
kenjiArai 0:5b88d5760320 3721 ssl_swap_epochs( ssl );
kenjiArai 0:5b88d5760320 3722
kenjiArai 0:5b88d5760320 3723 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
kenjiArai 0:5b88d5760320 3724 }
kenjiArai 0:5b88d5760320 3725
kenjiArai 0:5b88d5760320 3726 while( ssl->handshake->cur_msg != NULL )
kenjiArai 0:5b88d5760320 3727 {
kenjiArai 0:5b88d5760320 3728 size_t max_frag_len;
kenjiArai 0:5b88d5760320 3729 const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
kenjiArai 0:5b88d5760320 3730
kenjiArai 0:5b88d5760320 3731 int const is_finished =
kenjiArai 0:5b88d5760320 3732 ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 3733 cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
kenjiArai 0:5b88d5760320 3734
kenjiArai 0:5b88d5760320 3735 uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
kenjiArai 0:5b88d5760320 3736 SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
kenjiArai 0:5b88d5760320 3737
kenjiArai 0:5b88d5760320 3738 /* Swap epochs before sending Finished: we can't do it after
kenjiArai 0:5b88d5760320 3739 * sending ChangeCipherSpec, in case write returns WANT_READ.
kenjiArai 0:5b88d5760320 3740 * Must be done before copying, may change out_msg pointer */
kenjiArai 0:5b88d5760320 3741 if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
kenjiArai 0:5b88d5760320 3742 {
kenjiArai 0:5b88d5760320 3743 MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
kenjiArai 0:5b88d5760320 3744 ssl_swap_epochs( ssl );
kenjiArai 0:5b88d5760320 3745 }
kenjiArai 0:5b88d5760320 3746
kenjiArai 0:5b88d5760320 3747 ret = ssl_get_remaining_payload_in_datagram( ssl );
kenjiArai 0:5b88d5760320 3748 if( ret < 0 )
kenjiArai 0:5b88d5760320 3749 return( ret );
kenjiArai 0:5b88d5760320 3750 max_frag_len = (size_t) ret;
kenjiArai 0:5b88d5760320 3751
kenjiArai 0:5b88d5760320 3752 /* CCS is copied as is, while HS messages may need fragmentation */
kenjiArai 0:5b88d5760320 3753 if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
kenjiArai 0:5b88d5760320 3754 {
kenjiArai 0:5b88d5760320 3755 if( max_frag_len == 0 )
kenjiArai 0:5b88d5760320 3756 {
kenjiArai 0:5b88d5760320 3757 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 3758 return( ret );
kenjiArai 0:5b88d5760320 3759
kenjiArai 0:5b88d5760320 3760 continue;
kenjiArai 0:5b88d5760320 3761 }
kenjiArai 0:5b88d5760320 3762
kenjiArai 0:5b88d5760320 3763 memcpy( ssl->out_msg, cur->p, cur->len );
kenjiArai 0:5b88d5760320 3764 ssl->out_msglen = cur->len;
kenjiArai 0:5b88d5760320 3765 ssl->out_msgtype = cur->type;
kenjiArai 0:5b88d5760320 3766
kenjiArai 0:5b88d5760320 3767 /* Update position inside current message */
kenjiArai 0:5b88d5760320 3768 ssl->handshake->cur_msg_p += cur->len;
kenjiArai 0:5b88d5760320 3769 }
kenjiArai 0:5b88d5760320 3770 else
kenjiArai 0:5b88d5760320 3771 {
kenjiArai 0:5b88d5760320 3772 const unsigned char * const p = ssl->handshake->cur_msg_p;
kenjiArai 0:5b88d5760320 3773 const size_t hs_len = cur->len - 12;
kenjiArai 0:5b88d5760320 3774 const size_t frag_off = p - ( cur->p + 12 );
kenjiArai 0:5b88d5760320 3775 const size_t rem_len = hs_len - frag_off;
kenjiArai 0:5b88d5760320 3776 size_t cur_hs_frag_len, max_hs_frag_len;
kenjiArai 0:5b88d5760320 3777
kenjiArai 0:5b88d5760320 3778 if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
kenjiArai 0:5b88d5760320 3779 {
kenjiArai 0:5b88d5760320 3780 if( is_finished )
kenjiArai 0:5b88d5760320 3781 ssl_swap_epochs( ssl );
kenjiArai 0:5b88d5760320 3782
kenjiArai 0:5b88d5760320 3783 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 3784 return( ret );
kenjiArai 0:5b88d5760320 3785
kenjiArai 0:5b88d5760320 3786 continue;
kenjiArai 0:5b88d5760320 3787 }
kenjiArai 0:5b88d5760320 3788 max_hs_frag_len = max_frag_len - 12;
kenjiArai 0:5b88d5760320 3789
kenjiArai 0:5b88d5760320 3790 cur_hs_frag_len = rem_len > max_hs_frag_len ?
kenjiArai 0:5b88d5760320 3791 max_hs_frag_len : rem_len;
kenjiArai 0:5b88d5760320 3792
kenjiArai 0:5b88d5760320 3793 if( frag_off == 0 && cur_hs_frag_len != hs_len )
kenjiArai 0:5b88d5760320 3794 {
kenjiArai 0:5b88d5760320 3795 MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
kenjiArai 0:5b88d5760320 3796 (unsigned) cur_hs_frag_len,
kenjiArai 0:5b88d5760320 3797 (unsigned) max_hs_frag_len ) );
kenjiArai 0:5b88d5760320 3798 }
kenjiArai 0:5b88d5760320 3799
kenjiArai 0:5b88d5760320 3800 /* Messages are stored with handshake headers as if not fragmented,
kenjiArai 0:5b88d5760320 3801 * copy beginning of headers then fill fragmentation fields.
kenjiArai 0:5b88d5760320 3802 * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
kenjiArai 0:5b88d5760320 3803 memcpy( ssl->out_msg, cur->p, 6 );
kenjiArai 0:5b88d5760320 3804
kenjiArai 0:5b88d5760320 3805 ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff );
kenjiArai 0:5b88d5760320 3806 ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff );
kenjiArai 0:5b88d5760320 3807 ssl->out_msg[8] = ( ( frag_off ) & 0xff );
kenjiArai 0:5b88d5760320 3808
kenjiArai 0:5b88d5760320 3809 ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff );
kenjiArai 0:5b88d5760320 3810 ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff );
kenjiArai 0:5b88d5760320 3811 ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff );
kenjiArai 0:5b88d5760320 3812
kenjiArai 0:5b88d5760320 3813 MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
kenjiArai 0:5b88d5760320 3814
kenjiArai 0:5b88d5760320 3815 /* Copy the handshake message content and set records fields */
kenjiArai 0:5b88d5760320 3816 memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
kenjiArai 0:5b88d5760320 3817 ssl->out_msglen = cur_hs_frag_len + 12;
kenjiArai 0:5b88d5760320 3818 ssl->out_msgtype = cur->type;
kenjiArai 0:5b88d5760320 3819
kenjiArai 0:5b88d5760320 3820 /* Update position inside current message */
kenjiArai 0:5b88d5760320 3821 ssl->handshake->cur_msg_p += cur_hs_frag_len;
kenjiArai 0:5b88d5760320 3822 }
kenjiArai 0:5b88d5760320 3823
kenjiArai 0:5b88d5760320 3824 /* If done with the current message move to the next one if any */
kenjiArai 0:5b88d5760320 3825 if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
kenjiArai 0:5b88d5760320 3826 {
kenjiArai 0:5b88d5760320 3827 if( cur->next != NULL )
kenjiArai 0:5b88d5760320 3828 {
kenjiArai 0:5b88d5760320 3829 ssl->handshake->cur_msg = cur->next;
kenjiArai 0:5b88d5760320 3830 ssl->handshake->cur_msg_p = cur->next->p + 12;
kenjiArai 0:5b88d5760320 3831 }
kenjiArai 0:5b88d5760320 3832 else
kenjiArai 0:5b88d5760320 3833 {
kenjiArai 0:5b88d5760320 3834 ssl->handshake->cur_msg = NULL;
kenjiArai 0:5b88d5760320 3835 ssl->handshake->cur_msg_p = NULL;
kenjiArai 0:5b88d5760320 3836 }
kenjiArai 0:5b88d5760320 3837 }
kenjiArai 0:5b88d5760320 3838
kenjiArai 0:5b88d5760320 3839 /* Actually send the message out */
kenjiArai 0:5b88d5760320 3840 if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
kenjiArai 0:5b88d5760320 3841 {
kenjiArai 0:5b88d5760320 3842 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
kenjiArai 0:5b88d5760320 3843 return( ret );
kenjiArai 0:5b88d5760320 3844 }
kenjiArai 0:5b88d5760320 3845 }
kenjiArai 0:5b88d5760320 3846
kenjiArai 0:5b88d5760320 3847 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 3848 return( ret );
kenjiArai 0:5b88d5760320 3849
kenjiArai 0:5b88d5760320 3850 /* Update state and set timer */
kenjiArai 0:5b88d5760320 3851 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 3852 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
kenjiArai 0:5b88d5760320 3853 else
kenjiArai 0:5b88d5760320 3854 {
kenjiArai 0:5b88d5760320 3855 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
kenjiArai 0:5b88d5760320 3856 ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
kenjiArai 0:5b88d5760320 3857 }
kenjiArai 0:5b88d5760320 3858
kenjiArai 0:5b88d5760320 3859 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
kenjiArai 0:5b88d5760320 3860
kenjiArai 0:5b88d5760320 3861 return( 0 );
kenjiArai 0:5b88d5760320 3862 }
kenjiArai 0:5b88d5760320 3863
kenjiArai 0:5b88d5760320 3864 /*
kenjiArai 0:5b88d5760320 3865 * To be called when the last message of an incoming flight is received.
kenjiArai 0:5b88d5760320 3866 */
kenjiArai 0:5b88d5760320 3867 void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3868 {
kenjiArai 0:5b88d5760320 3869 /* We won't need to resend that one any more */
kenjiArai 0:5b88d5760320 3870 ssl_flight_free( ssl->handshake->flight );
kenjiArai 0:5b88d5760320 3871 ssl->handshake->flight = NULL;
kenjiArai 0:5b88d5760320 3872 ssl->handshake->cur_msg = NULL;
kenjiArai 0:5b88d5760320 3873
kenjiArai 0:5b88d5760320 3874 /* The next incoming flight will start with this msg_seq */
kenjiArai 0:5b88d5760320 3875 ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
kenjiArai 0:5b88d5760320 3876
kenjiArai 0:5b88d5760320 3877 /* We don't want to remember CCS's across flight boundaries. */
kenjiArai 0:5b88d5760320 3878 ssl->handshake->buffering.seen_ccs = 0;
kenjiArai 0:5b88d5760320 3879
kenjiArai 0:5b88d5760320 3880 /* Clear future message buffering structure. */
kenjiArai 0:5b88d5760320 3881 ssl_buffering_free( ssl );
kenjiArai 0:5b88d5760320 3882
kenjiArai 0:5b88d5760320 3883 /* Cancel timer */
kenjiArai 0:5b88d5760320 3884 ssl_set_timer( ssl, 0 );
kenjiArai 0:5b88d5760320 3885
kenjiArai 0:5b88d5760320 3886 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 3887 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
kenjiArai 0:5b88d5760320 3888 {
kenjiArai 0:5b88d5760320 3889 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
kenjiArai 0:5b88d5760320 3890 }
kenjiArai 0:5b88d5760320 3891 else
kenjiArai 0:5b88d5760320 3892 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
kenjiArai 0:5b88d5760320 3893 }
kenjiArai 0:5b88d5760320 3894
kenjiArai 0:5b88d5760320 3895 /*
kenjiArai 0:5b88d5760320 3896 * To be called when the last message of an outgoing flight is send.
kenjiArai 0:5b88d5760320 3897 */
kenjiArai 0:5b88d5760320 3898 void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3899 {
kenjiArai 0:5b88d5760320 3900 ssl_reset_retransmit_timeout( ssl );
kenjiArai 0:5b88d5760320 3901 ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
kenjiArai 0:5b88d5760320 3902
kenjiArai 0:5b88d5760320 3903 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 3904 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
kenjiArai 0:5b88d5760320 3905 {
kenjiArai 0:5b88d5760320 3906 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
kenjiArai 0:5b88d5760320 3907 }
kenjiArai 0:5b88d5760320 3908 else
kenjiArai 0:5b88d5760320 3909 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
kenjiArai 0:5b88d5760320 3910 }
kenjiArai 0:5b88d5760320 3911 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 3912
kenjiArai 0:5b88d5760320 3913 /*
kenjiArai 0:5b88d5760320 3914 * Handshake layer functions
kenjiArai 0:5b88d5760320 3915 */
kenjiArai 0:5b88d5760320 3916
kenjiArai 0:5b88d5760320 3917 /*
kenjiArai 0:5b88d5760320 3918 * Write (DTLS: or queue) current handshake (including CCS) message.
kenjiArai 0:5b88d5760320 3919 *
kenjiArai 0:5b88d5760320 3920 * - fill in handshake headers
kenjiArai 0:5b88d5760320 3921 * - update handshake checksum
kenjiArai 0:5b88d5760320 3922 * - DTLS: save message for resending
kenjiArai 0:5b88d5760320 3923 * - then pass to the record layer
kenjiArai 0:5b88d5760320 3924 *
kenjiArai 0:5b88d5760320 3925 * DTLS: except for HelloRequest, messages are only queued, and will only be
kenjiArai 0:5b88d5760320 3926 * actually sent when calling flight_transmit() or resend().
kenjiArai 0:5b88d5760320 3927 *
kenjiArai 0:5b88d5760320 3928 * Inputs:
kenjiArai 0:5b88d5760320 3929 * - ssl->out_msglen: 4 + actual handshake message len
kenjiArai 0:5b88d5760320 3930 * (4 is the size of handshake headers for TLS)
kenjiArai 0:5b88d5760320 3931 * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
kenjiArai 0:5b88d5760320 3932 * - ssl->out_msg + 4: the handshake message body
kenjiArai 0:5b88d5760320 3933 *
kenjiArai 0:5b88d5760320 3934 * Outputs, ie state before passing to flight_append() or write_record():
kenjiArai 0:5b88d5760320 3935 * - ssl->out_msglen: the length of the record contents
kenjiArai 0:5b88d5760320 3936 * (including handshake headers but excluding record headers)
kenjiArai 0:5b88d5760320 3937 * - ssl->out_msg: the record contents (handshake headers + content)
kenjiArai 0:5b88d5760320 3938 */
kenjiArai 0:5b88d5760320 3939 int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 3940 {
kenjiArai 0:5b88d5760320 3941 int ret;
kenjiArai 0:5b88d5760320 3942 const size_t hs_len = ssl->out_msglen - 4;
kenjiArai 0:5b88d5760320 3943 const unsigned char hs_type = ssl->out_msg[0];
kenjiArai 0:5b88d5760320 3944
kenjiArai 0:5b88d5760320 3945 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) );
kenjiArai 0:5b88d5760320 3946
kenjiArai 0:5b88d5760320 3947 /*
kenjiArai 0:5b88d5760320 3948 * Sanity checks
kenjiArai 0:5b88d5760320 3949 */
kenjiArai 0:5b88d5760320 3950 if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 3951 ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
kenjiArai 0:5b88d5760320 3952 {
kenjiArai 0:5b88d5760320 3953 /* In SSLv3, the client might send a NoCertificate alert. */
kenjiArai 0:5b88d5760320 3954 #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 3955 if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
kenjiArai 0:5b88d5760320 3956 ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT &&
kenjiArai 0:5b88d5760320 3957 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) )
kenjiArai 0:5b88d5760320 3958 #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 3959 {
kenjiArai 0:5b88d5760320 3960 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 3961 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3962 }
kenjiArai 0:5b88d5760320 3963 }
kenjiArai 0:5b88d5760320 3964
kenjiArai 0:5b88d5760320 3965 /* Whenever we send anything different from a
kenjiArai 0:5b88d5760320 3966 * HelloRequest we should be in a handshake - double check. */
kenjiArai 0:5b88d5760320 3967 if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 3968 hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
kenjiArai 0:5b88d5760320 3969 ssl->handshake == NULL )
kenjiArai 0:5b88d5760320 3970 {
kenjiArai 0:5b88d5760320 3971 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 3972 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3973 }
kenjiArai 0:5b88d5760320 3974
kenjiArai 0:5b88d5760320 3975 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 3976 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 3977 ssl->handshake != NULL &&
kenjiArai 0:5b88d5760320 3978 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
kenjiArai 0:5b88d5760320 3979 {
kenjiArai 0:5b88d5760320 3980 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 3981 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 3982 }
kenjiArai 0:5b88d5760320 3983 #endif
kenjiArai 0:5b88d5760320 3984
kenjiArai 0:5b88d5760320 3985 /* Double-check that we did not exceed the bounds
kenjiArai 0:5b88d5760320 3986 * of the outgoing record buffer.
kenjiArai 0:5b88d5760320 3987 * This should never fail as the various message
kenjiArai 0:5b88d5760320 3988 * writing functions must obey the bounds of the
kenjiArai 0:5b88d5760320 3989 * outgoing record buffer, but better be safe.
kenjiArai 0:5b88d5760320 3990 *
kenjiArai 0:5b88d5760320 3991 * Note: We deliberately do not check for the MTU or MFL here.
kenjiArai 0:5b88d5760320 3992 */
kenjiArai 0:5b88d5760320 3993 if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
kenjiArai 0:5b88d5760320 3994 {
kenjiArai 0:5b88d5760320 3995 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
kenjiArai 0:5b88d5760320 3996 "size %u, maximum %u",
kenjiArai 0:5b88d5760320 3997 (unsigned) ssl->out_msglen,
kenjiArai 0:5b88d5760320 3998 (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
kenjiArai 0:5b88d5760320 3999 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 4000 }
kenjiArai 0:5b88d5760320 4001
kenjiArai 0:5b88d5760320 4002 /*
kenjiArai 0:5b88d5760320 4003 * Fill handshake headers
kenjiArai 0:5b88d5760320 4004 */
kenjiArai 0:5b88d5760320 4005 if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
kenjiArai 0:5b88d5760320 4006 {
kenjiArai 0:5b88d5760320 4007 ssl->out_msg[1] = (unsigned char)( hs_len >> 16 );
kenjiArai 0:5b88d5760320 4008 ssl->out_msg[2] = (unsigned char)( hs_len >> 8 );
kenjiArai 0:5b88d5760320 4009 ssl->out_msg[3] = (unsigned char)( hs_len );
kenjiArai 0:5b88d5760320 4010
kenjiArai 0:5b88d5760320 4011 /*
kenjiArai 0:5b88d5760320 4012 * DTLS has additional fields in the Handshake layer,
kenjiArai 0:5b88d5760320 4013 * between the length field and the actual payload:
kenjiArai 0:5b88d5760320 4014 * uint16 message_seq;
kenjiArai 0:5b88d5760320 4015 * uint24 fragment_offset;
kenjiArai 0:5b88d5760320 4016 * uint24 fragment_length;
kenjiArai 0:5b88d5760320 4017 */
kenjiArai 0:5b88d5760320 4018 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4019 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 4020 {
kenjiArai 0:5b88d5760320 4021 /* Make room for the additional DTLS fields */
kenjiArai 0:5b88d5760320 4022 if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
kenjiArai 0:5b88d5760320 4023 {
kenjiArai 0:5b88d5760320 4024 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
kenjiArai 0:5b88d5760320 4025 "size %u, maximum %u",
kenjiArai 0:5b88d5760320 4026 (unsigned) ( hs_len ),
kenjiArai 0:5b88d5760320 4027 (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) );
kenjiArai 0:5b88d5760320 4028 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 4029 }
kenjiArai 0:5b88d5760320 4030
kenjiArai 0:5b88d5760320 4031 memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len );
kenjiArai 0:5b88d5760320 4032 ssl->out_msglen += 8;
kenjiArai 0:5b88d5760320 4033
kenjiArai 0:5b88d5760320 4034 /* Write message_seq and update it, except for HelloRequest */
kenjiArai 0:5b88d5760320 4035 if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
kenjiArai 0:5b88d5760320 4036 {
kenjiArai 0:5b88d5760320 4037 ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
kenjiArai 0:5b88d5760320 4038 ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF;
kenjiArai 0:5b88d5760320 4039 ++( ssl->handshake->out_msg_seq );
kenjiArai 0:5b88d5760320 4040 }
kenjiArai 0:5b88d5760320 4041 else
kenjiArai 0:5b88d5760320 4042 {
kenjiArai 0:5b88d5760320 4043 ssl->out_msg[4] = 0;
kenjiArai 0:5b88d5760320 4044 ssl->out_msg[5] = 0;
kenjiArai 0:5b88d5760320 4045 }
kenjiArai 0:5b88d5760320 4046
kenjiArai 0:5b88d5760320 4047 /* Handshake hashes are computed without fragmentation,
kenjiArai 0:5b88d5760320 4048 * so set frag_offset = 0 and frag_len = hs_len for now */
kenjiArai 0:5b88d5760320 4049 memset( ssl->out_msg + 6, 0x00, 3 );
kenjiArai 0:5b88d5760320 4050 memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
kenjiArai 0:5b88d5760320 4051 }
kenjiArai 0:5b88d5760320 4052 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 4053
kenjiArai 0:5b88d5760320 4054 /* Update running hashes of handshake messages seen */
kenjiArai 0:5b88d5760320 4055 if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
kenjiArai 0:5b88d5760320 4056 ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
kenjiArai 0:5b88d5760320 4057 }
kenjiArai 0:5b88d5760320 4058
kenjiArai 0:5b88d5760320 4059 /* Either send now, or just save to be sent (and resent) later */
kenjiArai 0:5b88d5760320 4060 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4061 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 4062 ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 4063 hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
kenjiArai 0:5b88d5760320 4064 {
kenjiArai 0:5b88d5760320 4065 if( ( ret = ssl_flight_append( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 4066 {
kenjiArai 0:5b88d5760320 4067 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
kenjiArai 0:5b88d5760320 4068 return( ret );
kenjiArai 0:5b88d5760320 4069 }
kenjiArai 0:5b88d5760320 4070 }
kenjiArai 0:5b88d5760320 4071 else
kenjiArai 0:5b88d5760320 4072 #endif
kenjiArai 0:5b88d5760320 4073 {
kenjiArai 0:5b88d5760320 4074 if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
kenjiArai 0:5b88d5760320 4075 {
kenjiArai 0:5b88d5760320 4076 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
kenjiArai 0:5b88d5760320 4077 return( ret );
kenjiArai 0:5b88d5760320 4078 }
kenjiArai 0:5b88d5760320 4079 }
kenjiArai 0:5b88d5760320 4080
kenjiArai 0:5b88d5760320 4081 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
kenjiArai 0:5b88d5760320 4082
kenjiArai 0:5b88d5760320 4083 return( 0 );
kenjiArai 0:5b88d5760320 4084 }
kenjiArai 0:5b88d5760320 4085
kenjiArai 0:5b88d5760320 4086 /*
kenjiArai 0:5b88d5760320 4087 * Record layer functions
kenjiArai 0:5b88d5760320 4088 */
kenjiArai 0:5b88d5760320 4089
kenjiArai 0:5b88d5760320 4090 /*
kenjiArai 0:5b88d5760320 4091 * Write current record.
kenjiArai 0:5b88d5760320 4092 *
kenjiArai 0:5b88d5760320 4093 * Uses:
kenjiArai 0:5b88d5760320 4094 * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
kenjiArai 0:5b88d5760320 4095 * - ssl->out_msglen: length of the record content (excl headers)
kenjiArai 0:5b88d5760320 4096 * - ssl->out_msg: record content
kenjiArai 0:5b88d5760320 4097 */
kenjiArai 0:5b88d5760320 4098 int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
kenjiArai 0:5b88d5760320 4099 {
kenjiArai 0:5b88d5760320 4100 int ret, done = 0;
kenjiArai 0:5b88d5760320 4101 size_t len = ssl->out_msglen;
kenjiArai 0:5b88d5760320 4102 uint8_t flush = force_flush;
kenjiArai 0:5b88d5760320 4103
kenjiArai 0:5b88d5760320 4104 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
kenjiArai 0:5b88d5760320 4105
kenjiArai 0:5b88d5760320 4106 #if defined(MBEDTLS_ZLIB_SUPPORT)
kenjiArai 0:5b88d5760320 4107 if( ssl->transform_out != NULL &&
kenjiArai 0:5b88d5760320 4108 ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
kenjiArai 0:5b88d5760320 4109 {
kenjiArai 0:5b88d5760320 4110 if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 4111 {
kenjiArai 0:5b88d5760320 4112 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
kenjiArai 0:5b88d5760320 4113 return( ret );
kenjiArai 0:5b88d5760320 4114 }
kenjiArai 0:5b88d5760320 4115
kenjiArai 0:5b88d5760320 4116 len = ssl->out_msglen;
kenjiArai 0:5b88d5760320 4117 }
kenjiArai 0:5b88d5760320 4118 #endif /*MBEDTLS_ZLIB_SUPPORT */
kenjiArai 0:5b88d5760320 4119
kenjiArai 0:5b88d5760320 4120 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 4121 if( mbedtls_ssl_hw_record_write != NULL )
kenjiArai 0:5b88d5760320 4122 {
kenjiArai 0:5b88d5760320 4123 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
kenjiArai 0:5b88d5760320 4124
kenjiArai 0:5b88d5760320 4125 ret = mbedtls_ssl_hw_record_write( ssl );
kenjiArai 0:5b88d5760320 4126 if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
kenjiArai 0:5b88d5760320 4127 {
kenjiArai 0:5b88d5760320 4128 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
kenjiArai 0:5b88d5760320 4129 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 4130 }
kenjiArai 0:5b88d5760320 4131
kenjiArai 0:5b88d5760320 4132 if( ret == 0 )
kenjiArai 0:5b88d5760320 4133 done = 1;
kenjiArai 0:5b88d5760320 4134 }
kenjiArai 0:5b88d5760320 4135 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
kenjiArai 0:5b88d5760320 4136 if( !done )
kenjiArai 0:5b88d5760320 4137 {
kenjiArai 0:5b88d5760320 4138 unsigned i;
kenjiArai 0:5b88d5760320 4139 size_t protected_record_size;
kenjiArai 0:5b88d5760320 4140
kenjiArai 0:5b88d5760320 4141 /* Skip writing the record content type to after the encryption,
kenjiArai 0:5b88d5760320 4142 * as it may change when using the CID extension. */
kenjiArai 0:5b88d5760320 4143
kenjiArai 0:5b88d5760320 4144 mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
kenjiArai 0:5b88d5760320 4145 ssl->conf->transport, ssl->out_hdr + 1 );
kenjiArai 0:5b88d5760320 4146
kenjiArai 0:5b88d5760320 4147 memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
kenjiArai 0:5b88d5760320 4148 ssl->out_len[0] = (unsigned char)( len >> 8 );
kenjiArai 0:5b88d5760320 4149 ssl->out_len[1] = (unsigned char)( len );
kenjiArai 0:5b88d5760320 4150
kenjiArai 0:5b88d5760320 4151 if( ssl->transform_out != NULL )
kenjiArai 0:5b88d5760320 4152 {
kenjiArai 0:5b88d5760320 4153 mbedtls_record rec;
kenjiArai 0:5b88d5760320 4154
kenjiArai 0:5b88d5760320 4155 rec.buf = ssl->out_iv;
kenjiArai 0:5b88d5760320 4156 rec.buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN -
kenjiArai 0:5b88d5760320 4157 ( ssl->out_iv - ssl->out_buf );
kenjiArai 0:5b88d5760320 4158 rec.data_len = ssl->out_msglen;
kenjiArai 0:5b88d5760320 4159 rec.data_offset = ssl->out_msg - rec.buf;
kenjiArai 0:5b88d5760320 4160
kenjiArai 0:5b88d5760320 4161 memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
kenjiArai 0:5b88d5760320 4162 mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
kenjiArai 0:5b88d5760320 4163 ssl->conf->transport, rec.ver );
kenjiArai 0:5b88d5760320 4164 rec.type = ssl->out_msgtype;
kenjiArai 0:5b88d5760320 4165
kenjiArai 0:5b88d5760320 4166 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 4167 /* The CID is set by mbedtls_ssl_encrypt_buf(). */
kenjiArai 0:5b88d5760320 4168 rec.cid_len = 0;
kenjiArai 0:5b88d5760320 4169 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 4170
kenjiArai 0:5b88d5760320 4171 if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec,
kenjiArai 0:5b88d5760320 4172 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
kenjiArai 0:5b88d5760320 4173 {
kenjiArai 0:5b88d5760320 4174 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
kenjiArai 0:5b88d5760320 4175 return( ret );
kenjiArai 0:5b88d5760320 4176 }
kenjiArai 0:5b88d5760320 4177
kenjiArai 0:5b88d5760320 4178 if( rec.data_offset != 0 )
kenjiArai 0:5b88d5760320 4179 {
kenjiArai 0:5b88d5760320 4180 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 4181 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 4182 }
kenjiArai 0:5b88d5760320 4183
kenjiArai 0:5b88d5760320 4184 /* Update the record content type and CID. */
kenjiArai 0:5b88d5760320 4185 ssl->out_msgtype = rec.type;
kenjiArai 0:5b88d5760320 4186 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID )
kenjiArai 0:5b88d5760320 4187 memcpy( ssl->out_cid, rec.cid, rec.cid_len );
kenjiArai 0:5b88d5760320 4188 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 4189 ssl->out_msglen = len = rec.data_len;
kenjiArai 0:5b88d5760320 4190 ssl->out_len[0] = (unsigned char)( rec.data_len >> 8 );
kenjiArai 0:5b88d5760320 4191 ssl->out_len[1] = (unsigned char)( rec.data_len );
kenjiArai 0:5b88d5760320 4192 }
kenjiArai 0:5b88d5760320 4193
kenjiArai 0:5b88d5760320 4194 protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl );
kenjiArai 0:5b88d5760320 4195
kenjiArai 0:5b88d5760320 4196 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4197 /* In case of DTLS, double-check that we don't exceed
kenjiArai 0:5b88d5760320 4198 * the remaining space in the datagram. */
kenjiArai 0:5b88d5760320 4199 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 4200 {
kenjiArai 0:5b88d5760320 4201 ret = ssl_get_remaining_space_in_datagram( ssl );
kenjiArai 0:5b88d5760320 4202 if( ret < 0 )
kenjiArai 0:5b88d5760320 4203 return( ret );
kenjiArai 0:5b88d5760320 4204
kenjiArai 0:5b88d5760320 4205 if( protected_record_size > (size_t) ret )
kenjiArai 0:5b88d5760320 4206 {
kenjiArai 0:5b88d5760320 4207 /* Should never happen */
kenjiArai 0:5b88d5760320 4208 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 4209 }
kenjiArai 0:5b88d5760320 4210 }
kenjiArai 0:5b88d5760320 4211 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 4212
kenjiArai 0:5b88d5760320 4213 /* Now write the potentially updated record content type. */
kenjiArai 0:5b88d5760320 4214 ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
kenjiArai 0:5b88d5760320 4215
kenjiArai 0:5b88d5760320 4216 MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
kenjiArai 0:5b88d5760320 4217 "version = [%d:%d], msglen = %d",
kenjiArai 0:5b88d5760320 4218 ssl->out_hdr[0], ssl->out_hdr[1],
kenjiArai 0:5b88d5760320 4219 ssl->out_hdr[2], len ) );
kenjiArai 0:5b88d5760320 4220
kenjiArai 0:5b88d5760320 4221 MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
kenjiArai 0:5b88d5760320 4222 ssl->out_hdr, protected_record_size );
kenjiArai 0:5b88d5760320 4223
kenjiArai 0:5b88d5760320 4224 ssl->out_left += protected_record_size;
kenjiArai 0:5b88d5760320 4225 ssl->out_hdr += protected_record_size;
kenjiArai 0:5b88d5760320 4226 ssl_update_out_pointers( ssl, ssl->transform_out );
kenjiArai 0:5b88d5760320 4227
kenjiArai 0:5b88d5760320 4228 for( i = 8; i > ssl_ep_len( ssl ); i-- )
kenjiArai 0:5b88d5760320 4229 if( ++ssl->cur_out_ctr[i - 1] != 0 )
kenjiArai 0:5b88d5760320 4230 break;
kenjiArai 0:5b88d5760320 4231
kenjiArai 0:5b88d5760320 4232 /* The loop goes to its end iff the counter is wrapping */
kenjiArai 0:5b88d5760320 4233 if( i == ssl_ep_len( ssl ) )
kenjiArai 0:5b88d5760320 4234 {
kenjiArai 0:5b88d5760320 4235 MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
kenjiArai 0:5b88d5760320 4236 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
kenjiArai 0:5b88d5760320 4237 }
kenjiArai 0:5b88d5760320 4238 }
kenjiArai 0:5b88d5760320 4239
kenjiArai 0:5b88d5760320 4240 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4241 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 4242 flush == SSL_DONT_FORCE_FLUSH )
kenjiArai 0:5b88d5760320 4243 {
kenjiArai 0:5b88d5760320 4244 size_t remaining;
kenjiArai 0:5b88d5760320 4245 ret = ssl_get_remaining_payload_in_datagram( ssl );
kenjiArai 0:5b88d5760320 4246 if( ret < 0 )
kenjiArai 0:5b88d5760320 4247 {
kenjiArai 0:5b88d5760320 4248 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
kenjiArai 0:5b88d5760320 4249 ret );
kenjiArai 0:5b88d5760320 4250 return( ret );
kenjiArai 0:5b88d5760320 4251 }
kenjiArai 0:5b88d5760320 4252
kenjiArai 0:5b88d5760320 4253 remaining = (size_t) ret;
kenjiArai 0:5b88d5760320 4254 if( remaining == 0 )
kenjiArai 0:5b88d5760320 4255 {
kenjiArai 0:5b88d5760320 4256 flush = SSL_FORCE_FLUSH;
kenjiArai 0:5b88d5760320 4257 }
kenjiArai 0:5b88d5760320 4258 else
kenjiArai 0:5b88d5760320 4259 {
kenjiArai 0:5b88d5760320 4260 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
kenjiArai 0:5b88d5760320 4261 }
kenjiArai 0:5b88d5760320 4262 }
kenjiArai 0:5b88d5760320 4263 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 4264
kenjiArai 0:5b88d5760320 4265 if( ( flush == SSL_FORCE_FLUSH ) &&
kenjiArai 0:5b88d5760320 4266 ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 4267 {
kenjiArai 0:5b88d5760320 4268 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
kenjiArai 0:5b88d5760320 4269 return( ret );
kenjiArai 0:5b88d5760320 4270 }
kenjiArai 0:5b88d5760320 4271
kenjiArai 0:5b88d5760320 4272 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
kenjiArai 0:5b88d5760320 4273
kenjiArai 0:5b88d5760320 4274 return( 0 );
kenjiArai 0:5b88d5760320 4275 }
kenjiArai 0:5b88d5760320 4276
kenjiArai 0:5b88d5760320 4277 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4278
kenjiArai 0:5b88d5760320 4279 static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 4280 {
kenjiArai 0:5b88d5760320 4281 if( ssl->in_msglen < ssl->in_hslen ||
kenjiArai 0:5b88d5760320 4282 memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
kenjiArai 0:5b88d5760320 4283 memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
kenjiArai 0:5b88d5760320 4284 {
kenjiArai 0:5b88d5760320 4285 return( 1 );
kenjiArai 0:5b88d5760320 4286 }
kenjiArai 0:5b88d5760320 4287 return( 0 );
kenjiArai 0:5b88d5760320 4288 }
kenjiArai 0:5b88d5760320 4289
kenjiArai 0:5b88d5760320 4290 static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl )
kenjiArai 0:5b88d5760320 4291 {
kenjiArai 0:5b88d5760320 4292 return( ( ssl->in_msg[9] << 16 ) |
kenjiArai 0:5b88d5760320 4293 ( ssl->in_msg[10] << 8 ) |
kenjiArai 0:5b88d5760320 4294 ssl->in_msg[11] );
kenjiArai 0:5b88d5760320 4295 }
kenjiArai 0:5b88d5760320 4296
kenjiArai 0:5b88d5760320 4297 static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
kenjiArai 0:5b88d5760320 4298 {
kenjiArai 0:5b88d5760320 4299 return( ( ssl->in_msg[6] << 16 ) |
kenjiArai 0:5b88d5760320 4300 ( ssl->in_msg[7] << 8 ) |
kenjiArai 0:5b88d5760320 4301 ssl->in_msg[8] );
kenjiArai 0:5b88d5760320 4302 }
kenjiArai 0:5b88d5760320 4303
kenjiArai 0:5b88d5760320 4304 static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
kenjiArai 0:5b88d5760320 4305 {
kenjiArai 0:5b88d5760320 4306 uint32_t msg_len, frag_off, frag_len;
kenjiArai 0:5b88d5760320 4307
kenjiArai 0:5b88d5760320 4308 msg_len = ssl_get_hs_total_len( ssl );
kenjiArai 0:5b88d5760320 4309 frag_off = ssl_get_hs_frag_off( ssl );
kenjiArai 0:5b88d5760320 4310 frag_len = ssl_get_hs_frag_len( ssl );
kenjiArai 0:5b88d5760320 4311
kenjiArai 0:5b88d5760320 4312 if( frag_off > msg_len )
kenjiArai 0:5b88d5760320 4313 return( -1 );
kenjiArai 0:5b88d5760320 4314
kenjiArai 0:5b88d5760320 4315 if( frag_len > msg_len - frag_off )
kenjiArai 0:5b88d5760320 4316 return( -1 );
kenjiArai 0:5b88d5760320 4317
kenjiArai 0:5b88d5760320 4318 if( frag_len + 12 > ssl->in_msglen )
kenjiArai 0:5b88d5760320 4319 return( -1 );
kenjiArai 0:5b88d5760320 4320
kenjiArai 0:5b88d5760320 4321 return( 0 );
kenjiArai 0:5b88d5760320 4322 }
kenjiArai 0:5b88d5760320 4323
kenjiArai 0:5b88d5760320 4324 /*
kenjiArai 0:5b88d5760320 4325 * Mark bits in bitmask (used for DTLS HS reassembly)
kenjiArai 0:5b88d5760320 4326 */
kenjiArai 0:5b88d5760320 4327 static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
kenjiArai 0:5b88d5760320 4328 {
kenjiArai 0:5b88d5760320 4329 unsigned int start_bits, end_bits;
kenjiArai 0:5b88d5760320 4330
kenjiArai 0:5b88d5760320 4331 start_bits = 8 - ( offset % 8 );
kenjiArai 0:5b88d5760320 4332 if( start_bits != 8 )
kenjiArai 0:5b88d5760320 4333 {
kenjiArai 0:5b88d5760320 4334 size_t first_byte_idx = offset / 8;
kenjiArai 0:5b88d5760320 4335
kenjiArai 0:5b88d5760320 4336 /* Special case */
kenjiArai 0:5b88d5760320 4337 if( len <= start_bits )
kenjiArai 0:5b88d5760320 4338 {
kenjiArai 0:5b88d5760320 4339 for( ; len != 0; len-- )
kenjiArai 0:5b88d5760320 4340 mask[first_byte_idx] |= 1 << ( start_bits - len );
kenjiArai 0:5b88d5760320 4341
kenjiArai 0:5b88d5760320 4342 /* Avoid potential issues with offset or len becoming invalid */
kenjiArai 0:5b88d5760320 4343 return;
kenjiArai 0:5b88d5760320 4344 }
kenjiArai 0:5b88d5760320 4345
kenjiArai 0:5b88d5760320 4346 offset += start_bits; /* Now offset % 8 == 0 */
kenjiArai 0:5b88d5760320 4347 len -= start_bits;
kenjiArai 0:5b88d5760320 4348
kenjiArai 0:5b88d5760320 4349 for( ; start_bits != 0; start_bits-- )
kenjiArai 0:5b88d5760320 4350 mask[first_byte_idx] |= 1 << ( start_bits - 1 );
kenjiArai 0:5b88d5760320 4351 }
kenjiArai 0:5b88d5760320 4352
kenjiArai 0:5b88d5760320 4353 end_bits = len % 8;
kenjiArai 0:5b88d5760320 4354 if( end_bits != 0 )
kenjiArai 0:5b88d5760320 4355 {
kenjiArai 0:5b88d5760320 4356 size_t last_byte_idx = ( offset + len ) / 8;
kenjiArai 0:5b88d5760320 4357
kenjiArai 0:5b88d5760320 4358 len -= end_bits; /* Now len % 8 == 0 */
kenjiArai 0:5b88d5760320 4359
kenjiArai 0:5b88d5760320 4360 for( ; end_bits != 0; end_bits-- )
kenjiArai 0:5b88d5760320 4361 mask[last_byte_idx] |= 1 << ( 8 - end_bits );
kenjiArai 0:5b88d5760320 4362 }
kenjiArai 0:5b88d5760320 4363
kenjiArai 0:5b88d5760320 4364 memset( mask + offset / 8, 0xFF, len / 8 );
kenjiArai 0:5b88d5760320 4365 }
kenjiArai 0:5b88d5760320 4366
kenjiArai 0:5b88d5760320 4367 /*
kenjiArai 0:5b88d5760320 4368 * Check that bitmask is full
kenjiArai 0:5b88d5760320 4369 */
kenjiArai 0:5b88d5760320 4370 static int ssl_bitmask_check( unsigned char *mask, size_t len )
kenjiArai 0:5b88d5760320 4371 {
kenjiArai 0:5b88d5760320 4372 size_t i;
kenjiArai 0:5b88d5760320 4373
kenjiArai 0:5b88d5760320 4374 for( i = 0; i < len / 8; i++ )
kenjiArai 0:5b88d5760320 4375 if( mask[i] != 0xFF )
kenjiArai 0:5b88d5760320 4376 return( -1 );
kenjiArai 0:5b88d5760320 4377
kenjiArai 0:5b88d5760320 4378 for( i = 0; i < len % 8; i++ )
kenjiArai 0:5b88d5760320 4379 if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
kenjiArai 0:5b88d5760320 4380 return( -1 );
kenjiArai 0:5b88d5760320 4381
kenjiArai 0:5b88d5760320 4382 return( 0 );
kenjiArai 0:5b88d5760320 4383 }
kenjiArai 0:5b88d5760320 4384
kenjiArai 0:5b88d5760320 4385 /* msg_len does not include the handshake header */
kenjiArai 0:5b88d5760320 4386 static size_t ssl_get_reassembly_buffer_size( size_t msg_len,
kenjiArai 0:5b88d5760320 4387 unsigned add_bitmap )
kenjiArai 0:5b88d5760320 4388 {
kenjiArai 0:5b88d5760320 4389 size_t alloc_len;
kenjiArai 0:5b88d5760320 4390
kenjiArai 0:5b88d5760320 4391 alloc_len = 12; /* Handshake header */
kenjiArai 0:5b88d5760320 4392 alloc_len += msg_len; /* Content buffer */
kenjiArai 0:5b88d5760320 4393
kenjiArai 0:5b88d5760320 4394 if( add_bitmap )
kenjiArai 0:5b88d5760320 4395 alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */
kenjiArai 0:5b88d5760320 4396
kenjiArai 0:5b88d5760320 4397 return( alloc_len );
kenjiArai 0:5b88d5760320 4398 }
kenjiArai 0:5b88d5760320 4399
kenjiArai 0:5b88d5760320 4400 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 4401
kenjiArai 0:5b88d5760320 4402 static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl )
kenjiArai 0:5b88d5760320 4403 {
kenjiArai 0:5b88d5760320 4404 return( ( ssl->in_msg[1] << 16 ) |
kenjiArai 0:5b88d5760320 4405 ( ssl->in_msg[2] << 8 ) |
kenjiArai 0:5b88d5760320 4406 ssl->in_msg[3] );
kenjiArai 0:5b88d5760320 4407 }
kenjiArai 0:5b88d5760320 4408
kenjiArai 0:5b88d5760320 4409 int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 4410 {
kenjiArai 0:5b88d5760320 4411 if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
kenjiArai 0:5b88d5760320 4412 {
kenjiArai 0:5b88d5760320 4413 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d",
kenjiArai 0:5b88d5760320 4414 ssl->in_msglen ) );
kenjiArai 0:5b88d5760320 4415 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 4416 }
kenjiArai 0:5b88d5760320 4417
kenjiArai 0:5b88d5760320 4418 ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl );
kenjiArai 0:5b88d5760320 4419
kenjiArai 0:5b88d5760320 4420 MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
kenjiArai 0:5b88d5760320 4421 " %d, type = %d, hslen = %d",
kenjiArai 0:5b88d5760320 4422 ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
kenjiArai 0:5b88d5760320 4423
kenjiArai 0:5b88d5760320 4424 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4425 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 4426 {
kenjiArai 0:5b88d5760320 4427 int ret;
kenjiArai 0:5b88d5760320 4428 unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
kenjiArai 0:5b88d5760320 4429
kenjiArai 0:5b88d5760320 4430 if( ssl_check_hs_header( ssl ) != 0 )
kenjiArai 0:5b88d5760320 4431 {
kenjiArai 0:5b88d5760320 4432 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) );
kenjiArai 0:5b88d5760320 4433 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 4434 }
kenjiArai 0:5b88d5760320 4435
kenjiArai 0:5b88d5760320 4436 if( ssl->handshake != NULL &&
kenjiArai 0:5b88d5760320 4437 ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
kenjiArai 0:5b88d5760320 4438 recv_msg_seq != ssl->handshake->in_msg_seq ) ||
kenjiArai 0:5b88d5760320 4439 ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
kenjiArai 0:5b88d5760320 4440 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) )
kenjiArai 0:5b88d5760320 4441 {
kenjiArai 0:5b88d5760320 4442 if( recv_msg_seq > ssl->handshake->in_msg_seq )
kenjiArai 0:5b88d5760320 4443 {
kenjiArai 0:5b88d5760320 4444 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)",
kenjiArai 0:5b88d5760320 4445 recv_msg_seq,
kenjiArai 0:5b88d5760320 4446 ssl->handshake->in_msg_seq ) );
kenjiArai 0:5b88d5760320 4447 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
kenjiArai 0:5b88d5760320 4448 }
kenjiArai 0:5b88d5760320 4449
kenjiArai 0:5b88d5760320 4450 /* Retransmit only on last message from previous flight, to avoid
kenjiArai 0:5b88d5760320 4451 * too many retransmissions.
kenjiArai 0:5b88d5760320 4452 * Besides, No sane server ever retransmits HelloVerifyRequest */
kenjiArai 0:5b88d5760320 4453 if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
kenjiArai 0:5b88d5760320 4454 ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
kenjiArai 0:5b88d5760320 4455 {
kenjiArai 0:5b88d5760320 4456 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
kenjiArai 0:5b88d5760320 4457 "message_seq = %d, start_of_flight = %d",
kenjiArai 0:5b88d5760320 4458 recv_msg_seq,
kenjiArai 0:5b88d5760320 4459 ssl->handshake->in_flight_start_seq ) );
kenjiArai 0:5b88d5760320 4460
kenjiArai 0:5b88d5760320 4461 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 4462 {
kenjiArai 0:5b88d5760320 4463 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
kenjiArai 0:5b88d5760320 4464 return( ret );
kenjiArai 0:5b88d5760320 4465 }
kenjiArai 0:5b88d5760320 4466 }
kenjiArai 0:5b88d5760320 4467 else
kenjiArai 0:5b88d5760320 4468 {
kenjiArai 0:5b88d5760320 4469 MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
kenjiArai 0:5b88d5760320 4470 "message_seq = %d, expected = %d",
kenjiArai 0:5b88d5760320 4471 recv_msg_seq,
kenjiArai 0:5b88d5760320 4472 ssl->handshake->in_msg_seq ) );
kenjiArai 0:5b88d5760320 4473 }
kenjiArai 0:5b88d5760320 4474
kenjiArai 0:5b88d5760320 4475 return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
kenjiArai 0:5b88d5760320 4476 }
kenjiArai 0:5b88d5760320 4477 /* Wait until message completion to increment in_msg_seq */
kenjiArai 0:5b88d5760320 4478
kenjiArai 0:5b88d5760320 4479 /* Message reassembly is handled alongside buffering of future
kenjiArai 0:5b88d5760320 4480 * messages; the commonality is that both handshake fragments and
kenjiArai 0:5b88d5760320 4481 * future messages cannot be forwarded immediately to the
kenjiArai 0:5b88d5760320 4482 * handshake logic layer. */
kenjiArai 0:5b88d5760320 4483 if( ssl_hs_is_proper_fragment( ssl ) == 1 )
kenjiArai 0:5b88d5760320 4484 {
kenjiArai 0:5b88d5760320 4485 MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
kenjiArai 0:5b88d5760320 4486 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
kenjiArai 0:5b88d5760320 4487 }
kenjiArai 0:5b88d5760320 4488 }
kenjiArai 0:5b88d5760320 4489 else
kenjiArai 0:5b88d5760320 4490 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 4491 /* With TLS we don't handle fragmentation (for now) */
kenjiArai 0:5b88d5760320 4492 if( ssl->in_msglen < ssl->in_hslen )
kenjiArai 0:5b88d5760320 4493 {
kenjiArai 0:5b88d5760320 4494 MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
kenjiArai 0:5b88d5760320 4495 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
kenjiArai 0:5b88d5760320 4496 }
kenjiArai 0:5b88d5760320 4497
kenjiArai 0:5b88d5760320 4498 return( 0 );
kenjiArai 0:5b88d5760320 4499 }
kenjiArai 0:5b88d5760320 4500
kenjiArai 0:5b88d5760320 4501 void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 4502 {
kenjiArai 0:5b88d5760320 4503 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 4504
kenjiArai 0:5b88d5760320 4505 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
kenjiArai 0:5b88d5760320 4506 {
kenjiArai 0:5b88d5760320 4507 ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
kenjiArai 0:5b88d5760320 4508 }
kenjiArai 0:5b88d5760320 4509
kenjiArai 0:5b88d5760320 4510 /* Handshake message is complete, increment counter */
kenjiArai 0:5b88d5760320 4511 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4512 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 4513 ssl->handshake != NULL )
kenjiArai 0:5b88d5760320 4514 {
kenjiArai 0:5b88d5760320 4515 unsigned offset;
kenjiArai 0:5b88d5760320 4516 mbedtls_ssl_hs_buffer *hs_buf;
kenjiArai 0:5b88d5760320 4517
kenjiArai 0:5b88d5760320 4518 /* Increment handshake sequence number */
kenjiArai 0:5b88d5760320 4519 hs->in_msg_seq++;
kenjiArai 0:5b88d5760320 4520
kenjiArai 0:5b88d5760320 4521 /*
kenjiArai 0:5b88d5760320 4522 * Clear up handshake buffering and reassembly structure.
kenjiArai 0:5b88d5760320 4523 */
kenjiArai 0:5b88d5760320 4524
kenjiArai 0:5b88d5760320 4525 /* Free first entry */
kenjiArai 0:5b88d5760320 4526 ssl_buffering_free_slot( ssl, 0 );
kenjiArai 0:5b88d5760320 4527
kenjiArai 0:5b88d5760320 4528 /* Shift all other entries */
kenjiArai 0:5b88d5760320 4529 for( offset = 0, hs_buf = &hs->buffering.hs[0];
kenjiArai 0:5b88d5760320 4530 offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
kenjiArai 0:5b88d5760320 4531 offset++, hs_buf++ )
kenjiArai 0:5b88d5760320 4532 {
kenjiArai 0:5b88d5760320 4533 *hs_buf = *(hs_buf + 1);
kenjiArai 0:5b88d5760320 4534 }
kenjiArai 0:5b88d5760320 4535
kenjiArai 0:5b88d5760320 4536 /* Create a fresh last entry */
kenjiArai 0:5b88d5760320 4537 memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
kenjiArai 0:5b88d5760320 4538 }
kenjiArai 0:5b88d5760320 4539 #endif
kenjiArai 0:5b88d5760320 4540 }
kenjiArai 0:5b88d5760320 4541
kenjiArai 0:5b88d5760320 4542 /*
kenjiArai 0:5b88d5760320 4543 * DTLS anti-replay: RFC 6347 4.1.2.6
kenjiArai 0:5b88d5760320 4544 *
kenjiArai 0:5b88d5760320 4545 * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
kenjiArai 0:5b88d5760320 4546 * Bit n is set iff record number in_window_top - n has been seen.
kenjiArai 0:5b88d5760320 4547 *
kenjiArai 0:5b88d5760320 4548 * Usually, in_window_top is the last record number seen and the lsb of
kenjiArai 0:5b88d5760320 4549 * in_window is set. The only exception is the initial state (record number 0
kenjiArai 0:5b88d5760320 4550 * not seen yet).
kenjiArai 0:5b88d5760320 4551 */
kenjiArai 0:5b88d5760320 4552 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
kenjiArai 0:5b88d5760320 4553 static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 4554 {
kenjiArai 0:5b88d5760320 4555 ssl->in_window_top = 0;
kenjiArai 0:5b88d5760320 4556 ssl->in_window = 0;
kenjiArai 0:5b88d5760320 4557 }
kenjiArai 0:5b88d5760320 4558
kenjiArai 0:5b88d5760320 4559 static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
kenjiArai 0:5b88d5760320 4560 {
kenjiArai 0:5b88d5760320 4561 return( ( (uint64_t) buf[0] << 40 ) |
kenjiArai 0:5b88d5760320 4562 ( (uint64_t) buf[1] << 32 ) |
kenjiArai 0:5b88d5760320 4563 ( (uint64_t) buf[2] << 24 ) |
kenjiArai 0:5b88d5760320 4564 ( (uint64_t) buf[3] << 16 ) |
kenjiArai 0:5b88d5760320 4565 ( (uint64_t) buf[4] << 8 ) |
kenjiArai 0:5b88d5760320 4566 ( (uint64_t) buf[5] ) );
kenjiArai 0:5b88d5760320 4567 }
kenjiArai 0:5b88d5760320 4568
kenjiArai 0:5b88d5760320 4569 /*
kenjiArai 0:5b88d5760320 4570 * Return 0 if sequence number is acceptable, -1 otherwise
kenjiArai 0:5b88d5760320 4571 */
kenjiArai 0:5b88d5760320 4572 int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 4573 {
kenjiArai 0:5b88d5760320 4574 uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
kenjiArai 0:5b88d5760320 4575 uint64_t bit;
kenjiArai 0:5b88d5760320 4576
kenjiArai 0:5b88d5760320 4577 if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
kenjiArai 0:5b88d5760320 4578 return( 0 );
kenjiArai 0:5b88d5760320 4579
kenjiArai 0:5b88d5760320 4580 if( rec_seqnum > ssl->in_window_top )
kenjiArai 0:5b88d5760320 4581 return( 0 );
kenjiArai 0:5b88d5760320 4582
kenjiArai 0:5b88d5760320 4583 bit = ssl->in_window_top - rec_seqnum;
kenjiArai 0:5b88d5760320 4584
kenjiArai 0:5b88d5760320 4585 if( bit >= 64 )
kenjiArai 0:5b88d5760320 4586 return( -1 );
kenjiArai 0:5b88d5760320 4587
kenjiArai 0:5b88d5760320 4588 if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
kenjiArai 0:5b88d5760320 4589 return( -1 );
kenjiArai 0:5b88d5760320 4590
kenjiArai 0:5b88d5760320 4591 return( 0 );
kenjiArai 0:5b88d5760320 4592 }
kenjiArai 0:5b88d5760320 4593
kenjiArai 0:5b88d5760320 4594 /*
kenjiArai 0:5b88d5760320 4595 * Update replay window on new validated record
kenjiArai 0:5b88d5760320 4596 */
kenjiArai 0:5b88d5760320 4597 void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 4598 {
kenjiArai 0:5b88d5760320 4599 uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
kenjiArai 0:5b88d5760320 4600
kenjiArai 0:5b88d5760320 4601 if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
kenjiArai 0:5b88d5760320 4602 return;
kenjiArai 0:5b88d5760320 4603
kenjiArai 0:5b88d5760320 4604 if( rec_seqnum > ssl->in_window_top )
kenjiArai 0:5b88d5760320 4605 {
kenjiArai 0:5b88d5760320 4606 /* Update window_top and the contents of the window */
kenjiArai 0:5b88d5760320 4607 uint64_t shift = rec_seqnum - ssl->in_window_top;
kenjiArai 0:5b88d5760320 4608
kenjiArai 0:5b88d5760320 4609 if( shift >= 64 )
kenjiArai 0:5b88d5760320 4610 ssl->in_window = 1;
kenjiArai 0:5b88d5760320 4611 else
kenjiArai 0:5b88d5760320 4612 {
kenjiArai 0:5b88d5760320 4613 ssl->in_window <<= shift;
kenjiArai 0:5b88d5760320 4614 ssl->in_window |= 1;
kenjiArai 0:5b88d5760320 4615 }
kenjiArai 0:5b88d5760320 4616
kenjiArai 0:5b88d5760320 4617 ssl->in_window_top = rec_seqnum;
kenjiArai 0:5b88d5760320 4618 }
kenjiArai 0:5b88d5760320 4619 else
kenjiArai 0:5b88d5760320 4620 {
kenjiArai 0:5b88d5760320 4621 /* Mark that number as seen in the current window */
kenjiArai 0:5b88d5760320 4622 uint64_t bit = ssl->in_window_top - rec_seqnum;
kenjiArai 0:5b88d5760320 4623
kenjiArai 0:5b88d5760320 4624 if( bit < 64 ) /* Always true, but be extra sure */
kenjiArai 0:5b88d5760320 4625 ssl->in_window |= (uint64_t) 1 << bit;
kenjiArai 0:5b88d5760320 4626 }
kenjiArai 0:5b88d5760320 4627 }
kenjiArai 0:5b88d5760320 4628 #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
kenjiArai 0:5b88d5760320 4629
kenjiArai 0:5b88d5760320 4630 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 4631 /* Forward declaration */
kenjiArai 0:5b88d5760320 4632 static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
kenjiArai 0:5b88d5760320 4633
kenjiArai 0:5b88d5760320 4634 /*
kenjiArai 0:5b88d5760320 4635 * Without any SSL context, check if a datagram looks like a ClientHello with
kenjiArai 0:5b88d5760320 4636 * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
kenjiArai 0:5b88d5760320 4637 * Both input and output include full DTLS headers.
kenjiArai 0:5b88d5760320 4638 *
kenjiArai 0:5b88d5760320 4639 * - if cookie is valid, return 0
kenjiArai 0:5b88d5760320 4640 * - if ClientHello looks superficially valid but cookie is not,
kenjiArai 0:5b88d5760320 4641 * fill obuf and set olen, then
kenjiArai 0:5b88d5760320 4642 * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
kenjiArai 0:5b88d5760320 4643 * - otherwise return a specific error code
kenjiArai 0:5b88d5760320 4644 */
kenjiArai 0:5b88d5760320 4645 static int ssl_check_dtls_clihlo_cookie(
kenjiArai 0:5b88d5760320 4646 mbedtls_ssl_cookie_write_t *f_cookie_write,
kenjiArai 0:5b88d5760320 4647 mbedtls_ssl_cookie_check_t *f_cookie_check,
kenjiArai 0:5b88d5760320 4648 void *p_cookie,
kenjiArai 0:5b88d5760320 4649 const unsigned char *cli_id, size_t cli_id_len,
kenjiArai 0:5b88d5760320 4650 const unsigned char *in, size_t in_len,
kenjiArai 0:5b88d5760320 4651 unsigned char *obuf, size_t buf_len, size_t *olen )
kenjiArai 0:5b88d5760320 4652 {
kenjiArai 0:5b88d5760320 4653 size_t sid_len, cookie_len;
kenjiArai 0:5b88d5760320 4654 unsigned char *p;
kenjiArai 0:5b88d5760320 4655
kenjiArai 0:5b88d5760320 4656 if( f_cookie_write == NULL || f_cookie_check == NULL )
kenjiArai 0:5b88d5760320 4657 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 4658
kenjiArai 0:5b88d5760320 4659 /*
kenjiArai 0:5b88d5760320 4660 * Structure of ClientHello with record and handshake headers,
kenjiArai 0:5b88d5760320 4661 * and expected values. We don't need to check a lot, more checks will be
kenjiArai 0:5b88d5760320 4662 * done when actually parsing the ClientHello - skipping those checks
kenjiArai 0:5b88d5760320 4663 * avoids code duplication and does not make cookie forging any easier.
kenjiArai 0:5b88d5760320 4664 *
kenjiArai 0:5b88d5760320 4665 * 0-0 ContentType type; copied, must be handshake
kenjiArai 0:5b88d5760320 4666 * 1-2 ProtocolVersion version; copied
kenjiArai 0:5b88d5760320 4667 * 3-4 uint16 epoch; copied, must be 0
kenjiArai 0:5b88d5760320 4668 * 5-10 uint48 sequence_number; copied
kenjiArai 0:5b88d5760320 4669 * 11-12 uint16 length; (ignored)
kenjiArai 0:5b88d5760320 4670 *
kenjiArai 0:5b88d5760320 4671 * 13-13 HandshakeType msg_type; (ignored)
kenjiArai 0:5b88d5760320 4672 * 14-16 uint24 length; (ignored)
kenjiArai 0:5b88d5760320 4673 * 17-18 uint16 message_seq; copied
kenjiArai 0:5b88d5760320 4674 * 19-21 uint24 fragment_offset; copied, must be 0
kenjiArai 0:5b88d5760320 4675 * 22-24 uint24 fragment_length; (ignored)
kenjiArai 0:5b88d5760320 4676 *
kenjiArai 0:5b88d5760320 4677 * 25-26 ProtocolVersion client_version; (ignored)
kenjiArai 0:5b88d5760320 4678 * 27-58 Random random; (ignored)
kenjiArai 0:5b88d5760320 4679 * 59-xx SessionID session_id; 1 byte len + sid_len content
kenjiArai 0:5b88d5760320 4680 * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
kenjiArai 0:5b88d5760320 4681 * ...
kenjiArai 0:5b88d5760320 4682 *
kenjiArai 0:5b88d5760320 4683 * Minimum length is 61 bytes.
kenjiArai 0:5b88d5760320 4684 */
kenjiArai 0:5b88d5760320 4685 if( in_len < 61 ||
kenjiArai 0:5b88d5760320 4686 in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
kenjiArai 0:5b88d5760320 4687 in[3] != 0 || in[4] != 0 ||
kenjiArai 0:5b88d5760320 4688 in[19] != 0 || in[20] != 0 || in[21] != 0 )
kenjiArai 0:5b88d5760320 4689 {
kenjiArai 0:5b88d5760320 4690 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
kenjiArai 0:5b88d5760320 4691 }
kenjiArai 0:5b88d5760320 4692
kenjiArai 0:5b88d5760320 4693 sid_len = in[59];
kenjiArai 0:5b88d5760320 4694 if( sid_len > in_len - 61 )
kenjiArai 0:5b88d5760320 4695 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
kenjiArai 0:5b88d5760320 4696
kenjiArai 0:5b88d5760320 4697 cookie_len = in[60 + sid_len];
kenjiArai 0:5b88d5760320 4698 if( cookie_len > in_len - 60 )
kenjiArai 0:5b88d5760320 4699 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
kenjiArai 0:5b88d5760320 4700
kenjiArai 0:5b88d5760320 4701 if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
kenjiArai 0:5b88d5760320 4702 cli_id, cli_id_len ) == 0 )
kenjiArai 0:5b88d5760320 4703 {
kenjiArai 0:5b88d5760320 4704 /* Valid cookie */
kenjiArai 0:5b88d5760320 4705 return( 0 );
kenjiArai 0:5b88d5760320 4706 }
kenjiArai 0:5b88d5760320 4707
kenjiArai 0:5b88d5760320 4708 /*
kenjiArai 0:5b88d5760320 4709 * If we get here, we've got an invalid cookie, let's prepare HVR.
kenjiArai 0:5b88d5760320 4710 *
kenjiArai 0:5b88d5760320 4711 * 0-0 ContentType type; copied
kenjiArai 0:5b88d5760320 4712 * 1-2 ProtocolVersion version; copied
kenjiArai 0:5b88d5760320 4713 * 3-4 uint16 epoch; copied
kenjiArai 0:5b88d5760320 4714 * 5-10 uint48 sequence_number; copied
kenjiArai 0:5b88d5760320 4715 * 11-12 uint16 length; olen - 13
kenjiArai 0:5b88d5760320 4716 *
kenjiArai 0:5b88d5760320 4717 * 13-13 HandshakeType msg_type; hello_verify_request
kenjiArai 0:5b88d5760320 4718 * 14-16 uint24 length; olen - 25
kenjiArai 0:5b88d5760320 4719 * 17-18 uint16 message_seq; copied
kenjiArai 0:5b88d5760320 4720 * 19-21 uint24 fragment_offset; copied
kenjiArai 0:5b88d5760320 4721 * 22-24 uint24 fragment_length; olen - 25
kenjiArai 0:5b88d5760320 4722 *
kenjiArai 0:5b88d5760320 4723 * 25-26 ProtocolVersion server_version; 0xfe 0xff
kenjiArai 0:5b88d5760320 4724 * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
kenjiArai 0:5b88d5760320 4725 *
kenjiArai 0:5b88d5760320 4726 * Minimum length is 28.
kenjiArai 0:5b88d5760320 4727 */
kenjiArai 0:5b88d5760320 4728 if( buf_len < 28 )
kenjiArai 0:5b88d5760320 4729 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
kenjiArai 0:5b88d5760320 4730
kenjiArai 0:5b88d5760320 4731 /* Copy most fields and adapt others */
kenjiArai 0:5b88d5760320 4732 memcpy( obuf, in, 25 );
kenjiArai 0:5b88d5760320 4733 obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
kenjiArai 0:5b88d5760320 4734 obuf[25] = 0xfe;
kenjiArai 0:5b88d5760320 4735 obuf[26] = 0xff;
kenjiArai 0:5b88d5760320 4736
kenjiArai 0:5b88d5760320 4737 /* Generate and write actual cookie */
kenjiArai 0:5b88d5760320 4738 p = obuf + 28;
kenjiArai 0:5b88d5760320 4739 if( f_cookie_write( p_cookie,
kenjiArai 0:5b88d5760320 4740 &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
kenjiArai 0:5b88d5760320 4741 {
kenjiArai 0:5b88d5760320 4742 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 4743 }
kenjiArai 0:5b88d5760320 4744
kenjiArai 0:5b88d5760320 4745 *olen = p - obuf;
kenjiArai 0:5b88d5760320 4746
kenjiArai 0:5b88d5760320 4747 /* Go back and fill length fields */
kenjiArai 0:5b88d5760320 4748 obuf[27] = (unsigned char)( *olen - 28 );
kenjiArai 0:5b88d5760320 4749
kenjiArai 0:5b88d5760320 4750 obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 );
kenjiArai 0:5b88d5760320 4751 obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 );
kenjiArai 0:5b88d5760320 4752 obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) );
kenjiArai 0:5b88d5760320 4753
kenjiArai 0:5b88d5760320 4754 obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 );
kenjiArai 0:5b88d5760320 4755 obuf[12] = (unsigned char)( ( *olen - 13 ) );
kenjiArai 0:5b88d5760320 4756
kenjiArai 0:5b88d5760320 4757 return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
kenjiArai 0:5b88d5760320 4758 }
kenjiArai 0:5b88d5760320 4759
kenjiArai 0:5b88d5760320 4760 /*
kenjiArai 0:5b88d5760320 4761 * Handle possible client reconnect with the same UDP quadruplet
kenjiArai 0:5b88d5760320 4762 * (RFC 6347 Section 4.2.8).
kenjiArai 0:5b88d5760320 4763 *
kenjiArai 0:5b88d5760320 4764 * Called by ssl_parse_record_header() in case we receive an epoch 0 record
kenjiArai 0:5b88d5760320 4765 * that looks like a ClientHello.
kenjiArai 0:5b88d5760320 4766 *
kenjiArai 0:5b88d5760320 4767 * - if the input looks like a ClientHello without cookies,
kenjiArai 0:5b88d5760320 4768 * send back HelloVerifyRequest, then
kenjiArai 0:5b88d5760320 4769 * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
kenjiArai 0:5b88d5760320 4770 * - if the input looks like a ClientHello with a valid cookie,
kenjiArai 0:5b88d5760320 4771 * reset the session of the current context, and
kenjiArai 0:5b88d5760320 4772 * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
kenjiArai 0:5b88d5760320 4773 * - if anything goes wrong, return a specific error code
kenjiArai 0:5b88d5760320 4774 *
kenjiArai 0:5b88d5760320 4775 * mbedtls_ssl_read_record() will ignore the record if anything else than
kenjiArai 0:5b88d5760320 4776 * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function
kenjiArai 0:5b88d5760320 4777 * cannot not return 0.
kenjiArai 0:5b88d5760320 4778 */
kenjiArai 0:5b88d5760320 4779 static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 4780 {
kenjiArai 0:5b88d5760320 4781 int ret;
kenjiArai 0:5b88d5760320 4782 size_t len;
kenjiArai 0:5b88d5760320 4783
kenjiArai 0:5b88d5760320 4784 ret = ssl_check_dtls_clihlo_cookie(
kenjiArai 0:5b88d5760320 4785 ssl->conf->f_cookie_write,
kenjiArai 0:5b88d5760320 4786 ssl->conf->f_cookie_check,
kenjiArai 0:5b88d5760320 4787 ssl->conf->p_cookie,
kenjiArai 0:5b88d5760320 4788 ssl->cli_id, ssl->cli_id_len,
kenjiArai 0:5b88d5760320 4789 ssl->in_buf, ssl->in_left,
kenjiArai 0:5b88d5760320 4790 ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
kenjiArai 0:5b88d5760320 4791
kenjiArai 0:5b88d5760320 4792 MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
kenjiArai 0:5b88d5760320 4793
kenjiArai 0:5b88d5760320 4794 if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
kenjiArai 0:5b88d5760320 4795 {
kenjiArai 0:5b88d5760320 4796 /* Don't check write errors as we can't do anything here.
kenjiArai 0:5b88d5760320 4797 * If the error is permanent we'll catch it later,
kenjiArai 0:5b88d5760320 4798 * if it's not, then hopefully it'll work next time. */
kenjiArai 0:5b88d5760320 4799 (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
kenjiArai 0:5b88d5760320 4800
kenjiArai 0:5b88d5760320 4801 return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
kenjiArai 0:5b88d5760320 4802 }
kenjiArai 0:5b88d5760320 4803
kenjiArai 0:5b88d5760320 4804 if( ret == 0 )
kenjiArai 0:5b88d5760320 4805 {
kenjiArai 0:5b88d5760320 4806 /* Got a valid cookie, partially reset context */
kenjiArai 0:5b88d5760320 4807 if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 4808 {
kenjiArai 0:5b88d5760320 4809 MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
kenjiArai 0:5b88d5760320 4810 return( ret );
kenjiArai 0:5b88d5760320 4811 }
kenjiArai 0:5b88d5760320 4812
kenjiArai 0:5b88d5760320 4813 return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
kenjiArai 0:5b88d5760320 4814 }
kenjiArai 0:5b88d5760320 4815
kenjiArai 0:5b88d5760320 4816 return( ret );
kenjiArai 0:5b88d5760320 4817 }
kenjiArai 0:5b88d5760320 4818 #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 4819
kenjiArai 0:5b88d5760320 4820 static int ssl_check_record_type( uint8_t record_type )
kenjiArai 0:5b88d5760320 4821 {
kenjiArai 0:5b88d5760320 4822 if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 4823 record_type != MBEDTLS_SSL_MSG_ALERT &&
kenjiArai 0:5b88d5760320 4824 record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
kenjiArai 0:5b88d5760320 4825 record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
kenjiArai 0:5b88d5760320 4826 {
kenjiArai 0:5b88d5760320 4827 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 4828 }
kenjiArai 0:5b88d5760320 4829
kenjiArai 0:5b88d5760320 4830 return( 0 );
kenjiArai 0:5b88d5760320 4831 }
kenjiArai 0:5b88d5760320 4832
kenjiArai 0:5b88d5760320 4833 /*
kenjiArai 0:5b88d5760320 4834 * ContentType type;
kenjiArai 0:5b88d5760320 4835 * ProtocolVersion version;
kenjiArai 0:5b88d5760320 4836 * uint16 epoch; // DTLS only
kenjiArai 0:5b88d5760320 4837 * uint48 sequence_number; // DTLS only
kenjiArai 0:5b88d5760320 4838 * uint16 length;
kenjiArai 0:5b88d5760320 4839 *
kenjiArai 0:5b88d5760320 4840 * Return 0 if header looks sane (and, for DTLS, the record is expected)
kenjiArai 0:5b88d5760320 4841 * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
kenjiArai 0:5b88d5760320 4842 * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
kenjiArai 0:5b88d5760320 4843 *
kenjiArai 0:5b88d5760320 4844 * With DTLS, mbedtls_ssl_read_record() will:
kenjiArai 0:5b88d5760320 4845 * 1. proceed with the record if this function returns 0
kenjiArai 0:5b88d5760320 4846 * 2. drop only the current record if this function returns UNEXPECTED_RECORD
kenjiArai 0:5b88d5760320 4847 * 3. return CLIENT_RECONNECT if this function return that value
kenjiArai 0:5b88d5760320 4848 * 4. drop the whole datagram if this function returns anything else.
kenjiArai 0:5b88d5760320 4849 * Point 2 is needed when the peer is resending, and we have already received
kenjiArai 0:5b88d5760320 4850 * the first record from a datagram but are still waiting for the others.
kenjiArai 0:5b88d5760320 4851 */
kenjiArai 0:5b88d5760320 4852 static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 4853 {
kenjiArai 0:5b88d5760320 4854 int major_ver, minor_ver;
kenjiArai 0:5b88d5760320 4855 int ret;
kenjiArai 0:5b88d5760320 4856
kenjiArai 0:5b88d5760320 4857 /* Parse and validate record content type and version */
kenjiArai 0:5b88d5760320 4858
kenjiArai 0:5b88d5760320 4859 ssl->in_msgtype = ssl->in_hdr[0];
kenjiArai 0:5b88d5760320 4860 mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 );
kenjiArai 0:5b88d5760320 4861
kenjiArai 0:5b88d5760320 4862 /* Check record type */
kenjiArai 0:5b88d5760320 4863 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 4864 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 4865 ssl->in_msgtype == MBEDTLS_SSL_MSG_CID &&
kenjiArai 0:5b88d5760320 4866 ssl->conf->cid_len != 0 )
kenjiArai 0:5b88d5760320 4867 {
kenjiArai 0:5b88d5760320 4868 /* Shift pointers to account for record header including CID
kenjiArai 0:5b88d5760320 4869 * struct {
kenjiArai 0:5b88d5760320 4870 * ContentType special_type = tls12_cid;
kenjiArai 0:5b88d5760320 4871 * ProtocolVersion version;
kenjiArai 0:5b88d5760320 4872 * uint16 epoch;
kenjiArai 0:5b88d5760320 4873 * uint48 sequence_number;
kenjiArai 0:5b88d5760320 4874 * opaque cid[cid_length]; // Additional field compared to
kenjiArai 0:5b88d5760320 4875 * // default DTLS record format
kenjiArai 0:5b88d5760320 4876 * uint16 length;
kenjiArai 0:5b88d5760320 4877 * opaque enc_content[DTLSCiphertext.length];
kenjiArai 0:5b88d5760320 4878 * } DTLSCiphertext;
kenjiArai 0:5b88d5760320 4879 */
kenjiArai 0:5b88d5760320 4880
kenjiArai 0:5b88d5760320 4881 /* So far, we only support static CID lengths
kenjiArai 0:5b88d5760320 4882 * fixed in the configuration. */
kenjiArai 0:5b88d5760320 4883 ssl->in_len = ssl->in_cid + ssl->conf->cid_len;
kenjiArai 0:5b88d5760320 4884 ssl->in_iv = ssl->in_msg = ssl->in_len + 2;
kenjiArai 0:5b88d5760320 4885 }
kenjiArai 0:5b88d5760320 4886 else
kenjiArai 0:5b88d5760320 4887 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 4888 if( ssl_check_record_type( ssl->in_msgtype ) )
kenjiArai 0:5b88d5760320 4889 {
kenjiArai 0:5b88d5760320 4890 MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
kenjiArai 0:5b88d5760320 4891
kenjiArai 0:5b88d5760320 4892 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4893 /* Silently ignore invalid DTLS records as recommended by RFC 6347
kenjiArai 0:5b88d5760320 4894 * Section 4.1.2.7 */
kenjiArai 0:5b88d5760320 4895 if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 4896 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 4897 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 4898 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 4899
kenjiArai 0:5b88d5760320 4900 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 4901 }
kenjiArai 0:5b88d5760320 4902
kenjiArai 0:5b88d5760320 4903 /* Check version */
kenjiArai 0:5b88d5760320 4904 if( major_ver != ssl->major_ver )
kenjiArai 0:5b88d5760320 4905 {
kenjiArai 0:5b88d5760320 4906 MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
kenjiArai 0:5b88d5760320 4907 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 4908 }
kenjiArai 0:5b88d5760320 4909
kenjiArai 0:5b88d5760320 4910 if( minor_ver > ssl->conf->max_minor_ver )
kenjiArai 0:5b88d5760320 4911 {
kenjiArai 0:5b88d5760320 4912 MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
kenjiArai 0:5b88d5760320 4913 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 4914 }
kenjiArai 0:5b88d5760320 4915
kenjiArai 0:5b88d5760320 4916 /* Now that the total length of the record header is known, ensure
kenjiArai 0:5b88d5760320 4917 * that the current datagram is large enough to hold it.
kenjiArai 0:5b88d5760320 4918 * This would fail, for example, if we received a datagram of
kenjiArai 0:5b88d5760320 4919 * size 13 + n Bytes where n is less than the size of incoming CIDs. */
kenjiArai 0:5b88d5760320 4920 ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) );
kenjiArai 0:5b88d5760320 4921 if( ret != 0 )
kenjiArai 0:5b88d5760320 4922 {
kenjiArai 0:5b88d5760320 4923 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
kenjiArai 0:5b88d5760320 4924 return( ret );
kenjiArai 0:5b88d5760320 4925 }
kenjiArai 0:5b88d5760320 4926 MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_in_hdr_len( ssl ) );
kenjiArai 0:5b88d5760320 4927
kenjiArai 0:5b88d5760320 4928 /* Parse and validate record length
kenjiArai 0:5b88d5760320 4929 * This must happen after the CID parsing because
kenjiArai 0:5b88d5760320 4930 * its position in the record header depends on
kenjiArai 0:5b88d5760320 4931 * the presence of a CID. */
kenjiArai 0:5b88d5760320 4932
kenjiArai 0:5b88d5760320 4933 ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
kenjiArai 0:5b88d5760320 4934 if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN
kenjiArai 0:5b88d5760320 4935 - (size_t)( ssl->in_msg - ssl->in_buf ) )
kenjiArai 0:5b88d5760320 4936 {
kenjiArai 0:5b88d5760320 4937 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
kenjiArai 0:5b88d5760320 4938 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 4939 }
kenjiArai 0:5b88d5760320 4940
kenjiArai 0:5b88d5760320 4941 MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
kenjiArai 0:5b88d5760320 4942 "version = [%d:%d], msglen = %d",
kenjiArai 0:5b88d5760320 4943 ssl->in_msgtype,
kenjiArai 0:5b88d5760320 4944 major_ver, minor_ver, ssl->in_msglen ) );
kenjiArai 0:5b88d5760320 4945
kenjiArai 0:5b88d5760320 4946 /*
kenjiArai 0:5b88d5760320 4947 * DTLS-related tests.
kenjiArai 0:5b88d5760320 4948 * Check epoch before checking length constraint because
kenjiArai 0:5b88d5760320 4949 * the latter varies with the epoch. E.g., if a ChangeCipherSpec
kenjiArai 0:5b88d5760320 4950 * message gets duplicated before the corresponding Finished message,
kenjiArai 0:5b88d5760320 4951 * the second ChangeCipherSpec should be discarded because it belongs
kenjiArai 0:5b88d5760320 4952 * to an old epoch, but not because its length is shorter than
kenjiArai 0:5b88d5760320 4953 * the minimum record length for packets using the new record transform.
kenjiArai 0:5b88d5760320 4954 * Note that these two kinds of failures are handled differently,
kenjiArai 0:5b88d5760320 4955 * as an unexpected record is silently skipped but an invalid
kenjiArai 0:5b88d5760320 4956 * record leads to the entire datagram being dropped.
kenjiArai 0:5b88d5760320 4957 */
kenjiArai 0:5b88d5760320 4958 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 4959 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 4960 {
kenjiArai 0:5b88d5760320 4961 unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
kenjiArai 0:5b88d5760320 4962
kenjiArai 0:5b88d5760320 4963 /* Check epoch (and sequence number) with DTLS */
kenjiArai 0:5b88d5760320 4964 if( rec_epoch != ssl->in_epoch )
kenjiArai 0:5b88d5760320 4965 {
kenjiArai 0:5b88d5760320 4966 MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
kenjiArai 0:5b88d5760320 4967 "expected %d, received %d",
kenjiArai 0:5b88d5760320 4968 ssl->in_epoch, rec_epoch ) );
kenjiArai 0:5b88d5760320 4969
kenjiArai 0:5b88d5760320 4970 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 4971 /*
kenjiArai 0:5b88d5760320 4972 * Check for an epoch 0 ClientHello. We can't use in_msg here to
kenjiArai 0:5b88d5760320 4973 * access the first byte of record content (handshake type), as we
kenjiArai 0:5b88d5760320 4974 * have an active transform (possibly iv_len != 0), so use the
kenjiArai 0:5b88d5760320 4975 * fact that the record header len is 13 instead.
kenjiArai 0:5b88d5760320 4976 */
kenjiArai 0:5b88d5760320 4977 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
kenjiArai 0:5b88d5760320 4978 ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
kenjiArai 0:5b88d5760320 4979 rec_epoch == 0 &&
kenjiArai 0:5b88d5760320 4980 ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 4981 ssl->in_left > 13 &&
kenjiArai 0:5b88d5760320 4982 ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
kenjiArai 0:5b88d5760320 4983 {
kenjiArai 0:5b88d5760320 4984 MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
kenjiArai 0:5b88d5760320 4985 "from the same port" ) );
kenjiArai 0:5b88d5760320 4986 return( ssl_handle_possible_reconnect( ssl ) );
kenjiArai 0:5b88d5760320 4987 }
kenjiArai 0:5b88d5760320 4988 else
kenjiArai 0:5b88d5760320 4989 #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 4990 {
kenjiArai 0:5b88d5760320 4991 /* Consider buffering the record. */
kenjiArai 0:5b88d5760320 4992 if( rec_epoch == (unsigned int) ssl->in_epoch + 1 )
kenjiArai 0:5b88d5760320 4993 {
kenjiArai 0:5b88d5760320 4994 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) );
kenjiArai 0:5b88d5760320 4995 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
kenjiArai 0:5b88d5760320 4996 }
kenjiArai 0:5b88d5760320 4997
kenjiArai 0:5b88d5760320 4998 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
kenjiArai 0:5b88d5760320 4999 }
kenjiArai 0:5b88d5760320 5000 }
kenjiArai 0:5b88d5760320 5001
kenjiArai 0:5b88d5760320 5002 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
kenjiArai 0:5b88d5760320 5003 /* Replay detection only works for the current epoch */
kenjiArai 0:5b88d5760320 5004 if( rec_epoch == ssl->in_epoch &&
kenjiArai 0:5b88d5760320 5005 mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
kenjiArai 0:5b88d5760320 5006 {
kenjiArai 0:5b88d5760320 5007 MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
kenjiArai 0:5b88d5760320 5008 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
kenjiArai 0:5b88d5760320 5009 }
kenjiArai 0:5b88d5760320 5010 #endif
kenjiArai 0:5b88d5760320 5011 }
kenjiArai 0:5b88d5760320 5012 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 5013
kenjiArai 0:5b88d5760320 5014
kenjiArai 0:5b88d5760320 5015 /* Check length against bounds of the current transform and version */
kenjiArai 0:5b88d5760320 5016 if( ssl->transform_in == NULL )
kenjiArai 0:5b88d5760320 5017 {
kenjiArai 0:5b88d5760320 5018 if( ssl->in_msglen < 1 ||
kenjiArai 0:5b88d5760320 5019 ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
kenjiArai 0:5b88d5760320 5020 {
kenjiArai 0:5b88d5760320 5021 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
kenjiArai 0:5b88d5760320 5022 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 5023 }
kenjiArai 0:5b88d5760320 5024 }
kenjiArai 0:5b88d5760320 5025 else
kenjiArai 0:5b88d5760320 5026 {
kenjiArai 0:5b88d5760320 5027 if( ssl->in_msglen < ssl->transform_in->minlen )
kenjiArai 0:5b88d5760320 5028 {
kenjiArai 0:5b88d5760320 5029 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
kenjiArai 0:5b88d5760320 5030 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 5031 }
kenjiArai 0:5b88d5760320 5032
kenjiArai 0:5b88d5760320 5033 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 5034 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
kenjiArai 0:5b88d5760320 5035 ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_IN_CONTENT_LEN )
kenjiArai 0:5b88d5760320 5036 {
kenjiArai 0:5b88d5760320 5037 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
kenjiArai 0:5b88d5760320 5038 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 5039 }
kenjiArai 0:5b88d5760320 5040 #endif
kenjiArai 0:5b88d5760320 5041 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 5042 defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 5043 /*
kenjiArai 0:5b88d5760320 5044 * TLS encrypted messages can have up to 256 bytes of padding
kenjiArai 0:5b88d5760320 5045 */
kenjiArai 0:5b88d5760320 5046 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
kenjiArai 0:5b88d5760320 5047 ssl->in_msglen > ssl->transform_in->minlen +
kenjiArai 0:5b88d5760320 5048 MBEDTLS_SSL_IN_CONTENT_LEN + 256 )
kenjiArai 0:5b88d5760320 5049 {
kenjiArai 0:5b88d5760320 5050 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
kenjiArai 0:5b88d5760320 5051 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 5052 }
kenjiArai 0:5b88d5760320 5053 #endif
kenjiArai 0:5b88d5760320 5054 }
kenjiArai 0:5b88d5760320 5055
kenjiArai 0:5b88d5760320 5056 return( 0 );
kenjiArai 0:5b88d5760320 5057 }
kenjiArai 0:5b88d5760320 5058
kenjiArai 0:5b88d5760320 5059 /*
kenjiArai 0:5b88d5760320 5060 * If applicable, decrypt (and decompress) record content
kenjiArai 0:5b88d5760320 5061 */
kenjiArai 0:5b88d5760320 5062 static int ssl_prepare_record_content( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5063 {
kenjiArai 0:5b88d5760320 5064 int ret, done = 0;
kenjiArai 0:5b88d5760320 5065
kenjiArai 0:5b88d5760320 5066 MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
kenjiArai 0:5b88d5760320 5067 ssl->in_hdr, mbedtls_ssl_in_hdr_len( ssl ) + ssl->in_msglen );
kenjiArai 0:5b88d5760320 5068
kenjiArai 0:5b88d5760320 5069 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 5070 if( mbedtls_ssl_hw_record_read != NULL )
kenjiArai 0:5b88d5760320 5071 {
kenjiArai 0:5b88d5760320 5072 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
kenjiArai 0:5b88d5760320 5073
kenjiArai 0:5b88d5760320 5074 ret = mbedtls_ssl_hw_record_read( ssl );
kenjiArai 0:5b88d5760320 5075 if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
kenjiArai 0:5b88d5760320 5076 {
kenjiArai 0:5b88d5760320 5077 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
kenjiArai 0:5b88d5760320 5078 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 5079 }
kenjiArai 0:5b88d5760320 5080
kenjiArai 0:5b88d5760320 5081 if( ret == 0 )
kenjiArai 0:5b88d5760320 5082 done = 1;
kenjiArai 0:5b88d5760320 5083 }
kenjiArai 0:5b88d5760320 5084 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
kenjiArai 0:5b88d5760320 5085 if( !done && ssl->transform_in != NULL )
kenjiArai 0:5b88d5760320 5086 {
kenjiArai 0:5b88d5760320 5087 mbedtls_record rec;
kenjiArai 0:5b88d5760320 5088
kenjiArai 0:5b88d5760320 5089 rec.buf = ssl->in_iv;
kenjiArai 0:5b88d5760320 5090 rec.buf_len = MBEDTLS_SSL_IN_BUFFER_LEN
kenjiArai 0:5b88d5760320 5091 - ( ssl->in_iv - ssl->in_buf );
kenjiArai 0:5b88d5760320 5092 rec.data_len = ssl->in_msglen;
kenjiArai 0:5b88d5760320 5093 rec.data_offset = 0;
kenjiArai 0:5b88d5760320 5094 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID )
kenjiArai 0:5b88d5760320 5095 rec.cid_len = (uint8_t)( ssl->in_len - ssl->in_cid );
kenjiArai 0:5b88d5760320 5096 memcpy( rec.cid, ssl->in_cid, rec.cid_len );
kenjiArai 0:5b88d5760320 5097 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 5098
kenjiArai 0:5b88d5760320 5099 memcpy( &rec.ctr[0], ssl->in_ctr, 8 );
kenjiArai 0:5b88d5760320 5100 mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
kenjiArai 0:5b88d5760320 5101 ssl->conf->transport, rec.ver );
kenjiArai 0:5b88d5760320 5102 rec.type = ssl->in_msgtype;
kenjiArai 0:5b88d5760320 5103 if( ( ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in,
kenjiArai 0:5b88d5760320 5104 &rec ) ) != 0 )
kenjiArai 0:5b88d5760320 5105 {
kenjiArai 0:5b88d5760320 5106 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
kenjiArai 0:5b88d5760320 5107
kenjiArai 0:5b88d5760320 5108 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 5109 if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
kenjiArai 0:5b88d5760320 5110 ssl->conf->ignore_unexpected_cid
kenjiArai 0:5b88d5760320 5111 == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE )
kenjiArai 0:5b88d5760320 5112 {
kenjiArai 0:5b88d5760320 5113 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) );
kenjiArai 0:5b88d5760320 5114 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
kenjiArai 0:5b88d5760320 5115 }
kenjiArai 0:5b88d5760320 5116 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 5117
kenjiArai 0:5b88d5760320 5118 return( ret );
kenjiArai 0:5b88d5760320 5119 }
kenjiArai 0:5b88d5760320 5120
kenjiArai 0:5b88d5760320 5121 if( ssl->in_msgtype != rec.type )
kenjiArai 0:5b88d5760320 5122 {
kenjiArai 0:5b88d5760320 5123 MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d",
kenjiArai 0:5b88d5760320 5124 ssl->in_msgtype, rec.type ) );
kenjiArai 0:5b88d5760320 5125 }
kenjiArai 0:5b88d5760320 5126
kenjiArai 0:5b88d5760320 5127 /* The record content type may change during decryption,
kenjiArai 0:5b88d5760320 5128 * so re-read it. */
kenjiArai 0:5b88d5760320 5129 ssl->in_msgtype = rec.type;
kenjiArai 0:5b88d5760320 5130 /* Also update the input buffer, because unfortunately
kenjiArai 0:5b88d5760320 5131 * the server-side ssl_parse_client_hello() reparses the
kenjiArai 0:5b88d5760320 5132 * record header when receiving a ClientHello initiating
kenjiArai 0:5b88d5760320 5133 * a renegotiation. */
kenjiArai 0:5b88d5760320 5134 ssl->in_hdr[0] = rec.type;
kenjiArai 0:5b88d5760320 5135 ssl->in_msg = rec.buf + rec.data_offset;
kenjiArai 0:5b88d5760320 5136 ssl->in_msglen = rec.data_len;
kenjiArai 0:5b88d5760320 5137 ssl->in_len[0] = (unsigned char)( rec.data_len >> 8 );
kenjiArai 0:5b88d5760320 5138 ssl->in_len[1] = (unsigned char)( rec.data_len );
kenjiArai 0:5b88d5760320 5139
kenjiArai 0:5b88d5760320 5140 MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
kenjiArai 0:5b88d5760320 5141 ssl->in_msg, ssl->in_msglen );
kenjiArai 0:5b88d5760320 5142
kenjiArai 0:5b88d5760320 5143 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 5144 /* We have already checked the record content type
kenjiArai 0:5b88d5760320 5145 * in ssl_parse_record_header(), failing or silently
kenjiArai 0:5b88d5760320 5146 * dropping the record in the case of an unknown type.
kenjiArai 0:5b88d5760320 5147 *
kenjiArai 0:5b88d5760320 5148 * Since with the use of CIDs, the record content type
kenjiArai 0:5b88d5760320 5149 * might change during decryption, re-check the record
kenjiArai 0:5b88d5760320 5150 * content type, but treat a failure as fatal this time. */
kenjiArai 0:5b88d5760320 5151 if( ssl_check_record_type( ssl->in_msgtype ) )
kenjiArai 0:5b88d5760320 5152 {
kenjiArai 0:5b88d5760320 5153 MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
kenjiArai 0:5b88d5760320 5154 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 5155 }
kenjiArai 0:5b88d5760320 5156 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 5157
kenjiArai 0:5b88d5760320 5158 if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
kenjiArai 0:5b88d5760320 5159 {
kenjiArai 0:5b88d5760320 5160 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
kenjiArai 0:5b88d5760320 5161 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 5162 }
kenjiArai 0:5b88d5760320 5163 else if( ssl->in_msglen == 0 )
kenjiArai 0:5b88d5760320 5164 {
kenjiArai 0:5b88d5760320 5165 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 5166 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
kenjiArai 0:5b88d5760320 5167 && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
kenjiArai 0:5b88d5760320 5168 {
kenjiArai 0:5b88d5760320 5169 /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
kenjiArai 0:5b88d5760320 5170 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
kenjiArai 0:5b88d5760320 5171 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 5172 }
kenjiArai 0:5b88d5760320 5173 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 5174
kenjiArai 0:5b88d5760320 5175 ssl->nb_zero++;
kenjiArai 0:5b88d5760320 5176
kenjiArai 0:5b88d5760320 5177 /*
kenjiArai 0:5b88d5760320 5178 * Three or more empty messages may be a DoS attack
kenjiArai 0:5b88d5760320 5179 * (excessive CPU consumption).
kenjiArai 0:5b88d5760320 5180 */
kenjiArai 0:5b88d5760320 5181 if( ssl->nb_zero > 3 )
kenjiArai 0:5b88d5760320 5182 {
kenjiArai 0:5b88d5760320 5183 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
kenjiArai 0:5b88d5760320 5184 "messages, possible DoS attack" ) );
kenjiArai 0:5b88d5760320 5185 /* Treat the records as if they were not properly authenticated,
kenjiArai 0:5b88d5760320 5186 * thereby failing the connection if we see more than allowed
kenjiArai 0:5b88d5760320 5187 * by the configured bad MAC threshold. */
kenjiArai 0:5b88d5760320 5188 return( MBEDTLS_ERR_SSL_INVALID_MAC );
kenjiArai 0:5b88d5760320 5189 }
kenjiArai 0:5b88d5760320 5190 }
kenjiArai 0:5b88d5760320 5191 else
kenjiArai 0:5b88d5760320 5192 ssl->nb_zero = 0;
kenjiArai 0:5b88d5760320 5193
kenjiArai 0:5b88d5760320 5194 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 5195 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 5196 {
kenjiArai 0:5b88d5760320 5197 ; /* in_ctr read from peer, not maintained internally */
kenjiArai 0:5b88d5760320 5198 }
kenjiArai 0:5b88d5760320 5199 else
kenjiArai 0:5b88d5760320 5200 #endif
kenjiArai 0:5b88d5760320 5201 {
kenjiArai 0:5b88d5760320 5202 unsigned i;
kenjiArai 0:5b88d5760320 5203 for( i = 8; i > ssl_ep_len( ssl ); i-- )
kenjiArai 0:5b88d5760320 5204 if( ++ssl->in_ctr[i - 1] != 0 )
kenjiArai 0:5b88d5760320 5205 break;
kenjiArai 0:5b88d5760320 5206
kenjiArai 0:5b88d5760320 5207 /* The loop goes to its end iff the counter is wrapping */
kenjiArai 0:5b88d5760320 5208 if( i == ssl_ep_len( ssl ) )
kenjiArai 0:5b88d5760320 5209 {
kenjiArai 0:5b88d5760320 5210 MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
kenjiArai 0:5b88d5760320 5211 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
kenjiArai 0:5b88d5760320 5212 }
kenjiArai 0:5b88d5760320 5213 }
kenjiArai 0:5b88d5760320 5214
kenjiArai 0:5b88d5760320 5215 }
kenjiArai 0:5b88d5760320 5216
kenjiArai 0:5b88d5760320 5217 #if defined(MBEDTLS_ZLIB_SUPPORT)
kenjiArai 0:5b88d5760320 5218 if( ssl->transform_in != NULL &&
kenjiArai 0:5b88d5760320 5219 ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
kenjiArai 0:5b88d5760320 5220 {
kenjiArai 0:5b88d5760320 5221 if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 5222 {
kenjiArai 0:5b88d5760320 5223 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
kenjiArai 0:5b88d5760320 5224 return( ret );
kenjiArai 0:5b88d5760320 5225 }
kenjiArai 0:5b88d5760320 5226 }
kenjiArai 0:5b88d5760320 5227 #endif /* MBEDTLS_ZLIB_SUPPORT */
kenjiArai 0:5b88d5760320 5228
kenjiArai 0:5b88d5760320 5229 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
kenjiArai 0:5b88d5760320 5230 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 5231 {
kenjiArai 0:5b88d5760320 5232 mbedtls_ssl_dtls_replay_update( ssl );
kenjiArai 0:5b88d5760320 5233 }
kenjiArai 0:5b88d5760320 5234 #endif
kenjiArai 0:5b88d5760320 5235
kenjiArai 0:5b88d5760320 5236 return( 0 );
kenjiArai 0:5b88d5760320 5237 }
kenjiArai 0:5b88d5760320 5238
kenjiArai 0:5b88d5760320 5239 static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 5240
kenjiArai 0:5b88d5760320 5241 /*
kenjiArai 0:5b88d5760320 5242 * Read a record.
kenjiArai 0:5b88d5760320 5243 *
kenjiArai 0:5b88d5760320 5244 * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
kenjiArai 0:5b88d5760320 5245 * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
kenjiArai 0:5b88d5760320 5246 *
kenjiArai 0:5b88d5760320 5247 */
kenjiArai 0:5b88d5760320 5248
kenjiArai 0:5b88d5760320 5249 /* Helper functions for mbedtls_ssl_read_record(). */
kenjiArai 0:5b88d5760320 5250 static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 5251 static int ssl_get_next_record( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 5252 static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
kenjiArai 0:5b88d5760320 5253
kenjiArai 0:5b88d5760320 5254 int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 5255 unsigned update_hs_digest )
kenjiArai 0:5b88d5760320 5256 {
kenjiArai 0:5b88d5760320 5257 int ret;
kenjiArai 0:5b88d5760320 5258
kenjiArai 0:5b88d5760320 5259 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
kenjiArai 0:5b88d5760320 5260
kenjiArai 0:5b88d5760320 5261 if( ssl->keep_current_message == 0 )
kenjiArai 0:5b88d5760320 5262 {
kenjiArai 0:5b88d5760320 5263 do {
kenjiArai 0:5b88d5760320 5264
kenjiArai 0:5b88d5760320 5265 ret = ssl_consume_current_message( ssl );
kenjiArai 0:5b88d5760320 5266 if( ret != 0 )
kenjiArai 0:5b88d5760320 5267 return( ret );
kenjiArai 0:5b88d5760320 5268
kenjiArai 0:5b88d5760320 5269 if( ssl_record_is_in_progress( ssl ) == 0 )
kenjiArai 0:5b88d5760320 5270 {
kenjiArai 0:5b88d5760320 5271 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 5272 int have_buffered = 0;
kenjiArai 0:5b88d5760320 5273
kenjiArai 0:5b88d5760320 5274 /* We only check for buffered messages if the
kenjiArai 0:5b88d5760320 5275 * current datagram is fully consumed. */
kenjiArai 0:5b88d5760320 5276 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 5277 ssl_next_record_is_in_datagram( ssl ) == 0 )
kenjiArai 0:5b88d5760320 5278 {
kenjiArai 0:5b88d5760320 5279 if( ssl_load_buffered_message( ssl ) == 0 )
kenjiArai 0:5b88d5760320 5280 have_buffered = 1;
kenjiArai 0:5b88d5760320 5281 }
kenjiArai 0:5b88d5760320 5282
kenjiArai 0:5b88d5760320 5283 if( have_buffered == 0 )
kenjiArai 0:5b88d5760320 5284 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 5285 {
kenjiArai 0:5b88d5760320 5286 ret = ssl_get_next_record( ssl );
kenjiArai 0:5b88d5760320 5287 if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
kenjiArai 0:5b88d5760320 5288 continue;
kenjiArai 0:5b88d5760320 5289
kenjiArai 0:5b88d5760320 5290 if( ret != 0 )
kenjiArai 0:5b88d5760320 5291 {
kenjiArai 0:5b88d5760320 5292 MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
kenjiArai 0:5b88d5760320 5293 return( ret );
kenjiArai 0:5b88d5760320 5294 }
kenjiArai 0:5b88d5760320 5295 }
kenjiArai 0:5b88d5760320 5296 }
kenjiArai 0:5b88d5760320 5297
kenjiArai 0:5b88d5760320 5298 ret = mbedtls_ssl_handle_message_type( ssl );
kenjiArai 0:5b88d5760320 5299
kenjiArai 0:5b88d5760320 5300 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 5301 if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
kenjiArai 0:5b88d5760320 5302 {
kenjiArai 0:5b88d5760320 5303 /* Buffer future message */
kenjiArai 0:5b88d5760320 5304 ret = ssl_buffer_message( ssl );
kenjiArai 0:5b88d5760320 5305 if( ret != 0 )
kenjiArai 0:5b88d5760320 5306 return( ret );
kenjiArai 0:5b88d5760320 5307
kenjiArai 0:5b88d5760320 5308 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
kenjiArai 0:5b88d5760320 5309 }
kenjiArai 0:5b88d5760320 5310 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 5311
kenjiArai 0:5b88d5760320 5312 } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ||
kenjiArai 0:5b88d5760320 5313 MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret );
kenjiArai 0:5b88d5760320 5314
kenjiArai 0:5b88d5760320 5315 if( 0 != ret )
kenjiArai 0:5b88d5760320 5316 {
kenjiArai 0:5b88d5760320 5317 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
kenjiArai 0:5b88d5760320 5318 return( ret );
kenjiArai 0:5b88d5760320 5319 }
kenjiArai 0:5b88d5760320 5320
kenjiArai 0:5b88d5760320 5321 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 5322 update_hs_digest == 1 )
kenjiArai 0:5b88d5760320 5323 {
kenjiArai 0:5b88d5760320 5324 mbedtls_ssl_update_handshake_status( ssl );
kenjiArai 0:5b88d5760320 5325 }
kenjiArai 0:5b88d5760320 5326 }
kenjiArai 0:5b88d5760320 5327 else
kenjiArai 0:5b88d5760320 5328 {
kenjiArai 0:5b88d5760320 5329 MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
kenjiArai 0:5b88d5760320 5330 ssl->keep_current_message = 0;
kenjiArai 0:5b88d5760320 5331 }
kenjiArai 0:5b88d5760320 5332
kenjiArai 0:5b88d5760320 5333 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
kenjiArai 0:5b88d5760320 5334
kenjiArai 0:5b88d5760320 5335 return( 0 );
kenjiArai 0:5b88d5760320 5336 }
kenjiArai 0:5b88d5760320 5337
kenjiArai 0:5b88d5760320 5338 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 5339 static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5340 {
kenjiArai 0:5b88d5760320 5341 if( ssl->in_left > ssl->next_record_offset )
kenjiArai 0:5b88d5760320 5342 return( 1 );
kenjiArai 0:5b88d5760320 5343
kenjiArai 0:5b88d5760320 5344 return( 0 );
kenjiArai 0:5b88d5760320 5345 }
kenjiArai 0:5b88d5760320 5346
kenjiArai 0:5b88d5760320 5347 static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5348 {
kenjiArai 0:5b88d5760320 5349 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 5350 mbedtls_ssl_hs_buffer * hs_buf;
kenjiArai 0:5b88d5760320 5351 int ret = 0;
kenjiArai 0:5b88d5760320 5352
kenjiArai 0:5b88d5760320 5353 if( hs == NULL )
kenjiArai 0:5b88d5760320 5354 return( -1 );
kenjiArai 0:5b88d5760320 5355
kenjiArai 0:5b88d5760320 5356 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) );
kenjiArai 0:5b88d5760320 5357
kenjiArai 0:5b88d5760320 5358 if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
kenjiArai 0:5b88d5760320 5359 ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
kenjiArai 0:5b88d5760320 5360 {
kenjiArai 0:5b88d5760320 5361 /* Check if we have seen a ChangeCipherSpec before.
kenjiArai 0:5b88d5760320 5362 * If yes, synthesize a CCS record. */
kenjiArai 0:5b88d5760320 5363 if( !hs->buffering.seen_ccs )
kenjiArai 0:5b88d5760320 5364 {
kenjiArai 0:5b88d5760320 5365 MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) );
kenjiArai 0:5b88d5760320 5366 ret = -1;
kenjiArai 0:5b88d5760320 5367 goto exit;
kenjiArai 0:5b88d5760320 5368 }
kenjiArai 0:5b88d5760320 5369
kenjiArai 0:5b88d5760320 5370 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) );
kenjiArai 0:5b88d5760320 5371 ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
kenjiArai 0:5b88d5760320 5372 ssl->in_msglen = 1;
kenjiArai 0:5b88d5760320 5373 ssl->in_msg[0] = 1;
kenjiArai 0:5b88d5760320 5374
kenjiArai 0:5b88d5760320 5375 /* As long as they are equal, the exact value doesn't matter. */
kenjiArai 0:5b88d5760320 5376 ssl->in_left = 0;
kenjiArai 0:5b88d5760320 5377 ssl->next_record_offset = 0;
kenjiArai 0:5b88d5760320 5378
kenjiArai 0:5b88d5760320 5379 hs->buffering.seen_ccs = 0;
kenjiArai 0:5b88d5760320 5380 goto exit;
kenjiArai 0:5b88d5760320 5381 }
kenjiArai 0:5b88d5760320 5382
kenjiArai 0:5b88d5760320 5383 #if defined(MBEDTLS_DEBUG_C)
kenjiArai 0:5b88d5760320 5384 /* Debug only */
kenjiArai 0:5b88d5760320 5385 {
kenjiArai 0:5b88d5760320 5386 unsigned offset;
kenjiArai 0:5b88d5760320 5387 for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
kenjiArai 0:5b88d5760320 5388 {
kenjiArai 0:5b88d5760320 5389 hs_buf = &hs->buffering.hs[offset];
kenjiArai 0:5b88d5760320 5390 if( hs_buf->is_valid == 1 )
kenjiArai 0:5b88d5760320 5391 {
kenjiArai 0:5b88d5760320 5392 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.",
kenjiArai 0:5b88d5760320 5393 hs->in_msg_seq + offset,
kenjiArai 0:5b88d5760320 5394 hs_buf->is_complete ? "fully" : "partially" ) );
kenjiArai 0:5b88d5760320 5395 }
kenjiArai 0:5b88d5760320 5396 }
kenjiArai 0:5b88d5760320 5397 }
kenjiArai 0:5b88d5760320 5398 #endif /* MBEDTLS_DEBUG_C */
kenjiArai 0:5b88d5760320 5399
kenjiArai 0:5b88d5760320 5400 /* Check if we have buffered and/or fully reassembled the
kenjiArai 0:5b88d5760320 5401 * next handshake message. */
kenjiArai 0:5b88d5760320 5402 hs_buf = &hs->buffering.hs[0];
kenjiArai 0:5b88d5760320 5403 if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) )
kenjiArai 0:5b88d5760320 5404 {
kenjiArai 0:5b88d5760320 5405 /* Synthesize a record containing the buffered HS message. */
kenjiArai 0:5b88d5760320 5406 size_t msg_len = ( hs_buf->data[1] << 16 ) |
kenjiArai 0:5b88d5760320 5407 ( hs_buf->data[2] << 8 ) |
kenjiArai 0:5b88d5760320 5408 hs_buf->data[3];
kenjiArai 0:5b88d5760320 5409
kenjiArai 0:5b88d5760320 5410 /* Double-check that we haven't accidentally buffered
kenjiArai 0:5b88d5760320 5411 * a message that doesn't fit into the input buffer. */
kenjiArai 0:5b88d5760320 5412 if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
kenjiArai 0:5b88d5760320 5413 {
kenjiArai 0:5b88d5760320 5414 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 5415 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 5416 }
kenjiArai 0:5b88d5760320 5417
kenjiArai 0:5b88d5760320 5418 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) );
kenjiArai 0:5b88d5760320 5419 MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)",
kenjiArai 0:5b88d5760320 5420 hs_buf->data, msg_len + 12 );
kenjiArai 0:5b88d5760320 5421
kenjiArai 0:5b88d5760320 5422 ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
kenjiArai 0:5b88d5760320 5423 ssl->in_hslen = msg_len + 12;
kenjiArai 0:5b88d5760320 5424 ssl->in_msglen = msg_len + 12;
kenjiArai 0:5b88d5760320 5425 memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen );
kenjiArai 0:5b88d5760320 5426
kenjiArai 0:5b88d5760320 5427 ret = 0;
kenjiArai 0:5b88d5760320 5428 goto exit;
kenjiArai 0:5b88d5760320 5429 }
kenjiArai 0:5b88d5760320 5430 else
kenjiArai 0:5b88d5760320 5431 {
kenjiArai 0:5b88d5760320 5432 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered",
kenjiArai 0:5b88d5760320 5433 hs->in_msg_seq ) );
kenjiArai 0:5b88d5760320 5434 }
kenjiArai 0:5b88d5760320 5435
kenjiArai 0:5b88d5760320 5436 ret = -1;
kenjiArai 0:5b88d5760320 5437
kenjiArai 0:5b88d5760320 5438 exit:
kenjiArai 0:5b88d5760320 5439
kenjiArai 0:5b88d5760320 5440 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) );
kenjiArai 0:5b88d5760320 5441 return( ret );
kenjiArai 0:5b88d5760320 5442 }
kenjiArai 0:5b88d5760320 5443
kenjiArai 0:5b88d5760320 5444 static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 5445 size_t desired )
kenjiArai 0:5b88d5760320 5446 {
kenjiArai 0:5b88d5760320 5447 int offset;
kenjiArai 0:5b88d5760320 5448 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 5449 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available",
kenjiArai 0:5b88d5760320 5450 (unsigned) desired ) );
kenjiArai 0:5b88d5760320 5451
kenjiArai 0:5b88d5760320 5452 /* Get rid of future records epoch first, if such exist. */
kenjiArai 0:5b88d5760320 5453 ssl_free_buffered_record( ssl );
kenjiArai 0:5b88d5760320 5454
kenjiArai 0:5b88d5760320 5455 /* Check if we have enough space available now. */
kenjiArai 0:5b88d5760320 5456 if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
kenjiArai 0:5b88d5760320 5457 hs->buffering.total_bytes_buffered ) )
kenjiArai 0:5b88d5760320 5458 {
kenjiArai 0:5b88d5760320 5459 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) );
kenjiArai 0:5b88d5760320 5460 return( 0 );
kenjiArai 0:5b88d5760320 5461 }
kenjiArai 0:5b88d5760320 5462
kenjiArai 0:5b88d5760320 5463 /* We don't have enough space to buffer the next expected handshake
kenjiArai 0:5b88d5760320 5464 * message. Remove buffers used for future messages to gain space,
kenjiArai 0:5b88d5760320 5465 * starting with the most distant one. */
kenjiArai 0:5b88d5760320 5466 for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
kenjiArai 0:5b88d5760320 5467 offset >= 0; offset-- )
kenjiArai 0:5b88d5760320 5468 {
kenjiArai 0:5b88d5760320 5469 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message",
kenjiArai 0:5b88d5760320 5470 offset ) );
kenjiArai 0:5b88d5760320 5471
kenjiArai 0:5b88d5760320 5472 ssl_buffering_free_slot( ssl, (uint8_t) offset );
kenjiArai 0:5b88d5760320 5473
kenjiArai 0:5b88d5760320 5474 /* Check if we have enough space available now. */
kenjiArai 0:5b88d5760320 5475 if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
kenjiArai 0:5b88d5760320 5476 hs->buffering.total_bytes_buffered ) )
kenjiArai 0:5b88d5760320 5477 {
kenjiArai 0:5b88d5760320 5478 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) );
kenjiArai 0:5b88d5760320 5479 return( 0 );
kenjiArai 0:5b88d5760320 5480 }
kenjiArai 0:5b88d5760320 5481 }
kenjiArai 0:5b88d5760320 5482
kenjiArai 0:5b88d5760320 5483 return( -1 );
kenjiArai 0:5b88d5760320 5484 }
kenjiArai 0:5b88d5760320 5485
kenjiArai 0:5b88d5760320 5486 static int ssl_buffer_message( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5487 {
kenjiArai 0:5b88d5760320 5488 int ret = 0;
kenjiArai 0:5b88d5760320 5489 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 5490
kenjiArai 0:5b88d5760320 5491 if( hs == NULL )
kenjiArai 0:5b88d5760320 5492 return( 0 );
kenjiArai 0:5b88d5760320 5493
kenjiArai 0:5b88d5760320 5494 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) );
kenjiArai 0:5b88d5760320 5495
kenjiArai 0:5b88d5760320 5496 switch( ssl->in_msgtype )
kenjiArai 0:5b88d5760320 5497 {
kenjiArai 0:5b88d5760320 5498 case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
kenjiArai 0:5b88d5760320 5499 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) );
kenjiArai 0:5b88d5760320 5500
kenjiArai 0:5b88d5760320 5501 hs->buffering.seen_ccs = 1;
kenjiArai 0:5b88d5760320 5502 break;
kenjiArai 0:5b88d5760320 5503
kenjiArai 0:5b88d5760320 5504 case MBEDTLS_SSL_MSG_HANDSHAKE:
kenjiArai 0:5b88d5760320 5505 {
kenjiArai 0:5b88d5760320 5506 unsigned recv_msg_seq_offset;
kenjiArai 0:5b88d5760320 5507 unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
kenjiArai 0:5b88d5760320 5508 mbedtls_ssl_hs_buffer *hs_buf;
kenjiArai 0:5b88d5760320 5509 size_t msg_len = ssl->in_hslen - 12;
kenjiArai 0:5b88d5760320 5510
kenjiArai 0:5b88d5760320 5511 /* We should never receive an old handshake
kenjiArai 0:5b88d5760320 5512 * message - double-check nonetheless. */
kenjiArai 0:5b88d5760320 5513 if( recv_msg_seq < ssl->handshake->in_msg_seq )
kenjiArai 0:5b88d5760320 5514 {
kenjiArai 0:5b88d5760320 5515 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 5516 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 5517 }
kenjiArai 0:5b88d5760320 5518
kenjiArai 0:5b88d5760320 5519 recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
kenjiArai 0:5b88d5760320 5520 if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS )
kenjiArai 0:5b88d5760320 5521 {
kenjiArai 0:5b88d5760320 5522 /* Silently ignore -- message too far in the future */
kenjiArai 0:5b88d5760320 5523 MBEDTLS_SSL_DEBUG_MSG( 2,
kenjiArai 0:5b88d5760320 5524 ( "Ignore future HS message with sequence number %u, "
kenjiArai 0:5b88d5760320 5525 "buffering window %u - %u",
kenjiArai 0:5b88d5760320 5526 recv_msg_seq, ssl->handshake->in_msg_seq,
kenjiArai 0:5b88d5760320 5527 ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) );
kenjiArai 0:5b88d5760320 5528
kenjiArai 0:5b88d5760320 5529 goto exit;
kenjiArai 0:5b88d5760320 5530 }
kenjiArai 0:5b88d5760320 5531
kenjiArai 0:5b88d5760320 5532 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ",
kenjiArai 0:5b88d5760320 5533 recv_msg_seq, recv_msg_seq_offset ) );
kenjiArai 0:5b88d5760320 5534
kenjiArai 0:5b88d5760320 5535 hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ];
kenjiArai 0:5b88d5760320 5536
kenjiArai 0:5b88d5760320 5537 /* Check if the buffering for this seq nr has already commenced. */
kenjiArai 0:5b88d5760320 5538 if( !hs_buf->is_valid )
kenjiArai 0:5b88d5760320 5539 {
kenjiArai 0:5b88d5760320 5540 size_t reassembly_buf_sz;
kenjiArai 0:5b88d5760320 5541
kenjiArai 0:5b88d5760320 5542 hs_buf->is_fragmented =
kenjiArai 0:5b88d5760320 5543 ( ssl_hs_is_proper_fragment( ssl ) == 1 );
kenjiArai 0:5b88d5760320 5544
kenjiArai 0:5b88d5760320 5545 /* We copy the message back into the input buffer
kenjiArai 0:5b88d5760320 5546 * after reassembly, so check that it's not too large.
kenjiArai 0:5b88d5760320 5547 * This is an implementation-specific limitation
kenjiArai 0:5b88d5760320 5548 * and not one from the standard, hence it is not
kenjiArai 0:5b88d5760320 5549 * checked in ssl_check_hs_header(). */
kenjiArai 0:5b88d5760320 5550 if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
kenjiArai 0:5b88d5760320 5551 {
kenjiArai 0:5b88d5760320 5552 /* Ignore message */
kenjiArai 0:5b88d5760320 5553 goto exit;
kenjiArai 0:5b88d5760320 5554 }
kenjiArai 0:5b88d5760320 5555
kenjiArai 0:5b88d5760320 5556 /* Check if we have enough space to buffer the message. */
kenjiArai 0:5b88d5760320 5557 if( hs->buffering.total_bytes_buffered >
kenjiArai 0:5b88d5760320 5558 MBEDTLS_SSL_DTLS_MAX_BUFFERING )
kenjiArai 0:5b88d5760320 5559 {
kenjiArai 0:5b88d5760320 5560 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 5561 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 5562 }
kenjiArai 0:5b88d5760320 5563
kenjiArai 0:5b88d5760320 5564 reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
kenjiArai 0:5b88d5760320 5565 hs_buf->is_fragmented );
kenjiArai 0:5b88d5760320 5566
kenjiArai 0:5b88d5760320 5567 if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
kenjiArai 0:5b88d5760320 5568 hs->buffering.total_bytes_buffered ) )
kenjiArai 0:5b88d5760320 5569 {
kenjiArai 0:5b88d5760320 5570 if( recv_msg_seq_offset > 0 )
kenjiArai 0:5b88d5760320 5571 {
kenjiArai 0:5b88d5760320 5572 /* If we can't buffer a future message because
kenjiArai 0:5b88d5760320 5573 * of space limitations -- ignore. */
kenjiArai 0:5b88d5760320 5574 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
kenjiArai 0:5b88d5760320 5575 (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
kenjiArai 0:5b88d5760320 5576 (unsigned) hs->buffering.total_bytes_buffered ) );
kenjiArai 0:5b88d5760320 5577 goto exit;
kenjiArai 0:5b88d5760320 5578 }
kenjiArai 0:5b88d5760320 5579 else
kenjiArai 0:5b88d5760320 5580 {
kenjiArai 0:5b88d5760320 5581 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n",
kenjiArai 0:5b88d5760320 5582 (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
kenjiArai 0:5b88d5760320 5583 (unsigned) hs->buffering.total_bytes_buffered ) );
kenjiArai 0:5b88d5760320 5584 }
kenjiArai 0:5b88d5760320 5585
kenjiArai 0:5b88d5760320 5586 if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 )
kenjiArai 0:5b88d5760320 5587 {
kenjiArai 0:5b88d5760320 5588 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n",
kenjiArai 0:5b88d5760320 5589 (unsigned) msg_len,
kenjiArai 0:5b88d5760320 5590 (unsigned) reassembly_buf_sz,
kenjiArai 0:5b88d5760320 5591 MBEDTLS_SSL_DTLS_MAX_BUFFERING,
kenjiArai 0:5b88d5760320 5592 (unsigned) hs->buffering.total_bytes_buffered ) );
kenjiArai 0:5b88d5760320 5593 ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
kenjiArai 0:5b88d5760320 5594 goto exit;
kenjiArai 0:5b88d5760320 5595 }
kenjiArai 0:5b88d5760320 5596 }
kenjiArai 0:5b88d5760320 5597
kenjiArai 0:5b88d5760320 5598 MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d",
kenjiArai 0:5b88d5760320 5599 msg_len ) );
kenjiArai 0:5b88d5760320 5600
kenjiArai 0:5b88d5760320 5601 hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
kenjiArai 0:5b88d5760320 5602 if( hs_buf->data == NULL )
kenjiArai 0:5b88d5760320 5603 {
kenjiArai 0:5b88d5760320 5604 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
kenjiArai 0:5b88d5760320 5605 goto exit;
kenjiArai 0:5b88d5760320 5606 }
kenjiArai 0:5b88d5760320 5607 hs_buf->data_len = reassembly_buf_sz;
kenjiArai 0:5b88d5760320 5608
kenjiArai 0:5b88d5760320 5609 /* Prepare final header: copy msg_type, length and message_seq,
kenjiArai 0:5b88d5760320 5610 * then add standardised fragment_offset and fragment_length */
kenjiArai 0:5b88d5760320 5611 memcpy( hs_buf->data, ssl->in_msg, 6 );
kenjiArai 0:5b88d5760320 5612 memset( hs_buf->data + 6, 0, 3 );
kenjiArai 0:5b88d5760320 5613 memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
kenjiArai 0:5b88d5760320 5614
kenjiArai 0:5b88d5760320 5615 hs_buf->is_valid = 1;
kenjiArai 0:5b88d5760320 5616
kenjiArai 0:5b88d5760320 5617 hs->buffering.total_bytes_buffered += reassembly_buf_sz;
kenjiArai 0:5b88d5760320 5618 }
kenjiArai 0:5b88d5760320 5619 else
kenjiArai 0:5b88d5760320 5620 {
kenjiArai 0:5b88d5760320 5621 /* Make sure msg_type and length are consistent */
kenjiArai 0:5b88d5760320 5622 if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 )
kenjiArai 0:5b88d5760320 5623 {
kenjiArai 0:5b88d5760320 5624 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) );
kenjiArai 0:5b88d5760320 5625 /* Ignore */
kenjiArai 0:5b88d5760320 5626 goto exit;
kenjiArai 0:5b88d5760320 5627 }
kenjiArai 0:5b88d5760320 5628 }
kenjiArai 0:5b88d5760320 5629
kenjiArai 0:5b88d5760320 5630 if( !hs_buf->is_complete )
kenjiArai 0:5b88d5760320 5631 {
kenjiArai 0:5b88d5760320 5632 size_t frag_len, frag_off;
kenjiArai 0:5b88d5760320 5633 unsigned char * const msg = hs_buf->data + 12;
kenjiArai 0:5b88d5760320 5634
kenjiArai 0:5b88d5760320 5635 /*
kenjiArai 0:5b88d5760320 5636 * Check and copy current fragment
kenjiArai 0:5b88d5760320 5637 */
kenjiArai 0:5b88d5760320 5638
kenjiArai 0:5b88d5760320 5639 /* Validation of header fields already done in
kenjiArai 0:5b88d5760320 5640 * mbedtls_ssl_prepare_handshake_record(). */
kenjiArai 0:5b88d5760320 5641 frag_off = ssl_get_hs_frag_off( ssl );
kenjiArai 0:5b88d5760320 5642 frag_len = ssl_get_hs_frag_len( ssl );
kenjiArai 0:5b88d5760320 5643
kenjiArai 0:5b88d5760320 5644 MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d",
kenjiArai 0:5b88d5760320 5645 frag_off, frag_len ) );
kenjiArai 0:5b88d5760320 5646 memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
kenjiArai 0:5b88d5760320 5647
kenjiArai 0:5b88d5760320 5648 if( hs_buf->is_fragmented )
kenjiArai 0:5b88d5760320 5649 {
kenjiArai 0:5b88d5760320 5650 unsigned char * const bitmask = msg + msg_len;
kenjiArai 0:5b88d5760320 5651 ssl_bitmask_set( bitmask, frag_off, frag_len );
kenjiArai 0:5b88d5760320 5652 hs_buf->is_complete = ( ssl_bitmask_check( bitmask,
kenjiArai 0:5b88d5760320 5653 msg_len ) == 0 );
kenjiArai 0:5b88d5760320 5654 }
kenjiArai 0:5b88d5760320 5655 else
kenjiArai 0:5b88d5760320 5656 {
kenjiArai 0:5b88d5760320 5657 hs_buf->is_complete = 1;
kenjiArai 0:5b88d5760320 5658 }
kenjiArai 0:5b88d5760320 5659
kenjiArai 0:5b88d5760320 5660 MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete",
kenjiArai 0:5b88d5760320 5661 hs_buf->is_complete ? "" : "not yet " ) );
kenjiArai 0:5b88d5760320 5662 }
kenjiArai 0:5b88d5760320 5663
kenjiArai 0:5b88d5760320 5664 break;
kenjiArai 0:5b88d5760320 5665 }
kenjiArai 0:5b88d5760320 5666
kenjiArai 0:5b88d5760320 5667 default:
kenjiArai 0:5b88d5760320 5668 /* We don't buffer other types of messages. */
kenjiArai 0:5b88d5760320 5669 break;
kenjiArai 0:5b88d5760320 5670 }
kenjiArai 0:5b88d5760320 5671
kenjiArai 0:5b88d5760320 5672 exit:
kenjiArai 0:5b88d5760320 5673
kenjiArai 0:5b88d5760320 5674 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) );
kenjiArai 0:5b88d5760320 5675 return( ret );
kenjiArai 0:5b88d5760320 5676 }
kenjiArai 0:5b88d5760320 5677 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 5678
kenjiArai 0:5b88d5760320 5679 static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5680 {
kenjiArai 0:5b88d5760320 5681 /*
kenjiArai 0:5b88d5760320 5682 * Consume last content-layer message and potentially
kenjiArai 0:5b88d5760320 5683 * update in_msglen which keeps track of the contents'
kenjiArai 0:5b88d5760320 5684 * consumption state.
kenjiArai 0:5b88d5760320 5685 *
kenjiArai 0:5b88d5760320 5686 * (1) Handshake messages:
kenjiArai 0:5b88d5760320 5687 * Remove last handshake message, move content
kenjiArai 0:5b88d5760320 5688 * and adapt in_msglen.
kenjiArai 0:5b88d5760320 5689 *
kenjiArai 0:5b88d5760320 5690 * (2) Alert messages:
kenjiArai 0:5b88d5760320 5691 * Consume whole record content, in_msglen = 0.
kenjiArai 0:5b88d5760320 5692 *
kenjiArai 0:5b88d5760320 5693 * (3) Change cipher spec:
kenjiArai 0:5b88d5760320 5694 * Consume whole record content, in_msglen = 0.
kenjiArai 0:5b88d5760320 5695 *
kenjiArai 0:5b88d5760320 5696 * (4) Application data:
kenjiArai 0:5b88d5760320 5697 * Don't do anything - the record layer provides
kenjiArai 0:5b88d5760320 5698 * the application data as a stream transport
kenjiArai 0:5b88d5760320 5699 * and consumes through mbedtls_ssl_read only.
kenjiArai 0:5b88d5760320 5700 *
kenjiArai 0:5b88d5760320 5701 */
kenjiArai 0:5b88d5760320 5702
kenjiArai 0:5b88d5760320 5703 /* Case (1): Handshake messages */
kenjiArai 0:5b88d5760320 5704 if( ssl->in_hslen != 0 )
kenjiArai 0:5b88d5760320 5705 {
kenjiArai 0:5b88d5760320 5706 /* Hard assertion to be sure that no application data
kenjiArai 0:5b88d5760320 5707 * is in flight, as corrupting ssl->in_msglen during
kenjiArai 0:5b88d5760320 5708 * ssl->in_offt != NULL is fatal. */
kenjiArai 0:5b88d5760320 5709 if( ssl->in_offt != NULL )
kenjiArai 0:5b88d5760320 5710 {
kenjiArai 0:5b88d5760320 5711 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 5712 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 5713 }
kenjiArai 0:5b88d5760320 5714
kenjiArai 0:5b88d5760320 5715 /*
kenjiArai 0:5b88d5760320 5716 * Get next Handshake message in the current record
kenjiArai 0:5b88d5760320 5717 */
kenjiArai 0:5b88d5760320 5718
kenjiArai 0:5b88d5760320 5719 /* Notes:
kenjiArai 0:5b88d5760320 5720 * (1) in_hslen is not necessarily the size of the
kenjiArai 0:5b88d5760320 5721 * current handshake content: If DTLS handshake
kenjiArai 0:5b88d5760320 5722 * fragmentation is used, that's the fragment
kenjiArai 0:5b88d5760320 5723 * size instead. Using the total handshake message
kenjiArai 0:5b88d5760320 5724 * size here is faulty and should be changed at
kenjiArai 0:5b88d5760320 5725 * some point.
kenjiArai 0:5b88d5760320 5726 * (2) While it doesn't seem to cause problems, one
kenjiArai 0:5b88d5760320 5727 * has to be very careful not to assume that in_hslen
kenjiArai 0:5b88d5760320 5728 * is always <= in_msglen in a sensible communication.
kenjiArai 0:5b88d5760320 5729 * Again, it's wrong for DTLS handshake fragmentation.
kenjiArai 0:5b88d5760320 5730 * The following check is therefore mandatory, and
kenjiArai 0:5b88d5760320 5731 * should not be treated as a silently corrected assertion.
kenjiArai 0:5b88d5760320 5732 * Additionally, ssl->in_hslen might be arbitrarily out of
kenjiArai 0:5b88d5760320 5733 * bounds after handling a DTLS message with an unexpected
kenjiArai 0:5b88d5760320 5734 * sequence number, see mbedtls_ssl_prepare_handshake_record.
kenjiArai 0:5b88d5760320 5735 */
kenjiArai 0:5b88d5760320 5736 if( ssl->in_hslen < ssl->in_msglen )
kenjiArai 0:5b88d5760320 5737 {
kenjiArai 0:5b88d5760320 5738 ssl->in_msglen -= ssl->in_hslen;
kenjiArai 0:5b88d5760320 5739 memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
kenjiArai 0:5b88d5760320 5740 ssl->in_msglen );
kenjiArai 0:5b88d5760320 5741
kenjiArai 0:5b88d5760320 5742 MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
kenjiArai 0:5b88d5760320 5743 ssl->in_msg, ssl->in_msglen );
kenjiArai 0:5b88d5760320 5744 }
kenjiArai 0:5b88d5760320 5745 else
kenjiArai 0:5b88d5760320 5746 {
kenjiArai 0:5b88d5760320 5747 ssl->in_msglen = 0;
kenjiArai 0:5b88d5760320 5748 }
kenjiArai 0:5b88d5760320 5749
kenjiArai 0:5b88d5760320 5750 ssl->in_hslen = 0;
kenjiArai 0:5b88d5760320 5751 }
kenjiArai 0:5b88d5760320 5752 /* Case (4): Application data */
kenjiArai 0:5b88d5760320 5753 else if( ssl->in_offt != NULL )
kenjiArai 0:5b88d5760320 5754 {
kenjiArai 0:5b88d5760320 5755 return( 0 );
kenjiArai 0:5b88d5760320 5756 }
kenjiArai 0:5b88d5760320 5757 /* Everything else (CCS & Alerts) */
kenjiArai 0:5b88d5760320 5758 else
kenjiArai 0:5b88d5760320 5759 {
kenjiArai 0:5b88d5760320 5760 ssl->in_msglen = 0;
kenjiArai 0:5b88d5760320 5761 }
kenjiArai 0:5b88d5760320 5762
kenjiArai 0:5b88d5760320 5763 return( 0 );
kenjiArai 0:5b88d5760320 5764 }
kenjiArai 0:5b88d5760320 5765
kenjiArai 0:5b88d5760320 5766 static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5767 {
kenjiArai 0:5b88d5760320 5768 if( ssl->in_msglen > 0 )
kenjiArai 0:5b88d5760320 5769 return( 1 );
kenjiArai 0:5b88d5760320 5770
kenjiArai 0:5b88d5760320 5771 return( 0 );
kenjiArai 0:5b88d5760320 5772 }
kenjiArai 0:5b88d5760320 5773
kenjiArai 0:5b88d5760320 5774 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 5775
kenjiArai 0:5b88d5760320 5776 static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5777 {
kenjiArai 0:5b88d5760320 5778 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 5779 if( hs == NULL )
kenjiArai 0:5b88d5760320 5780 return;
kenjiArai 0:5b88d5760320 5781
kenjiArai 0:5b88d5760320 5782 if( hs->buffering.future_record.data != NULL )
kenjiArai 0:5b88d5760320 5783 {
kenjiArai 0:5b88d5760320 5784 hs->buffering.total_bytes_buffered -=
kenjiArai 0:5b88d5760320 5785 hs->buffering.future_record.len;
kenjiArai 0:5b88d5760320 5786
kenjiArai 0:5b88d5760320 5787 mbedtls_free( hs->buffering.future_record.data );
kenjiArai 0:5b88d5760320 5788 hs->buffering.future_record.data = NULL;
kenjiArai 0:5b88d5760320 5789 }
kenjiArai 0:5b88d5760320 5790 }
kenjiArai 0:5b88d5760320 5791
kenjiArai 0:5b88d5760320 5792 static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5793 {
kenjiArai 0:5b88d5760320 5794 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 5795 unsigned char * rec;
kenjiArai 0:5b88d5760320 5796 size_t rec_len;
kenjiArai 0:5b88d5760320 5797 unsigned rec_epoch;
kenjiArai 0:5b88d5760320 5798
kenjiArai 0:5b88d5760320 5799 if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 5800 return( 0 );
kenjiArai 0:5b88d5760320 5801
kenjiArai 0:5b88d5760320 5802 if( hs == NULL )
kenjiArai 0:5b88d5760320 5803 return( 0 );
kenjiArai 0:5b88d5760320 5804
kenjiArai 0:5b88d5760320 5805 rec = hs->buffering.future_record.data;
kenjiArai 0:5b88d5760320 5806 rec_len = hs->buffering.future_record.len;
kenjiArai 0:5b88d5760320 5807 rec_epoch = hs->buffering.future_record.epoch;
kenjiArai 0:5b88d5760320 5808
kenjiArai 0:5b88d5760320 5809 if( rec == NULL )
kenjiArai 0:5b88d5760320 5810 return( 0 );
kenjiArai 0:5b88d5760320 5811
kenjiArai 0:5b88d5760320 5812 /* Only consider loading future records if the
kenjiArai 0:5b88d5760320 5813 * input buffer is empty. */
kenjiArai 0:5b88d5760320 5814 if( ssl_next_record_is_in_datagram( ssl ) == 1 )
kenjiArai 0:5b88d5760320 5815 return( 0 );
kenjiArai 0:5b88d5760320 5816
kenjiArai 0:5b88d5760320 5817 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) );
kenjiArai 0:5b88d5760320 5818
kenjiArai 0:5b88d5760320 5819 if( rec_epoch != ssl->in_epoch )
kenjiArai 0:5b88d5760320 5820 {
kenjiArai 0:5b88d5760320 5821 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) );
kenjiArai 0:5b88d5760320 5822 goto exit;
kenjiArai 0:5b88d5760320 5823 }
kenjiArai 0:5b88d5760320 5824
kenjiArai 0:5b88d5760320 5825 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
kenjiArai 0:5b88d5760320 5826
kenjiArai 0:5b88d5760320 5827 /* Double-check that the record is not too large */
kenjiArai 0:5b88d5760320 5828 if( rec_len > MBEDTLS_SSL_IN_BUFFER_LEN -
kenjiArai 0:5b88d5760320 5829 (size_t)( ssl->in_hdr - ssl->in_buf ) )
kenjiArai 0:5b88d5760320 5830 {
kenjiArai 0:5b88d5760320 5831 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 5832 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 5833 }
kenjiArai 0:5b88d5760320 5834
kenjiArai 0:5b88d5760320 5835 memcpy( ssl->in_hdr, rec, rec_len );
kenjiArai 0:5b88d5760320 5836 ssl->in_left = rec_len;
kenjiArai 0:5b88d5760320 5837 ssl->next_record_offset = 0;
kenjiArai 0:5b88d5760320 5838
kenjiArai 0:5b88d5760320 5839 ssl_free_buffered_record( ssl );
kenjiArai 0:5b88d5760320 5840
kenjiArai 0:5b88d5760320 5841 exit:
kenjiArai 0:5b88d5760320 5842 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) );
kenjiArai 0:5b88d5760320 5843 return( 0 );
kenjiArai 0:5b88d5760320 5844 }
kenjiArai 0:5b88d5760320 5845
kenjiArai 0:5b88d5760320 5846 static int ssl_buffer_future_record( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5847 {
kenjiArai 0:5b88d5760320 5848 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 5849 size_t const rec_hdr_len = 13;
kenjiArai 0:5b88d5760320 5850 size_t const total_buf_sz = rec_hdr_len + ssl->in_msglen;
kenjiArai 0:5b88d5760320 5851
kenjiArai 0:5b88d5760320 5852 /* Don't buffer future records outside handshakes. */
kenjiArai 0:5b88d5760320 5853 if( hs == NULL )
kenjiArai 0:5b88d5760320 5854 return( 0 );
kenjiArai 0:5b88d5760320 5855
kenjiArai 0:5b88d5760320 5856 /* Only buffer handshake records (we are only interested
kenjiArai 0:5b88d5760320 5857 * in Finished messages). */
kenjiArai 0:5b88d5760320 5858 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
kenjiArai 0:5b88d5760320 5859 return( 0 );
kenjiArai 0:5b88d5760320 5860
kenjiArai 0:5b88d5760320 5861 /* Don't buffer more than one future epoch record. */
kenjiArai 0:5b88d5760320 5862 if( hs->buffering.future_record.data != NULL )
kenjiArai 0:5b88d5760320 5863 return( 0 );
kenjiArai 0:5b88d5760320 5864
kenjiArai 0:5b88d5760320 5865 /* Don't buffer record if there's not enough buffering space remaining. */
kenjiArai 0:5b88d5760320 5866 if( total_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
kenjiArai 0:5b88d5760320 5867 hs->buffering.total_bytes_buffered ) )
kenjiArai 0:5b88d5760320 5868 {
kenjiArai 0:5b88d5760320 5869 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
kenjiArai 0:5b88d5760320 5870 (unsigned) total_buf_sz, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
kenjiArai 0:5b88d5760320 5871 (unsigned) hs->buffering.total_bytes_buffered ) );
kenjiArai 0:5b88d5760320 5872 return( 0 );
kenjiArai 0:5b88d5760320 5873 }
kenjiArai 0:5b88d5760320 5874
kenjiArai 0:5b88d5760320 5875 /* Buffer record */
kenjiArai 0:5b88d5760320 5876 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u",
kenjiArai 0:5b88d5760320 5877 ssl->in_epoch + 1 ) );
kenjiArai 0:5b88d5760320 5878 MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", ssl->in_hdr,
kenjiArai 0:5b88d5760320 5879 rec_hdr_len + ssl->in_msglen );
kenjiArai 0:5b88d5760320 5880
kenjiArai 0:5b88d5760320 5881 /* ssl_parse_record_header() only considers records
kenjiArai 0:5b88d5760320 5882 * of the next epoch as candidates for buffering. */
kenjiArai 0:5b88d5760320 5883 hs->buffering.future_record.epoch = ssl->in_epoch + 1;
kenjiArai 0:5b88d5760320 5884 hs->buffering.future_record.len = total_buf_sz;
kenjiArai 0:5b88d5760320 5885
kenjiArai 0:5b88d5760320 5886 hs->buffering.future_record.data =
kenjiArai 0:5b88d5760320 5887 mbedtls_calloc( 1, hs->buffering.future_record.len );
kenjiArai 0:5b88d5760320 5888 if( hs->buffering.future_record.data == NULL )
kenjiArai 0:5b88d5760320 5889 {
kenjiArai 0:5b88d5760320 5890 /* If we run out of RAM trying to buffer a
kenjiArai 0:5b88d5760320 5891 * record from the next epoch, just ignore. */
kenjiArai 0:5b88d5760320 5892 return( 0 );
kenjiArai 0:5b88d5760320 5893 }
kenjiArai 0:5b88d5760320 5894
kenjiArai 0:5b88d5760320 5895 memcpy( hs->buffering.future_record.data, ssl->in_hdr, total_buf_sz );
kenjiArai 0:5b88d5760320 5896
kenjiArai 0:5b88d5760320 5897 hs->buffering.total_bytes_buffered += total_buf_sz;
kenjiArai 0:5b88d5760320 5898 return( 0 );
kenjiArai 0:5b88d5760320 5899 }
kenjiArai 0:5b88d5760320 5900
kenjiArai 0:5b88d5760320 5901 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 5902
kenjiArai 0:5b88d5760320 5903 static int ssl_get_next_record( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 5904 {
kenjiArai 0:5b88d5760320 5905 int ret;
kenjiArai 0:5b88d5760320 5906
kenjiArai 0:5b88d5760320 5907 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 5908 /* We might have buffered a future record; if so,
kenjiArai 0:5b88d5760320 5909 * and if the epoch matches now, load it.
kenjiArai 0:5b88d5760320 5910 * On success, this call will set ssl->in_left to
kenjiArai 0:5b88d5760320 5911 * the length of the buffered record, so that
kenjiArai 0:5b88d5760320 5912 * the calls to ssl_fetch_input() below will
kenjiArai 0:5b88d5760320 5913 * essentially be no-ops. */
kenjiArai 0:5b88d5760320 5914 ret = ssl_load_buffered_record( ssl );
kenjiArai 0:5b88d5760320 5915 if( ret != 0 )
kenjiArai 0:5b88d5760320 5916 return( ret );
kenjiArai 0:5b88d5760320 5917 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 5918
kenjiArai 0:5b88d5760320 5919 /* Reset in pointers to default state for TLS/DTLS records,
kenjiArai 0:5b88d5760320 5920 * assuming no CID and no offset between record content and
kenjiArai 0:5b88d5760320 5921 * record plaintext. */
kenjiArai 0:5b88d5760320 5922 ssl_update_in_pointers( ssl );
kenjiArai 0:5b88d5760320 5923
kenjiArai 0:5b88d5760320 5924 /* Ensure that we have enough space available for the default form
kenjiArai 0:5b88d5760320 5925 * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
kenjiArai 0:5b88d5760320 5926 * with no space for CIDs counted in). */
kenjiArai 0:5b88d5760320 5927 ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) );
kenjiArai 0:5b88d5760320 5928 if( ret != 0 )
kenjiArai 0:5b88d5760320 5929 {
kenjiArai 0:5b88d5760320 5930 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
kenjiArai 0:5b88d5760320 5931 return( ret );
kenjiArai 0:5b88d5760320 5932 }
kenjiArai 0:5b88d5760320 5933
kenjiArai 0:5b88d5760320 5934 if( ( ret = ssl_parse_record_header( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 5935 {
kenjiArai 0:5b88d5760320 5936 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 5937 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 5938 ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
kenjiArai 0:5b88d5760320 5939 {
kenjiArai 0:5b88d5760320 5940 if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
kenjiArai 0:5b88d5760320 5941 {
kenjiArai 0:5b88d5760320 5942 ret = ssl_buffer_future_record( ssl );
kenjiArai 0:5b88d5760320 5943 if( ret != 0 )
kenjiArai 0:5b88d5760320 5944 return( ret );
kenjiArai 0:5b88d5760320 5945
kenjiArai 0:5b88d5760320 5946 /* Fall through to handling of unexpected records */
kenjiArai 0:5b88d5760320 5947 ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
kenjiArai 0:5b88d5760320 5948 }
kenjiArai 0:5b88d5760320 5949
kenjiArai 0:5b88d5760320 5950 if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
kenjiArai 0:5b88d5760320 5951 {
kenjiArai 0:5b88d5760320 5952 /* Skip unexpected record (but not whole datagram) */
kenjiArai 0:5b88d5760320 5953 ssl->next_record_offset = ssl->in_msglen
kenjiArai 0:5b88d5760320 5954 + mbedtls_ssl_in_hdr_len( ssl );
kenjiArai 0:5b88d5760320 5955
kenjiArai 0:5b88d5760320 5956 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
kenjiArai 0:5b88d5760320 5957 "(header)" ) );
kenjiArai 0:5b88d5760320 5958 }
kenjiArai 0:5b88d5760320 5959 else
kenjiArai 0:5b88d5760320 5960 {
kenjiArai 0:5b88d5760320 5961 /* Skip invalid record and the rest of the datagram */
kenjiArai 0:5b88d5760320 5962 ssl->next_record_offset = 0;
kenjiArai 0:5b88d5760320 5963 ssl->in_left = 0;
kenjiArai 0:5b88d5760320 5964
kenjiArai 0:5b88d5760320 5965 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
kenjiArai 0:5b88d5760320 5966 "(header)" ) );
kenjiArai 0:5b88d5760320 5967 }
kenjiArai 0:5b88d5760320 5968
kenjiArai 0:5b88d5760320 5969 /* Get next record */
kenjiArai 0:5b88d5760320 5970 return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
kenjiArai 0:5b88d5760320 5971 }
kenjiArai 0:5b88d5760320 5972 #endif
kenjiArai 0:5b88d5760320 5973 return( ret );
kenjiArai 0:5b88d5760320 5974 }
kenjiArai 0:5b88d5760320 5975
kenjiArai 0:5b88d5760320 5976 /*
kenjiArai 0:5b88d5760320 5977 * Read and optionally decrypt the message contents
kenjiArai 0:5b88d5760320 5978 */
kenjiArai 0:5b88d5760320 5979 if( ( ret = mbedtls_ssl_fetch_input( ssl,
kenjiArai 0:5b88d5760320 5980 mbedtls_ssl_in_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 )
kenjiArai 0:5b88d5760320 5981 {
kenjiArai 0:5b88d5760320 5982 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
kenjiArai 0:5b88d5760320 5983 return( ret );
kenjiArai 0:5b88d5760320 5984 }
kenjiArai 0:5b88d5760320 5985
kenjiArai 0:5b88d5760320 5986 /* Done reading this record, get ready for the next one */
kenjiArai 0:5b88d5760320 5987 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 5988 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 5989 {
kenjiArai 0:5b88d5760320 5990 ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_in_hdr_len( ssl );
kenjiArai 0:5b88d5760320 5991 if( ssl->next_record_offset < ssl->in_left )
kenjiArai 0:5b88d5760320 5992 {
kenjiArai 0:5b88d5760320 5993 MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
kenjiArai 0:5b88d5760320 5994 }
kenjiArai 0:5b88d5760320 5995 }
kenjiArai 0:5b88d5760320 5996 else
kenjiArai 0:5b88d5760320 5997 #endif
kenjiArai 0:5b88d5760320 5998 ssl->in_left = 0;
kenjiArai 0:5b88d5760320 5999
kenjiArai 0:5b88d5760320 6000 if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 6001 {
kenjiArai 0:5b88d5760320 6002 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 6003 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 6004 {
kenjiArai 0:5b88d5760320 6005 /* Silently discard invalid records */
kenjiArai 0:5b88d5760320 6006 if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
kenjiArai 0:5b88d5760320 6007 {
kenjiArai 0:5b88d5760320 6008 /* Except when waiting for Finished as a bad mac here
kenjiArai 0:5b88d5760320 6009 * probably means something went wrong in the handshake
kenjiArai 0:5b88d5760320 6010 * (eg wrong psk used, mitm downgrade attempt, etc.) */
kenjiArai 0:5b88d5760320 6011 if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
kenjiArai 0:5b88d5760320 6012 ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
kenjiArai 0:5b88d5760320 6013 {
kenjiArai 0:5b88d5760320 6014 #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
kenjiArai 0:5b88d5760320 6015 if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
kenjiArai 0:5b88d5760320 6016 {
kenjiArai 0:5b88d5760320 6017 mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 6018 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6019 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
kenjiArai 0:5b88d5760320 6020 }
kenjiArai 0:5b88d5760320 6021 #endif
kenjiArai 0:5b88d5760320 6022 return( ret );
kenjiArai 0:5b88d5760320 6023 }
kenjiArai 0:5b88d5760320 6024
kenjiArai 0:5b88d5760320 6025 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
kenjiArai 0:5b88d5760320 6026 if( ssl->conf->badmac_limit != 0 &&
kenjiArai 0:5b88d5760320 6027 ++ssl->badmac_seen >= ssl->conf->badmac_limit )
kenjiArai 0:5b88d5760320 6028 {
kenjiArai 0:5b88d5760320 6029 MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
kenjiArai 0:5b88d5760320 6030 return( MBEDTLS_ERR_SSL_INVALID_MAC );
kenjiArai 0:5b88d5760320 6031 }
kenjiArai 0:5b88d5760320 6032 #endif
kenjiArai 0:5b88d5760320 6033
kenjiArai 0:5b88d5760320 6034 /* As above, invalid records cause
kenjiArai 0:5b88d5760320 6035 * dismissal of the whole datagram. */
kenjiArai 0:5b88d5760320 6036
kenjiArai 0:5b88d5760320 6037 ssl->next_record_offset = 0;
kenjiArai 0:5b88d5760320 6038 ssl->in_left = 0;
kenjiArai 0:5b88d5760320 6039
kenjiArai 0:5b88d5760320 6040 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
kenjiArai 0:5b88d5760320 6041 return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
kenjiArai 0:5b88d5760320 6042 }
kenjiArai 0:5b88d5760320 6043
kenjiArai 0:5b88d5760320 6044 return( ret );
kenjiArai 0:5b88d5760320 6045 }
kenjiArai 0:5b88d5760320 6046 else
kenjiArai 0:5b88d5760320 6047 #endif
kenjiArai 0:5b88d5760320 6048 {
kenjiArai 0:5b88d5760320 6049 /* Error out (and send alert) on invalid records */
kenjiArai 0:5b88d5760320 6050 #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
kenjiArai 0:5b88d5760320 6051 if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
kenjiArai 0:5b88d5760320 6052 {
kenjiArai 0:5b88d5760320 6053 mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 6054 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6055 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
kenjiArai 0:5b88d5760320 6056 }
kenjiArai 0:5b88d5760320 6057 #endif
kenjiArai 0:5b88d5760320 6058 return( ret );
kenjiArai 0:5b88d5760320 6059 }
kenjiArai 0:5b88d5760320 6060 }
kenjiArai 0:5b88d5760320 6061
kenjiArai 0:5b88d5760320 6062 return( 0 );
kenjiArai 0:5b88d5760320 6063 }
kenjiArai 0:5b88d5760320 6064
kenjiArai 0:5b88d5760320 6065 int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 6066 {
kenjiArai 0:5b88d5760320 6067 int ret;
kenjiArai 0:5b88d5760320 6068
kenjiArai 0:5b88d5760320 6069 /*
kenjiArai 0:5b88d5760320 6070 * Handle particular types of records
kenjiArai 0:5b88d5760320 6071 */
kenjiArai 0:5b88d5760320 6072 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
kenjiArai 0:5b88d5760320 6073 {
kenjiArai 0:5b88d5760320 6074 if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 6075 {
kenjiArai 0:5b88d5760320 6076 return( ret );
kenjiArai 0:5b88d5760320 6077 }
kenjiArai 0:5b88d5760320 6078 }
kenjiArai 0:5b88d5760320 6079
kenjiArai 0:5b88d5760320 6080 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
kenjiArai 0:5b88d5760320 6081 {
kenjiArai 0:5b88d5760320 6082 if( ssl->in_msglen != 1 )
kenjiArai 0:5b88d5760320 6083 {
kenjiArai 0:5b88d5760320 6084 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d",
kenjiArai 0:5b88d5760320 6085 ssl->in_msglen ) );
kenjiArai 0:5b88d5760320 6086 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 6087 }
kenjiArai 0:5b88d5760320 6088
kenjiArai 0:5b88d5760320 6089 if( ssl->in_msg[0] != 1 )
kenjiArai 0:5b88d5760320 6090 {
kenjiArai 0:5b88d5760320 6091 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x",
kenjiArai 0:5b88d5760320 6092 ssl->in_msg[0] ) );
kenjiArai 0:5b88d5760320 6093 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 6094 }
kenjiArai 0:5b88d5760320 6095
kenjiArai 0:5b88d5760320 6096 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 6097 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 6098 ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
kenjiArai 0:5b88d5760320 6099 ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
kenjiArai 0:5b88d5760320 6100 {
kenjiArai 0:5b88d5760320 6101 if( ssl->handshake == NULL )
kenjiArai 0:5b88d5760320 6102 {
kenjiArai 0:5b88d5760320 6103 MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) );
kenjiArai 0:5b88d5760320 6104 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
kenjiArai 0:5b88d5760320 6105 }
kenjiArai 0:5b88d5760320 6106
kenjiArai 0:5b88d5760320 6107 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) );
kenjiArai 0:5b88d5760320 6108 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
kenjiArai 0:5b88d5760320 6109 }
kenjiArai 0:5b88d5760320 6110 #endif
kenjiArai 0:5b88d5760320 6111 }
kenjiArai 0:5b88d5760320 6112
kenjiArai 0:5b88d5760320 6113 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
kenjiArai 0:5b88d5760320 6114 {
kenjiArai 0:5b88d5760320 6115 if( ssl->in_msglen != 2 )
kenjiArai 0:5b88d5760320 6116 {
kenjiArai 0:5b88d5760320 6117 /* Note: Standard allows for more than one 2 byte alert
kenjiArai 0:5b88d5760320 6118 to be packed in a single message, but Mbed TLS doesn't
kenjiArai 0:5b88d5760320 6119 currently support this. */
kenjiArai 0:5b88d5760320 6120 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d",
kenjiArai 0:5b88d5760320 6121 ssl->in_msglen ) );
kenjiArai 0:5b88d5760320 6122 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
kenjiArai 0:5b88d5760320 6123 }
kenjiArai 0:5b88d5760320 6124
kenjiArai 0:5b88d5760320 6125 MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
kenjiArai 0:5b88d5760320 6126 ssl->in_msg[0], ssl->in_msg[1] ) );
kenjiArai 0:5b88d5760320 6127
kenjiArai 0:5b88d5760320 6128 /*
kenjiArai 0:5b88d5760320 6129 * Ignore non-fatal alerts, except close_notify and no_renegotiation
kenjiArai 0:5b88d5760320 6130 */
kenjiArai 0:5b88d5760320 6131 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
kenjiArai 0:5b88d5760320 6132 {
kenjiArai 0:5b88d5760320 6133 MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
kenjiArai 0:5b88d5760320 6134 ssl->in_msg[1] ) );
kenjiArai 0:5b88d5760320 6135 return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
kenjiArai 0:5b88d5760320 6136 }
kenjiArai 0:5b88d5760320 6137
kenjiArai 0:5b88d5760320 6138 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
kenjiArai 0:5b88d5760320 6139 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
kenjiArai 0:5b88d5760320 6140 {
kenjiArai 0:5b88d5760320 6141 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
kenjiArai 0:5b88d5760320 6142 return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
kenjiArai 0:5b88d5760320 6143 }
kenjiArai 0:5b88d5760320 6144
kenjiArai 0:5b88d5760320 6145 #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
kenjiArai 0:5b88d5760320 6146 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
kenjiArai 0:5b88d5760320 6147 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
kenjiArai 0:5b88d5760320 6148 {
kenjiArai 0:5b88d5760320 6149 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) );
kenjiArai 0:5b88d5760320 6150 /* Will be handled when trying to parse ServerHello */
kenjiArai 0:5b88d5760320 6151 return( 0 );
kenjiArai 0:5b88d5760320 6152 }
kenjiArai 0:5b88d5760320 6153 #endif
kenjiArai 0:5b88d5760320 6154
kenjiArai 0:5b88d5760320 6155 #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 6156 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
kenjiArai 0:5b88d5760320 6157 ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
kenjiArai 0:5b88d5760320 6158 ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
kenjiArai 0:5b88d5760320 6159 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
kenjiArai 0:5b88d5760320 6160 {
kenjiArai 0:5b88d5760320 6161 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
kenjiArai 0:5b88d5760320 6162 /* Will be handled in mbedtls_ssl_parse_certificate() */
kenjiArai 0:5b88d5760320 6163 return( 0 );
kenjiArai 0:5b88d5760320 6164 }
kenjiArai 0:5b88d5760320 6165 #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 6166
kenjiArai 0:5b88d5760320 6167 /* Silently ignore: fetch new message */
kenjiArai 0:5b88d5760320 6168 return MBEDTLS_ERR_SSL_NON_FATAL;
kenjiArai 0:5b88d5760320 6169 }
kenjiArai 0:5b88d5760320 6170
kenjiArai 0:5b88d5760320 6171 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 6172 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 6173 {
kenjiArai 0:5b88d5760320 6174 /* Drop unexpected ApplicationData records,
kenjiArai 0:5b88d5760320 6175 * except at the beginning of renegotiations */
kenjiArai 0:5b88d5760320 6176 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
kenjiArai 0:5b88d5760320 6177 ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
kenjiArai 0:5b88d5760320 6178 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 6179 && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
kenjiArai 0:5b88d5760320 6180 ssl->state == MBEDTLS_SSL_SERVER_HELLO )
kenjiArai 0:5b88d5760320 6181 #endif
kenjiArai 0:5b88d5760320 6182 )
kenjiArai 0:5b88d5760320 6183 {
kenjiArai 0:5b88d5760320 6184 MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
kenjiArai 0:5b88d5760320 6185 return( MBEDTLS_ERR_SSL_NON_FATAL );
kenjiArai 0:5b88d5760320 6186 }
kenjiArai 0:5b88d5760320 6187
kenjiArai 0:5b88d5760320 6188 if( ssl->handshake != NULL &&
kenjiArai 0:5b88d5760320 6189 ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 6190 {
kenjiArai 0:5b88d5760320 6191 ssl_handshake_wrapup_free_hs_transform( ssl );
kenjiArai 0:5b88d5760320 6192 }
kenjiArai 0:5b88d5760320 6193 }
kenjiArai 0:5b88d5760320 6194 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 6195
kenjiArai 0:5b88d5760320 6196 return( 0 );
kenjiArai 0:5b88d5760320 6197 }
kenjiArai 0:5b88d5760320 6198
kenjiArai 0:5b88d5760320 6199 int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 6200 {
kenjiArai 0:5b88d5760320 6201 int ret;
kenjiArai 0:5b88d5760320 6202
kenjiArai 0:5b88d5760320 6203 if( ( ret = mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 6204 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6205 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 )
kenjiArai 0:5b88d5760320 6206 {
kenjiArai 0:5b88d5760320 6207 return( ret );
kenjiArai 0:5b88d5760320 6208 }
kenjiArai 0:5b88d5760320 6209
kenjiArai 0:5b88d5760320 6210 return( 0 );
kenjiArai 0:5b88d5760320 6211 }
kenjiArai 0:5b88d5760320 6212
kenjiArai 0:5b88d5760320 6213 int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 6214 unsigned char level,
kenjiArai 0:5b88d5760320 6215 unsigned char message )
kenjiArai 0:5b88d5760320 6216 {
kenjiArai 0:5b88d5760320 6217 int ret;
kenjiArai 0:5b88d5760320 6218
kenjiArai 0:5b88d5760320 6219 if( ssl == NULL || ssl->conf == NULL )
kenjiArai 0:5b88d5760320 6220 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 6221
kenjiArai 0:5b88d5760320 6222 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
kenjiArai 0:5b88d5760320 6223 MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
kenjiArai 0:5b88d5760320 6224
kenjiArai 0:5b88d5760320 6225 ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
kenjiArai 0:5b88d5760320 6226 ssl->out_msglen = 2;
kenjiArai 0:5b88d5760320 6227 ssl->out_msg[0] = level;
kenjiArai 0:5b88d5760320 6228 ssl->out_msg[1] = message;
kenjiArai 0:5b88d5760320 6229
kenjiArai 0:5b88d5760320 6230 if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
kenjiArai 0:5b88d5760320 6231 {
kenjiArai 0:5b88d5760320 6232 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
kenjiArai 0:5b88d5760320 6233 return( ret );
kenjiArai 0:5b88d5760320 6234 }
kenjiArai 0:5b88d5760320 6235 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
kenjiArai 0:5b88d5760320 6236
kenjiArai 0:5b88d5760320 6237 return( 0 );
kenjiArai 0:5b88d5760320 6238 }
kenjiArai 0:5b88d5760320 6239
kenjiArai 0:5b88d5760320 6240 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 6241 static void ssl_clear_peer_cert( mbedtls_ssl_session *session )
kenjiArai 0:5b88d5760320 6242 {
kenjiArai 0:5b88d5760320 6243 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 6244 if( session->peer_cert != NULL )
kenjiArai 0:5b88d5760320 6245 {
kenjiArai 0:5b88d5760320 6246 mbedtls_x509_crt_free( session->peer_cert );
kenjiArai 0:5b88d5760320 6247 mbedtls_free( session->peer_cert );
kenjiArai 0:5b88d5760320 6248 session->peer_cert = NULL;
kenjiArai 0:5b88d5760320 6249 }
kenjiArai 0:5b88d5760320 6250 #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 6251 if( session->peer_cert_digest != NULL )
kenjiArai 0:5b88d5760320 6252 {
kenjiArai 0:5b88d5760320 6253 /* Zeroization is not necessary. */
kenjiArai 0:5b88d5760320 6254 mbedtls_free( session->peer_cert_digest );
kenjiArai 0:5b88d5760320 6255 session->peer_cert_digest = NULL;
kenjiArai 0:5b88d5760320 6256 session->peer_cert_digest_type = MBEDTLS_MD_NONE;
kenjiArai 0:5b88d5760320 6257 session->peer_cert_digest_len = 0;
kenjiArai 0:5b88d5760320 6258 }
kenjiArai 0:5b88d5760320 6259 #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 6260 }
kenjiArai 0:5b88d5760320 6261 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 6262
kenjiArai 0:5b88d5760320 6263 /*
kenjiArai 0:5b88d5760320 6264 * Handshake functions
kenjiArai 0:5b88d5760320 6265 */
kenjiArai 0:5b88d5760320 6266 #if !defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 6267 /* No certificate support -> dummy functions */
kenjiArai 0:5b88d5760320 6268 int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 6269 {
kenjiArai 0:5b88d5760320 6270 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
kenjiArai 0:5b88d5760320 6271 ssl->handshake->ciphersuite_info;
kenjiArai 0:5b88d5760320 6272
kenjiArai 0:5b88d5760320 6273 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
kenjiArai 0:5b88d5760320 6274
kenjiArai 0:5b88d5760320 6275 if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
kenjiArai 0:5b88d5760320 6276 {
kenjiArai 0:5b88d5760320 6277 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
kenjiArai 0:5b88d5760320 6278 ssl->state++;
kenjiArai 0:5b88d5760320 6279 return( 0 );
kenjiArai 0:5b88d5760320 6280 }
kenjiArai 0:5b88d5760320 6281
kenjiArai 0:5b88d5760320 6282 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 6283 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 6284 }
kenjiArai 0:5b88d5760320 6285
kenjiArai 0:5b88d5760320 6286 int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 6287 {
kenjiArai 0:5b88d5760320 6288 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
kenjiArai 0:5b88d5760320 6289 ssl->handshake->ciphersuite_info;
kenjiArai 0:5b88d5760320 6290
kenjiArai 0:5b88d5760320 6291 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
kenjiArai 0:5b88d5760320 6292
kenjiArai 0:5b88d5760320 6293 if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
kenjiArai 0:5b88d5760320 6294 {
kenjiArai 0:5b88d5760320 6295 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
kenjiArai 0:5b88d5760320 6296 ssl->state++;
kenjiArai 0:5b88d5760320 6297 return( 0 );
kenjiArai 0:5b88d5760320 6298 }
kenjiArai 0:5b88d5760320 6299
kenjiArai 0:5b88d5760320 6300 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 6301 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 6302 }
kenjiArai 0:5b88d5760320 6303
kenjiArai 0:5b88d5760320 6304 #else /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
kenjiArai 0:5b88d5760320 6305 /* Some certificate support -> implement write and parse */
kenjiArai 0:5b88d5760320 6306
kenjiArai 0:5b88d5760320 6307 int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 6308 {
kenjiArai 0:5b88d5760320 6309 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
kenjiArai 0:5b88d5760320 6310 size_t i, n;
kenjiArai 0:5b88d5760320 6311 const mbedtls_x509_crt *crt;
kenjiArai 0:5b88d5760320 6312 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
kenjiArai 0:5b88d5760320 6313 ssl->handshake->ciphersuite_info;
kenjiArai 0:5b88d5760320 6314
kenjiArai 0:5b88d5760320 6315 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
kenjiArai 0:5b88d5760320 6316
kenjiArai 0:5b88d5760320 6317 if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
kenjiArai 0:5b88d5760320 6318 {
kenjiArai 0:5b88d5760320 6319 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
kenjiArai 0:5b88d5760320 6320 ssl->state++;
kenjiArai 0:5b88d5760320 6321 return( 0 );
kenjiArai 0:5b88d5760320 6322 }
kenjiArai 0:5b88d5760320 6323
kenjiArai 0:5b88d5760320 6324 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 6325 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 6326 {
kenjiArai 0:5b88d5760320 6327 if( ssl->client_auth == 0 )
kenjiArai 0:5b88d5760320 6328 {
kenjiArai 0:5b88d5760320 6329 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
kenjiArai 0:5b88d5760320 6330 ssl->state++;
kenjiArai 0:5b88d5760320 6331 return( 0 );
kenjiArai 0:5b88d5760320 6332 }
kenjiArai 0:5b88d5760320 6333
kenjiArai 0:5b88d5760320 6334 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 6335 /*
kenjiArai 0:5b88d5760320 6336 * If using SSLv3 and got no cert, send an Alert message
kenjiArai 0:5b88d5760320 6337 * (otherwise an empty Certificate message will be sent).
kenjiArai 0:5b88d5760320 6338 */
kenjiArai 0:5b88d5760320 6339 if( mbedtls_ssl_own_cert( ssl ) == NULL &&
kenjiArai 0:5b88d5760320 6340 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 6341 {
kenjiArai 0:5b88d5760320 6342 ssl->out_msglen = 2;
kenjiArai 0:5b88d5760320 6343 ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
kenjiArai 0:5b88d5760320 6344 ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING;
kenjiArai 0:5b88d5760320 6345 ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT;
kenjiArai 0:5b88d5760320 6346
kenjiArai 0:5b88d5760320 6347 MBEDTLS_SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) );
kenjiArai 0:5b88d5760320 6348 goto write_msg;
kenjiArai 0:5b88d5760320 6349 }
kenjiArai 0:5b88d5760320 6350 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 6351 }
kenjiArai 0:5b88d5760320 6352 #endif /* MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 6353 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 6354 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 6355 {
kenjiArai 0:5b88d5760320 6356 if( mbedtls_ssl_own_cert( ssl ) == NULL )
kenjiArai 0:5b88d5760320 6357 {
kenjiArai 0:5b88d5760320 6358 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) );
kenjiArai 0:5b88d5760320 6359 return( MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED );
kenjiArai 0:5b88d5760320 6360 }
kenjiArai 0:5b88d5760320 6361 }
kenjiArai 0:5b88d5760320 6362 #endif
kenjiArai 0:5b88d5760320 6363
kenjiArai 0:5b88d5760320 6364 MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) );
kenjiArai 0:5b88d5760320 6365
kenjiArai 0:5b88d5760320 6366 /*
kenjiArai 0:5b88d5760320 6367 * 0 . 0 handshake type
kenjiArai 0:5b88d5760320 6368 * 1 . 3 handshake length
kenjiArai 0:5b88d5760320 6369 * 4 . 6 length of all certs
kenjiArai 0:5b88d5760320 6370 * 7 . 9 length of cert. 1
kenjiArai 0:5b88d5760320 6371 * 10 . n-1 peer certificate
kenjiArai 0:5b88d5760320 6372 * n . n+2 length of cert. 2
kenjiArai 0:5b88d5760320 6373 * n+3 . ... upper level cert, etc.
kenjiArai 0:5b88d5760320 6374 */
kenjiArai 0:5b88d5760320 6375 i = 7;
kenjiArai 0:5b88d5760320 6376 crt = mbedtls_ssl_own_cert( ssl );
kenjiArai 0:5b88d5760320 6377
kenjiArai 0:5b88d5760320 6378 while( crt != NULL )
kenjiArai 0:5b88d5760320 6379 {
kenjiArai 0:5b88d5760320 6380 n = crt->raw.len;
kenjiArai 0:5b88d5760320 6381 if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i )
kenjiArai 0:5b88d5760320 6382 {
kenjiArai 0:5b88d5760320 6383 MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d",
kenjiArai 0:5b88d5760320 6384 i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) );
kenjiArai 0:5b88d5760320 6385 return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE );
kenjiArai 0:5b88d5760320 6386 }
kenjiArai 0:5b88d5760320 6387
kenjiArai 0:5b88d5760320 6388 ssl->out_msg[i ] = (unsigned char)( n >> 16 );
kenjiArai 0:5b88d5760320 6389 ssl->out_msg[i + 1] = (unsigned char)( n >> 8 );
kenjiArai 0:5b88d5760320 6390 ssl->out_msg[i + 2] = (unsigned char)( n );
kenjiArai 0:5b88d5760320 6391
kenjiArai 0:5b88d5760320 6392 i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
kenjiArai 0:5b88d5760320 6393 i += n; crt = crt->next;
kenjiArai 0:5b88d5760320 6394 }
kenjiArai 0:5b88d5760320 6395
kenjiArai 0:5b88d5760320 6396 ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 );
kenjiArai 0:5b88d5760320 6397 ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 );
kenjiArai 0:5b88d5760320 6398 ssl->out_msg[6] = (unsigned char)( ( i - 7 ) );
kenjiArai 0:5b88d5760320 6399
kenjiArai 0:5b88d5760320 6400 ssl->out_msglen = i;
kenjiArai 0:5b88d5760320 6401 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
kenjiArai 0:5b88d5760320 6402 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE;
kenjiArai 0:5b88d5760320 6403
kenjiArai 0:5b88d5760320 6404 #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 6405 write_msg:
kenjiArai 0:5b88d5760320 6406 #endif
kenjiArai 0:5b88d5760320 6407
kenjiArai 0:5b88d5760320 6408 ssl->state++;
kenjiArai 0:5b88d5760320 6409
kenjiArai 0:5b88d5760320 6410 if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 6411 {
kenjiArai 0:5b88d5760320 6412 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
kenjiArai 0:5b88d5760320 6413 return( ret );
kenjiArai 0:5b88d5760320 6414 }
kenjiArai 0:5b88d5760320 6415
kenjiArai 0:5b88d5760320 6416 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) );
kenjiArai 0:5b88d5760320 6417
kenjiArai 0:5b88d5760320 6418 return( ret );
kenjiArai 0:5b88d5760320 6419 }
kenjiArai 0:5b88d5760320 6420
kenjiArai 0:5b88d5760320 6421 #if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 6422
kenjiArai 0:5b88d5760320 6423 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 6424 static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 6425 unsigned char *crt_buf,
kenjiArai 0:5b88d5760320 6426 size_t crt_buf_len )
kenjiArai 0:5b88d5760320 6427 {
kenjiArai 0:5b88d5760320 6428 mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
kenjiArai 0:5b88d5760320 6429
kenjiArai 0:5b88d5760320 6430 if( peer_crt == NULL )
kenjiArai 0:5b88d5760320 6431 return( -1 );
kenjiArai 0:5b88d5760320 6432
kenjiArai 0:5b88d5760320 6433 if( peer_crt->raw.len != crt_buf_len )
kenjiArai 0:5b88d5760320 6434 return( -1 );
kenjiArai 0:5b88d5760320 6435
kenjiArai 0:5b88d5760320 6436 return( memcmp( peer_crt->raw.p, crt_buf, crt_buf_len ) );
kenjiArai 0:5b88d5760320 6437 }
kenjiArai 0:5b88d5760320 6438 #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 6439 static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 6440 unsigned char *crt_buf,
kenjiArai 0:5b88d5760320 6441 size_t crt_buf_len )
kenjiArai 0:5b88d5760320 6442 {
kenjiArai 0:5b88d5760320 6443 int ret;
kenjiArai 0:5b88d5760320 6444 unsigned char const * const peer_cert_digest =
kenjiArai 0:5b88d5760320 6445 ssl->session->peer_cert_digest;
kenjiArai 0:5b88d5760320 6446 mbedtls_md_type_t const peer_cert_digest_type =
kenjiArai 0:5b88d5760320 6447 ssl->session->peer_cert_digest_type;
kenjiArai 0:5b88d5760320 6448 mbedtls_md_info_t const * const digest_info =
kenjiArai 0:5b88d5760320 6449 mbedtls_md_info_from_type( peer_cert_digest_type );
kenjiArai 0:5b88d5760320 6450 unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN];
kenjiArai 0:5b88d5760320 6451 size_t digest_len;
kenjiArai 0:5b88d5760320 6452
kenjiArai 0:5b88d5760320 6453 if( peer_cert_digest == NULL || digest_info == NULL )
kenjiArai 0:5b88d5760320 6454 return( -1 );
kenjiArai 0:5b88d5760320 6455
kenjiArai 0:5b88d5760320 6456 digest_len = mbedtls_md_get_size( digest_info );
kenjiArai 0:5b88d5760320 6457 if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN )
kenjiArai 0:5b88d5760320 6458 return( -1 );
kenjiArai 0:5b88d5760320 6459
kenjiArai 0:5b88d5760320 6460 ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest );
kenjiArai 0:5b88d5760320 6461 if( ret != 0 )
kenjiArai 0:5b88d5760320 6462 return( -1 );
kenjiArai 0:5b88d5760320 6463
kenjiArai 0:5b88d5760320 6464 return( memcmp( tmp_digest, peer_cert_digest, digest_len ) );
kenjiArai 0:5b88d5760320 6465 }
kenjiArai 0:5b88d5760320 6466 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 6467 #endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 6468
kenjiArai 0:5b88d5760320 6469 /*
kenjiArai 0:5b88d5760320 6470 * Once the certificate message is read, parse it into a cert chain and
kenjiArai 0:5b88d5760320 6471 * perform basic checks, but leave actual verification to the caller
kenjiArai 0:5b88d5760320 6472 */
kenjiArai 0:5b88d5760320 6473 static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 6474 mbedtls_x509_crt *chain )
kenjiArai 0:5b88d5760320 6475 {
kenjiArai 0:5b88d5760320 6476 int ret;
kenjiArai 0:5b88d5760320 6477 #if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 6478 int crt_cnt=0;
kenjiArai 0:5b88d5760320 6479 #endif
kenjiArai 0:5b88d5760320 6480 size_t i, n;
kenjiArai 0:5b88d5760320 6481 uint8_t alert;
kenjiArai 0:5b88d5760320 6482
kenjiArai 0:5b88d5760320 6483 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
kenjiArai 0:5b88d5760320 6484 {
kenjiArai 0:5b88d5760320 6485 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
kenjiArai 0:5b88d5760320 6486 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6487 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 6488 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 6489 }
kenjiArai 0:5b88d5760320 6490
kenjiArai 0:5b88d5760320 6491 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE ||
kenjiArai 0:5b88d5760320 6492 ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
kenjiArai 0:5b88d5760320 6493 {
kenjiArai 0:5b88d5760320 6494 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
kenjiArai 0:5b88d5760320 6495 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6496 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
kenjiArai 0:5b88d5760320 6497 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
kenjiArai 0:5b88d5760320 6498 }
kenjiArai 0:5b88d5760320 6499
kenjiArai 0:5b88d5760320 6500 i = mbedtls_ssl_hs_hdr_len( ssl );
kenjiArai 0:5b88d5760320 6501
kenjiArai 0:5b88d5760320 6502 /*
kenjiArai 0:5b88d5760320 6503 * Same message structure as in mbedtls_ssl_write_certificate()
kenjiArai 0:5b88d5760320 6504 */
kenjiArai 0:5b88d5760320 6505 n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2];
kenjiArai 0:5b88d5760320 6506
kenjiArai 0:5b88d5760320 6507 if( ssl->in_msg[i] != 0 ||
kenjiArai 0:5b88d5760320 6508 ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) )
kenjiArai 0:5b88d5760320 6509 {
kenjiArai 0:5b88d5760320 6510 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
kenjiArai 0:5b88d5760320 6511 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6512 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
kenjiArai 0:5b88d5760320 6513 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
kenjiArai 0:5b88d5760320 6514 }
kenjiArai 0:5b88d5760320 6515
kenjiArai 0:5b88d5760320 6516 /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
kenjiArai 0:5b88d5760320 6517 i += 3;
kenjiArai 0:5b88d5760320 6518
kenjiArai 0:5b88d5760320 6519 /* Iterate through and parse the CRTs in the provided chain. */
kenjiArai 0:5b88d5760320 6520 while( i < ssl->in_hslen )
kenjiArai 0:5b88d5760320 6521 {
kenjiArai 0:5b88d5760320 6522 /* Check that there's room for the next CRT's length fields. */
kenjiArai 0:5b88d5760320 6523 if ( i + 3 > ssl->in_hslen ) {
kenjiArai 0:5b88d5760320 6524 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
kenjiArai 0:5b88d5760320 6525 mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 6526 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6527 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
kenjiArai 0:5b88d5760320 6528 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
kenjiArai 0:5b88d5760320 6529 }
kenjiArai 0:5b88d5760320 6530 /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
kenjiArai 0:5b88d5760320 6531 * anything beyond 2**16 ~ 64K. */
kenjiArai 0:5b88d5760320 6532 if( ssl->in_msg[i] != 0 )
kenjiArai 0:5b88d5760320 6533 {
kenjiArai 0:5b88d5760320 6534 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
kenjiArai 0:5b88d5760320 6535 mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 6536 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6537 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
kenjiArai 0:5b88d5760320 6538 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
kenjiArai 0:5b88d5760320 6539 }
kenjiArai 0:5b88d5760320 6540
kenjiArai 0:5b88d5760320 6541 /* Read length of the next CRT in the chain. */
kenjiArai 0:5b88d5760320 6542 n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
kenjiArai 0:5b88d5760320 6543 | (unsigned int) ssl->in_msg[i + 2];
kenjiArai 0:5b88d5760320 6544 i += 3;
kenjiArai 0:5b88d5760320 6545
kenjiArai 0:5b88d5760320 6546 if( n < 128 || i + n > ssl->in_hslen )
kenjiArai 0:5b88d5760320 6547 {
kenjiArai 0:5b88d5760320 6548 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
kenjiArai 0:5b88d5760320 6549 mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 6550 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6551 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
kenjiArai 0:5b88d5760320 6552 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
kenjiArai 0:5b88d5760320 6553 }
kenjiArai 0:5b88d5760320 6554
kenjiArai 0:5b88d5760320 6555 /* Check if we're handling the first CRT in the chain. */
kenjiArai 0:5b88d5760320 6556 #if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 6557 if( crt_cnt++ == 0 &&
kenjiArai 0:5b88d5760320 6558 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
kenjiArai 0:5b88d5760320 6559 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
kenjiArai 0:5b88d5760320 6560 {
kenjiArai 0:5b88d5760320 6561 /* During client-side renegotiation, check that the server's
kenjiArai 0:5b88d5760320 6562 * end-CRTs hasn't changed compared to the initial handshake,
kenjiArai 0:5b88d5760320 6563 * mitigating the triple handshake attack. On success, reuse
kenjiArai 0:5b88d5760320 6564 * the original end-CRT instead of parsing it again. */
kenjiArai 0:5b88d5760320 6565 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Check that peer CRT hasn't changed during renegotiation" ) );
kenjiArai 0:5b88d5760320 6566 if( ssl_check_peer_crt_unchanged( ssl,
kenjiArai 0:5b88d5760320 6567 &ssl->in_msg[i],
kenjiArai 0:5b88d5760320 6568 n ) != 0 )
kenjiArai 0:5b88d5760320 6569 {
kenjiArai 0:5b88d5760320 6570 MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
kenjiArai 0:5b88d5760320 6571 mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 6572 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6573 MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
kenjiArai 0:5b88d5760320 6574 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
kenjiArai 0:5b88d5760320 6575 }
kenjiArai 0:5b88d5760320 6576
kenjiArai 0:5b88d5760320 6577 /* Now we can safely free the original chain. */
kenjiArai 0:5b88d5760320 6578 ssl_clear_peer_cert( ssl->session );
kenjiArai 0:5b88d5760320 6579 }
kenjiArai 0:5b88d5760320 6580 #endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 6581
kenjiArai 0:5b88d5760320 6582 /* Parse the next certificate in the chain. */
kenjiArai 0:5b88d5760320 6583 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 6584 ret = mbedtls_x509_crt_parse_der( chain, ssl->in_msg + i, n );
kenjiArai 0:5b88d5760320 6585 #else
kenjiArai 0:5b88d5760320 6586 /* If we don't need to store the CRT chain permanently, parse
kenjiArai 0:5b88d5760320 6587 * it in-place from the input buffer instead of making a copy. */
kenjiArai 0:5b88d5760320 6588 ret = mbedtls_x509_crt_parse_der_nocopy( chain, ssl->in_msg + i, n );
kenjiArai 0:5b88d5760320 6589 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 6590 switch( ret )
kenjiArai 0:5b88d5760320 6591 {
kenjiArai 0:5b88d5760320 6592 case 0: /*ok*/
kenjiArai 0:5b88d5760320 6593 case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
kenjiArai 0:5b88d5760320 6594 /* Ignore certificate with an unknown algorithm: maybe a
kenjiArai 0:5b88d5760320 6595 prior certificate was already trusted. */
kenjiArai 0:5b88d5760320 6596 break;
kenjiArai 0:5b88d5760320 6597
kenjiArai 0:5b88d5760320 6598 case MBEDTLS_ERR_X509_ALLOC_FAILED:
kenjiArai 0:5b88d5760320 6599 alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
kenjiArai 0:5b88d5760320 6600 goto crt_parse_der_failed;
kenjiArai 0:5b88d5760320 6601
kenjiArai 0:5b88d5760320 6602 case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
kenjiArai 0:5b88d5760320 6603 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
kenjiArai 0:5b88d5760320 6604 goto crt_parse_der_failed;
kenjiArai 0:5b88d5760320 6605
kenjiArai 0:5b88d5760320 6606 default:
kenjiArai 0:5b88d5760320 6607 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
kenjiArai 0:5b88d5760320 6608 crt_parse_der_failed:
kenjiArai 0:5b88d5760320 6609 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
kenjiArai 0:5b88d5760320 6610 MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
kenjiArai 0:5b88d5760320 6611 return( ret );
kenjiArai 0:5b88d5760320 6612 }
kenjiArai 0:5b88d5760320 6613
kenjiArai 0:5b88d5760320 6614 i += n;
kenjiArai 0:5b88d5760320 6615 }
kenjiArai 0:5b88d5760320 6616
kenjiArai 0:5b88d5760320 6617 MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", chain );
kenjiArai 0:5b88d5760320 6618 return( 0 );
kenjiArai 0:5b88d5760320 6619 }
kenjiArai 0:5b88d5760320 6620
kenjiArai 0:5b88d5760320 6621 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 6622 static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 6623 {
kenjiArai 0:5b88d5760320 6624 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 6625 return( -1 );
kenjiArai 0:5b88d5760320 6626
kenjiArai 0:5b88d5760320 6627 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 6628 /*
kenjiArai 0:5b88d5760320 6629 * Check if the client sent an empty certificate
kenjiArai 0:5b88d5760320 6630 */
kenjiArai 0:5b88d5760320 6631 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 6632 {
kenjiArai 0:5b88d5760320 6633 if( ssl->in_msglen == 2 &&
kenjiArai 0:5b88d5760320 6634 ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
kenjiArai 0:5b88d5760320 6635 ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
kenjiArai 0:5b88d5760320 6636 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
kenjiArai 0:5b88d5760320 6637 {
kenjiArai 0:5b88d5760320 6638 MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
kenjiArai 0:5b88d5760320 6639 return( 0 );
kenjiArai 0:5b88d5760320 6640 }
kenjiArai 0:5b88d5760320 6641
kenjiArai 0:5b88d5760320 6642 return( -1 );
kenjiArai 0:5b88d5760320 6643 }
kenjiArai 0:5b88d5760320 6644 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 6645
kenjiArai 0:5b88d5760320 6646 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 6647 defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 6648 if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
kenjiArai 0:5b88d5760320 6649 ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
kenjiArai 0:5b88d5760320 6650 ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
kenjiArai 0:5b88d5760320 6651 memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
kenjiArai 0:5b88d5760320 6652 {
kenjiArai 0:5b88d5760320 6653 MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
kenjiArai 0:5b88d5760320 6654 return( 0 );
kenjiArai 0:5b88d5760320 6655 }
kenjiArai 0:5b88d5760320 6656
kenjiArai 0:5b88d5760320 6657 return( -1 );
kenjiArai 0:5b88d5760320 6658 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
kenjiArai 0:5b88d5760320 6659 MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 6660 }
kenjiArai 0:5b88d5760320 6661 #endif /* MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 6662
kenjiArai 0:5b88d5760320 6663 /* Check if a certificate message is expected.
kenjiArai 0:5b88d5760320 6664 * Return either
kenjiArai 0:5b88d5760320 6665 * - SSL_CERTIFICATE_EXPECTED, or
kenjiArai 0:5b88d5760320 6666 * - SSL_CERTIFICATE_SKIP
kenjiArai 0:5b88d5760320 6667 * indicating whether a Certificate message is expected or not.
kenjiArai 0:5b88d5760320 6668 */
kenjiArai 0:5b88d5760320 6669 #define SSL_CERTIFICATE_EXPECTED 0
kenjiArai 0:5b88d5760320 6670 #define SSL_CERTIFICATE_SKIP 1
kenjiArai 0:5b88d5760320 6671 static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 6672 int authmode )
kenjiArai 0:5b88d5760320 6673 {
kenjiArai 0:5b88d5760320 6674 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
kenjiArai 0:5b88d5760320 6675 ssl->handshake->ciphersuite_info;
kenjiArai 0:5b88d5760320 6676
kenjiArai 0:5b88d5760320 6677 if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
kenjiArai 0:5b88d5760320 6678 return( SSL_CERTIFICATE_SKIP );
kenjiArai 0:5b88d5760320 6679
kenjiArai 0:5b88d5760320 6680 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 6681 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 6682 {
kenjiArai 0:5b88d5760320 6683 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
kenjiArai 0:5b88d5760320 6684 return( SSL_CERTIFICATE_SKIP );
kenjiArai 0:5b88d5760320 6685
kenjiArai 0:5b88d5760320 6686 if( authmode == MBEDTLS_SSL_VERIFY_NONE )
kenjiArai 0:5b88d5760320 6687 {
kenjiArai 0:5b88d5760320 6688 ssl->session_negotiate->verify_result =
kenjiArai 0:5b88d5760320 6689 MBEDTLS_X509_BADCERT_SKIP_VERIFY;
kenjiArai 0:5b88d5760320 6690 return( SSL_CERTIFICATE_SKIP );
kenjiArai 0:5b88d5760320 6691 }
kenjiArai 0:5b88d5760320 6692 }
kenjiArai 0:5b88d5760320 6693 #else
kenjiArai 0:5b88d5760320 6694 ((void) authmode);
kenjiArai 0:5b88d5760320 6695 #endif /* MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 6696
kenjiArai 0:5b88d5760320 6697 return( SSL_CERTIFICATE_EXPECTED );
kenjiArai 0:5b88d5760320 6698 }
kenjiArai 0:5b88d5760320 6699
kenjiArai 0:5b88d5760320 6700 static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 6701 int authmode,
kenjiArai 0:5b88d5760320 6702 mbedtls_x509_crt *chain,
kenjiArai 0:5b88d5760320 6703 void *rs_ctx )
kenjiArai 0:5b88d5760320 6704 {
kenjiArai 0:5b88d5760320 6705 int ret = 0;
kenjiArai 0:5b88d5760320 6706 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
kenjiArai 0:5b88d5760320 6707 ssl->handshake->ciphersuite_info;
kenjiArai 0:5b88d5760320 6708 int have_ca_chain = 0;
kenjiArai 0:5b88d5760320 6709
kenjiArai 0:5b88d5760320 6710 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
kenjiArai 0:5b88d5760320 6711 void *p_vrfy;
kenjiArai 0:5b88d5760320 6712
kenjiArai 0:5b88d5760320 6713 if( authmode == MBEDTLS_SSL_VERIFY_NONE )
kenjiArai 0:5b88d5760320 6714 return( 0 );
kenjiArai 0:5b88d5760320 6715
kenjiArai 0:5b88d5760320 6716 if( ssl->f_vrfy != NULL )
kenjiArai 0:5b88d5760320 6717 {
kenjiArai 0:5b88d5760320 6718 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use context-specific verification callback" ) );
kenjiArai 0:5b88d5760320 6719 f_vrfy = ssl->f_vrfy;
kenjiArai 0:5b88d5760320 6720 p_vrfy = ssl->p_vrfy;
kenjiArai 0:5b88d5760320 6721 }
kenjiArai 0:5b88d5760320 6722 else
kenjiArai 0:5b88d5760320 6723 {
kenjiArai 0:5b88d5760320 6724 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use configuration-specific verification callback" ) );
kenjiArai 0:5b88d5760320 6725 f_vrfy = ssl->conf->f_vrfy;
kenjiArai 0:5b88d5760320 6726 p_vrfy = ssl->conf->p_vrfy;
kenjiArai 0:5b88d5760320 6727 }
kenjiArai 0:5b88d5760320 6728
kenjiArai 0:5b88d5760320 6729 /*
kenjiArai 0:5b88d5760320 6730 * Main check: verify certificate
kenjiArai 0:5b88d5760320 6731 */
kenjiArai 0:5b88d5760320 6732 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
kenjiArai 0:5b88d5760320 6733 if( ssl->conf->f_ca_cb != NULL )
kenjiArai 0:5b88d5760320 6734 {
kenjiArai 0:5b88d5760320 6735 ((void) rs_ctx);
kenjiArai 0:5b88d5760320 6736 have_ca_chain = 1;
kenjiArai 0:5b88d5760320 6737
kenjiArai 0:5b88d5760320 6738 MBEDTLS_SSL_DEBUG_MSG( 3, ( "use CA callback for X.509 CRT verification" ) );
kenjiArai 0:5b88d5760320 6739 ret = mbedtls_x509_crt_verify_with_ca_cb(
kenjiArai 0:5b88d5760320 6740 chain,
kenjiArai 0:5b88d5760320 6741 ssl->conf->f_ca_cb,
kenjiArai 0:5b88d5760320 6742 ssl->conf->p_ca_cb,
kenjiArai 0:5b88d5760320 6743 ssl->conf->cert_profile,
kenjiArai 0:5b88d5760320 6744 ssl->hostname,
kenjiArai 0:5b88d5760320 6745 &ssl->session_negotiate->verify_result,
kenjiArai 0:5b88d5760320 6746 f_vrfy, p_vrfy );
kenjiArai 0:5b88d5760320 6747 }
kenjiArai 0:5b88d5760320 6748 else
kenjiArai 0:5b88d5760320 6749 #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
kenjiArai 0:5b88d5760320 6750 {
kenjiArai 0:5b88d5760320 6751 mbedtls_x509_crt *ca_chain;
kenjiArai 0:5b88d5760320 6752 mbedtls_x509_crl *ca_crl;
kenjiArai 0:5b88d5760320 6753
kenjiArai 0:5b88d5760320 6754 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
kenjiArai 0:5b88d5760320 6755 if( ssl->handshake->sni_ca_chain != NULL )
kenjiArai 0:5b88d5760320 6756 {
kenjiArai 0:5b88d5760320 6757 ca_chain = ssl->handshake->sni_ca_chain;
kenjiArai 0:5b88d5760320 6758 ca_crl = ssl->handshake->sni_ca_crl;
kenjiArai 0:5b88d5760320 6759 }
kenjiArai 0:5b88d5760320 6760 else
kenjiArai 0:5b88d5760320 6761 #endif
kenjiArai 0:5b88d5760320 6762 {
kenjiArai 0:5b88d5760320 6763 ca_chain = ssl->conf->ca_chain;
kenjiArai 0:5b88d5760320 6764 ca_crl = ssl->conf->ca_crl;
kenjiArai 0:5b88d5760320 6765 }
kenjiArai 0:5b88d5760320 6766
kenjiArai 0:5b88d5760320 6767 if( ca_chain != NULL )
kenjiArai 0:5b88d5760320 6768 have_ca_chain = 1;
kenjiArai 0:5b88d5760320 6769
kenjiArai 0:5b88d5760320 6770 ret = mbedtls_x509_crt_verify_restartable(
kenjiArai 0:5b88d5760320 6771 chain,
kenjiArai 0:5b88d5760320 6772 ca_chain, ca_crl,
kenjiArai 0:5b88d5760320 6773 ssl->conf->cert_profile,
kenjiArai 0:5b88d5760320 6774 ssl->hostname,
kenjiArai 0:5b88d5760320 6775 &ssl->session_negotiate->verify_result,
kenjiArai 0:5b88d5760320 6776 f_vrfy, p_vrfy, rs_ctx );
kenjiArai 0:5b88d5760320 6777 }
kenjiArai 0:5b88d5760320 6778
kenjiArai 0:5b88d5760320 6779 if( ret != 0 )
kenjiArai 0:5b88d5760320 6780 {
kenjiArai 0:5b88d5760320 6781 MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
kenjiArai 0:5b88d5760320 6782 }
kenjiArai 0:5b88d5760320 6783
kenjiArai 0:5b88d5760320 6784 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 6785 if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
kenjiArai 0:5b88d5760320 6786 return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
kenjiArai 0:5b88d5760320 6787 #endif
kenjiArai 0:5b88d5760320 6788
kenjiArai 0:5b88d5760320 6789 /*
kenjiArai 0:5b88d5760320 6790 * Secondary checks: always done, but change 'ret' only if it was 0
kenjiArai 0:5b88d5760320 6791 */
kenjiArai 0:5b88d5760320 6792
kenjiArai 0:5b88d5760320 6793 #if defined(MBEDTLS_ECP_C)
kenjiArai 0:5b88d5760320 6794 {
kenjiArai 0:5b88d5760320 6795 const mbedtls_pk_context *pk = &chain->pk;
kenjiArai 0:5b88d5760320 6796
kenjiArai 0:5b88d5760320 6797 /* If certificate uses an EC key, make sure the curve is OK */
kenjiArai 0:5b88d5760320 6798 if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
kenjiArai 0:5b88d5760320 6799 mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
kenjiArai 0:5b88d5760320 6800 {
kenjiArai 0:5b88d5760320 6801 ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
kenjiArai 0:5b88d5760320 6802
kenjiArai 0:5b88d5760320 6803 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
kenjiArai 0:5b88d5760320 6804 if( ret == 0 )
kenjiArai 0:5b88d5760320 6805 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
kenjiArai 0:5b88d5760320 6806 }
kenjiArai 0:5b88d5760320 6807 }
kenjiArai 0:5b88d5760320 6808 #endif /* MBEDTLS_ECP_C */
kenjiArai 0:5b88d5760320 6809
kenjiArai 0:5b88d5760320 6810 if( mbedtls_ssl_check_cert_usage( chain,
kenjiArai 0:5b88d5760320 6811 ciphersuite_info,
kenjiArai 0:5b88d5760320 6812 ! ssl->conf->endpoint,
kenjiArai 0:5b88d5760320 6813 &ssl->session_negotiate->verify_result ) != 0 )
kenjiArai 0:5b88d5760320 6814 {
kenjiArai 0:5b88d5760320 6815 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
kenjiArai 0:5b88d5760320 6816 if( ret == 0 )
kenjiArai 0:5b88d5760320 6817 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
kenjiArai 0:5b88d5760320 6818 }
kenjiArai 0:5b88d5760320 6819
kenjiArai 0:5b88d5760320 6820 /* mbedtls_x509_crt_verify_with_profile is supposed to report a
kenjiArai 0:5b88d5760320 6821 * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
kenjiArai 0:5b88d5760320 6822 * with details encoded in the verification flags. All other kinds
kenjiArai 0:5b88d5760320 6823 * of error codes, including those from the user provided f_vrfy
kenjiArai 0:5b88d5760320 6824 * functions, are treated as fatal and lead to a failure of
kenjiArai 0:5b88d5760320 6825 * ssl_parse_certificate even if verification was optional. */
kenjiArai 0:5b88d5760320 6826 if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
kenjiArai 0:5b88d5760320 6827 ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
kenjiArai 0:5b88d5760320 6828 ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
kenjiArai 0:5b88d5760320 6829 {
kenjiArai 0:5b88d5760320 6830 ret = 0;
kenjiArai 0:5b88d5760320 6831 }
kenjiArai 0:5b88d5760320 6832
kenjiArai 0:5b88d5760320 6833 if( have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
kenjiArai 0:5b88d5760320 6834 {
kenjiArai 0:5b88d5760320 6835 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
kenjiArai 0:5b88d5760320 6836 ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
kenjiArai 0:5b88d5760320 6837 }
kenjiArai 0:5b88d5760320 6838
kenjiArai 0:5b88d5760320 6839 if( ret != 0 )
kenjiArai 0:5b88d5760320 6840 {
kenjiArai 0:5b88d5760320 6841 uint8_t alert;
kenjiArai 0:5b88d5760320 6842
kenjiArai 0:5b88d5760320 6843 /* The certificate may have been rejected for several reasons.
kenjiArai 0:5b88d5760320 6844 Pick one and send the corresponding alert. Which alert to send
kenjiArai 0:5b88d5760320 6845 may be a subject of debate in some cases. */
kenjiArai 0:5b88d5760320 6846 if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
kenjiArai 0:5b88d5760320 6847 alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
kenjiArai 0:5b88d5760320 6848 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
kenjiArai 0:5b88d5760320 6849 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
kenjiArai 0:5b88d5760320 6850 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
kenjiArai 0:5b88d5760320 6851 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
kenjiArai 0:5b88d5760320 6852 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
kenjiArai 0:5b88d5760320 6853 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
kenjiArai 0:5b88d5760320 6854 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
kenjiArai 0:5b88d5760320 6855 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
kenjiArai 0:5b88d5760320 6856 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
kenjiArai 0:5b88d5760320 6857 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
kenjiArai 0:5b88d5760320 6858 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
kenjiArai 0:5b88d5760320 6859 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
kenjiArai 0:5b88d5760320 6860 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
kenjiArai 0:5b88d5760320 6861 alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
kenjiArai 0:5b88d5760320 6862 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
kenjiArai 0:5b88d5760320 6863 alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
kenjiArai 0:5b88d5760320 6864 else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
kenjiArai 0:5b88d5760320 6865 alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
kenjiArai 0:5b88d5760320 6866 else
kenjiArai 0:5b88d5760320 6867 alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
kenjiArai 0:5b88d5760320 6868 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6869 alert );
kenjiArai 0:5b88d5760320 6870 }
kenjiArai 0:5b88d5760320 6871
kenjiArai 0:5b88d5760320 6872 #if defined(MBEDTLS_DEBUG_C)
kenjiArai 0:5b88d5760320 6873 if( ssl->session_negotiate->verify_result != 0 )
kenjiArai 0:5b88d5760320 6874 {
kenjiArai 0:5b88d5760320 6875 MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x",
kenjiArai 0:5b88d5760320 6876 ssl->session_negotiate->verify_result ) );
kenjiArai 0:5b88d5760320 6877 }
kenjiArai 0:5b88d5760320 6878 else
kenjiArai 0:5b88d5760320 6879 {
kenjiArai 0:5b88d5760320 6880 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
kenjiArai 0:5b88d5760320 6881 }
kenjiArai 0:5b88d5760320 6882 #endif /* MBEDTLS_DEBUG_C */
kenjiArai 0:5b88d5760320 6883
kenjiArai 0:5b88d5760320 6884 return( ret );
kenjiArai 0:5b88d5760320 6885 }
kenjiArai 0:5b88d5760320 6886
kenjiArai 0:5b88d5760320 6887 #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 6888 static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 6889 unsigned char *start, size_t len )
kenjiArai 0:5b88d5760320 6890 {
kenjiArai 0:5b88d5760320 6891 int ret;
kenjiArai 0:5b88d5760320 6892 /* Remember digest of the peer's end-CRT. */
kenjiArai 0:5b88d5760320 6893 ssl->session_negotiate->peer_cert_digest =
kenjiArai 0:5b88d5760320 6894 mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN );
kenjiArai 0:5b88d5760320 6895 if( ssl->session_negotiate->peer_cert_digest == NULL )
kenjiArai 0:5b88d5760320 6896 {
kenjiArai 0:5b88d5760320 6897 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
kenjiArai 0:5b88d5760320 6898 sizeof( MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ) ) );
kenjiArai 0:5b88d5760320 6899 mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 6900 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 6901 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 6902
kenjiArai 0:5b88d5760320 6903 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 6904 }
kenjiArai 0:5b88d5760320 6905
kenjiArai 0:5b88d5760320 6906 ret = mbedtls_md( mbedtls_md_info_from_type(
kenjiArai 0:5b88d5760320 6907 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ),
kenjiArai 0:5b88d5760320 6908 start, len,
kenjiArai 0:5b88d5760320 6909 ssl->session_negotiate->peer_cert_digest );
kenjiArai 0:5b88d5760320 6910
kenjiArai 0:5b88d5760320 6911 ssl->session_negotiate->peer_cert_digest_type =
kenjiArai 0:5b88d5760320 6912 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
kenjiArai 0:5b88d5760320 6913 ssl->session_negotiate->peer_cert_digest_len =
kenjiArai 0:5b88d5760320 6914 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
kenjiArai 0:5b88d5760320 6915
kenjiArai 0:5b88d5760320 6916 return( ret );
kenjiArai 0:5b88d5760320 6917 }
kenjiArai 0:5b88d5760320 6918
kenjiArai 0:5b88d5760320 6919 static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 6920 unsigned char *start, size_t len )
kenjiArai 0:5b88d5760320 6921 {
kenjiArai 0:5b88d5760320 6922 unsigned char *end = start + len;
kenjiArai 0:5b88d5760320 6923 int ret;
kenjiArai 0:5b88d5760320 6924
kenjiArai 0:5b88d5760320 6925 /* Make a copy of the peer's raw public key. */
kenjiArai 0:5b88d5760320 6926 mbedtls_pk_init( &ssl->handshake->peer_pubkey );
kenjiArai 0:5b88d5760320 6927 ret = mbedtls_pk_parse_subpubkey( &start, end,
kenjiArai 0:5b88d5760320 6928 &ssl->handshake->peer_pubkey );
kenjiArai 0:5b88d5760320 6929 if( ret != 0 )
kenjiArai 0:5b88d5760320 6930 {
kenjiArai 0:5b88d5760320 6931 /* We should have parsed the public key before. */
kenjiArai 0:5b88d5760320 6932 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 6933 }
kenjiArai 0:5b88d5760320 6934
kenjiArai 0:5b88d5760320 6935 return( 0 );
kenjiArai 0:5b88d5760320 6936 }
kenjiArai 0:5b88d5760320 6937 #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 6938
kenjiArai 0:5b88d5760320 6939 int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 6940 {
kenjiArai 0:5b88d5760320 6941 int ret = 0;
kenjiArai 0:5b88d5760320 6942 int crt_expected;
kenjiArai 0:5b88d5760320 6943 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
kenjiArai 0:5b88d5760320 6944 const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
kenjiArai 0:5b88d5760320 6945 ? ssl->handshake->sni_authmode
kenjiArai 0:5b88d5760320 6946 : ssl->conf->authmode;
kenjiArai 0:5b88d5760320 6947 #else
kenjiArai 0:5b88d5760320 6948 const int authmode = ssl->conf->authmode;
kenjiArai 0:5b88d5760320 6949 #endif
kenjiArai 0:5b88d5760320 6950 void *rs_ctx = NULL;
kenjiArai 0:5b88d5760320 6951 mbedtls_x509_crt *chain = NULL;
kenjiArai 0:5b88d5760320 6952
kenjiArai 0:5b88d5760320 6953 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
kenjiArai 0:5b88d5760320 6954
kenjiArai 0:5b88d5760320 6955 crt_expected = ssl_parse_certificate_coordinate( ssl, authmode );
kenjiArai 0:5b88d5760320 6956 if( crt_expected == SSL_CERTIFICATE_SKIP )
kenjiArai 0:5b88d5760320 6957 {
kenjiArai 0:5b88d5760320 6958 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
kenjiArai 0:5b88d5760320 6959 goto exit;
kenjiArai 0:5b88d5760320 6960 }
kenjiArai 0:5b88d5760320 6961
kenjiArai 0:5b88d5760320 6962 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 6963 if( ssl->handshake->ecrs_enabled &&
kenjiArai 0:5b88d5760320 6964 ssl->handshake->ecrs_state == ssl_ecrs_crt_verify )
kenjiArai 0:5b88d5760320 6965 {
kenjiArai 0:5b88d5760320 6966 chain = ssl->handshake->ecrs_peer_cert;
kenjiArai 0:5b88d5760320 6967 ssl->handshake->ecrs_peer_cert = NULL;
kenjiArai 0:5b88d5760320 6968 goto crt_verify;
kenjiArai 0:5b88d5760320 6969 }
kenjiArai 0:5b88d5760320 6970 #endif
kenjiArai 0:5b88d5760320 6971
kenjiArai 0:5b88d5760320 6972 if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 6973 {
kenjiArai 0:5b88d5760320 6974 /* mbedtls_ssl_read_record may have sent an alert already. We
kenjiArai 0:5b88d5760320 6975 let it decide whether to alert. */
kenjiArai 0:5b88d5760320 6976 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
kenjiArai 0:5b88d5760320 6977 goto exit;
kenjiArai 0:5b88d5760320 6978 }
kenjiArai 0:5b88d5760320 6979
kenjiArai 0:5b88d5760320 6980 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 6981 if( ssl_srv_check_client_no_crt_notification( ssl ) == 0 )
kenjiArai 0:5b88d5760320 6982 {
kenjiArai 0:5b88d5760320 6983 ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
kenjiArai 0:5b88d5760320 6984
kenjiArai 0:5b88d5760320 6985 if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
kenjiArai 0:5b88d5760320 6986 ret = 0;
kenjiArai 0:5b88d5760320 6987 else
kenjiArai 0:5b88d5760320 6988 ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
kenjiArai 0:5b88d5760320 6989
kenjiArai 0:5b88d5760320 6990 goto exit;
kenjiArai 0:5b88d5760320 6991 }
kenjiArai 0:5b88d5760320 6992 #endif /* MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 6993
kenjiArai 0:5b88d5760320 6994 /* Clear existing peer CRT structure in case we tried to
kenjiArai 0:5b88d5760320 6995 * reuse a session but it failed, and allocate a new one. */
kenjiArai 0:5b88d5760320 6996 ssl_clear_peer_cert( ssl->session_negotiate );
kenjiArai 0:5b88d5760320 6997
kenjiArai 0:5b88d5760320 6998 chain = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
kenjiArai 0:5b88d5760320 6999 if( chain == NULL )
kenjiArai 0:5b88d5760320 7000 {
kenjiArai 0:5b88d5760320 7001 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
kenjiArai 0:5b88d5760320 7002 sizeof( mbedtls_x509_crt ) ) );
kenjiArai 0:5b88d5760320 7003 mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 7004 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 7005 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 7006
kenjiArai 0:5b88d5760320 7007 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
kenjiArai 0:5b88d5760320 7008 goto exit;
kenjiArai 0:5b88d5760320 7009 }
kenjiArai 0:5b88d5760320 7010 mbedtls_x509_crt_init( chain );
kenjiArai 0:5b88d5760320 7011
kenjiArai 0:5b88d5760320 7012 ret = ssl_parse_certificate_chain( ssl, chain );
kenjiArai 0:5b88d5760320 7013 if( ret != 0 )
kenjiArai 0:5b88d5760320 7014 goto exit;
kenjiArai 0:5b88d5760320 7015
kenjiArai 0:5b88d5760320 7016 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 7017 if( ssl->handshake->ecrs_enabled)
kenjiArai 0:5b88d5760320 7018 ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
kenjiArai 0:5b88d5760320 7019
kenjiArai 0:5b88d5760320 7020 crt_verify:
kenjiArai 0:5b88d5760320 7021 if( ssl->handshake->ecrs_enabled)
kenjiArai 0:5b88d5760320 7022 rs_ctx = &ssl->handshake->ecrs_ctx;
kenjiArai 0:5b88d5760320 7023 #endif
kenjiArai 0:5b88d5760320 7024
kenjiArai 0:5b88d5760320 7025 ret = ssl_parse_certificate_verify( ssl, authmode,
kenjiArai 0:5b88d5760320 7026 chain, rs_ctx );
kenjiArai 0:5b88d5760320 7027 if( ret != 0 )
kenjiArai 0:5b88d5760320 7028 goto exit;
kenjiArai 0:5b88d5760320 7029
kenjiArai 0:5b88d5760320 7030 #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 7031 {
kenjiArai 0:5b88d5760320 7032 unsigned char *crt_start, *pk_start;
kenjiArai 0:5b88d5760320 7033 size_t crt_len, pk_len;
kenjiArai 0:5b88d5760320 7034
kenjiArai 0:5b88d5760320 7035 /* We parse the CRT chain without copying, so
kenjiArai 0:5b88d5760320 7036 * these pointers point into the input buffer,
kenjiArai 0:5b88d5760320 7037 * and are hence still valid after freeing the
kenjiArai 0:5b88d5760320 7038 * CRT chain. */
kenjiArai 0:5b88d5760320 7039
kenjiArai 0:5b88d5760320 7040 crt_start = chain->raw.p;
kenjiArai 0:5b88d5760320 7041 crt_len = chain->raw.len;
kenjiArai 0:5b88d5760320 7042
kenjiArai 0:5b88d5760320 7043 pk_start = chain->pk_raw.p;
kenjiArai 0:5b88d5760320 7044 pk_len = chain->pk_raw.len;
kenjiArai 0:5b88d5760320 7045
kenjiArai 0:5b88d5760320 7046 /* Free the CRT structures before computing
kenjiArai 0:5b88d5760320 7047 * digest and copying the peer's public key. */
kenjiArai 0:5b88d5760320 7048 mbedtls_x509_crt_free( chain );
kenjiArai 0:5b88d5760320 7049 mbedtls_free( chain );
kenjiArai 0:5b88d5760320 7050 chain = NULL;
kenjiArai 0:5b88d5760320 7051
kenjiArai 0:5b88d5760320 7052 ret = ssl_remember_peer_crt_digest( ssl, crt_start, crt_len );
kenjiArai 0:5b88d5760320 7053 if( ret != 0 )
kenjiArai 0:5b88d5760320 7054 goto exit;
kenjiArai 0:5b88d5760320 7055
kenjiArai 0:5b88d5760320 7056 ret = ssl_remember_peer_pubkey( ssl, pk_start, pk_len );
kenjiArai 0:5b88d5760320 7057 if( ret != 0 )
kenjiArai 0:5b88d5760320 7058 goto exit;
kenjiArai 0:5b88d5760320 7059 }
kenjiArai 0:5b88d5760320 7060 #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 7061 /* Pass ownership to session structure. */
kenjiArai 0:5b88d5760320 7062 ssl->session_negotiate->peer_cert = chain;
kenjiArai 0:5b88d5760320 7063 chain = NULL;
kenjiArai 0:5b88d5760320 7064 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 7065
kenjiArai 0:5b88d5760320 7066 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
kenjiArai 0:5b88d5760320 7067
kenjiArai 0:5b88d5760320 7068 exit:
kenjiArai 0:5b88d5760320 7069
kenjiArai 0:5b88d5760320 7070 if( ret == 0 )
kenjiArai 0:5b88d5760320 7071 ssl->state++;
kenjiArai 0:5b88d5760320 7072
kenjiArai 0:5b88d5760320 7073 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 7074 if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
kenjiArai 0:5b88d5760320 7075 {
kenjiArai 0:5b88d5760320 7076 ssl->handshake->ecrs_peer_cert = chain;
kenjiArai 0:5b88d5760320 7077 chain = NULL;
kenjiArai 0:5b88d5760320 7078 }
kenjiArai 0:5b88d5760320 7079 #endif
kenjiArai 0:5b88d5760320 7080
kenjiArai 0:5b88d5760320 7081 if( chain != NULL )
kenjiArai 0:5b88d5760320 7082 {
kenjiArai 0:5b88d5760320 7083 mbedtls_x509_crt_free( chain );
kenjiArai 0:5b88d5760320 7084 mbedtls_free( chain );
kenjiArai 0:5b88d5760320 7085 }
kenjiArai 0:5b88d5760320 7086
kenjiArai 0:5b88d5760320 7087 return( ret );
kenjiArai 0:5b88d5760320 7088 }
kenjiArai 0:5b88d5760320 7089 #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
kenjiArai 0:5b88d5760320 7090
kenjiArai 0:5b88d5760320 7091 int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 7092 {
kenjiArai 0:5b88d5760320 7093 int ret;
kenjiArai 0:5b88d5760320 7094
kenjiArai 0:5b88d5760320 7095 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
kenjiArai 0:5b88d5760320 7096
kenjiArai 0:5b88d5760320 7097 ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
kenjiArai 0:5b88d5760320 7098 ssl->out_msglen = 1;
kenjiArai 0:5b88d5760320 7099 ssl->out_msg[0] = 1;
kenjiArai 0:5b88d5760320 7100
kenjiArai 0:5b88d5760320 7101 ssl->state++;
kenjiArai 0:5b88d5760320 7102
kenjiArai 0:5b88d5760320 7103 if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 7104 {
kenjiArai 0:5b88d5760320 7105 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
kenjiArai 0:5b88d5760320 7106 return( ret );
kenjiArai 0:5b88d5760320 7107 }
kenjiArai 0:5b88d5760320 7108
kenjiArai 0:5b88d5760320 7109 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
kenjiArai 0:5b88d5760320 7110
kenjiArai 0:5b88d5760320 7111 return( 0 );
kenjiArai 0:5b88d5760320 7112 }
kenjiArai 0:5b88d5760320 7113
kenjiArai 0:5b88d5760320 7114 int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 7115 {
kenjiArai 0:5b88d5760320 7116 int ret;
kenjiArai 0:5b88d5760320 7117
kenjiArai 0:5b88d5760320 7118 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
kenjiArai 0:5b88d5760320 7119
kenjiArai 0:5b88d5760320 7120 if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 7121 {
kenjiArai 0:5b88d5760320 7122 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
kenjiArai 0:5b88d5760320 7123 return( ret );
kenjiArai 0:5b88d5760320 7124 }
kenjiArai 0:5b88d5760320 7125
kenjiArai 0:5b88d5760320 7126 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
kenjiArai 0:5b88d5760320 7127 {
kenjiArai 0:5b88d5760320 7128 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
kenjiArai 0:5b88d5760320 7129 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 7130 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 7131 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 7132 }
kenjiArai 0:5b88d5760320 7133
kenjiArai 0:5b88d5760320 7134 /* CCS records are only accepted if they have length 1 and content '1',
kenjiArai 0:5b88d5760320 7135 * so we don't need to check this here. */
kenjiArai 0:5b88d5760320 7136
kenjiArai 0:5b88d5760320 7137 /*
kenjiArai 0:5b88d5760320 7138 * Switch to our negotiated transform and session parameters for inbound
kenjiArai 0:5b88d5760320 7139 * data.
kenjiArai 0:5b88d5760320 7140 */
kenjiArai 0:5b88d5760320 7141 MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
kenjiArai 0:5b88d5760320 7142 ssl->transform_in = ssl->transform_negotiate;
kenjiArai 0:5b88d5760320 7143 ssl->session_in = ssl->session_negotiate;
kenjiArai 0:5b88d5760320 7144
kenjiArai 0:5b88d5760320 7145 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 7146 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 7147 {
kenjiArai 0:5b88d5760320 7148 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
kenjiArai 0:5b88d5760320 7149 ssl_dtls_replay_reset( ssl );
kenjiArai 0:5b88d5760320 7150 #endif
kenjiArai 0:5b88d5760320 7151
kenjiArai 0:5b88d5760320 7152 /* Increment epoch */
kenjiArai 0:5b88d5760320 7153 if( ++ssl->in_epoch == 0 )
kenjiArai 0:5b88d5760320 7154 {
kenjiArai 0:5b88d5760320 7155 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
kenjiArai 0:5b88d5760320 7156 /* This is highly unlikely to happen for legitimate reasons, so
kenjiArai 0:5b88d5760320 7157 treat it as an attack and don't send an alert. */
kenjiArai 0:5b88d5760320 7158 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
kenjiArai 0:5b88d5760320 7159 }
kenjiArai 0:5b88d5760320 7160 }
kenjiArai 0:5b88d5760320 7161 else
kenjiArai 0:5b88d5760320 7162 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 7163 memset( ssl->in_ctr, 0, 8 );
kenjiArai 0:5b88d5760320 7164
kenjiArai 0:5b88d5760320 7165 ssl_update_in_pointers( ssl );
kenjiArai 0:5b88d5760320 7166
kenjiArai 0:5b88d5760320 7167 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 7168 if( mbedtls_ssl_hw_record_activate != NULL )
kenjiArai 0:5b88d5760320 7169 {
kenjiArai 0:5b88d5760320 7170 if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
kenjiArai 0:5b88d5760320 7171 {
kenjiArai 0:5b88d5760320 7172 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
kenjiArai 0:5b88d5760320 7173 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 7174 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 7175 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 7176 }
kenjiArai 0:5b88d5760320 7177 }
kenjiArai 0:5b88d5760320 7178 #endif
kenjiArai 0:5b88d5760320 7179
kenjiArai 0:5b88d5760320 7180 ssl->state++;
kenjiArai 0:5b88d5760320 7181
kenjiArai 0:5b88d5760320 7182 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
kenjiArai 0:5b88d5760320 7183
kenjiArai 0:5b88d5760320 7184 return( 0 );
kenjiArai 0:5b88d5760320 7185 }
kenjiArai 0:5b88d5760320 7186
kenjiArai 0:5b88d5760320 7187 void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 7188 const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
kenjiArai 0:5b88d5760320 7189 {
kenjiArai 0:5b88d5760320 7190 ((void) ciphersuite_info);
kenjiArai 0:5b88d5760320 7191
kenjiArai 0:5b88d5760320 7192 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 7193 defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 7194 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 7195 ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
kenjiArai 0:5b88d5760320 7196 else
kenjiArai 0:5b88d5760320 7197 #endif
kenjiArai 0:5b88d5760320 7198 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 7199 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 7200 if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
kenjiArai 0:5b88d5760320 7201 ssl->handshake->update_checksum = ssl_update_checksum_sha384;
kenjiArai 0:5b88d5760320 7202 else
kenjiArai 0:5b88d5760320 7203 #endif
kenjiArai 0:5b88d5760320 7204 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 7205 if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 )
kenjiArai 0:5b88d5760320 7206 ssl->handshake->update_checksum = ssl_update_checksum_sha256;
kenjiArai 0:5b88d5760320 7207 else
kenjiArai 0:5b88d5760320 7208 #endif
kenjiArai 0:5b88d5760320 7209 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 7210 {
kenjiArai 0:5b88d5760320 7211 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 7212 return;
kenjiArai 0:5b88d5760320 7213 }
kenjiArai 0:5b88d5760320 7214 }
kenjiArai 0:5b88d5760320 7215
kenjiArai 0:5b88d5760320 7216 void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 7217 {
kenjiArai 0:5b88d5760320 7218 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 7219 defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 7220 mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 );
kenjiArai 0:5b88d5760320 7221 mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 );
kenjiArai 0:5b88d5760320 7222 #endif
kenjiArai 0:5b88d5760320 7223 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 7224 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 7225 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7226 psa_hash_abort( &ssl->handshake->fin_sha256_psa );
kenjiArai 0:5b88d5760320 7227 psa_hash_setup( &ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
kenjiArai 0:5b88d5760320 7228 #else
kenjiArai 0:5b88d5760320 7229 mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 );
kenjiArai 0:5b88d5760320 7230 #endif
kenjiArai 0:5b88d5760320 7231 #endif
kenjiArai 0:5b88d5760320 7232 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 7233 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7234 psa_hash_abort( &ssl->handshake->fin_sha384_psa );
kenjiArai 0:5b88d5760320 7235 psa_hash_setup( &ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
kenjiArai 0:5b88d5760320 7236 #else
kenjiArai 0:5b88d5760320 7237 mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 );
kenjiArai 0:5b88d5760320 7238 #endif
kenjiArai 0:5b88d5760320 7239 #endif
kenjiArai 0:5b88d5760320 7240 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 7241 }
kenjiArai 0:5b88d5760320 7242
kenjiArai 0:5b88d5760320 7243 static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 7244 const unsigned char *buf, size_t len )
kenjiArai 0:5b88d5760320 7245 {
kenjiArai 0:5b88d5760320 7246 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 7247 defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 7248 mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
kenjiArai 0:5b88d5760320 7249 mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
kenjiArai 0:5b88d5760320 7250 #endif
kenjiArai 0:5b88d5760320 7251 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 7252 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 7253 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7254 psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
kenjiArai 0:5b88d5760320 7255 #else
kenjiArai 0:5b88d5760320 7256 mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
kenjiArai 0:5b88d5760320 7257 #endif
kenjiArai 0:5b88d5760320 7258 #endif
kenjiArai 0:5b88d5760320 7259 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 7260 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7261 psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
kenjiArai 0:5b88d5760320 7262 #else
kenjiArai 0:5b88d5760320 7263 mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
kenjiArai 0:5b88d5760320 7264 #endif
kenjiArai 0:5b88d5760320 7265 #endif
kenjiArai 0:5b88d5760320 7266 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 7267 }
kenjiArai 0:5b88d5760320 7268
kenjiArai 0:5b88d5760320 7269 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 7270 defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 7271 static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 7272 const unsigned char *buf, size_t len )
kenjiArai 0:5b88d5760320 7273 {
kenjiArai 0:5b88d5760320 7274 mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
kenjiArai 0:5b88d5760320 7275 mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
kenjiArai 0:5b88d5760320 7276 }
kenjiArai 0:5b88d5760320 7277 #endif
kenjiArai 0:5b88d5760320 7278
kenjiArai 0:5b88d5760320 7279 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 7280 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 7281 static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 7282 const unsigned char *buf, size_t len )
kenjiArai 0:5b88d5760320 7283 {
kenjiArai 0:5b88d5760320 7284 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7285 psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
kenjiArai 0:5b88d5760320 7286 #else
kenjiArai 0:5b88d5760320 7287 mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
kenjiArai 0:5b88d5760320 7288 #endif
kenjiArai 0:5b88d5760320 7289 }
kenjiArai 0:5b88d5760320 7290 #endif
kenjiArai 0:5b88d5760320 7291
kenjiArai 0:5b88d5760320 7292 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 7293 static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 7294 const unsigned char *buf, size_t len )
kenjiArai 0:5b88d5760320 7295 {
kenjiArai 0:5b88d5760320 7296 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7297 psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
kenjiArai 0:5b88d5760320 7298 #else
kenjiArai 0:5b88d5760320 7299 mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
kenjiArai 0:5b88d5760320 7300 #endif
kenjiArai 0:5b88d5760320 7301 }
kenjiArai 0:5b88d5760320 7302 #endif
kenjiArai 0:5b88d5760320 7303 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 7304
kenjiArai 0:5b88d5760320 7305 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 7306 static void ssl_calc_finished_ssl(
kenjiArai 0:5b88d5760320 7307 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
kenjiArai 0:5b88d5760320 7308 {
kenjiArai 0:5b88d5760320 7309 const char *sender;
kenjiArai 0:5b88d5760320 7310 mbedtls_md5_context md5;
kenjiArai 0:5b88d5760320 7311 mbedtls_sha1_context sha1;
kenjiArai 0:5b88d5760320 7312
kenjiArai 0:5b88d5760320 7313 unsigned char padbuf[48];
kenjiArai 0:5b88d5760320 7314 unsigned char md5sum[16];
kenjiArai 0:5b88d5760320 7315 unsigned char sha1sum[20];
kenjiArai 0:5b88d5760320 7316
kenjiArai 0:5b88d5760320 7317 mbedtls_ssl_session *session = ssl->session_negotiate;
kenjiArai 0:5b88d5760320 7318 if( !session )
kenjiArai 0:5b88d5760320 7319 session = ssl->session;
kenjiArai 0:5b88d5760320 7320
kenjiArai 0:5b88d5760320 7321 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) );
kenjiArai 0:5b88d5760320 7322
kenjiArai 0:5b88d5760320 7323 mbedtls_md5_init( &md5 );
kenjiArai 0:5b88d5760320 7324 mbedtls_sha1_init( &sha1 );
kenjiArai 0:5b88d5760320 7325
kenjiArai 0:5b88d5760320 7326 mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
kenjiArai 0:5b88d5760320 7327 mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
kenjiArai 0:5b88d5760320 7328
kenjiArai 0:5b88d5760320 7329 /*
kenjiArai 0:5b88d5760320 7330 * SSLv3:
kenjiArai 0:5b88d5760320 7331 * hash =
kenjiArai 0:5b88d5760320 7332 * MD5( master + pad2 +
kenjiArai 0:5b88d5760320 7333 * MD5( handshake + sender + master + pad1 ) )
kenjiArai 0:5b88d5760320 7334 * + SHA1( master + pad2 +
kenjiArai 0:5b88d5760320 7335 * SHA1( handshake + sender + master + pad1 ) )
kenjiArai 0:5b88d5760320 7336 */
kenjiArai 0:5b88d5760320 7337
kenjiArai 0:5b88d5760320 7338 #if !defined(MBEDTLS_MD5_ALT)
kenjiArai 0:5b88d5760320 7339 MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
kenjiArai 0:5b88d5760320 7340 md5.state, sizeof( md5.state ) );
kenjiArai 0:5b88d5760320 7341 #endif
kenjiArai 0:5b88d5760320 7342
kenjiArai 0:5b88d5760320 7343 #if !defined(MBEDTLS_SHA1_ALT)
kenjiArai 0:5b88d5760320 7344 MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
kenjiArai 0:5b88d5760320 7345 sha1.state, sizeof( sha1.state ) );
kenjiArai 0:5b88d5760320 7346 #endif
kenjiArai 0:5b88d5760320 7347
kenjiArai 0:5b88d5760320 7348 sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT"
kenjiArai 0:5b88d5760320 7349 : "SRVR";
kenjiArai 0:5b88d5760320 7350
kenjiArai 0:5b88d5760320 7351 memset( padbuf, 0x36, 48 );
kenjiArai 0:5b88d5760320 7352
kenjiArai 0:5b88d5760320 7353 mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 );
kenjiArai 0:5b88d5760320 7354 mbedtls_md5_update_ret( &md5, session->master, 48 );
kenjiArai 0:5b88d5760320 7355 mbedtls_md5_update_ret( &md5, padbuf, 48 );
kenjiArai 0:5b88d5760320 7356 mbedtls_md5_finish_ret( &md5, md5sum );
kenjiArai 0:5b88d5760320 7357
kenjiArai 0:5b88d5760320 7358 mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 );
kenjiArai 0:5b88d5760320 7359 mbedtls_sha1_update_ret( &sha1, session->master, 48 );
kenjiArai 0:5b88d5760320 7360 mbedtls_sha1_update_ret( &sha1, padbuf, 40 );
kenjiArai 0:5b88d5760320 7361 mbedtls_sha1_finish_ret( &sha1, sha1sum );
kenjiArai 0:5b88d5760320 7362
kenjiArai 0:5b88d5760320 7363 memset( padbuf, 0x5C, 48 );
kenjiArai 0:5b88d5760320 7364
kenjiArai 0:5b88d5760320 7365 mbedtls_md5_starts_ret( &md5 );
kenjiArai 0:5b88d5760320 7366 mbedtls_md5_update_ret( &md5, session->master, 48 );
kenjiArai 0:5b88d5760320 7367 mbedtls_md5_update_ret( &md5, padbuf, 48 );
kenjiArai 0:5b88d5760320 7368 mbedtls_md5_update_ret( &md5, md5sum, 16 );
kenjiArai 0:5b88d5760320 7369 mbedtls_md5_finish_ret( &md5, buf );
kenjiArai 0:5b88d5760320 7370
kenjiArai 0:5b88d5760320 7371 mbedtls_sha1_starts_ret( &sha1 );
kenjiArai 0:5b88d5760320 7372 mbedtls_sha1_update_ret( &sha1, session->master, 48 );
kenjiArai 0:5b88d5760320 7373 mbedtls_sha1_update_ret( &sha1, padbuf , 40 );
kenjiArai 0:5b88d5760320 7374 mbedtls_sha1_update_ret( &sha1, sha1sum, 20 );
kenjiArai 0:5b88d5760320 7375 mbedtls_sha1_finish_ret( &sha1, buf + 16 );
kenjiArai 0:5b88d5760320 7376
kenjiArai 0:5b88d5760320 7377 MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
kenjiArai 0:5b88d5760320 7378
kenjiArai 0:5b88d5760320 7379 mbedtls_md5_free( &md5 );
kenjiArai 0:5b88d5760320 7380 mbedtls_sha1_free( &sha1 );
kenjiArai 0:5b88d5760320 7381
kenjiArai 0:5b88d5760320 7382 mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
kenjiArai 0:5b88d5760320 7383 mbedtls_platform_zeroize( md5sum, sizeof( md5sum ) );
kenjiArai 0:5b88d5760320 7384 mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
kenjiArai 0:5b88d5760320 7385
kenjiArai 0:5b88d5760320 7386 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
kenjiArai 0:5b88d5760320 7387 }
kenjiArai 0:5b88d5760320 7388 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 7389
kenjiArai 0:5b88d5760320 7390 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 7391 static void ssl_calc_finished_tls(
kenjiArai 0:5b88d5760320 7392 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
kenjiArai 0:5b88d5760320 7393 {
kenjiArai 0:5b88d5760320 7394 int len = 12;
kenjiArai 0:5b88d5760320 7395 const char *sender;
kenjiArai 0:5b88d5760320 7396 mbedtls_md5_context md5;
kenjiArai 0:5b88d5760320 7397 mbedtls_sha1_context sha1;
kenjiArai 0:5b88d5760320 7398 unsigned char padbuf[36];
kenjiArai 0:5b88d5760320 7399
kenjiArai 0:5b88d5760320 7400 mbedtls_ssl_session *session = ssl->session_negotiate;
kenjiArai 0:5b88d5760320 7401 if( !session )
kenjiArai 0:5b88d5760320 7402 session = ssl->session;
kenjiArai 0:5b88d5760320 7403
kenjiArai 0:5b88d5760320 7404 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) );
kenjiArai 0:5b88d5760320 7405
kenjiArai 0:5b88d5760320 7406 mbedtls_md5_init( &md5 );
kenjiArai 0:5b88d5760320 7407 mbedtls_sha1_init( &sha1 );
kenjiArai 0:5b88d5760320 7408
kenjiArai 0:5b88d5760320 7409 mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
kenjiArai 0:5b88d5760320 7410 mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
kenjiArai 0:5b88d5760320 7411
kenjiArai 0:5b88d5760320 7412 /*
kenjiArai 0:5b88d5760320 7413 * TLSv1:
kenjiArai 0:5b88d5760320 7414 * hash = PRF( master, finished_label,
kenjiArai 0:5b88d5760320 7415 * MD5( handshake ) + SHA1( handshake ) )[0..11]
kenjiArai 0:5b88d5760320 7416 */
kenjiArai 0:5b88d5760320 7417
kenjiArai 0:5b88d5760320 7418 #if !defined(MBEDTLS_MD5_ALT)
kenjiArai 0:5b88d5760320 7419 MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
kenjiArai 0:5b88d5760320 7420 md5.state, sizeof( md5.state ) );
kenjiArai 0:5b88d5760320 7421 #endif
kenjiArai 0:5b88d5760320 7422
kenjiArai 0:5b88d5760320 7423 #if !defined(MBEDTLS_SHA1_ALT)
kenjiArai 0:5b88d5760320 7424 MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
kenjiArai 0:5b88d5760320 7425 sha1.state, sizeof( sha1.state ) );
kenjiArai 0:5b88d5760320 7426 #endif
kenjiArai 0:5b88d5760320 7427
kenjiArai 0:5b88d5760320 7428 sender = ( from == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 7429 ? "client finished"
kenjiArai 0:5b88d5760320 7430 : "server finished";
kenjiArai 0:5b88d5760320 7431
kenjiArai 0:5b88d5760320 7432 mbedtls_md5_finish_ret( &md5, padbuf );
kenjiArai 0:5b88d5760320 7433 mbedtls_sha1_finish_ret( &sha1, padbuf + 16 );
kenjiArai 0:5b88d5760320 7434
kenjiArai 0:5b88d5760320 7435 ssl->handshake->tls_prf( session->master, 48, sender,
kenjiArai 0:5b88d5760320 7436 padbuf, 36, buf, len );
kenjiArai 0:5b88d5760320 7437
kenjiArai 0:5b88d5760320 7438 MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
kenjiArai 0:5b88d5760320 7439
kenjiArai 0:5b88d5760320 7440 mbedtls_md5_free( &md5 );
kenjiArai 0:5b88d5760320 7441 mbedtls_sha1_free( &sha1 );
kenjiArai 0:5b88d5760320 7442
kenjiArai 0:5b88d5760320 7443 mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
kenjiArai 0:5b88d5760320 7444
kenjiArai 0:5b88d5760320 7445 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
kenjiArai 0:5b88d5760320 7446 }
kenjiArai 0:5b88d5760320 7447 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
kenjiArai 0:5b88d5760320 7448
kenjiArai 0:5b88d5760320 7449 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 7450 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 7451 static void ssl_calc_finished_tls_sha256(
kenjiArai 0:5b88d5760320 7452 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
kenjiArai 0:5b88d5760320 7453 {
kenjiArai 0:5b88d5760320 7454 int len = 12;
kenjiArai 0:5b88d5760320 7455 const char *sender;
kenjiArai 0:5b88d5760320 7456 unsigned char padbuf[32];
kenjiArai 0:5b88d5760320 7457 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7458 size_t hash_size;
kenjiArai 0:5b88d5760320 7459 psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT;
kenjiArai 0:5b88d5760320 7460 psa_status_t status;
kenjiArai 0:5b88d5760320 7461 #else
kenjiArai 0:5b88d5760320 7462 mbedtls_sha256_context sha256;
kenjiArai 0:5b88d5760320 7463 #endif
kenjiArai 0:5b88d5760320 7464
kenjiArai 0:5b88d5760320 7465 mbedtls_ssl_session *session = ssl->session_negotiate;
kenjiArai 0:5b88d5760320 7466 if( !session )
kenjiArai 0:5b88d5760320 7467 session = ssl->session;
kenjiArai 0:5b88d5760320 7468
kenjiArai 0:5b88d5760320 7469 sender = ( from == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 7470 ? "client finished"
kenjiArai 0:5b88d5760320 7471 : "server finished";
kenjiArai 0:5b88d5760320 7472
kenjiArai 0:5b88d5760320 7473 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7474 sha256_psa = psa_hash_operation_init();
kenjiArai 0:5b88d5760320 7475
kenjiArai 0:5b88d5760320 7476 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha256" ) );
kenjiArai 0:5b88d5760320 7477
kenjiArai 0:5b88d5760320 7478 status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
kenjiArai 0:5b88d5760320 7479 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 7480 {
kenjiArai 0:5b88d5760320 7481 MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
kenjiArai 0:5b88d5760320 7482 return;
kenjiArai 0:5b88d5760320 7483 }
kenjiArai 0:5b88d5760320 7484
kenjiArai 0:5b88d5760320 7485 status = psa_hash_finish( &sha256_psa, padbuf, sizeof( padbuf ), &hash_size );
kenjiArai 0:5b88d5760320 7486 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 7487 {
kenjiArai 0:5b88d5760320 7488 MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
kenjiArai 0:5b88d5760320 7489 return;
kenjiArai 0:5b88d5760320 7490 }
kenjiArai 0:5b88d5760320 7491 MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 32 );
kenjiArai 0:5b88d5760320 7492 #else
kenjiArai 0:5b88d5760320 7493
kenjiArai 0:5b88d5760320 7494 mbedtls_sha256_init( &sha256 );
kenjiArai 0:5b88d5760320 7495
kenjiArai 0:5b88d5760320 7496 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) );
kenjiArai 0:5b88d5760320 7497
kenjiArai 0:5b88d5760320 7498 mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
kenjiArai 0:5b88d5760320 7499
kenjiArai 0:5b88d5760320 7500 /*
kenjiArai 0:5b88d5760320 7501 * TLSv1.2:
kenjiArai 0:5b88d5760320 7502 * hash = PRF( master, finished_label,
kenjiArai 0:5b88d5760320 7503 * Hash( handshake ) )[0.11]
kenjiArai 0:5b88d5760320 7504 */
kenjiArai 0:5b88d5760320 7505
kenjiArai 0:5b88d5760320 7506 #if !defined(MBEDTLS_SHA256_ALT)
kenjiArai 0:5b88d5760320 7507 MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
kenjiArai 0:5b88d5760320 7508 sha256.state, sizeof( sha256.state ) );
kenjiArai 0:5b88d5760320 7509 #endif
kenjiArai 0:5b88d5760320 7510
kenjiArai 0:5b88d5760320 7511 mbedtls_sha256_finish_ret( &sha256, padbuf );
kenjiArai 0:5b88d5760320 7512 mbedtls_sha256_free( &sha256 );
kenjiArai 0:5b88d5760320 7513 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 7514
kenjiArai 0:5b88d5760320 7515 ssl->handshake->tls_prf( session->master, 48, sender,
kenjiArai 0:5b88d5760320 7516 padbuf, 32, buf, len );
kenjiArai 0:5b88d5760320 7517
kenjiArai 0:5b88d5760320 7518 MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
kenjiArai 0:5b88d5760320 7519
kenjiArai 0:5b88d5760320 7520 mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
kenjiArai 0:5b88d5760320 7521
kenjiArai 0:5b88d5760320 7522 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
kenjiArai 0:5b88d5760320 7523 }
kenjiArai 0:5b88d5760320 7524 #endif /* MBEDTLS_SHA256_C */
kenjiArai 0:5b88d5760320 7525
kenjiArai 0:5b88d5760320 7526 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 7527 static void ssl_calc_finished_tls_sha384(
kenjiArai 0:5b88d5760320 7528 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
kenjiArai 0:5b88d5760320 7529 {
kenjiArai 0:5b88d5760320 7530 int len = 12;
kenjiArai 0:5b88d5760320 7531 const char *sender;
kenjiArai 0:5b88d5760320 7532 unsigned char padbuf[48];
kenjiArai 0:5b88d5760320 7533 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7534 size_t hash_size;
kenjiArai 0:5b88d5760320 7535 psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT;
kenjiArai 0:5b88d5760320 7536 psa_status_t status;
kenjiArai 0:5b88d5760320 7537 #else
kenjiArai 0:5b88d5760320 7538 mbedtls_sha512_context sha512;
kenjiArai 0:5b88d5760320 7539 #endif
kenjiArai 0:5b88d5760320 7540
kenjiArai 0:5b88d5760320 7541 mbedtls_ssl_session *session = ssl->session_negotiate;
kenjiArai 0:5b88d5760320 7542 if( !session )
kenjiArai 0:5b88d5760320 7543 session = ssl->session;
kenjiArai 0:5b88d5760320 7544
kenjiArai 0:5b88d5760320 7545 sender = ( from == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 7546 ? "client finished"
kenjiArai 0:5b88d5760320 7547 : "server finished";
kenjiArai 0:5b88d5760320 7548
kenjiArai 0:5b88d5760320 7549 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7550 sha384_psa = psa_hash_operation_init();
kenjiArai 0:5b88d5760320 7551
kenjiArai 0:5b88d5760320 7552 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha384" ) );
kenjiArai 0:5b88d5760320 7553
kenjiArai 0:5b88d5760320 7554 status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
kenjiArai 0:5b88d5760320 7555 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 7556 {
kenjiArai 0:5b88d5760320 7557 MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
kenjiArai 0:5b88d5760320 7558 return;
kenjiArai 0:5b88d5760320 7559 }
kenjiArai 0:5b88d5760320 7560
kenjiArai 0:5b88d5760320 7561 status = psa_hash_finish( &sha384_psa, padbuf, sizeof( padbuf ), &hash_size );
kenjiArai 0:5b88d5760320 7562 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 7563 {
kenjiArai 0:5b88d5760320 7564 MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
kenjiArai 0:5b88d5760320 7565 return;
kenjiArai 0:5b88d5760320 7566 }
kenjiArai 0:5b88d5760320 7567 MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 48 );
kenjiArai 0:5b88d5760320 7568 #else
kenjiArai 0:5b88d5760320 7569 mbedtls_sha512_init( &sha512 );
kenjiArai 0:5b88d5760320 7570
kenjiArai 0:5b88d5760320 7571 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) );
kenjiArai 0:5b88d5760320 7572
kenjiArai 0:5b88d5760320 7573 mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
kenjiArai 0:5b88d5760320 7574
kenjiArai 0:5b88d5760320 7575 /*
kenjiArai 0:5b88d5760320 7576 * TLSv1.2:
kenjiArai 0:5b88d5760320 7577 * hash = PRF( master, finished_label,
kenjiArai 0:5b88d5760320 7578 * Hash( handshake ) )[0.11]
kenjiArai 0:5b88d5760320 7579 */
kenjiArai 0:5b88d5760320 7580
kenjiArai 0:5b88d5760320 7581 #if !defined(MBEDTLS_SHA512_ALT)
kenjiArai 0:5b88d5760320 7582 MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
kenjiArai 0:5b88d5760320 7583 sha512.state, sizeof( sha512.state ) );
kenjiArai 0:5b88d5760320 7584 #endif
kenjiArai 0:5b88d5760320 7585
kenjiArai 0:5b88d5760320 7586 mbedtls_sha512_finish_ret( &sha512, padbuf );
kenjiArai 0:5b88d5760320 7587 mbedtls_sha512_free( &sha512 );
kenjiArai 0:5b88d5760320 7588 #endif
kenjiArai 0:5b88d5760320 7589
kenjiArai 0:5b88d5760320 7590 ssl->handshake->tls_prf( session->master, 48, sender,
kenjiArai 0:5b88d5760320 7591 padbuf, 48, buf, len );
kenjiArai 0:5b88d5760320 7592
kenjiArai 0:5b88d5760320 7593 MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
kenjiArai 0:5b88d5760320 7594
kenjiArai 0:5b88d5760320 7595 mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
kenjiArai 0:5b88d5760320 7596
kenjiArai 0:5b88d5760320 7597 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
kenjiArai 0:5b88d5760320 7598 }
kenjiArai 0:5b88d5760320 7599 #endif /* MBEDTLS_SHA512_C */
kenjiArai 0:5b88d5760320 7600 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 7601
kenjiArai 0:5b88d5760320 7602 static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 7603 {
kenjiArai 0:5b88d5760320 7604 MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
kenjiArai 0:5b88d5760320 7605
kenjiArai 0:5b88d5760320 7606 /*
kenjiArai 0:5b88d5760320 7607 * Free our handshake params
kenjiArai 0:5b88d5760320 7608 */
kenjiArai 0:5b88d5760320 7609 mbedtls_ssl_handshake_free( ssl );
kenjiArai 0:5b88d5760320 7610 mbedtls_free( ssl->handshake );
kenjiArai 0:5b88d5760320 7611 ssl->handshake = NULL;
kenjiArai 0:5b88d5760320 7612
kenjiArai 0:5b88d5760320 7613 /*
kenjiArai 0:5b88d5760320 7614 * Free the previous transform and swith in the current one
kenjiArai 0:5b88d5760320 7615 */
kenjiArai 0:5b88d5760320 7616 if( ssl->transform )
kenjiArai 0:5b88d5760320 7617 {
kenjiArai 0:5b88d5760320 7618 mbedtls_ssl_transform_free( ssl->transform );
kenjiArai 0:5b88d5760320 7619 mbedtls_free( ssl->transform );
kenjiArai 0:5b88d5760320 7620 }
kenjiArai 0:5b88d5760320 7621 ssl->transform = ssl->transform_negotiate;
kenjiArai 0:5b88d5760320 7622 ssl->transform_negotiate = NULL;
kenjiArai 0:5b88d5760320 7623
kenjiArai 0:5b88d5760320 7624 MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) );
kenjiArai 0:5b88d5760320 7625 }
kenjiArai 0:5b88d5760320 7626
kenjiArai 0:5b88d5760320 7627 void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 7628 {
kenjiArai 0:5b88d5760320 7629 int resume = ssl->handshake->resume;
kenjiArai 0:5b88d5760320 7630
kenjiArai 0:5b88d5760320 7631 MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
kenjiArai 0:5b88d5760320 7632
kenjiArai 0:5b88d5760320 7633 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 7634 if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
kenjiArai 0:5b88d5760320 7635 {
kenjiArai 0:5b88d5760320 7636 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE;
kenjiArai 0:5b88d5760320 7637 ssl->renego_records_seen = 0;
kenjiArai 0:5b88d5760320 7638 }
kenjiArai 0:5b88d5760320 7639 #endif
kenjiArai 0:5b88d5760320 7640
kenjiArai 0:5b88d5760320 7641 /*
kenjiArai 0:5b88d5760320 7642 * Free the previous session and switch in the current one
kenjiArai 0:5b88d5760320 7643 */
kenjiArai 0:5b88d5760320 7644 if( ssl->session )
kenjiArai 0:5b88d5760320 7645 {
kenjiArai 0:5b88d5760320 7646 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
kenjiArai 0:5b88d5760320 7647 /* RFC 7366 3.1: keep the EtM state */
kenjiArai 0:5b88d5760320 7648 ssl->session_negotiate->encrypt_then_mac =
kenjiArai 0:5b88d5760320 7649 ssl->session->encrypt_then_mac;
kenjiArai 0:5b88d5760320 7650 #endif
kenjiArai 0:5b88d5760320 7651
kenjiArai 0:5b88d5760320 7652 mbedtls_ssl_session_free( ssl->session );
kenjiArai 0:5b88d5760320 7653 mbedtls_free( ssl->session );
kenjiArai 0:5b88d5760320 7654 }
kenjiArai 0:5b88d5760320 7655 ssl->session = ssl->session_negotiate;
kenjiArai 0:5b88d5760320 7656 ssl->session_negotiate = NULL;
kenjiArai 0:5b88d5760320 7657
kenjiArai 0:5b88d5760320 7658 /*
kenjiArai 0:5b88d5760320 7659 * Add cache entry
kenjiArai 0:5b88d5760320 7660 */
kenjiArai 0:5b88d5760320 7661 if( ssl->conf->f_set_cache != NULL &&
kenjiArai 0:5b88d5760320 7662 ssl->session->id_len != 0 &&
kenjiArai 0:5b88d5760320 7663 resume == 0 )
kenjiArai 0:5b88d5760320 7664 {
kenjiArai 0:5b88d5760320 7665 if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 )
kenjiArai 0:5b88d5760320 7666 MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) );
kenjiArai 0:5b88d5760320 7667 }
kenjiArai 0:5b88d5760320 7668
kenjiArai 0:5b88d5760320 7669 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 7670 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 7671 ssl->handshake->flight != NULL )
kenjiArai 0:5b88d5760320 7672 {
kenjiArai 0:5b88d5760320 7673 /* Cancel handshake timer */
kenjiArai 0:5b88d5760320 7674 ssl_set_timer( ssl, 0 );
kenjiArai 0:5b88d5760320 7675
kenjiArai 0:5b88d5760320 7676 /* Keep last flight around in case we need to resend it:
kenjiArai 0:5b88d5760320 7677 * we need the handshake and transform structures for that */
kenjiArai 0:5b88d5760320 7678 MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) );
kenjiArai 0:5b88d5760320 7679 }
kenjiArai 0:5b88d5760320 7680 else
kenjiArai 0:5b88d5760320 7681 #endif
kenjiArai 0:5b88d5760320 7682 ssl_handshake_wrapup_free_hs_transform( ssl );
kenjiArai 0:5b88d5760320 7683
kenjiArai 0:5b88d5760320 7684 ssl->state++;
kenjiArai 0:5b88d5760320 7685
kenjiArai 0:5b88d5760320 7686 MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
kenjiArai 0:5b88d5760320 7687 }
kenjiArai 0:5b88d5760320 7688
kenjiArai 0:5b88d5760320 7689 int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 7690 {
kenjiArai 0:5b88d5760320 7691 int ret, hash_len;
kenjiArai 0:5b88d5760320 7692
kenjiArai 0:5b88d5760320 7693 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
kenjiArai 0:5b88d5760320 7694
kenjiArai 0:5b88d5760320 7695 ssl_update_out_pointers( ssl, ssl->transform_negotiate );
kenjiArai 0:5b88d5760320 7696
kenjiArai 0:5b88d5760320 7697 ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
kenjiArai 0:5b88d5760320 7698
kenjiArai 0:5b88d5760320 7699 /*
kenjiArai 0:5b88d5760320 7700 * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
kenjiArai 0:5b88d5760320 7701 * may define some other value. Currently (early 2016), no defined
kenjiArai 0:5b88d5760320 7702 * ciphersuite does this (and this is unlikely to change as activity has
kenjiArai 0:5b88d5760320 7703 * moved to TLS 1.3 now) so we can keep the hardcoded 12 here.
kenjiArai 0:5b88d5760320 7704 */
kenjiArai 0:5b88d5760320 7705 hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12;
kenjiArai 0:5b88d5760320 7706
kenjiArai 0:5b88d5760320 7707 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 7708 ssl->verify_data_len = hash_len;
kenjiArai 0:5b88d5760320 7709 memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
kenjiArai 0:5b88d5760320 7710 #endif
kenjiArai 0:5b88d5760320 7711
kenjiArai 0:5b88d5760320 7712 ssl->out_msglen = 4 + hash_len;
kenjiArai 0:5b88d5760320 7713 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
kenjiArai 0:5b88d5760320 7714 ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED;
kenjiArai 0:5b88d5760320 7715
kenjiArai 0:5b88d5760320 7716 /*
kenjiArai 0:5b88d5760320 7717 * In case of session resuming, invert the client and server
kenjiArai 0:5b88d5760320 7718 * ChangeCipherSpec messages order.
kenjiArai 0:5b88d5760320 7719 */
kenjiArai 0:5b88d5760320 7720 if( ssl->handshake->resume != 0 )
kenjiArai 0:5b88d5760320 7721 {
kenjiArai 0:5b88d5760320 7722 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 7723 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 7724 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
kenjiArai 0:5b88d5760320 7725 #endif
kenjiArai 0:5b88d5760320 7726 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 7727 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 7728 ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
kenjiArai 0:5b88d5760320 7729 #endif
kenjiArai 0:5b88d5760320 7730 }
kenjiArai 0:5b88d5760320 7731 else
kenjiArai 0:5b88d5760320 7732 ssl->state++;
kenjiArai 0:5b88d5760320 7733
kenjiArai 0:5b88d5760320 7734 /*
kenjiArai 0:5b88d5760320 7735 * Switch to our negotiated transform and session parameters for outbound
kenjiArai 0:5b88d5760320 7736 * data.
kenjiArai 0:5b88d5760320 7737 */
kenjiArai 0:5b88d5760320 7738 MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
kenjiArai 0:5b88d5760320 7739
kenjiArai 0:5b88d5760320 7740 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 7741 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 7742 {
kenjiArai 0:5b88d5760320 7743 unsigned char i;
kenjiArai 0:5b88d5760320 7744
kenjiArai 0:5b88d5760320 7745 /* Remember current epoch settings for resending */
kenjiArai 0:5b88d5760320 7746 ssl->handshake->alt_transform_out = ssl->transform_out;
kenjiArai 0:5b88d5760320 7747 memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 );
kenjiArai 0:5b88d5760320 7748
kenjiArai 0:5b88d5760320 7749 /* Set sequence_number to zero */
kenjiArai 0:5b88d5760320 7750 memset( ssl->cur_out_ctr + 2, 0, 6 );
kenjiArai 0:5b88d5760320 7751
kenjiArai 0:5b88d5760320 7752 /* Increment epoch */
kenjiArai 0:5b88d5760320 7753 for( i = 2; i > 0; i-- )
kenjiArai 0:5b88d5760320 7754 if( ++ssl->cur_out_ctr[i - 1] != 0 )
kenjiArai 0:5b88d5760320 7755 break;
kenjiArai 0:5b88d5760320 7756
kenjiArai 0:5b88d5760320 7757 /* The loop goes to its end iff the counter is wrapping */
kenjiArai 0:5b88d5760320 7758 if( i == 0 )
kenjiArai 0:5b88d5760320 7759 {
kenjiArai 0:5b88d5760320 7760 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
kenjiArai 0:5b88d5760320 7761 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
kenjiArai 0:5b88d5760320 7762 }
kenjiArai 0:5b88d5760320 7763 }
kenjiArai 0:5b88d5760320 7764 else
kenjiArai 0:5b88d5760320 7765 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 7766 memset( ssl->cur_out_ctr, 0, 8 );
kenjiArai 0:5b88d5760320 7767
kenjiArai 0:5b88d5760320 7768 ssl->transform_out = ssl->transform_negotiate;
kenjiArai 0:5b88d5760320 7769 ssl->session_out = ssl->session_negotiate;
kenjiArai 0:5b88d5760320 7770
kenjiArai 0:5b88d5760320 7771 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 7772 if( mbedtls_ssl_hw_record_activate != NULL )
kenjiArai 0:5b88d5760320 7773 {
kenjiArai 0:5b88d5760320 7774 if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
kenjiArai 0:5b88d5760320 7775 {
kenjiArai 0:5b88d5760320 7776 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
kenjiArai 0:5b88d5760320 7777 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 7778 }
kenjiArai 0:5b88d5760320 7779 }
kenjiArai 0:5b88d5760320 7780 #endif
kenjiArai 0:5b88d5760320 7781
kenjiArai 0:5b88d5760320 7782 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 7783 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 7784 mbedtls_ssl_send_flight_completed( ssl );
kenjiArai 0:5b88d5760320 7785 #endif
kenjiArai 0:5b88d5760320 7786
kenjiArai 0:5b88d5760320 7787 if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 7788 {
kenjiArai 0:5b88d5760320 7789 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
kenjiArai 0:5b88d5760320 7790 return( ret );
kenjiArai 0:5b88d5760320 7791 }
kenjiArai 0:5b88d5760320 7792
kenjiArai 0:5b88d5760320 7793 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 7794 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 7795 ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 7796 {
kenjiArai 0:5b88d5760320 7797 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
kenjiArai 0:5b88d5760320 7798 return( ret );
kenjiArai 0:5b88d5760320 7799 }
kenjiArai 0:5b88d5760320 7800 #endif
kenjiArai 0:5b88d5760320 7801
kenjiArai 0:5b88d5760320 7802 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
kenjiArai 0:5b88d5760320 7803
kenjiArai 0:5b88d5760320 7804 return( 0 );
kenjiArai 0:5b88d5760320 7805 }
kenjiArai 0:5b88d5760320 7806
kenjiArai 0:5b88d5760320 7807 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 7808 #define SSL_MAX_HASH_LEN 36
kenjiArai 0:5b88d5760320 7809 #else
kenjiArai 0:5b88d5760320 7810 #define SSL_MAX_HASH_LEN 12
kenjiArai 0:5b88d5760320 7811 #endif
kenjiArai 0:5b88d5760320 7812
kenjiArai 0:5b88d5760320 7813 int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 7814 {
kenjiArai 0:5b88d5760320 7815 int ret;
kenjiArai 0:5b88d5760320 7816 unsigned int hash_len;
kenjiArai 0:5b88d5760320 7817 unsigned char buf[SSL_MAX_HASH_LEN];
kenjiArai 0:5b88d5760320 7818
kenjiArai 0:5b88d5760320 7819 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
kenjiArai 0:5b88d5760320 7820
kenjiArai 0:5b88d5760320 7821 ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
kenjiArai 0:5b88d5760320 7822
kenjiArai 0:5b88d5760320 7823 if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 7824 {
kenjiArai 0:5b88d5760320 7825 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
kenjiArai 0:5b88d5760320 7826 return( ret );
kenjiArai 0:5b88d5760320 7827 }
kenjiArai 0:5b88d5760320 7828
kenjiArai 0:5b88d5760320 7829 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
kenjiArai 0:5b88d5760320 7830 {
kenjiArai 0:5b88d5760320 7831 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
kenjiArai 0:5b88d5760320 7832 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 7833 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 7834 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 7835 }
kenjiArai 0:5b88d5760320 7836
kenjiArai 0:5b88d5760320 7837 /* There is currently no ciphersuite using another length with TLS 1.2 */
kenjiArai 0:5b88d5760320 7838 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 7839 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 7840 hash_len = 36;
kenjiArai 0:5b88d5760320 7841 else
kenjiArai 0:5b88d5760320 7842 #endif
kenjiArai 0:5b88d5760320 7843 hash_len = 12;
kenjiArai 0:5b88d5760320 7844
kenjiArai 0:5b88d5760320 7845 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
kenjiArai 0:5b88d5760320 7846 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
kenjiArai 0:5b88d5760320 7847 {
kenjiArai 0:5b88d5760320 7848 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
kenjiArai 0:5b88d5760320 7849 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 7850 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
kenjiArai 0:5b88d5760320 7851 return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
kenjiArai 0:5b88d5760320 7852 }
kenjiArai 0:5b88d5760320 7853
kenjiArai 0:5b88d5760320 7854 if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
kenjiArai 0:5b88d5760320 7855 buf, hash_len ) != 0 )
kenjiArai 0:5b88d5760320 7856 {
kenjiArai 0:5b88d5760320 7857 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
kenjiArai 0:5b88d5760320 7858 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 7859 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
kenjiArai 0:5b88d5760320 7860 return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
kenjiArai 0:5b88d5760320 7861 }
kenjiArai 0:5b88d5760320 7862
kenjiArai 0:5b88d5760320 7863 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 7864 ssl->verify_data_len = hash_len;
kenjiArai 0:5b88d5760320 7865 memcpy( ssl->peer_verify_data, buf, hash_len );
kenjiArai 0:5b88d5760320 7866 #endif
kenjiArai 0:5b88d5760320 7867
kenjiArai 0:5b88d5760320 7868 if( ssl->handshake->resume != 0 )
kenjiArai 0:5b88d5760320 7869 {
kenjiArai 0:5b88d5760320 7870 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 7871 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 7872 ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
kenjiArai 0:5b88d5760320 7873 #endif
kenjiArai 0:5b88d5760320 7874 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 7875 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 7876 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
kenjiArai 0:5b88d5760320 7877 #endif
kenjiArai 0:5b88d5760320 7878 }
kenjiArai 0:5b88d5760320 7879 else
kenjiArai 0:5b88d5760320 7880 ssl->state++;
kenjiArai 0:5b88d5760320 7881
kenjiArai 0:5b88d5760320 7882 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 7883 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 7884 mbedtls_ssl_recv_flight_completed( ssl );
kenjiArai 0:5b88d5760320 7885 #endif
kenjiArai 0:5b88d5760320 7886
kenjiArai 0:5b88d5760320 7887 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) );
kenjiArai 0:5b88d5760320 7888
kenjiArai 0:5b88d5760320 7889 return( 0 );
kenjiArai 0:5b88d5760320 7890 }
kenjiArai 0:5b88d5760320 7891
kenjiArai 0:5b88d5760320 7892 static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
kenjiArai 0:5b88d5760320 7893 {
kenjiArai 0:5b88d5760320 7894 memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) );
kenjiArai 0:5b88d5760320 7895
kenjiArai 0:5b88d5760320 7896 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 7897 defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 7898 mbedtls_md5_init( &handshake->fin_md5 );
kenjiArai 0:5b88d5760320 7899 mbedtls_sha1_init( &handshake->fin_sha1 );
kenjiArai 0:5b88d5760320 7900 mbedtls_md5_starts_ret( &handshake->fin_md5 );
kenjiArai 0:5b88d5760320 7901 mbedtls_sha1_starts_ret( &handshake->fin_sha1 );
kenjiArai 0:5b88d5760320 7902 #endif
kenjiArai 0:5b88d5760320 7903 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 7904 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 7905 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7906 handshake->fin_sha256_psa = psa_hash_operation_init();
kenjiArai 0:5b88d5760320 7907 psa_hash_setup( &handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
kenjiArai 0:5b88d5760320 7908 #else
kenjiArai 0:5b88d5760320 7909 mbedtls_sha256_init( &handshake->fin_sha256 );
kenjiArai 0:5b88d5760320 7910 mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 );
kenjiArai 0:5b88d5760320 7911 #endif
kenjiArai 0:5b88d5760320 7912 #endif
kenjiArai 0:5b88d5760320 7913 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 7914 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 7915 handshake->fin_sha384_psa = psa_hash_operation_init();
kenjiArai 0:5b88d5760320 7916 psa_hash_setup( &handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
kenjiArai 0:5b88d5760320 7917 #else
kenjiArai 0:5b88d5760320 7918 mbedtls_sha512_init( &handshake->fin_sha512 );
kenjiArai 0:5b88d5760320 7919 mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 );
kenjiArai 0:5b88d5760320 7920 #endif
kenjiArai 0:5b88d5760320 7921 #endif
kenjiArai 0:5b88d5760320 7922 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 7923
kenjiArai 0:5b88d5760320 7924 handshake->update_checksum = ssl_update_checksum_start;
kenjiArai 0:5b88d5760320 7925
kenjiArai 0:5b88d5760320 7926 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
kenjiArai 0:5b88d5760320 7927 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 7928 mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs );
kenjiArai 0:5b88d5760320 7929 #endif
kenjiArai 0:5b88d5760320 7930
kenjiArai 0:5b88d5760320 7931 #if defined(MBEDTLS_DHM_C)
kenjiArai 0:5b88d5760320 7932 mbedtls_dhm_init( &handshake->dhm_ctx );
kenjiArai 0:5b88d5760320 7933 #endif
kenjiArai 0:5b88d5760320 7934 #if defined(MBEDTLS_ECDH_C)
kenjiArai 0:5b88d5760320 7935 mbedtls_ecdh_init( &handshake->ecdh_ctx );
kenjiArai 0:5b88d5760320 7936 #endif
kenjiArai 0:5b88d5760320 7937 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
kenjiArai 0:5b88d5760320 7938 mbedtls_ecjpake_init( &handshake->ecjpake_ctx );
kenjiArai 0:5b88d5760320 7939 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 7940 handshake->ecjpake_cache = NULL;
kenjiArai 0:5b88d5760320 7941 handshake->ecjpake_cache_len = 0;
kenjiArai 0:5b88d5760320 7942 #endif
kenjiArai 0:5b88d5760320 7943 #endif
kenjiArai 0:5b88d5760320 7944
kenjiArai 0:5b88d5760320 7945 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 7946 mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx );
kenjiArai 0:5b88d5760320 7947 #endif
kenjiArai 0:5b88d5760320 7948
kenjiArai 0:5b88d5760320 7949 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
kenjiArai 0:5b88d5760320 7950 handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
kenjiArai 0:5b88d5760320 7951 #endif
kenjiArai 0:5b88d5760320 7952
kenjiArai 0:5b88d5760320 7953 #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
kenjiArai 0:5b88d5760320 7954 !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 7955 mbedtls_pk_init( &handshake->peer_pubkey );
kenjiArai 0:5b88d5760320 7956 #endif
kenjiArai 0:5b88d5760320 7957 }
kenjiArai 0:5b88d5760320 7958
kenjiArai 0:5b88d5760320 7959 void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform )
kenjiArai 0:5b88d5760320 7960 {
kenjiArai 0:5b88d5760320 7961 memset( transform, 0, sizeof(mbedtls_ssl_transform) );
kenjiArai 0:5b88d5760320 7962
kenjiArai 0:5b88d5760320 7963 mbedtls_cipher_init( &transform->cipher_ctx_enc );
kenjiArai 0:5b88d5760320 7964 mbedtls_cipher_init( &transform->cipher_ctx_dec );
kenjiArai 0:5b88d5760320 7965
kenjiArai 0:5b88d5760320 7966 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
kenjiArai 0:5b88d5760320 7967 mbedtls_md_init( &transform->md_ctx_enc );
kenjiArai 0:5b88d5760320 7968 mbedtls_md_init( &transform->md_ctx_dec );
kenjiArai 0:5b88d5760320 7969 #endif
kenjiArai 0:5b88d5760320 7970 }
kenjiArai 0:5b88d5760320 7971
kenjiArai 0:5b88d5760320 7972 void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
kenjiArai 0:5b88d5760320 7973 {
kenjiArai 0:5b88d5760320 7974 memset( session, 0, sizeof(mbedtls_ssl_session) );
kenjiArai 0:5b88d5760320 7975 }
kenjiArai 0:5b88d5760320 7976
kenjiArai 0:5b88d5760320 7977 static int ssl_handshake_init( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 7978 {
kenjiArai 0:5b88d5760320 7979 /* Clear old handshake information if present */
kenjiArai 0:5b88d5760320 7980 if( ssl->transform_negotiate )
kenjiArai 0:5b88d5760320 7981 mbedtls_ssl_transform_free( ssl->transform_negotiate );
kenjiArai 0:5b88d5760320 7982 if( ssl->session_negotiate )
kenjiArai 0:5b88d5760320 7983 mbedtls_ssl_session_free( ssl->session_negotiate );
kenjiArai 0:5b88d5760320 7984 if( ssl->handshake )
kenjiArai 0:5b88d5760320 7985 mbedtls_ssl_handshake_free( ssl );
kenjiArai 0:5b88d5760320 7986
kenjiArai 0:5b88d5760320 7987 /*
kenjiArai 0:5b88d5760320 7988 * Either the pointers are now NULL or cleared properly and can be freed.
kenjiArai 0:5b88d5760320 7989 * Now allocate missing structures.
kenjiArai 0:5b88d5760320 7990 */
kenjiArai 0:5b88d5760320 7991 if( ssl->transform_negotiate == NULL )
kenjiArai 0:5b88d5760320 7992 {
kenjiArai 0:5b88d5760320 7993 ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) );
kenjiArai 0:5b88d5760320 7994 }
kenjiArai 0:5b88d5760320 7995
kenjiArai 0:5b88d5760320 7996 if( ssl->session_negotiate == NULL )
kenjiArai 0:5b88d5760320 7997 {
kenjiArai 0:5b88d5760320 7998 ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) );
kenjiArai 0:5b88d5760320 7999 }
kenjiArai 0:5b88d5760320 8000
kenjiArai 0:5b88d5760320 8001 if( ssl->handshake == NULL )
kenjiArai 0:5b88d5760320 8002 {
kenjiArai 0:5b88d5760320 8003 ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
kenjiArai 0:5b88d5760320 8004 }
kenjiArai 0:5b88d5760320 8005
kenjiArai 0:5b88d5760320 8006 /* All pointers should exist and can be directly freed without issue */
kenjiArai 0:5b88d5760320 8007 if( ssl->handshake == NULL ||
kenjiArai 0:5b88d5760320 8008 ssl->transform_negotiate == NULL ||
kenjiArai 0:5b88d5760320 8009 ssl->session_negotiate == NULL )
kenjiArai 0:5b88d5760320 8010 {
kenjiArai 0:5b88d5760320 8011 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc() of ssl sub-contexts failed" ) );
kenjiArai 0:5b88d5760320 8012
kenjiArai 0:5b88d5760320 8013 mbedtls_free( ssl->handshake );
kenjiArai 0:5b88d5760320 8014 mbedtls_free( ssl->transform_negotiate );
kenjiArai 0:5b88d5760320 8015 mbedtls_free( ssl->session_negotiate );
kenjiArai 0:5b88d5760320 8016
kenjiArai 0:5b88d5760320 8017 ssl->handshake = NULL;
kenjiArai 0:5b88d5760320 8018 ssl->transform_negotiate = NULL;
kenjiArai 0:5b88d5760320 8019 ssl->session_negotiate = NULL;
kenjiArai 0:5b88d5760320 8020
kenjiArai 0:5b88d5760320 8021 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 8022 }
kenjiArai 0:5b88d5760320 8023
kenjiArai 0:5b88d5760320 8024 /* Initialize structures */
kenjiArai 0:5b88d5760320 8025 mbedtls_ssl_session_init( ssl->session_negotiate );
kenjiArai 0:5b88d5760320 8026 mbedtls_ssl_transform_init( ssl->transform_negotiate );
kenjiArai 0:5b88d5760320 8027 ssl_handshake_params_init( ssl->handshake );
kenjiArai 0:5b88d5760320 8028
kenjiArai 0:5b88d5760320 8029 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 8030 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 8031 {
kenjiArai 0:5b88d5760320 8032 ssl->handshake->alt_transform_out = ssl->transform_out;
kenjiArai 0:5b88d5760320 8033
kenjiArai 0:5b88d5760320 8034 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 8035 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
kenjiArai 0:5b88d5760320 8036 else
kenjiArai 0:5b88d5760320 8037 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
kenjiArai 0:5b88d5760320 8038
kenjiArai 0:5b88d5760320 8039 ssl_set_timer( ssl, 0 );
kenjiArai 0:5b88d5760320 8040 }
kenjiArai 0:5b88d5760320 8041 #endif
kenjiArai 0:5b88d5760320 8042
kenjiArai 0:5b88d5760320 8043 return( 0 );
kenjiArai 0:5b88d5760320 8044 }
kenjiArai 0:5b88d5760320 8045
kenjiArai 0:5b88d5760320 8046 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 8047 /* Dummy cookie callbacks for defaults */
kenjiArai 0:5b88d5760320 8048 static int ssl_cookie_write_dummy( void *ctx,
kenjiArai 0:5b88d5760320 8049 unsigned char **p, unsigned char *end,
kenjiArai 0:5b88d5760320 8050 const unsigned char *cli_id, size_t cli_id_len )
kenjiArai 0:5b88d5760320 8051 {
kenjiArai 0:5b88d5760320 8052 ((void) ctx);
kenjiArai 0:5b88d5760320 8053 ((void) p);
kenjiArai 0:5b88d5760320 8054 ((void) end);
kenjiArai 0:5b88d5760320 8055 ((void) cli_id);
kenjiArai 0:5b88d5760320 8056 ((void) cli_id_len);
kenjiArai 0:5b88d5760320 8057
kenjiArai 0:5b88d5760320 8058 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
kenjiArai 0:5b88d5760320 8059 }
kenjiArai 0:5b88d5760320 8060
kenjiArai 0:5b88d5760320 8061 static int ssl_cookie_check_dummy( void *ctx,
kenjiArai 0:5b88d5760320 8062 const unsigned char *cookie, size_t cookie_len,
kenjiArai 0:5b88d5760320 8063 const unsigned char *cli_id, size_t cli_id_len )
kenjiArai 0:5b88d5760320 8064 {
kenjiArai 0:5b88d5760320 8065 ((void) ctx);
kenjiArai 0:5b88d5760320 8066 ((void) cookie);
kenjiArai 0:5b88d5760320 8067 ((void) cookie_len);
kenjiArai 0:5b88d5760320 8068 ((void) cli_id);
kenjiArai 0:5b88d5760320 8069 ((void) cli_id_len);
kenjiArai 0:5b88d5760320 8070
kenjiArai 0:5b88d5760320 8071 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
kenjiArai 0:5b88d5760320 8072 }
kenjiArai 0:5b88d5760320 8073 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 8074
kenjiArai 0:5b88d5760320 8075 /* Once ssl->out_hdr as the address of the beginning of the
kenjiArai 0:5b88d5760320 8076 * next outgoing record is set, deduce the other pointers.
kenjiArai 0:5b88d5760320 8077 *
kenjiArai 0:5b88d5760320 8078 * Note: For TLS, we save the implicit record sequence number
kenjiArai 0:5b88d5760320 8079 * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
kenjiArai 0:5b88d5760320 8080 * and the caller has to make sure there's space for this.
kenjiArai 0:5b88d5760320 8081 */
kenjiArai 0:5b88d5760320 8082
kenjiArai 0:5b88d5760320 8083 static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8084 mbedtls_ssl_transform *transform )
kenjiArai 0:5b88d5760320 8085 {
kenjiArai 0:5b88d5760320 8086 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 8087 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 8088 {
kenjiArai 0:5b88d5760320 8089 ssl->out_ctr = ssl->out_hdr + 3;
kenjiArai 0:5b88d5760320 8090 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 8091 ssl->out_cid = ssl->out_ctr + 8;
kenjiArai 0:5b88d5760320 8092 ssl->out_len = ssl->out_cid;
kenjiArai 0:5b88d5760320 8093 if( transform != NULL )
kenjiArai 0:5b88d5760320 8094 ssl->out_len += transform->out_cid_len;
kenjiArai 0:5b88d5760320 8095 #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 8096 ssl->out_len = ssl->out_ctr + 8;
kenjiArai 0:5b88d5760320 8097 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 8098 ssl->out_iv = ssl->out_len + 2;
kenjiArai 0:5b88d5760320 8099 }
kenjiArai 0:5b88d5760320 8100 else
kenjiArai 0:5b88d5760320 8101 #endif
kenjiArai 0:5b88d5760320 8102 {
kenjiArai 0:5b88d5760320 8103 ssl->out_ctr = ssl->out_hdr - 8;
kenjiArai 0:5b88d5760320 8104 ssl->out_len = ssl->out_hdr + 3;
kenjiArai 0:5b88d5760320 8105 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 8106 ssl->out_cid = ssl->out_len;
kenjiArai 0:5b88d5760320 8107 #endif
kenjiArai 0:5b88d5760320 8108 ssl->out_iv = ssl->out_hdr + 5;
kenjiArai 0:5b88d5760320 8109 }
kenjiArai 0:5b88d5760320 8110
kenjiArai 0:5b88d5760320 8111 /* Adjust out_msg to make space for explicit IV, if used. */
kenjiArai 0:5b88d5760320 8112 if( transform != NULL &&
kenjiArai 0:5b88d5760320 8113 ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
kenjiArai 0:5b88d5760320 8114 {
kenjiArai 0:5b88d5760320 8115 ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen;
kenjiArai 0:5b88d5760320 8116 }
kenjiArai 0:5b88d5760320 8117 else
kenjiArai 0:5b88d5760320 8118 ssl->out_msg = ssl->out_iv;
kenjiArai 0:5b88d5760320 8119 }
kenjiArai 0:5b88d5760320 8120
kenjiArai 0:5b88d5760320 8121 /* Once ssl->in_hdr as the address of the beginning of the
kenjiArai 0:5b88d5760320 8122 * next incoming record is set, deduce the other pointers.
kenjiArai 0:5b88d5760320 8123 *
kenjiArai 0:5b88d5760320 8124 * Note: For TLS, we save the implicit record sequence number
kenjiArai 0:5b88d5760320 8125 * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
kenjiArai 0:5b88d5760320 8126 * and the caller has to make sure there's space for this.
kenjiArai 0:5b88d5760320 8127 */
kenjiArai 0:5b88d5760320 8128
kenjiArai 0:5b88d5760320 8129 static void ssl_update_in_pointers( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 8130 {
kenjiArai 0:5b88d5760320 8131 /* This function sets the pointers to match the case
kenjiArai 0:5b88d5760320 8132 * of unprotected TLS/DTLS records, with both ssl->in_iv
kenjiArai 0:5b88d5760320 8133 * and ssl->in_msg pointing to the beginning of the record
kenjiArai 0:5b88d5760320 8134 * content.
kenjiArai 0:5b88d5760320 8135 *
kenjiArai 0:5b88d5760320 8136 * When decrypting a protected record, ssl->in_msg
kenjiArai 0:5b88d5760320 8137 * will be shifted to point to the beginning of the
kenjiArai 0:5b88d5760320 8138 * record plaintext.
kenjiArai 0:5b88d5760320 8139 */
kenjiArai 0:5b88d5760320 8140
kenjiArai 0:5b88d5760320 8141 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 8142 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 8143 {
kenjiArai 0:5b88d5760320 8144 /* This sets the header pointers to match records
kenjiArai 0:5b88d5760320 8145 * without CID. When we receive a record containing
kenjiArai 0:5b88d5760320 8146 * a CID, the fields are shifted accordingly in
kenjiArai 0:5b88d5760320 8147 * ssl_parse_record_header(). */
kenjiArai 0:5b88d5760320 8148 ssl->in_ctr = ssl->in_hdr + 3;
kenjiArai 0:5b88d5760320 8149 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 8150 ssl->in_cid = ssl->in_ctr + 8;
kenjiArai 0:5b88d5760320 8151 ssl->in_len = ssl->in_cid; /* Default: no CID */
kenjiArai 0:5b88d5760320 8152 #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 8153 ssl->in_len = ssl->in_ctr + 8;
kenjiArai 0:5b88d5760320 8154 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 8155 ssl->in_iv = ssl->in_len + 2;
kenjiArai 0:5b88d5760320 8156 }
kenjiArai 0:5b88d5760320 8157 else
kenjiArai 0:5b88d5760320 8158 #endif
kenjiArai 0:5b88d5760320 8159 {
kenjiArai 0:5b88d5760320 8160 ssl->in_ctr = ssl->in_hdr - 8;
kenjiArai 0:5b88d5760320 8161 ssl->in_len = ssl->in_hdr + 3;
kenjiArai 0:5b88d5760320 8162 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 8163 ssl->in_cid = ssl->in_len;
kenjiArai 0:5b88d5760320 8164 #endif
kenjiArai 0:5b88d5760320 8165 ssl->in_iv = ssl->in_hdr + 5;
kenjiArai 0:5b88d5760320 8166 }
kenjiArai 0:5b88d5760320 8167
kenjiArai 0:5b88d5760320 8168 /* This will be adjusted at record decryption time. */
kenjiArai 0:5b88d5760320 8169 ssl->in_msg = ssl->in_iv;
kenjiArai 0:5b88d5760320 8170 }
kenjiArai 0:5b88d5760320 8171
kenjiArai 0:5b88d5760320 8172 /*
kenjiArai 0:5b88d5760320 8173 * Initialize an SSL context
kenjiArai 0:5b88d5760320 8174 */
kenjiArai 0:5b88d5760320 8175 void mbedtls_ssl_init( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 8176 {
kenjiArai 0:5b88d5760320 8177 memset( ssl, 0, sizeof( mbedtls_ssl_context ) );
kenjiArai 0:5b88d5760320 8178 }
kenjiArai 0:5b88d5760320 8179
kenjiArai 0:5b88d5760320 8180 /*
kenjiArai 0:5b88d5760320 8181 * Setup an SSL context
kenjiArai 0:5b88d5760320 8182 */
kenjiArai 0:5b88d5760320 8183
kenjiArai 0:5b88d5760320 8184 static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 8185 {
kenjiArai 0:5b88d5760320 8186 /* Set the incoming and outgoing record pointers. */
kenjiArai 0:5b88d5760320 8187 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 8188 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 8189 {
kenjiArai 0:5b88d5760320 8190 ssl->out_hdr = ssl->out_buf;
kenjiArai 0:5b88d5760320 8191 ssl->in_hdr = ssl->in_buf;
kenjiArai 0:5b88d5760320 8192 }
kenjiArai 0:5b88d5760320 8193 else
kenjiArai 0:5b88d5760320 8194 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 8195 {
kenjiArai 0:5b88d5760320 8196 ssl->out_hdr = ssl->out_buf + 8;
kenjiArai 0:5b88d5760320 8197 ssl->in_hdr = ssl->in_buf + 8;
kenjiArai 0:5b88d5760320 8198 }
kenjiArai 0:5b88d5760320 8199
kenjiArai 0:5b88d5760320 8200 /* Derive other internal pointers. */
kenjiArai 0:5b88d5760320 8201 ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
kenjiArai 0:5b88d5760320 8202 ssl_update_in_pointers ( ssl );
kenjiArai 0:5b88d5760320 8203 }
kenjiArai 0:5b88d5760320 8204
kenjiArai 0:5b88d5760320 8205 int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8206 const mbedtls_ssl_config *conf )
kenjiArai 0:5b88d5760320 8207 {
kenjiArai 0:5b88d5760320 8208 int ret;
kenjiArai 0:5b88d5760320 8209
kenjiArai 0:5b88d5760320 8210 ssl->conf = conf;
kenjiArai 0:5b88d5760320 8211
kenjiArai 0:5b88d5760320 8212 /*
kenjiArai 0:5b88d5760320 8213 * Prepare base structures
kenjiArai 0:5b88d5760320 8214 */
kenjiArai 0:5b88d5760320 8215
kenjiArai 0:5b88d5760320 8216 /* Set to NULL in case of an error condition */
kenjiArai 0:5b88d5760320 8217 ssl->out_buf = NULL;
kenjiArai 0:5b88d5760320 8218
kenjiArai 0:5b88d5760320 8219 ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN );
kenjiArai 0:5b88d5760320 8220 if( ssl->in_buf == NULL )
kenjiArai 0:5b88d5760320 8221 {
kenjiArai 0:5b88d5760320 8222 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) );
kenjiArai 0:5b88d5760320 8223 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
kenjiArai 0:5b88d5760320 8224 goto error;
kenjiArai 0:5b88d5760320 8225 }
kenjiArai 0:5b88d5760320 8226
kenjiArai 0:5b88d5760320 8227 ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN );
kenjiArai 0:5b88d5760320 8228 if( ssl->out_buf == NULL )
kenjiArai 0:5b88d5760320 8229 {
kenjiArai 0:5b88d5760320 8230 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) );
kenjiArai 0:5b88d5760320 8231 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
kenjiArai 0:5b88d5760320 8232 goto error;
kenjiArai 0:5b88d5760320 8233 }
kenjiArai 0:5b88d5760320 8234
kenjiArai 0:5b88d5760320 8235 ssl_reset_in_out_pointers( ssl );
kenjiArai 0:5b88d5760320 8236
kenjiArai 0:5b88d5760320 8237 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 8238 goto error;
kenjiArai 0:5b88d5760320 8239
kenjiArai 0:5b88d5760320 8240 return( 0 );
kenjiArai 0:5b88d5760320 8241
kenjiArai 0:5b88d5760320 8242 error:
kenjiArai 0:5b88d5760320 8243 mbedtls_free( ssl->in_buf );
kenjiArai 0:5b88d5760320 8244 mbedtls_free( ssl->out_buf );
kenjiArai 0:5b88d5760320 8245
kenjiArai 0:5b88d5760320 8246 ssl->conf = NULL;
kenjiArai 0:5b88d5760320 8247
kenjiArai 0:5b88d5760320 8248 ssl->in_buf = NULL;
kenjiArai 0:5b88d5760320 8249 ssl->out_buf = NULL;
kenjiArai 0:5b88d5760320 8250
kenjiArai 0:5b88d5760320 8251 ssl->in_hdr = NULL;
kenjiArai 0:5b88d5760320 8252 ssl->in_ctr = NULL;
kenjiArai 0:5b88d5760320 8253 ssl->in_len = NULL;
kenjiArai 0:5b88d5760320 8254 ssl->in_iv = NULL;
kenjiArai 0:5b88d5760320 8255 ssl->in_msg = NULL;
kenjiArai 0:5b88d5760320 8256
kenjiArai 0:5b88d5760320 8257 ssl->out_hdr = NULL;
kenjiArai 0:5b88d5760320 8258 ssl->out_ctr = NULL;
kenjiArai 0:5b88d5760320 8259 ssl->out_len = NULL;
kenjiArai 0:5b88d5760320 8260 ssl->out_iv = NULL;
kenjiArai 0:5b88d5760320 8261 ssl->out_msg = NULL;
kenjiArai 0:5b88d5760320 8262
kenjiArai 0:5b88d5760320 8263 return( ret );
kenjiArai 0:5b88d5760320 8264 }
kenjiArai 0:5b88d5760320 8265
kenjiArai 0:5b88d5760320 8266 /*
kenjiArai 0:5b88d5760320 8267 * Reset an initialized and used SSL context for re-use while retaining
kenjiArai 0:5b88d5760320 8268 * all application-set variables, function pointers and data.
kenjiArai 0:5b88d5760320 8269 *
kenjiArai 0:5b88d5760320 8270 * If partial is non-zero, keep data in the input buffer and client ID.
kenjiArai 0:5b88d5760320 8271 * (Use when a DTLS client reconnects from the same port.)
kenjiArai 0:5b88d5760320 8272 */
kenjiArai 0:5b88d5760320 8273 static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
kenjiArai 0:5b88d5760320 8274 {
kenjiArai 0:5b88d5760320 8275 int ret;
kenjiArai 0:5b88d5760320 8276
kenjiArai 0:5b88d5760320 8277 #if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
kenjiArai 0:5b88d5760320 8278 !defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 8279 ((void) partial);
kenjiArai 0:5b88d5760320 8280 #endif
kenjiArai 0:5b88d5760320 8281
kenjiArai 0:5b88d5760320 8282 ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
kenjiArai 0:5b88d5760320 8283
kenjiArai 0:5b88d5760320 8284 /* Cancel any possibly running timer */
kenjiArai 0:5b88d5760320 8285 ssl_set_timer( ssl, 0 );
kenjiArai 0:5b88d5760320 8286
kenjiArai 0:5b88d5760320 8287 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 8288 ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
kenjiArai 0:5b88d5760320 8289 ssl->renego_records_seen = 0;
kenjiArai 0:5b88d5760320 8290
kenjiArai 0:5b88d5760320 8291 ssl->verify_data_len = 0;
kenjiArai 0:5b88d5760320 8292 memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN );
kenjiArai 0:5b88d5760320 8293 memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN );
kenjiArai 0:5b88d5760320 8294 #endif
kenjiArai 0:5b88d5760320 8295 ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
kenjiArai 0:5b88d5760320 8296
kenjiArai 0:5b88d5760320 8297 ssl->in_offt = NULL;
kenjiArai 0:5b88d5760320 8298 ssl_reset_in_out_pointers( ssl );
kenjiArai 0:5b88d5760320 8299
kenjiArai 0:5b88d5760320 8300 ssl->in_msgtype = 0;
kenjiArai 0:5b88d5760320 8301 ssl->in_msglen = 0;
kenjiArai 0:5b88d5760320 8302 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 8303 ssl->next_record_offset = 0;
kenjiArai 0:5b88d5760320 8304 ssl->in_epoch = 0;
kenjiArai 0:5b88d5760320 8305 #endif
kenjiArai 0:5b88d5760320 8306 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
kenjiArai 0:5b88d5760320 8307 ssl_dtls_replay_reset( ssl );
kenjiArai 0:5b88d5760320 8308 #endif
kenjiArai 0:5b88d5760320 8309
kenjiArai 0:5b88d5760320 8310 ssl->in_hslen = 0;
kenjiArai 0:5b88d5760320 8311 ssl->nb_zero = 0;
kenjiArai 0:5b88d5760320 8312
kenjiArai 0:5b88d5760320 8313 ssl->keep_current_message = 0;
kenjiArai 0:5b88d5760320 8314
kenjiArai 0:5b88d5760320 8315 ssl->out_msgtype = 0;
kenjiArai 0:5b88d5760320 8316 ssl->out_msglen = 0;
kenjiArai 0:5b88d5760320 8317 ssl->out_left = 0;
kenjiArai 0:5b88d5760320 8318 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
kenjiArai 0:5b88d5760320 8319 if( ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED )
kenjiArai 0:5b88d5760320 8320 ssl->split_done = 0;
kenjiArai 0:5b88d5760320 8321 #endif
kenjiArai 0:5b88d5760320 8322
kenjiArai 0:5b88d5760320 8323 memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
kenjiArai 0:5b88d5760320 8324
kenjiArai 0:5b88d5760320 8325 ssl->transform_in = NULL;
kenjiArai 0:5b88d5760320 8326 ssl->transform_out = NULL;
kenjiArai 0:5b88d5760320 8327
kenjiArai 0:5b88d5760320 8328 ssl->session_in = NULL;
kenjiArai 0:5b88d5760320 8329 ssl->session_out = NULL;
kenjiArai 0:5b88d5760320 8330
kenjiArai 0:5b88d5760320 8331 memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN );
kenjiArai 0:5b88d5760320 8332
kenjiArai 0:5b88d5760320 8333 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 8334 if( partial == 0 )
kenjiArai 0:5b88d5760320 8335 #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 8336 {
kenjiArai 0:5b88d5760320 8337 ssl->in_left = 0;
kenjiArai 0:5b88d5760320 8338 memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN );
kenjiArai 0:5b88d5760320 8339 }
kenjiArai 0:5b88d5760320 8340
kenjiArai 0:5b88d5760320 8341 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 8342 if( mbedtls_ssl_hw_record_reset != NULL )
kenjiArai 0:5b88d5760320 8343 {
kenjiArai 0:5b88d5760320 8344 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_reset()" ) );
kenjiArai 0:5b88d5760320 8345 if( ( ret = mbedtls_ssl_hw_record_reset( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 8346 {
kenjiArai 0:5b88d5760320 8347 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_reset", ret );
kenjiArai 0:5b88d5760320 8348 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 8349 }
kenjiArai 0:5b88d5760320 8350 }
kenjiArai 0:5b88d5760320 8351 #endif
kenjiArai 0:5b88d5760320 8352
kenjiArai 0:5b88d5760320 8353 if( ssl->transform )
kenjiArai 0:5b88d5760320 8354 {
kenjiArai 0:5b88d5760320 8355 mbedtls_ssl_transform_free( ssl->transform );
kenjiArai 0:5b88d5760320 8356 mbedtls_free( ssl->transform );
kenjiArai 0:5b88d5760320 8357 ssl->transform = NULL;
kenjiArai 0:5b88d5760320 8358 }
kenjiArai 0:5b88d5760320 8359
kenjiArai 0:5b88d5760320 8360 if( ssl->session )
kenjiArai 0:5b88d5760320 8361 {
kenjiArai 0:5b88d5760320 8362 mbedtls_ssl_session_free( ssl->session );
kenjiArai 0:5b88d5760320 8363 mbedtls_free( ssl->session );
kenjiArai 0:5b88d5760320 8364 ssl->session = NULL;
kenjiArai 0:5b88d5760320 8365 }
kenjiArai 0:5b88d5760320 8366
kenjiArai 0:5b88d5760320 8367 #if defined(MBEDTLS_SSL_ALPN)
kenjiArai 0:5b88d5760320 8368 ssl->alpn_chosen = NULL;
kenjiArai 0:5b88d5760320 8369 #endif
kenjiArai 0:5b88d5760320 8370
kenjiArai 0:5b88d5760320 8371 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 8372 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
kenjiArai 0:5b88d5760320 8373 if( partial == 0 )
kenjiArai 0:5b88d5760320 8374 #endif
kenjiArai 0:5b88d5760320 8375 {
kenjiArai 0:5b88d5760320 8376 mbedtls_free( ssl->cli_id );
kenjiArai 0:5b88d5760320 8377 ssl->cli_id = NULL;
kenjiArai 0:5b88d5760320 8378 ssl->cli_id_len = 0;
kenjiArai 0:5b88d5760320 8379 }
kenjiArai 0:5b88d5760320 8380 #endif
kenjiArai 0:5b88d5760320 8381
kenjiArai 0:5b88d5760320 8382 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 8383 return( ret );
kenjiArai 0:5b88d5760320 8384
kenjiArai 0:5b88d5760320 8385 return( 0 );
kenjiArai 0:5b88d5760320 8386 }
kenjiArai 0:5b88d5760320 8387
kenjiArai 0:5b88d5760320 8388 /*
kenjiArai 0:5b88d5760320 8389 * Reset an initialized and used SSL context for re-use while retaining
kenjiArai 0:5b88d5760320 8390 * all application-set variables, function pointers and data.
kenjiArai 0:5b88d5760320 8391 */
kenjiArai 0:5b88d5760320 8392 int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 8393 {
kenjiArai 0:5b88d5760320 8394 return( ssl_session_reset_int( ssl, 0 ) );
kenjiArai 0:5b88d5760320 8395 }
kenjiArai 0:5b88d5760320 8396
kenjiArai 0:5b88d5760320 8397 /*
kenjiArai 0:5b88d5760320 8398 * SSL set accessors
kenjiArai 0:5b88d5760320 8399 */
kenjiArai 0:5b88d5760320 8400 void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint )
kenjiArai 0:5b88d5760320 8401 {
kenjiArai 0:5b88d5760320 8402 conf->endpoint = endpoint;
kenjiArai 0:5b88d5760320 8403 }
kenjiArai 0:5b88d5760320 8404
kenjiArai 0:5b88d5760320 8405 void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport )
kenjiArai 0:5b88d5760320 8406 {
kenjiArai 0:5b88d5760320 8407 conf->transport = transport;
kenjiArai 0:5b88d5760320 8408 }
kenjiArai 0:5b88d5760320 8409
kenjiArai 0:5b88d5760320 8410 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
kenjiArai 0:5b88d5760320 8411 void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode )
kenjiArai 0:5b88d5760320 8412 {
kenjiArai 0:5b88d5760320 8413 conf->anti_replay = mode;
kenjiArai 0:5b88d5760320 8414 }
kenjiArai 0:5b88d5760320 8415 #endif
kenjiArai 0:5b88d5760320 8416
kenjiArai 0:5b88d5760320 8417 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
kenjiArai 0:5b88d5760320 8418 void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit )
kenjiArai 0:5b88d5760320 8419 {
kenjiArai 0:5b88d5760320 8420 conf->badmac_limit = limit;
kenjiArai 0:5b88d5760320 8421 }
kenjiArai 0:5b88d5760320 8422 #endif
kenjiArai 0:5b88d5760320 8423
kenjiArai 0:5b88d5760320 8424 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 8425
kenjiArai 0:5b88d5760320 8426 void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8427 unsigned allow_packing )
kenjiArai 0:5b88d5760320 8428 {
kenjiArai 0:5b88d5760320 8429 ssl->disable_datagram_packing = !allow_packing;
kenjiArai 0:5b88d5760320 8430 }
kenjiArai 0:5b88d5760320 8431
kenjiArai 0:5b88d5760320 8432 void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8433 uint32_t min, uint32_t max )
kenjiArai 0:5b88d5760320 8434 {
kenjiArai 0:5b88d5760320 8435 conf->hs_timeout_min = min;
kenjiArai 0:5b88d5760320 8436 conf->hs_timeout_max = max;
kenjiArai 0:5b88d5760320 8437 }
kenjiArai 0:5b88d5760320 8438 #endif
kenjiArai 0:5b88d5760320 8439
kenjiArai 0:5b88d5760320 8440 void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode )
kenjiArai 0:5b88d5760320 8441 {
kenjiArai 0:5b88d5760320 8442 conf->authmode = authmode;
kenjiArai 0:5b88d5760320 8443 }
kenjiArai 0:5b88d5760320 8444
kenjiArai 0:5b88d5760320 8445 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 8446 void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8447 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
kenjiArai 0:5b88d5760320 8448 void *p_vrfy )
kenjiArai 0:5b88d5760320 8449 {
kenjiArai 0:5b88d5760320 8450 conf->f_vrfy = f_vrfy;
kenjiArai 0:5b88d5760320 8451 conf->p_vrfy = p_vrfy;
kenjiArai 0:5b88d5760320 8452 }
kenjiArai 0:5b88d5760320 8453 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 8454
kenjiArai 0:5b88d5760320 8455 void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8456 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 8457 void *p_rng )
kenjiArai 0:5b88d5760320 8458 {
kenjiArai 0:5b88d5760320 8459 conf->f_rng = f_rng;
kenjiArai 0:5b88d5760320 8460 conf->p_rng = p_rng;
kenjiArai 0:5b88d5760320 8461 }
kenjiArai 0:5b88d5760320 8462
kenjiArai 0:5b88d5760320 8463 void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8464 void (*f_dbg)(void *, int, const char *, int, const char *),
kenjiArai 0:5b88d5760320 8465 void *p_dbg )
kenjiArai 0:5b88d5760320 8466 {
kenjiArai 0:5b88d5760320 8467 conf->f_dbg = f_dbg;
kenjiArai 0:5b88d5760320 8468 conf->p_dbg = p_dbg;
kenjiArai 0:5b88d5760320 8469 }
kenjiArai 0:5b88d5760320 8470
kenjiArai 0:5b88d5760320 8471 void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8472 void *p_bio,
kenjiArai 0:5b88d5760320 8473 mbedtls_ssl_send_t *f_send,
kenjiArai 0:5b88d5760320 8474 mbedtls_ssl_recv_t *f_recv,
kenjiArai 0:5b88d5760320 8475 mbedtls_ssl_recv_timeout_t *f_recv_timeout )
kenjiArai 0:5b88d5760320 8476 {
kenjiArai 0:5b88d5760320 8477 ssl->p_bio = p_bio;
kenjiArai 0:5b88d5760320 8478 ssl->f_send = f_send;
kenjiArai 0:5b88d5760320 8479 ssl->f_recv = f_recv;
kenjiArai 0:5b88d5760320 8480 ssl->f_recv_timeout = f_recv_timeout;
kenjiArai 0:5b88d5760320 8481 }
kenjiArai 0:5b88d5760320 8482
kenjiArai 0:5b88d5760320 8483 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 8484 void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu )
kenjiArai 0:5b88d5760320 8485 {
kenjiArai 0:5b88d5760320 8486 ssl->mtu = mtu;
kenjiArai 0:5b88d5760320 8487 }
kenjiArai 0:5b88d5760320 8488 #endif
kenjiArai 0:5b88d5760320 8489
kenjiArai 0:5b88d5760320 8490 void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout )
kenjiArai 0:5b88d5760320 8491 {
kenjiArai 0:5b88d5760320 8492 conf->read_timeout = timeout;
kenjiArai 0:5b88d5760320 8493 }
kenjiArai 0:5b88d5760320 8494
kenjiArai 0:5b88d5760320 8495 void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8496 void *p_timer,
kenjiArai 0:5b88d5760320 8497 mbedtls_ssl_set_timer_t *f_set_timer,
kenjiArai 0:5b88d5760320 8498 mbedtls_ssl_get_timer_t *f_get_timer )
kenjiArai 0:5b88d5760320 8499 {
kenjiArai 0:5b88d5760320 8500 ssl->p_timer = p_timer;
kenjiArai 0:5b88d5760320 8501 ssl->f_set_timer = f_set_timer;
kenjiArai 0:5b88d5760320 8502 ssl->f_get_timer = f_get_timer;
kenjiArai 0:5b88d5760320 8503
kenjiArai 0:5b88d5760320 8504 /* Make sure we start with no timer running */
kenjiArai 0:5b88d5760320 8505 ssl_set_timer( ssl, 0 );
kenjiArai 0:5b88d5760320 8506 }
kenjiArai 0:5b88d5760320 8507
kenjiArai 0:5b88d5760320 8508 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 8509 void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8510 void *p_cache,
kenjiArai 0:5b88d5760320 8511 int (*f_get_cache)(void *, mbedtls_ssl_session *),
kenjiArai 0:5b88d5760320 8512 int (*f_set_cache)(void *, const mbedtls_ssl_session *) )
kenjiArai 0:5b88d5760320 8513 {
kenjiArai 0:5b88d5760320 8514 conf->p_cache = p_cache;
kenjiArai 0:5b88d5760320 8515 conf->f_get_cache = f_get_cache;
kenjiArai 0:5b88d5760320 8516 conf->f_set_cache = f_set_cache;
kenjiArai 0:5b88d5760320 8517 }
kenjiArai 0:5b88d5760320 8518 #endif /* MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 8519
kenjiArai 0:5b88d5760320 8520 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 8521 int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session )
kenjiArai 0:5b88d5760320 8522 {
kenjiArai 0:5b88d5760320 8523 int ret;
kenjiArai 0:5b88d5760320 8524
kenjiArai 0:5b88d5760320 8525 if( ssl == NULL ||
kenjiArai 0:5b88d5760320 8526 session == NULL ||
kenjiArai 0:5b88d5760320 8527 ssl->session_negotiate == NULL ||
kenjiArai 0:5b88d5760320 8528 ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 8529 {
kenjiArai 0:5b88d5760320 8530 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8531 }
kenjiArai 0:5b88d5760320 8532
kenjiArai 0:5b88d5760320 8533 if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate,
kenjiArai 0:5b88d5760320 8534 session ) ) != 0 )
kenjiArai 0:5b88d5760320 8535 return( ret );
kenjiArai 0:5b88d5760320 8536
kenjiArai 0:5b88d5760320 8537 ssl->handshake->resume = 1;
kenjiArai 0:5b88d5760320 8538
kenjiArai 0:5b88d5760320 8539 return( 0 );
kenjiArai 0:5b88d5760320 8540 }
kenjiArai 0:5b88d5760320 8541 #endif /* MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 8542
kenjiArai 0:5b88d5760320 8543 void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8544 const int *ciphersuites )
kenjiArai 0:5b88d5760320 8545 {
kenjiArai 0:5b88d5760320 8546 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites;
kenjiArai 0:5b88d5760320 8547 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites;
kenjiArai 0:5b88d5760320 8548 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites;
kenjiArai 0:5b88d5760320 8549 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites;
kenjiArai 0:5b88d5760320 8550 }
kenjiArai 0:5b88d5760320 8551
kenjiArai 0:5b88d5760320 8552 void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8553 const int *ciphersuites,
kenjiArai 0:5b88d5760320 8554 int major, int minor )
kenjiArai 0:5b88d5760320 8555 {
kenjiArai 0:5b88d5760320 8556 if( major != MBEDTLS_SSL_MAJOR_VERSION_3 )
kenjiArai 0:5b88d5760320 8557 return;
kenjiArai 0:5b88d5760320 8558
kenjiArai 0:5b88d5760320 8559 if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 8560 return;
kenjiArai 0:5b88d5760320 8561
kenjiArai 0:5b88d5760320 8562 conf->ciphersuite_list[minor] = ciphersuites;
kenjiArai 0:5b88d5760320 8563 }
kenjiArai 0:5b88d5760320 8564
kenjiArai 0:5b88d5760320 8565 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 8566 void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8567 const mbedtls_x509_crt_profile *profile )
kenjiArai 0:5b88d5760320 8568 {
kenjiArai 0:5b88d5760320 8569 conf->cert_profile = profile;
kenjiArai 0:5b88d5760320 8570 }
kenjiArai 0:5b88d5760320 8571
kenjiArai 0:5b88d5760320 8572 /* Append a new keycert entry to a (possibly empty) list */
kenjiArai 0:5b88d5760320 8573 static int ssl_append_key_cert( mbedtls_ssl_key_cert **head,
kenjiArai 0:5b88d5760320 8574 mbedtls_x509_crt *cert,
kenjiArai 0:5b88d5760320 8575 mbedtls_pk_context *key )
kenjiArai 0:5b88d5760320 8576 {
kenjiArai 0:5b88d5760320 8577 mbedtls_ssl_key_cert *new_cert;
kenjiArai 0:5b88d5760320 8578
kenjiArai 0:5b88d5760320 8579 new_cert = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) );
kenjiArai 0:5b88d5760320 8580 if( new_cert == NULL )
kenjiArai 0:5b88d5760320 8581 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 8582
kenjiArai 0:5b88d5760320 8583 new_cert->cert = cert;
kenjiArai 0:5b88d5760320 8584 new_cert->key = key;
kenjiArai 0:5b88d5760320 8585 new_cert->next = NULL;
kenjiArai 0:5b88d5760320 8586
kenjiArai 0:5b88d5760320 8587 /* Update head is the list was null, else add to the end */
kenjiArai 0:5b88d5760320 8588 if( *head == NULL )
kenjiArai 0:5b88d5760320 8589 {
kenjiArai 0:5b88d5760320 8590 *head = new_cert;
kenjiArai 0:5b88d5760320 8591 }
kenjiArai 0:5b88d5760320 8592 else
kenjiArai 0:5b88d5760320 8593 {
kenjiArai 0:5b88d5760320 8594 mbedtls_ssl_key_cert *cur = *head;
kenjiArai 0:5b88d5760320 8595 while( cur->next != NULL )
kenjiArai 0:5b88d5760320 8596 cur = cur->next;
kenjiArai 0:5b88d5760320 8597 cur->next = new_cert;
kenjiArai 0:5b88d5760320 8598 }
kenjiArai 0:5b88d5760320 8599
kenjiArai 0:5b88d5760320 8600 return( 0 );
kenjiArai 0:5b88d5760320 8601 }
kenjiArai 0:5b88d5760320 8602
kenjiArai 0:5b88d5760320 8603 int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8604 mbedtls_x509_crt *own_cert,
kenjiArai 0:5b88d5760320 8605 mbedtls_pk_context *pk_key )
kenjiArai 0:5b88d5760320 8606 {
kenjiArai 0:5b88d5760320 8607 return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) );
kenjiArai 0:5b88d5760320 8608 }
kenjiArai 0:5b88d5760320 8609
kenjiArai 0:5b88d5760320 8610 void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8611 mbedtls_x509_crt *ca_chain,
kenjiArai 0:5b88d5760320 8612 mbedtls_x509_crl *ca_crl )
kenjiArai 0:5b88d5760320 8613 {
kenjiArai 0:5b88d5760320 8614 conf->ca_chain = ca_chain;
kenjiArai 0:5b88d5760320 8615 conf->ca_crl = ca_crl;
kenjiArai 0:5b88d5760320 8616
kenjiArai 0:5b88d5760320 8617 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
kenjiArai 0:5b88d5760320 8618 /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
kenjiArai 0:5b88d5760320 8619 * cannot be used together. */
kenjiArai 0:5b88d5760320 8620 conf->f_ca_cb = NULL;
kenjiArai 0:5b88d5760320 8621 conf->p_ca_cb = NULL;
kenjiArai 0:5b88d5760320 8622 #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
kenjiArai 0:5b88d5760320 8623 }
kenjiArai 0:5b88d5760320 8624
kenjiArai 0:5b88d5760320 8625 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
kenjiArai 0:5b88d5760320 8626 void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8627 mbedtls_x509_crt_ca_cb_t f_ca_cb,
kenjiArai 0:5b88d5760320 8628 void *p_ca_cb )
kenjiArai 0:5b88d5760320 8629 {
kenjiArai 0:5b88d5760320 8630 conf->f_ca_cb = f_ca_cb;
kenjiArai 0:5b88d5760320 8631 conf->p_ca_cb = p_ca_cb;
kenjiArai 0:5b88d5760320 8632
kenjiArai 0:5b88d5760320 8633 /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
kenjiArai 0:5b88d5760320 8634 * cannot be used together. */
kenjiArai 0:5b88d5760320 8635 conf->ca_chain = NULL;
kenjiArai 0:5b88d5760320 8636 conf->ca_crl = NULL;
kenjiArai 0:5b88d5760320 8637 }
kenjiArai 0:5b88d5760320 8638 #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
kenjiArai 0:5b88d5760320 8639 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 8640
kenjiArai 0:5b88d5760320 8641 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
kenjiArai 0:5b88d5760320 8642 int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8643 mbedtls_x509_crt *own_cert,
kenjiArai 0:5b88d5760320 8644 mbedtls_pk_context *pk_key )
kenjiArai 0:5b88d5760320 8645 {
kenjiArai 0:5b88d5760320 8646 return( ssl_append_key_cert( &ssl->handshake->sni_key_cert,
kenjiArai 0:5b88d5760320 8647 own_cert, pk_key ) );
kenjiArai 0:5b88d5760320 8648 }
kenjiArai 0:5b88d5760320 8649
kenjiArai 0:5b88d5760320 8650 void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8651 mbedtls_x509_crt *ca_chain,
kenjiArai 0:5b88d5760320 8652 mbedtls_x509_crl *ca_crl )
kenjiArai 0:5b88d5760320 8653 {
kenjiArai 0:5b88d5760320 8654 ssl->handshake->sni_ca_chain = ca_chain;
kenjiArai 0:5b88d5760320 8655 ssl->handshake->sni_ca_crl = ca_crl;
kenjiArai 0:5b88d5760320 8656 }
kenjiArai 0:5b88d5760320 8657
kenjiArai 0:5b88d5760320 8658 void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8659 int authmode )
kenjiArai 0:5b88d5760320 8660 {
kenjiArai 0:5b88d5760320 8661 ssl->handshake->sni_authmode = authmode;
kenjiArai 0:5b88d5760320 8662 }
kenjiArai 0:5b88d5760320 8663 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
kenjiArai 0:5b88d5760320 8664
kenjiArai 0:5b88d5760320 8665 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 8666 void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8667 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
kenjiArai 0:5b88d5760320 8668 void *p_vrfy )
kenjiArai 0:5b88d5760320 8669 {
kenjiArai 0:5b88d5760320 8670 ssl->f_vrfy = f_vrfy;
kenjiArai 0:5b88d5760320 8671 ssl->p_vrfy = p_vrfy;
kenjiArai 0:5b88d5760320 8672 }
kenjiArai 0:5b88d5760320 8673 #endif
kenjiArai 0:5b88d5760320 8674
kenjiArai 0:5b88d5760320 8675 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
kenjiArai 0:5b88d5760320 8676 /*
kenjiArai 0:5b88d5760320 8677 * Set EC J-PAKE password for current handshake
kenjiArai 0:5b88d5760320 8678 */
kenjiArai 0:5b88d5760320 8679 int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8680 const unsigned char *pw,
kenjiArai 0:5b88d5760320 8681 size_t pw_len )
kenjiArai 0:5b88d5760320 8682 {
kenjiArai 0:5b88d5760320 8683 mbedtls_ecjpake_role role;
kenjiArai 0:5b88d5760320 8684
kenjiArai 0:5b88d5760320 8685 if( ssl->handshake == NULL || ssl->conf == NULL )
kenjiArai 0:5b88d5760320 8686 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8687
kenjiArai 0:5b88d5760320 8688 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 8689 role = MBEDTLS_ECJPAKE_SERVER;
kenjiArai 0:5b88d5760320 8690 else
kenjiArai 0:5b88d5760320 8691 role = MBEDTLS_ECJPAKE_CLIENT;
kenjiArai 0:5b88d5760320 8692
kenjiArai 0:5b88d5760320 8693 return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx,
kenjiArai 0:5b88d5760320 8694 role,
kenjiArai 0:5b88d5760320 8695 MBEDTLS_MD_SHA256,
kenjiArai 0:5b88d5760320 8696 MBEDTLS_ECP_DP_SECP256R1,
kenjiArai 0:5b88d5760320 8697 pw, pw_len ) );
kenjiArai 0:5b88d5760320 8698 }
kenjiArai 0:5b88d5760320 8699 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
kenjiArai 0:5b88d5760320 8700
kenjiArai 0:5b88d5760320 8701 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
kenjiArai 0:5b88d5760320 8702
kenjiArai 0:5b88d5760320 8703 static void ssl_conf_remove_psk( mbedtls_ssl_config *conf )
kenjiArai 0:5b88d5760320 8704 {
kenjiArai 0:5b88d5760320 8705 /* Remove reference to existing PSK, if any. */
kenjiArai 0:5b88d5760320 8706 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 8707 if( conf->psk_opaque != 0 )
kenjiArai 0:5b88d5760320 8708 {
kenjiArai 0:5b88d5760320 8709 /* The maintenance of the PSK key slot is the
kenjiArai 0:5b88d5760320 8710 * user's responsibility. */
kenjiArai 0:5b88d5760320 8711 conf->psk_opaque = 0;
kenjiArai 0:5b88d5760320 8712 }
kenjiArai 0:5b88d5760320 8713 /* This and the following branch should never
kenjiArai 0:5b88d5760320 8714 * be taken simultaenously as we maintain the
kenjiArai 0:5b88d5760320 8715 * invariant that raw and opaque PSKs are never
kenjiArai 0:5b88d5760320 8716 * configured simultaneously. As a safeguard,
kenjiArai 0:5b88d5760320 8717 * though, `else` is omitted here. */
kenjiArai 0:5b88d5760320 8718 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 8719 if( conf->psk != NULL )
kenjiArai 0:5b88d5760320 8720 {
kenjiArai 0:5b88d5760320 8721 mbedtls_platform_zeroize( conf->psk, conf->psk_len );
kenjiArai 0:5b88d5760320 8722
kenjiArai 0:5b88d5760320 8723 mbedtls_free( conf->psk );
kenjiArai 0:5b88d5760320 8724 conf->psk = NULL;
kenjiArai 0:5b88d5760320 8725 conf->psk_len = 0;
kenjiArai 0:5b88d5760320 8726 }
kenjiArai 0:5b88d5760320 8727
kenjiArai 0:5b88d5760320 8728 /* Remove reference to PSK identity, if any. */
kenjiArai 0:5b88d5760320 8729 if( conf->psk_identity != NULL )
kenjiArai 0:5b88d5760320 8730 {
kenjiArai 0:5b88d5760320 8731 mbedtls_free( conf->psk_identity );
kenjiArai 0:5b88d5760320 8732 conf->psk_identity = NULL;
kenjiArai 0:5b88d5760320 8733 conf->psk_identity_len = 0;
kenjiArai 0:5b88d5760320 8734 }
kenjiArai 0:5b88d5760320 8735 }
kenjiArai 0:5b88d5760320 8736
kenjiArai 0:5b88d5760320 8737 /* This function assumes that PSK identity in the SSL config is unset.
kenjiArai 0:5b88d5760320 8738 * It checks that the provided identity is well-formed and attempts
kenjiArai 0:5b88d5760320 8739 * to make a copy of it in the SSL config.
kenjiArai 0:5b88d5760320 8740 * On failure, the PSK identity in the config remains unset. */
kenjiArai 0:5b88d5760320 8741 static int ssl_conf_set_psk_identity( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8742 unsigned char const *psk_identity,
kenjiArai 0:5b88d5760320 8743 size_t psk_identity_len )
kenjiArai 0:5b88d5760320 8744 {
kenjiArai 0:5b88d5760320 8745 /* Identity len will be encoded on two bytes */
kenjiArai 0:5b88d5760320 8746 if( psk_identity == NULL ||
kenjiArai 0:5b88d5760320 8747 ( psk_identity_len >> 16 ) != 0 ||
kenjiArai 0:5b88d5760320 8748 psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
kenjiArai 0:5b88d5760320 8749 {
kenjiArai 0:5b88d5760320 8750 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8751 }
kenjiArai 0:5b88d5760320 8752
kenjiArai 0:5b88d5760320 8753 conf->psk_identity = mbedtls_calloc( 1, psk_identity_len );
kenjiArai 0:5b88d5760320 8754 if( conf->psk_identity == NULL )
kenjiArai 0:5b88d5760320 8755 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 8756
kenjiArai 0:5b88d5760320 8757 conf->psk_identity_len = psk_identity_len;
kenjiArai 0:5b88d5760320 8758 memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len );
kenjiArai 0:5b88d5760320 8759
kenjiArai 0:5b88d5760320 8760 return( 0 );
kenjiArai 0:5b88d5760320 8761 }
kenjiArai 0:5b88d5760320 8762
kenjiArai 0:5b88d5760320 8763 int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8764 const unsigned char *psk, size_t psk_len,
kenjiArai 0:5b88d5760320 8765 const unsigned char *psk_identity, size_t psk_identity_len )
kenjiArai 0:5b88d5760320 8766 {
kenjiArai 0:5b88d5760320 8767 int ret;
kenjiArai 0:5b88d5760320 8768 /* Remove opaque/raw PSK + PSK Identity */
kenjiArai 0:5b88d5760320 8769 ssl_conf_remove_psk( conf );
kenjiArai 0:5b88d5760320 8770
kenjiArai 0:5b88d5760320 8771 /* Check and set raw PSK */
kenjiArai 0:5b88d5760320 8772 if( psk == NULL || psk_len > MBEDTLS_PSK_MAX_LEN )
kenjiArai 0:5b88d5760320 8773 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8774 if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
kenjiArai 0:5b88d5760320 8775 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 8776 conf->psk_len = psk_len;
kenjiArai 0:5b88d5760320 8777 memcpy( conf->psk, psk, conf->psk_len );
kenjiArai 0:5b88d5760320 8778
kenjiArai 0:5b88d5760320 8779 /* Check and set PSK Identity */
kenjiArai 0:5b88d5760320 8780 ret = ssl_conf_set_psk_identity( conf, psk_identity, psk_identity_len );
kenjiArai 0:5b88d5760320 8781 if( ret != 0 )
kenjiArai 0:5b88d5760320 8782 ssl_conf_remove_psk( conf );
kenjiArai 0:5b88d5760320 8783
kenjiArai 0:5b88d5760320 8784 return( ret );
kenjiArai 0:5b88d5760320 8785 }
kenjiArai 0:5b88d5760320 8786
kenjiArai 0:5b88d5760320 8787 static void ssl_remove_psk( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 8788 {
kenjiArai 0:5b88d5760320 8789 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 8790 if( ssl->handshake->psk_opaque != 0 )
kenjiArai 0:5b88d5760320 8791 {
kenjiArai 0:5b88d5760320 8792 ssl->handshake->psk_opaque = 0;
kenjiArai 0:5b88d5760320 8793 }
kenjiArai 0:5b88d5760320 8794 else
kenjiArai 0:5b88d5760320 8795 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 8796 if( ssl->handshake->psk != NULL )
kenjiArai 0:5b88d5760320 8797 {
kenjiArai 0:5b88d5760320 8798 mbedtls_platform_zeroize( ssl->handshake->psk,
kenjiArai 0:5b88d5760320 8799 ssl->handshake->psk_len );
kenjiArai 0:5b88d5760320 8800 mbedtls_free( ssl->handshake->psk );
kenjiArai 0:5b88d5760320 8801 ssl->handshake->psk_len = 0;
kenjiArai 0:5b88d5760320 8802 }
kenjiArai 0:5b88d5760320 8803 }
kenjiArai 0:5b88d5760320 8804
kenjiArai 0:5b88d5760320 8805 int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8806 const unsigned char *psk, size_t psk_len )
kenjiArai 0:5b88d5760320 8807 {
kenjiArai 0:5b88d5760320 8808 if( psk == NULL || ssl->handshake == NULL )
kenjiArai 0:5b88d5760320 8809 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8810
kenjiArai 0:5b88d5760320 8811 if( psk_len > MBEDTLS_PSK_MAX_LEN )
kenjiArai 0:5b88d5760320 8812 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8813
kenjiArai 0:5b88d5760320 8814 ssl_remove_psk( ssl );
kenjiArai 0:5b88d5760320 8815
kenjiArai 0:5b88d5760320 8816 if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
kenjiArai 0:5b88d5760320 8817 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 8818
kenjiArai 0:5b88d5760320 8819 ssl->handshake->psk_len = psk_len;
kenjiArai 0:5b88d5760320 8820 memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len );
kenjiArai 0:5b88d5760320 8821
kenjiArai 0:5b88d5760320 8822 return( 0 );
kenjiArai 0:5b88d5760320 8823 }
kenjiArai 0:5b88d5760320 8824
kenjiArai 0:5b88d5760320 8825 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 8826 int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8827 psa_key_handle_t psk_slot,
kenjiArai 0:5b88d5760320 8828 const unsigned char *psk_identity,
kenjiArai 0:5b88d5760320 8829 size_t psk_identity_len )
kenjiArai 0:5b88d5760320 8830 {
kenjiArai 0:5b88d5760320 8831 int ret;
kenjiArai 0:5b88d5760320 8832 /* Clear opaque/raw PSK + PSK Identity, if present. */
kenjiArai 0:5b88d5760320 8833 ssl_conf_remove_psk( conf );
kenjiArai 0:5b88d5760320 8834
kenjiArai 0:5b88d5760320 8835 /* Check and set opaque PSK */
kenjiArai 0:5b88d5760320 8836 if( psk_slot == 0 )
kenjiArai 0:5b88d5760320 8837 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8838 conf->psk_opaque = psk_slot;
kenjiArai 0:5b88d5760320 8839
kenjiArai 0:5b88d5760320 8840 /* Check and set PSK Identity */
kenjiArai 0:5b88d5760320 8841 ret = ssl_conf_set_psk_identity( conf, psk_identity,
kenjiArai 0:5b88d5760320 8842 psk_identity_len );
kenjiArai 0:5b88d5760320 8843 if( ret != 0 )
kenjiArai 0:5b88d5760320 8844 ssl_conf_remove_psk( conf );
kenjiArai 0:5b88d5760320 8845
kenjiArai 0:5b88d5760320 8846 return( ret );
kenjiArai 0:5b88d5760320 8847 }
kenjiArai 0:5b88d5760320 8848
kenjiArai 0:5b88d5760320 8849 int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 8850 psa_key_handle_t psk_slot )
kenjiArai 0:5b88d5760320 8851 {
kenjiArai 0:5b88d5760320 8852 if( psk_slot == 0 || ssl->handshake == NULL )
kenjiArai 0:5b88d5760320 8853 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8854
kenjiArai 0:5b88d5760320 8855 ssl_remove_psk( ssl );
kenjiArai 0:5b88d5760320 8856 ssl->handshake->psk_opaque = psk_slot;
kenjiArai 0:5b88d5760320 8857 return( 0 );
kenjiArai 0:5b88d5760320 8858 }
kenjiArai 0:5b88d5760320 8859 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 8860
kenjiArai 0:5b88d5760320 8861 void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8862 int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
kenjiArai 0:5b88d5760320 8863 size_t),
kenjiArai 0:5b88d5760320 8864 void *p_psk )
kenjiArai 0:5b88d5760320 8865 {
kenjiArai 0:5b88d5760320 8866 conf->f_psk = f_psk;
kenjiArai 0:5b88d5760320 8867 conf->p_psk = p_psk;
kenjiArai 0:5b88d5760320 8868 }
kenjiArai 0:5b88d5760320 8869 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
kenjiArai 0:5b88d5760320 8870
kenjiArai 0:5b88d5760320 8871 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 8872
kenjiArai 0:5b88d5760320 8873 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
kenjiArai 0:5b88d5760320 8874 int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G )
kenjiArai 0:5b88d5760320 8875 {
kenjiArai 0:5b88d5760320 8876 int ret;
kenjiArai 0:5b88d5760320 8877
kenjiArai 0:5b88d5760320 8878 if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 ||
kenjiArai 0:5b88d5760320 8879 ( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 )
kenjiArai 0:5b88d5760320 8880 {
kenjiArai 0:5b88d5760320 8881 mbedtls_mpi_free( &conf->dhm_P );
kenjiArai 0:5b88d5760320 8882 mbedtls_mpi_free( &conf->dhm_G );
kenjiArai 0:5b88d5760320 8883 return( ret );
kenjiArai 0:5b88d5760320 8884 }
kenjiArai 0:5b88d5760320 8885
kenjiArai 0:5b88d5760320 8886 return( 0 );
kenjiArai 0:5b88d5760320 8887 }
kenjiArai 0:5b88d5760320 8888 #endif /* MBEDTLS_DEPRECATED_REMOVED */
kenjiArai 0:5b88d5760320 8889
kenjiArai 0:5b88d5760320 8890 int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8891 const unsigned char *dhm_P, size_t P_len,
kenjiArai 0:5b88d5760320 8892 const unsigned char *dhm_G, size_t G_len )
kenjiArai 0:5b88d5760320 8893 {
kenjiArai 0:5b88d5760320 8894 int ret;
kenjiArai 0:5b88d5760320 8895
kenjiArai 0:5b88d5760320 8896 if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 ||
kenjiArai 0:5b88d5760320 8897 ( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 )
kenjiArai 0:5b88d5760320 8898 {
kenjiArai 0:5b88d5760320 8899 mbedtls_mpi_free( &conf->dhm_P );
kenjiArai 0:5b88d5760320 8900 mbedtls_mpi_free( &conf->dhm_G );
kenjiArai 0:5b88d5760320 8901 return( ret );
kenjiArai 0:5b88d5760320 8902 }
kenjiArai 0:5b88d5760320 8903
kenjiArai 0:5b88d5760320 8904 return( 0 );
kenjiArai 0:5b88d5760320 8905 }
kenjiArai 0:5b88d5760320 8906
kenjiArai 0:5b88d5760320 8907 int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx )
kenjiArai 0:5b88d5760320 8908 {
kenjiArai 0:5b88d5760320 8909 int ret;
kenjiArai 0:5b88d5760320 8910
kenjiArai 0:5b88d5760320 8911 if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
kenjiArai 0:5b88d5760320 8912 ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
kenjiArai 0:5b88d5760320 8913 {
kenjiArai 0:5b88d5760320 8914 mbedtls_mpi_free( &conf->dhm_P );
kenjiArai 0:5b88d5760320 8915 mbedtls_mpi_free( &conf->dhm_G );
kenjiArai 0:5b88d5760320 8916 return( ret );
kenjiArai 0:5b88d5760320 8917 }
kenjiArai 0:5b88d5760320 8918
kenjiArai 0:5b88d5760320 8919 return( 0 );
kenjiArai 0:5b88d5760320 8920 }
kenjiArai 0:5b88d5760320 8921 #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 8922
kenjiArai 0:5b88d5760320 8923 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 8924 /*
kenjiArai 0:5b88d5760320 8925 * Set the minimum length for Diffie-Hellman parameters
kenjiArai 0:5b88d5760320 8926 */
kenjiArai 0:5b88d5760320 8927 void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8928 unsigned int bitlen )
kenjiArai 0:5b88d5760320 8929 {
kenjiArai 0:5b88d5760320 8930 conf->dhm_min_bitlen = bitlen;
kenjiArai 0:5b88d5760320 8931 }
kenjiArai 0:5b88d5760320 8932 #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 8933
kenjiArai 0:5b88d5760320 8934 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 8935 /*
kenjiArai 0:5b88d5760320 8936 * Set allowed/preferred hashes for handshake signatures
kenjiArai 0:5b88d5760320 8937 */
kenjiArai 0:5b88d5760320 8938 void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8939 const int *hashes )
kenjiArai 0:5b88d5760320 8940 {
kenjiArai 0:5b88d5760320 8941 conf->sig_hashes = hashes;
kenjiArai 0:5b88d5760320 8942 }
kenjiArai 0:5b88d5760320 8943 #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
kenjiArai 0:5b88d5760320 8944
kenjiArai 0:5b88d5760320 8945 #if defined(MBEDTLS_ECP_C)
kenjiArai 0:5b88d5760320 8946 /*
kenjiArai 0:5b88d5760320 8947 * Set the allowed elliptic curves
kenjiArai 0:5b88d5760320 8948 */
kenjiArai 0:5b88d5760320 8949 void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 8950 const mbedtls_ecp_group_id *curve_list )
kenjiArai 0:5b88d5760320 8951 {
kenjiArai 0:5b88d5760320 8952 conf->curve_list = curve_list;
kenjiArai 0:5b88d5760320 8953 }
kenjiArai 0:5b88d5760320 8954 #endif /* MBEDTLS_ECP_C */
kenjiArai 0:5b88d5760320 8955
kenjiArai 0:5b88d5760320 8956 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 8957 int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname )
kenjiArai 0:5b88d5760320 8958 {
kenjiArai 0:5b88d5760320 8959 /* Initialize to suppress unnecessary compiler warning */
kenjiArai 0:5b88d5760320 8960 size_t hostname_len = 0;
kenjiArai 0:5b88d5760320 8961
kenjiArai 0:5b88d5760320 8962 /* Check if new hostname is valid before
kenjiArai 0:5b88d5760320 8963 * making any change to current one */
kenjiArai 0:5b88d5760320 8964 if( hostname != NULL )
kenjiArai 0:5b88d5760320 8965 {
kenjiArai 0:5b88d5760320 8966 hostname_len = strlen( hostname );
kenjiArai 0:5b88d5760320 8967
kenjiArai 0:5b88d5760320 8968 if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN )
kenjiArai 0:5b88d5760320 8969 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 8970 }
kenjiArai 0:5b88d5760320 8971
kenjiArai 0:5b88d5760320 8972 /* Now it's clear that we will overwrite the old hostname,
kenjiArai 0:5b88d5760320 8973 * so we can free it safely */
kenjiArai 0:5b88d5760320 8974
kenjiArai 0:5b88d5760320 8975 if( ssl->hostname != NULL )
kenjiArai 0:5b88d5760320 8976 {
kenjiArai 0:5b88d5760320 8977 mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) );
kenjiArai 0:5b88d5760320 8978 mbedtls_free( ssl->hostname );
kenjiArai 0:5b88d5760320 8979 }
kenjiArai 0:5b88d5760320 8980
kenjiArai 0:5b88d5760320 8981 /* Passing NULL as hostname shall clear the old one */
kenjiArai 0:5b88d5760320 8982
kenjiArai 0:5b88d5760320 8983 if( hostname == NULL )
kenjiArai 0:5b88d5760320 8984 {
kenjiArai 0:5b88d5760320 8985 ssl->hostname = NULL;
kenjiArai 0:5b88d5760320 8986 }
kenjiArai 0:5b88d5760320 8987 else
kenjiArai 0:5b88d5760320 8988 {
kenjiArai 0:5b88d5760320 8989 ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 );
kenjiArai 0:5b88d5760320 8990 if( ssl->hostname == NULL )
kenjiArai 0:5b88d5760320 8991 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 8992
kenjiArai 0:5b88d5760320 8993 memcpy( ssl->hostname, hostname, hostname_len );
kenjiArai 0:5b88d5760320 8994
kenjiArai 0:5b88d5760320 8995 ssl->hostname[hostname_len] = '\0';
kenjiArai 0:5b88d5760320 8996 }
kenjiArai 0:5b88d5760320 8997
kenjiArai 0:5b88d5760320 8998 return( 0 );
kenjiArai 0:5b88d5760320 8999 }
kenjiArai 0:5b88d5760320 9000 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 9001
kenjiArai 0:5b88d5760320 9002 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
kenjiArai 0:5b88d5760320 9003 void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 9004 int (*f_sni)(void *, mbedtls_ssl_context *,
kenjiArai 0:5b88d5760320 9005 const unsigned char *, size_t),
kenjiArai 0:5b88d5760320 9006 void *p_sni )
kenjiArai 0:5b88d5760320 9007 {
kenjiArai 0:5b88d5760320 9008 conf->f_sni = f_sni;
kenjiArai 0:5b88d5760320 9009 conf->p_sni = p_sni;
kenjiArai 0:5b88d5760320 9010 }
kenjiArai 0:5b88d5760320 9011 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
kenjiArai 0:5b88d5760320 9012
kenjiArai 0:5b88d5760320 9013 #if defined(MBEDTLS_SSL_ALPN)
kenjiArai 0:5b88d5760320 9014 int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos )
kenjiArai 0:5b88d5760320 9015 {
kenjiArai 0:5b88d5760320 9016 size_t cur_len, tot_len;
kenjiArai 0:5b88d5760320 9017 const char **p;
kenjiArai 0:5b88d5760320 9018
kenjiArai 0:5b88d5760320 9019 /*
kenjiArai 0:5b88d5760320 9020 * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings
kenjiArai 0:5b88d5760320 9021 * MUST NOT be truncated."
kenjiArai 0:5b88d5760320 9022 * We check lengths now rather than later.
kenjiArai 0:5b88d5760320 9023 */
kenjiArai 0:5b88d5760320 9024 tot_len = 0;
kenjiArai 0:5b88d5760320 9025 for( p = protos; *p != NULL; p++ )
kenjiArai 0:5b88d5760320 9026 {
kenjiArai 0:5b88d5760320 9027 cur_len = strlen( *p );
kenjiArai 0:5b88d5760320 9028 tot_len += cur_len;
kenjiArai 0:5b88d5760320 9029
kenjiArai 0:5b88d5760320 9030 if( cur_len == 0 || cur_len > 255 || tot_len > 65535 )
kenjiArai 0:5b88d5760320 9031 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9032 }
kenjiArai 0:5b88d5760320 9033
kenjiArai 0:5b88d5760320 9034 conf->alpn_list = protos;
kenjiArai 0:5b88d5760320 9035
kenjiArai 0:5b88d5760320 9036 return( 0 );
kenjiArai 0:5b88d5760320 9037 }
kenjiArai 0:5b88d5760320 9038
kenjiArai 0:5b88d5760320 9039 const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9040 {
kenjiArai 0:5b88d5760320 9041 return( ssl->alpn_chosen );
kenjiArai 0:5b88d5760320 9042 }
kenjiArai 0:5b88d5760320 9043 #endif /* MBEDTLS_SSL_ALPN */
kenjiArai 0:5b88d5760320 9044
kenjiArai 0:5b88d5760320 9045 void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
kenjiArai 0:5b88d5760320 9046 {
kenjiArai 0:5b88d5760320 9047 conf->max_major_ver = major;
kenjiArai 0:5b88d5760320 9048 conf->max_minor_ver = minor;
kenjiArai 0:5b88d5760320 9049 }
kenjiArai 0:5b88d5760320 9050
kenjiArai 0:5b88d5760320 9051 void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor )
kenjiArai 0:5b88d5760320 9052 {
kenjiArai 0:5b88d5760320 9053 conf->min_major_ver = major;
kenjiArai 0:5b88d5760320 9054 conf->min_minor_ver = minor;
kenjiArai 0:5b88d5760320 9055 }
kenjiArai 0:5b88d5760320 9056
kenjiArai 0:5b88d5760320 9057 #if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 9058 void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback )
kenjiArai 0:5b88d5760320 9059 {
kenjiArai 0:5b88d5760320 9060 conf->fallback = fallback;
kenjiArai 0:5b88d5760320 9061 }
kenjiArai 0:5b88d5760320 9062 #endif
kenjiArai 0:5b88d5760320 9063
kenjiArai 0:5b88d5760320 9064 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 9065 void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 9066 char cert_req_ca_list )
kenjiArai 0:5b88d5760320 9067 {
kenjiArai 0:5b88d5760320 9068 conf->cert_req_ca_list = cert_req_ca_list;
kenjiArai 0:5b88d5760320 9069 }
kenjiArai 0:5b88d5760320 9070 #endif
kenjiArai 0:5b88d5760320 9071
kenjiArai 0:5b88d5760320 9072 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
kenjiArai 0:5b88d5760320 9073 void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm )
kenjiArai 0:5b88d5760320 9074 {
kenjiArai 0:5b88d5760320 9075 conf->encrypt_then_mac = etm;
kenjiArai 0:5b88d5760320 9076 }
kenjiArai 0:5b88d5760320 9077 #endif
kenjiArai 0:5b88d5760320 9078
kenjiArai 0:5b88d5760320 9079 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
kenjiArai 0:5b88d5760320 9080 void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems )
kenjiArai 0:5b88d5760320 9081 {
kenjiArai 0:5b88d5760320 9082 conf->extended_ms = ems;
kenjiArai 0:5b88d5760320 9083 }
kenjiArai 0:5b88d5760320 9084 #endif
kenjiArai 0:5b88d5760320 9085
kenjiArai 0:5b88d5760320 9086 #if defined(MBEDTLS_ARC4_C)
kenjiArai 0:5b88d5760320 9087 void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 )
kenjiArai 0:5b88d5760320 9088 {
kenjiArai 0:5b88d5760320 9089 conf->arc4_disabled = arc4;
kenjiArai 0:5b88d5760320 9090 }
kenjiArai 0:5b88d5760320 9091 #endif
kenjiArai 0:5b88d5760320 9092
kenjiArai 0:5b88d5760320 9093 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
kenjiArai 0:5b88d5760320 9094 int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code )
kenjiArai 0:5b88d5760320 9095 {
kenjiArai 0:5b88d5760320 9096 if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ||
kenjiArai 0:5b88d5760320 9097 ssl_mfl_code_to_length( mfl_code ) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN )
kenjiArai 0:5b88d5760320 9098 {
kenjiArai 0:5b88d5760320 9099 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9100 }
kenjiArai 0:5b88d5760320 9101
kenjiArai 0:5b88d5760320 9102 conf->mfl_code = mfl_code;
kenjiArai 0:5b88d5760320 9103
kenjiArai 0:5b88d5760320 9104 return( 0 );
kenjiArai 0:5b88d5760320 9105 }
kenjiArai 0:5b88d5760320 9106 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
kenjiArai 0:5b88d5760320 9107
kenjiArai 0:5b88d5760320 9108 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
kenjiArai 0:5b88d5760320 9109 void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate )
kenjiArai 0:5b88d5760320 9110 {
kenjiArai 0:5b88d5760320 9111 conf->trunc_hmac = truncate;
kenjiArai 0:5b88d5760320 9112 }
kenjiArai 0:5b88d5760320 9113 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
kenjiArai 0:5b88d5760320 9114
kenjiArai 0:5b88d5760320 9115 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
kenjiArai 0:5b88d5760320 9116 void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split )
kenjiArai 0:5b88d5760320 9117 {
kenjiArai 0:5b88d5760320 9118 conf->cbc_record_splitting = split;
kenjiArai 0:5b88d5760320 9119 }
kenjiArai 0:5b88d5760320 9120 #endif
kenjiArai 0:5b88d5760320 9121
kenjiArai 0:5b88d5760320 9122 void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy )
kenjiArai 0:5b88d5760320 9123 {
kenjiArai 0:5b88d5760320 9124 conf->allow_legacy_renegotiation = allow_legacy;
kenjiArai 0:5b88d5760320 9125 }
kenjiArai 0:5b88d5760320 9126
kenjiArai 0:5b88d5760320 9127 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 9128 void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation )
kenjiArai 0:5b88d5760320 9129 {
kenjiArai 0:5b88d5760320 9130 conf->disable_renegotiation = renegotiation;
kenjiArai 0:5b88d5760320 9131 }
kenjiArai 0:5b88d5760320 9132
kenjiArai 0:5b88d5760320 9133 void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records )
kenjiArai 0:5b88d5760320 9134 {
kenjiArai 0:5b88d5760320 9135 conf->renego_max_records = max_records;
kenjiArai 0:5b88d5760320 9136 }
kenjiArai 0:5b88d5760320 9137
kenjiArai 0:5b88d5760320 9138 void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 9139 const unsigned char period[8] )
kenjiArai 0:5b88d5760320 9140 {
kenjiArai 0:5b88d5760320 9141 memcpy( conf->renego_period, period, 8 );
kenjiArai 0:5b88d5760320 9142 }
kenjiArai 0:5b88d5760320 9143 #endif /* MBEDTLS_SSL_RENEGOTIATION */
kenjiArai 0:5b88d5760320 9144
kenjiArai 0:5b88d5760320 9145 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
kenjiArai 0:5b88d5760320 9146 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 9147 void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets )
kenjiArai 0:5b88d5760320 9148 {
kenjiArai 0:5b88d5760320 9149 conf->session_tickets = use_tickets;
kenjiArai 0:5b88d5760320 9150 }
kenjiArai 0:5b88d5760320 9151 #endif
kenjiArai 0:5b88d5760320 9152
kenjiArai 0:5b88d5760320 9153 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 9154 void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 9155 mbedtls_ssl_ticket_write_t *f_ticket_write,
kenjiArai 0:5b88d5760320 9156 mbedtls_ssl_ticket_parse_t *f_ticket_parse,
kenjiArai 0:5b88d5760320 9157 void *p_ticket )
kenjiArai 0:5b88d5760320 9158 {
kenjiArai 0:5b88d5760320 9159 conf->f_ticket_write = f_ticket_write;
kenjiArai 0:5b88d5760320 9160 conf->f_ticket_parse = f_ticket_parse;
kenjiArai 0:5b88d5760320 9161 conf->p_ticket = p_ticket;
kenjiArai 0:5b88d5760320 9162 }
kenjiArai 0:5b88d5760320 9163 #endif
kenjiArai 0:5b88d5760320 9164 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
kenjiArai 0:5b88d5760320 9165
kenjiArai 0:5b88d5760320 9166 #if defined(MBEDTLS_SSL_EXPORT_KEYS)
kenjiArai 0:5b88d5760320 9167 void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 9168 mbedtls_ssl_export_keys_t *f_export_keys,
kenjiArai 0:5b88d5760320 9169 void *p_export_keys )
kenjiArai 0:5b88d5760320 9170 {
kenjiArai 0:5b88d5760320 9171 conf->f_export_keys = f_export_keys;
kenjiArai 0:5b88d5760320 9172 conf->p_export_keys = p_export_keys;
kenjiArai 0:5b88d5760320 9173 }
kenjiArai 0:5b88d5760320 9174
kenjiArai 0:5b88d5760320 9175 void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 9176 mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
kenjiArai 0:5b88d5760320 9177 void *p_export_keys )
kenjiArai 0:5b88d5760320 9178 {
kenjiArai 0:5b88d5760320 9179 conf->f_export_keys_ext = f_export_keys_ext;
kenjiArai 0:5b88d5760320 9180 conf->p_export_keys = p_export_keys;
kenjiArai 0:5b88d5760320 9181 }
kenjiArai 0:5b88d5760320 9182 #endif
kenjiArai 0:5b88d5760320 9183
kenjiArai 0:5b88d5760320 9184 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
kenjiArai 0:5b88d5760320 9185 void mbedtls_ssl_conf_async_private_cb(
kenjiArai 0:5b88d5760320 9186 mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 9187 mbedtls_ssl_async_sign_t *f_async_sign,
kenjiArai 0:5b88d5760320 9188 mbedtls_ssl_async_decrypt_t *f_async_decrypt,
kenjiArai 0:5b88d5760320 9189 mbedtls_ssl_async_resume_t *f_async_resume,
kenjiArai 0:5b88d5760320 9190 mbedtls_ssl_async_cancel_t *f_async_cancel,
kenjiArai 0:5b88d5760320 9191 void *async_config_data )
kenjiArai 0:5b88d5760320 9192 {
kenjiArai 0:5b88d5760320 9193 conf->f_async_sign_start = f_async_sign;
kenjiArai 0:5b88d5760320 9194 conf->f_async_decrypt_start = f_async_decrypt;
kenjiArai 0:5b88d5760320 9195 conf->f_async_resume = f_async_resume;
kenjiArai 0:5b88d5760320 9196 conf->f_async_cancel = f_async_cancel;
kenjiArai 0:5b88d5760320 9197 conf->p_async_config_data = async_config_data;
kenjiArai 0:5b88d5760320 9198 }
kenjiArai 0:5b88d5760320 9199
kenjiArai 0:5b88d5760320 9200 void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf )
kenjiArai 0:5b88d5760320 9201 {
kenjiArai 0:5b88d5760320 9202 return( conf->p_async_config_data );
kenjiArai 0:5b88d5760320 9203 }
kenjiArai 0:5b88d5760320 9204
kenjiArai 0:5b88d5760320 9205 void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9206 {
kenjiArai 0:5b88d5760320 9207 if( ssl->handshake == NULL )
kenjiArai 0:5b88d5760320 9208 return( NULL );
kenjiArai 0:5b88d5760320 9209 else
kenjiArai 0:5b88d5760320 9210 return( ssl->handshake->user_async_ctx );
kenjiArai 0:5b88d5760320 9211 }
kenjiArai 0:5b88d5760320 9212
kenjiArai 0:5b88d5760320 9213 void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 9214 void *ctx )
kenjiArai 0:5b88d5760320 9215 {
kenjiArai 0:5b88d5760320 9216 if( ssl->handshake != NULL )
kenjiArai 0:5b88d5760320 9217 ssl->handshake->user_async_ctx = ctx;
kenjiArai 0:5b88d5760320 9218 }
kenjiArai 0:5b88d5760320 9219 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
kenjiArai 0:5b88d5760320 9220
kenjiArai 0:5b88d5760320 9221 /*
kenjiArai 0:5b88d5760320 9222 * SSL get accessors
kenjiArai 0:5b88d5760320 9223 */
kenjiArai 0:5b88d5760320 9224 size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9225 {
kenjiArai 0:5b88d5760320 9226 return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
kenjiArai 0:5b88d5760320 9227 }
kenjiArai 0:5b88d5760320 9228
kenjiArai 0:5b88d5760320 9229 int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9230 {
kenjiArai 0:5b88d5760320 9231 /*
kenjiArai 0:5b88d5760320 9232 * Case A: We're currently holding back
kenjiArai 0:5b88d5760320 9233 * a message for further processing.
kenjiArai 0:5b88d5760320 9234 */
kenjiArai 0:5b88d5760320 9235
kenjiArai 0:5b88d5760320 9236 if( ssl->keep_current_message == 1 )
kenjiArai 0:5b88d5760320 9237 {
kenjiArai 0:5b88d5760320 9238 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) );
kenjiArai 0:5b88d5760320 9239 return( 1 );
kenjiArai 0:5b88d5760320 9240 }
kenjiArai 0:5b88d5760320 9241
kenjiArai 0:5b88d5760320 9242 /*
kenjiArai 0:5b88d5760320 9243 * Case B: Further records are pending in the current datagram.
kenjiArai 0:5b88d5760320 9244 */
kenjiArai 0:5b88d5760320 9245
kenjiArai 0:5b88d5760320 9246 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9247 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 9248 ssl->in_left > ssl->next_record_offset )
kenjiArai 0:5b88d5760320 9249 {
kenjiArai 0:5b88d5760320 9250 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
kenjiArai 0:5b88d5760320 9251 return( 1 );
kenjiArai 0:5b88d5760320 9252 }
kenjiArai 0:5b88d5760320 9253 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 9254
kenjiArai 0:5b88d5760320 9255 /*
kenjiArai 0:5b88d5760320 9256 * Case C: A handshake message is being processed.
kenjiArai 0:5b88d5760320 9257 */
kenjiArai 0:5b88d5760320 9258
kenjiArai 0:5b88d5760320 9259 if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
kenjiArai 0:5b88d5760320 9260 {
kenjiArai 0:5b88d5760320 9261 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) );
kenjiArai 0:5b88d5760320 9262 return( 1 );
kenjiArai 0:5b88d5760320 9263 }
kenjiArai 0:5b88d5760320 9264
kenjiArai 0:5b88d5760320 9265 /*
kenjiArai 0:5b88d5760320 9266 * Case D: An application data message is being processed
kenjiArai 0:5b88d5760320 9267 */
kenjiArai 0:5b88d5760320 9268 if( ssl->in_offt != NULL )
kenjiArai 0:5b88d5760320 9269 {
kenjiArai 0:5b88d5760320 9270 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) );
kenjiArai 0:5b88d5760320 9271 return( 1 );
kenjiArai 0:5b88d5760320 9272 }
kenjiArai 0:5b88d5760320 9273
kenjiArai 0:5b88d5760320 9274 /*
kenjiArai 0:5b88d5760320 9275 * In all other cases, the rest of the message can be dropped.
kenjiArai 0:5b88d5760320 9276 * As in ssl_get_next_record, this needs to be adapted if
kenjiArai 0:5b88d5760320 9277 * we implement support for multiple alerts in single records.
kenjiArai 0:5b88d5760320 9278 */
kenjiArai 0:5b88d5760320 9279
kenjiArai 0:5b88d5760320 9280 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
kenjiArai 0:5b88d5760320 9281 return( 0 );
kenjiArai 0:5b88d5760320 9282 }
kenjiArai 0:5b88d5760320 9283
kenjiArai 0:5b88d5760320 9284 uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9285 {
kenjiArai 0:5b88d5760320 9286 if( ssl->session != NULL )
kenjiArai 0:5b88d5760320 9287 return( ssl->session->verify_result );
kenjiArai 0:5b88d5760320 9288
kenjiArai 0:5b88d5760320 9289 if( ssl->session_negotiate != NULL )
kenjiArai 0:5b88d5760320 9290 return( ssl->session_negotiate->verify_result );
kenjiArai 0:5b88d5760320 9291
kenjiArai 0:5b88d5760320 9292 return( 0xFFFFFFFF );
kenjiArai 0:5b88d5760320 9293 }
kenjiArai 0:5b88d5760320 9294
kenjiArai 0:5b88d5760320 9295 const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9296 {
kenjiArai 0:5b88d5760320 9297 if( ssl == NULL || ssl->session == NULL )
kenjiArai 0:5b88d5760320 9298 return( NULL );
kenjiArai 0:5b88d5760320 9299
kenjiArai 0:5b88d5760320 9300 return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite );
kenjiArai 0:5b88d5760320 9301 }
kenjiArai 0:5b88d5760320 9302
kenjiArai 0:5b88d5760320 9303 const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9304 {
kenjiArai 0:5b88d5760320 9305 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9306 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 9307 {
kenjiArai 0:5b88d5760320 9308 switch( ssl->minor_ver )
kenjiArai 0:5b88d5760320 9309 {
kenjiArai 0:5b88d5760320 9310 case MBEDTLS_SSL_MINOR_VERSION_2:
kenjiArai 0:5b88d5760320 9311 return( "DTLSv1.0" );
kenjiArai 0:5b88d5760320 9312
kenjiArai 0:5b88d5760320 9313 case MBEDTLS_SSL_MINOR_VERSION_3:
kenjiArai 0:5b88d5760320 9314 return( "DTLSv1.2" );
kenjiArai 0:5b88d5760320 9315
kenjiArai 0:5b88d5760320 9316 default:
kenjiArai 0:5b88d5760320 9317 return( "unknown (DTLS)" );
kenjiArai 0:5b88d5760320 9318 }
kenjiArai 0:5b88d5760320 9319 }
kenjiArai 0:5b88d5760320 9320 #endif
kenjiArai 0:5b88d5760320 9321
kenjiArai 0:5b88d5760320 9322 switch( ssl->minor_ver )
kenjiArai 0:5b88d5760320 9323 {
kenjiArai 0:5b88d5760320 9324 case MBEDTLS_SSL_MINOR_VERSION_0:
kenjiArai 0:5b88d5760320 9325 return( "SSLv3.0" );
kenjiArai 0:5b88d5760320 9326
kenjiArai 0:5b88d5760320 9327 case MBEDTLS_SSL_MINOR_VERSION_1:
kenjiArai 0:5b88d5760320 9328 return( "TLSv1.0" );
kenjiArai 0:5b88d5760320 9329
kenjiArai 0:5b88d5760320 9330 case MBEDTLS_SSL_MINOR_VERSION_2:
kenjiArai 0:5b88d5760320 9331 return( "TLSv1.1" );
kenjiArai 0:5b88d5760320 9332
kenjiArai 0:5b88d5760320 9333 case MBEDTLS_SSL_MINOR_VERSION_3:
kenjiArai 0:5b88d5760320 9334 return( "TLSv1.2" );
kenjiArai 0:5b88d5760320 9335
kenjiArai 0:5b88d5760320 9336 default:
kenjiArai 0:5b88d5760320 9337 return( "unknown" );
kenjiArai 0:5b88d5760320 9338 }
kenjiArai 0:5b88d5760320 9339 }
kenjiArai 0:5b88d5760320 9340
kenjiArai 0:5b88d5760320 9341 int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9342 {
kenjiArai 0:5b88d5760320 9343 size_t transform_expansion = 0;
kenjiArai 0:5b88d5760320 9344 const mbedtls_ssl_transform *transform = ssl->transform_out;
kenjiArai 0:5b88d5760320 9345 unsigned block_size;
kenjiArai 0:5b88d5760320 9346
kenjiArai 0:5b88d5760320 9347 size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl );
kenjiArai 0:5b88d5760320 9348
kenjiArai 0:5b88d5760320 9349 if( transform == NULL )
kenjiArai 0:5b88d5760320 9350 return( (int) out_hdr_len );
kenjiArai 0:5b88d5760320 9351
kenjiArai 0:5b88d5760320 9352 #if defined(MBEDTLS_ZLIB_SUPPORT)
kenjiArai 0:5b88d5760320 9353 if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
kenjiArai 0:5b88d5760320 9354 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
kenjiArai 0:5b88d5760320 9355 #endif
kenjiArai 0:5b88d5760320 9356
kenjiArai 0:5b88d5760320 9357 switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
kenjiArai 0:5b88d5760320 9358 {
kenjiArai 0:5b88d5760320 9359 case MBEDTLS_MODE_GCM:
kenjiArai 0:5b88d5760320 9360 case MBEDTLS_MODE_CCM:
kenjiArai 0:5b88d5760320 9361 case MBEDTLS_MODE_CHACHAPOLY:
kenjiArai 0:5b88d5760320 9362 case MBEDTLS_MODE_STREAM:
kenjiArai 0:5b88d5760320 9363 transform_expansion = transform->minlen;
kenjiArai 0:5b88d5760320 9364 break;
kenjiArai 0:5b88d5760320 9365
kenjiArai 0:5b88d5760320 9366 case MBEDTLS_MODE_CBC:
kenjiArai 0:5b88d5760320 9367
kenjiArai 0:5b88d5760320 9368 block_size = mbedtls_cipher_get_block_size(
kenjiArai 0:5b88d5760320 9369 &transform->cipher_ctx_enc );
kenjiArai 0:5b88d5760320 9370
kenjiArai 0:5b88d5760320 9371 /* Expansion due to the addition of the MAC. */
kenjiArai 0:5b88d5760320 9372 transform_expansion += transform->maclen;
kenjiArai 0:5b88d5760320 9373
kenjiArai 0:5b88d5760320 9374 /* Expansion due to the addition of CBC padding;
kenjiArai 0:5b88d5760320 9375 * Theoretically up to 256 bytes, but we never use
kenjiArai 0:5b88d5760320 9376 * more than the block size of the underlying cipher. */
kenjiArai 0:5b88d5760320 9377 transform_expansion += block_size;
kenjiArai 0:5b88d5760320 9378
kenjiArai 0:5b88d5760320 9379 /* For TLS 1.1 or higher, an explicit IV is added
kenjiArai 0:5b88d5760320 9380 * after the record header. */
kenjiArai 0:5b88d5760320 9381 #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 9382 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
kenjiArai 0:5b88d5760320 9383 transform_expansion += block_size;
kenjiArai 0:5b88d5760320 9384 #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 9385
kenjiArai 0:5b88d5760320 9386 break;
kenjiArai 0:5b88d5760320 9387
kenjiArai 0:5b88d5760320 9388 default:
kenjiArai 0:5b88d5760320 9389 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 9390 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 9391 }
kenjiArai 0:5b88d5760320 9392
kenjiArai 0:5b88d5760320 9393 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
kenjiArai 0:5b88d5760320 9394 if( transform->out_cid_len != 0 )
kenjiArai 0:5b88d5760320 9395 transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
kenjiArai 0:5b88d5760320 9396 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
kenjiArai 0:5b88d5760320 9397
kenjiArai 0:5b88d5760320 9398 return( (int)( out_hdr_len + transform_expansion ) );
kenjiArai 0:5b88d5760320 9399 }
kenjiArai 0:5b88d5760320 9400
kenjiArai 0:5b88d5760320 9401 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
kenjiArai 0:5b88d5760320 9402 size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9403 {
kenjiArai 0:5b88d5760320 9404 size_t max_len;
kenjiArai 0:5b88d5760320 9405
kenjiArai 0:5b88d5760320 9406 /*
kenjiArai 0:5b88d5760320 9407 * Assume mfl_code is correct since it was checked when set
kenjiArai 0:5b88d5760320 9408 */
kenjiArai 0:5b88d5760320 9409 max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code );
kenjiArai 0:5b88d5760320 9410
kenjiArai 0:5b88d5760320 9411 /* Check if a smaller max length was negotiated */
kenjiArai 0:5b88d5760320 9412 if( ssl->session_out != NULL &&
kenjiArai 0:5b88d5760320 9413 ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len )
kenjiArai 0:5b88d5760320 9414 {
kenjiArai 0:5b88d5760320 9415 max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code );
kenjiArai 0:5b88d5760320 9416 }
kenjiArai 0:5b88d5760320 9417
kenjiArai 0:5b88d5760320 9418 /* During a handshake, use the value being negotiated */
kenjiArai 0:5b88d5760320 9419 if( ssl->session_negotiate != NULL &&
kenjiArai 0:5b88d5760320 9420 ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ) < max_len )
kenjiArai 0:5b88d5760320 9421 {
kenjiArai 0:5b88d5760320 9422 max_len = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code );
kenjiArai 0:5b88d5760320 9423 }
kenjiArai 0:5b88d5760320 9424
kenjiArai 0:5b88d5760320 9425 return( max_len );
kenjiArai 0:5b88d5760320 9426 }
kenjiArai 0:5b88d5760320 9427 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
kenjiArai 0:5b88d5760320 9428
kenjiArai 0:5b88d5760320 9429 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9430 static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9431 {
kenjiArai 0:5b88d5760320 9432 /* Return unlimited mtu for client hello messages to avoid fragmentation. */
kenjiArai 0:5b88d5760320 9433 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
kenjiArai 0:5b88d5760320 9434 ( ssl->state == MBEDTLS_SSL_CLIENT_HELLO ||
kenjiArai 0:5b88d5760320 9435 ssl->state == MBEDTLS_SSL_SERVER_HELLO ) )
kenjiArai 0:5b88d5760320 9436 return ( 0 );
kenjiArai 0:5b88d5760320 9437
kenjiArai 0:5b88d5760320 9438 if( ssl->handshake == NULL || ssl->handshake->mtu == 0 )
kenjiArai 0:5b88d5760320 9439 return( ssl->mtu );
kenjiArai 0:5b88d5760320 9440
kenjiArai 0:5b88d5760320 9441 if( ssl->mtu == 0 )
kenjiArai 0:5b88d5760320 9442 return( ssl->handshake->mtu );
kenjiArai 0:5b88d5760320 9443
kenjiArai 0:5b88d5760320 9444 return( ssl->mtu < ssl->handshake->mtu ?
kenjiArai 0:5b88d5760320 9445 ssl->mtu : ssl->handshake->mtu );
kenjiArai 0:5b88d5760320 9446 }
kenjiArai 0:5b88d5760320 9447 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 9448
kenjiArai 0:5b88d5760320 9449 int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9450 {
kenjiArai 0:5b88d5760320 9451 size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
kenjiArai 0:5b88d5760320 9452
kenjiArai 0:5b88d5760320 9453 #if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
kenjiArai 0:5b88d5760320 9454 !defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9455 (void) ssl;
kenjiArai 0:5b88d5760320 9456 #endif
kenjiArai 0:5b88d5760320 9457
kenjiArai 0:5b88d5760320 9458 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
kenjiArai 0:5b88d5760320 9459 const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
kenjiArai 0:5b88d5760320 9460
kenjiArai 0:5b88d5760320 9461 if( max_len > mfl )
kenjiArai 0:5b88d5760320 9462 max_len = mfl;
kenjiArai 0:5b88d5760320 9463 #endif
kenjiArai 0:5b88d5760320 9464
kenjiArai 0:5b88d5760320 9465 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9466 if( ssl_get_current_mtu( ssl ) != 0 )
kenjiArai 0:5b88d5760320 9467 {
kenjiArai 0:5b88d5760320 9468 const size_t mtu = ssl_get_current_mtu( ssl );
kenjiArai 0:5b88d5760320 9469 const int ret = mbedtls_ssl_get_record_expansion( ssl );
kenjiArai 0:5b88d5760320 9470 const size_t overhead = (size_t) ret;
kenjiArai 0:5b88d5760320 9471
kenjiArai 0:5b88d5760320 9472 if( ret < 0 )
kenjiArai 0:5b88d5760320 9473 return( ret );
kenjiArai 0:5b88d5760320 9474
kenjiArai 0:5b88d5760320 9475 if( mtu <= overhead )
kenjiArai 0:5b88d5760320 9476 {
kenjiArai 0:5b88d5760320 9477 MBEDTLS_SSL_DEBUG_MSG( 1, ( "MTU too low for record expansion" ) );
kenjiArai 0:5b88d5760320 9478 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
kenjiArai 0:5b88d5760320 9479 }
kenjiArai 0:5b88d5760320 9480
kenjiArai 0:5b88d5760320 9481 if( max_len > mtu - overhead )
kenjiArai 0:5b88d5760320 9482 max_len = mtu - overhead;
kenjiArai 0:5b88d5760320 9483 }
kenjiArai 0:5b88d5760320 9484 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 9485
kenjiArai 0:5b88d5760320 9486 #if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
kenjiArai 0:5b88d5760320 9487 !defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9488 ((void) ssl);
kenjiArai 0:5b88d5760320 9489 #endif
kenjiArai 0:5b88d5760320 9490
kenjiArai 0:5b88d5760320 9491 return( (int) max_len );
kenjiArai 0:5b88d5760320 9492 }
kenjiArai 0:5b88d5760320 9493
kenjiArai 0:5b88d5760320 9494 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 9495 const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9496 {
kenjiArai 0:5b88d5760320 9497 if( ssl == NULL || ssl->session == NULL )
kenjiArai 0:5b88d5760320 9498 return( NULL );
kenjiArai 0:5b88d5760320 9499
kenjiArai 0:5b88d5760320 9500 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 9501 return( ssl->session->peer_cert );
kenjiArai 0:5b88d5760320 9502 #else
kenjiArai 0:5b88d5760320 9503 return( NULL );
kenjiArai 0:5b88d5760320 9504 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 9505 }
kenjiArai 0:5b88d5760320 9506 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 9507
kenjiArai 0:5b88d5760320 9508 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 9509 int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 9510 mbedtls_ssl_session *dst )
kenjiArai 0:5b88d5760320 9511 {
kenjiArai 0:5b88d5760320 9512 if( ssl == NULL ||
kenjiArai 0:5b88d5760320 9513 dst == NULL ||
kenjiArai 0:5b88d5760320 9514 ssl->session == NULL ||
kenjiArai 0:5b88d5760320 9515 ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 9516 {
kenjiArai 0:5b88d5760320 9517 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9518 }
kenjiArai 0:5b88d5760320 9519
kenjiArai 0:5b88d5760320 9520 return( mbedtls_ssl_session_copy( dst, ssl->session ) );
kenjiArai 0:5b88d5760320 9521 }
kenjiArai 0:5b88d5760320 9522 #endif /* MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 9523
kenjiArai 0:5b88d5760320 9524 /*
kenjiArai 0:5b88d5760320 9525 * Perform a single step of the SSL handshake
kenjiArai 0:5b88d5760320 9526 */
kenjiArai 0:5b88d5760320 9527 int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9528 {
kenjiArai 0:5b88d5760320 9529 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
kenjiArai 0:5b88d5760320 9530
kenjiArai 0:5b88d5760320 9531 if( ssl == NULL || ssl->conf == NULL )
kenjiArai 0:5b88d5760320 9532 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9533
kenjiArai 0:5b88d5760320 9534 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 9535 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 9536 ret = mbedtls_ssl_handshake_client_step( ssl );
kenjiArai 0:5b88d5760320 9537 #endif
kenjiArai 0:5b88d5760320 9538 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 9539 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 9540 ret = mbedtls_ssl_handshake_server_step( ssl );
kenjiArai 0:5b88d5760320 9541 #endif
kenjiArai 0:5b88d5760320 9542
kenjiArai 0:5b88d5760320 9543 return( ret );
kenjiArai 0:5b88d5760320 9544 }
kenjiArai 0:5b88d5760320 9545
kenjiArai 0:5b88d5760320 9546 /*
kenjiArai 0:5b88d5760320 9547 * Perform the SSL handshake
kenjiArai 0:5b88d5760320 9548 */
kenjiArai 0:5b88d5760320 9549 int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9550 {
kenjiArai 0:5b88d5760320 9551 int ret = 0;
kenjiArai 0:5b88d5760320 9552
kenjiArai 0:5b88d5760320 9553 if( ssl == NULL || ssl->conf == NULL )
kenjiArai 0:5b88d5760320 9554 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9555
kenjiArai 0:5b88d5760320 9556 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
kenjiArai 0:5b88d5760320 9557
kenjiArai 0:5b88d5760320 9558 while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 9559 {
kenjiArai 0:5b88d5760320 9560 ret = mbedtls_ssl_handshake_step( ssl );
kenjiArai 0:5b88d5760320 9561
kenjiArai 0:5b88d5760320 9562 if( ret != 0 )
kenjiArai 0:5b88d5760320 9563 break;
kenjiArai 0:5b88d5760320 9564 }
kenjiArai 0:5b88d5760320 9565
kenjiArai 0:5b88d5760320 9566 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= handshake" ) );
kenjiArai 0:5b88d5760320 9567
kenjiArai 0:5b88d5760320 9568 return( ret );
kenjiArai 0:5b88d5760320 9569 }
kenjiArai 0:5b88d5760320 9570
kenjiArai 0:5b88d5760320 9571 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 9572 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 9573 /*
kenjiArai 0:5b88d5760320 9574 * Write HelloRequest to request renegotiation on server
kenjiArai 0:5b88d5760320 9575 */
kenjiArai 0:5b88d5760320 9576 static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9577 {
kenjiArai 0:5b88d5760320 9578 int ret;
kenjiArai 0:5b88d5760320 9579
kenjiArai 0:5b88d5760320 9580 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) );
kenjiArai 0:5b88d5760320 9581
kenjiArai 0:5b88d5760320 9582 ssl->out_msglen = 4;
kenjiArai 0:5b88d5760320 9583 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
kenjiArai 0:5b88d5760320 9584 ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST;
kenjiArai 0:5b88d5760320 9585
kenjiArai 0:5b88d5760320 9586 if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 9587 {
kenjiArai 0:5b88d5760320 9588 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
kenjiArai 0:5b88d5760320 9589 return( ret );
kenjiArai 0:5b88d5760320 9590 }
kenjiArai 0:5b88d5760320 9591
kenjiArai 0:5b88d5760320 9592 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello request" ) );
kenjiArai 0:5b88d5760320 9593
kenjiArai 0:5b88d5760320 9594 return( 0 );
kenjiArai 0:5b88d5760320 9595 }
kenjiArai 0:5b88d5760320 9596 #endif /* MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 9597
kenjiArai 0:5b88d5760320 9598 /*
kenjiArai 0:5b88d5760320 9599 * Actually renegotiate current connection, triggered by either:
kenjiArai 0:5b88d5760320 9600 * - any side: calling mbedtls_ssl_renegotiate(),
kenjiArai 0:5b88d5760320 9601 * - client: receiving a HelloRequest during mbedtls_ssl_read(),
kenjiArai 0:5b88d5760320 9602 * - server: receiving any handshake message on server during mbedtls_ssl_read() after
kenjiArai 0:5b88d5760320 9603 * the initial handshake is completed.
kenjiArai 0:5b88d5760320 9604 * If the handshake doesn't complete due to waiting for I/O, it will continue
kenjiArai 0:5b88d5760320 9605 * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
kenjiArai 0:5b88d5760320 9606 */
kenjiArai 0:5b88d5760320 9607 static int ssl_start_renegotiation( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9608 {
kenjiArai 0:5b88d5760320 9609 int ret;
kenjiArai 0:5b88d5760320 9610
kenjiArai 0:5b88d5760320 9611 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
kenjiArai 0:5b88d5760320 9612
kenjiArai 0:5b88d5760320 9613 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 9614 return( ret );
kenjiArai 0:5b88d5760320 9615
kenjiArai 0:5b88d5760320 9616 /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and
kenjiArai 0:5b88d5760320 9617 * the ServerHello will have message_seq = 1" */
kenjiArai 0:5b88d5760320 9618 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9619 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 9620 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
kenjiArai 0:5b88d5760320 9621 {
kenjiArai 0:5b88d5760320 9622 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 9623 ssl->handshake->out_msg_seq = 1;
kenjiArai 0:5b88d5760320 9624 else
kenjiArai 0:5b88d5760320 9625 ssl->handshake->in_msg_seq = 1;
kenjiArai 0:5b88d5760320 9626 }
kenjiArai 0:5b88d5760320 9627 #endif
kenjiArai 0:5b88d5760320 9628
kenjiArai 0:5b88d5760320 9629 ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
kenjiArai 0:5b88d5760320 9630 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS;
kenjiArai 0:5b88d5760320 9631
kenjiArai 0:5b88d5760320 9632 if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 9633 {
kenjiArai 0:5b88d5760320 9634 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
kenjiArai 0:5b88d5760320 9635 return( ret );
kenjiArai 0:5b88d5760320 9636 }
kenjiArai 0:5b88d5760320 9637
kenjiArai 0:5b88d5760320 9638 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) );
kenjiArai 0:5b88d5760320 9639
kenjiArai 0:5b88d5760320 9640 return( 0 );
kenjiArai 0:5b88d5760320 9641 }
kenjiArai 0:5b88d5760320 9642
kenjiArai 0:5b88d5760320 9643 /*
kenjiArai 0:5b88d5760320 9644 * Renegotiate current connection on client,
kenjiArai 0:5b88d5760320 9645 * or request renegotiation on server
kenjiArai 0:5b88d5760320 9646 */
kenjiArai 0:5b88d5760320 9647 int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9648 {
kenjiArai 0:5b88d5760320 9649 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
kenjiArai 0:5b88d5760320 9650
kenjiArai 0:5b88d5760320 9651 if( ssl == NULL || ssl->conf == NULL )
kenjiArai 0:5b88d5760320 9652 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9653
kenjiArai 0:5b88d5760320 9654 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 9655 /* On server, just send the request */
kenjiArai 0:5b88d5760320 9656 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 9657 {
kenjiArai 0:5b88d5760320 9658 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 9659 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9660
kenjiArai 0:5b88d5760320 9661 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
kenjiArai 0:5b88d5760320 9662
kenjiArai 0:5b88d5760320 9663 /* Did we already try/start sending HelloRequest? */
kenjiArai 0:5b88d5760320 9664 if( ssl->out_left != 0 )
kenjiArai 0:5b88d5760320 9665 return( mbedtls_ssl_flush_output( ssl ) );
kenjiArai 0:5b88d5760320 9666
kenjiArai 0:5b88d5760320 9667 return( ssl_write_hello_request( ssl ) );
kenjiArai 0:5b88d5760320 9668 }
kenjiArai 0:5b88d5760320 9669 #endif /* MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 9670
kenjiArai 0:5b88d5760320 9671 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 9672 /*
kenjiArai 0:5b88d5760320 9673 * On client, either start the renegotiation process or,
kenjiArai 0:5b88d5760320 9674 * if already in progress, continue the handshake
kenjiArai 0:5b88d5760320 9675 */
kenjiArai 0:5b88d5760320 9676 if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
kenjiArai 0:5b88d5760320 9677 {
kenjiArai 0:5b88d5760320 9678 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 9679 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9680
kenjiArai 0:5b88d5760320 9681 if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 9682 {
kenjiArai 0:5b88d5760320 9683 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
kenjiArai 0:5b88d5760320 9684 return( ret );
kenjiArai 0:5b88d5760320 9685 }
kenjiArai 0:5b88d5760320 9686 }
kenjiArai 0:5b88d5760320 9687 else
kenjiArai 0:5b88d5760320 9688 {
kenjiArai 0:5b88d5760320 9689 if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 9690 {
kenjiArai 0:5b88d5760320 9691 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
kenjiArai 0:5b88d5760320 9692 return( ret );
kenjiArai 0:5b88d5760320 9693 }
kenjiArai 0:5b88d5760320 9694 }
kenjiArai 0:5b88d5760320 9695 #endif /* MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 9696
kenjiArai 0:5b88d5760320 9697 return( ret );
kenjiArai 0:5b88d5760320 9698 }
kenjiArai 0:5b88d5760320 9699
kenjiArai 0:5b88d5760320 9700 /*
kenjiArai 0:5b88d5760320 9701 * Check record counters and renegotiate if they're above the limit.
kenjiArai 0:5b88d5760320 9702 */
kenjiArai 0:5b88d5760320 9703 static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 9704 {
kenjiArai 0:5b88d5760320 9705 size_t ep_len = ssl_ep_len( ssl );
kenjiArai 0:5b88d5760320 9706 int in_ctr_cmp;
kenjiArai 0:5b88d5760320 9707 int out_ctr_cmp;
kenjiArai 0:5b88d5760320 9708
kenjiArai 0:5b88d5760320 9709 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
kenjiArai 0:5b88d5760320 9710 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
kenjiArai 0:5b88d5760320 9711 ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
kenjiArai 0:5b88d5760320 9712 {
kenjiArai 0:5b88d5760320 9713 return( 0 );
kenjiArai 0:5b88d5760320 9714 }
kenjiArai 0:5b88d5760320 9715
kenjiArai 0:5b88d5760320 9716 in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
kenjiArai 0:5b88d5760320 9717 ssl->conf->renego_period + ep_len, 8 - ep_len );
kenjiArai 0:5b88d5760320 9718 out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
kenjiArai 0:5b88d5760320 9719 ssl->conf->renego_period + ep_len, 8 - ep_len );
kenjiArai 0:5b88d5760320 9720
kenjiArai 0:5b88d5760320 9721 if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
kenjiArai 0:5b88d5760320 9722 {
kenjiArai 0:5b88d5760320 9723 return( 0 );
kenjiArai 0:5b88d5760320 9724 }
kenjiArai 0:5b88d5760320 9725
kenjiArai 0:5b88d5760320 9726 MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
kenjiArai 0:5b88d5760320 9727 return( mbedtls_ssl_renegotiate( ssl ) );
kenjiArai 0:5b88d5760320 9728 }
kenjiArai 0:5b88d5760320 9729 #endif /* MBEDTLS_SSL_RENEGOTIATION */
kenjiArai 0:5b88d5760320 9730
kenjiArai 0:5b88d5760320 9731 /*
kenjiArai 0:5b88d5760320 9732 * Receive application data decrypted from the SSL layer
kenjiArai 0:5b88d5760320 9733 */
kenjiArai 0:5b88d5760320 9734 int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
kenjiArai 0:5b88d5760320 9735 {
kenjiArai 0:5b88d5760320 9736 int ret;
kenjiArai 0:5b88d5760320 9737 size_t n;
kenjiArai 0:5b88d5760320 9738
kenjiArai 0:5b88d5760320 9739 if( ssl == NULL || ssl->conf == NULL )
kenjiArai 0:5b88d5760320 9740 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 9741
kenjiArai 0:5b88d5760320 9742 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
kenjiArai 0:5b88d5760320 9743
kenjiArai 0:5b88d5760320 9744 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9745 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 9746 {
kenjiArai 0:5b88d5760320 9747 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 9748 return( ret );
kenjiArai 0:5b88d5760320 9749
kenjiArai 0:5b88d5760320 9750 if( ssl->handshake != NULL &&
kenjiArai 0:5b88d5760320 9751 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
kenjiArai 0:5b88d5760320 9752 {
kenjiArai 0:5b88d5760320 9753 if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 9754 return( ret );
kenjiArai 0:5b88d5760320 9755 }
kenjiArai 0:5b88d5760320 9756 }
kenjiArai 0:5b88d5760320 9757 #endif
kenjiArai 0:5b88d5760320 9758
kenjiArai 0:5b88d5760320 9759 /*
kenjiArai 0:5b88d5760320 9760 * Check if renegotiation is necessary and/or handshake is
kenjiArai 0:5b88d5760320 9761 * in process. If yes, perform/continue, and fall through
kenjiArai 0:5b88d5760320 9762 * if an unexpected packet is received while the client
kenjiArai 0:5b88d5760320 9763 * is waiting for the ServerHello.
kenjiArai 0:5b88d5760320 9764 *
kenjiArai 0:5b88d5760320 9765 * (There is no equivalent to the last condition on
kenjiArai 0:5b88d5760320 9766 * the server-side as it is not treated as within
kenjiArai 0:5b88d5760320 9767 * a handshake while waiting for the ClientHello
kenjiArai 0:5b88d5760320 9768 * after a renegotiation request.)
kenjiArai 0:5b88d5760320 9769 */
kenjiArai 0:5b88d5760320 9770
kenjiArai 0:5b88d5760320 9771 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 9772 ret = ssl_check_ctr_renegotiate( ssl );
kenjiArai 0:5b88d5760320 9773 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
kenjiArai 0:5b88d5760320 9774 ret != 0 )
kenjiArai 0:5b88d5760320 9775 {
kenjiArai 0:5b88d5760320 9776 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
kenjiArai 0:5b88d5760320 9777 return( ret );
kenjiArai 0:5b88d5760320 9778 }
kenjiArai 0:5b88d5760320 9779 #endif
kenjiArai 0:5b88d5760320 9780
kenjiArai 0:5b88d5760320 9781 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 9782 {
kenjiArai 0:5b88d5760320 9783 ret = mbedtls_ssl_handshake( ssl );
kenjiArai 0:5b88d5760320 9784 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
kenjiArai 0:5b88d5760320 9785 ret != 0 )
kenjiArai 0:5b88d5760320 9786 {
kenjiArai 0:5b88d5760320 9787 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
kenjiArai 0:5b88d5760320 9788 return( ret );
kenjiArai 0:5b88d5760320 9789 }
kenjiArai 0:5b88d5760320 9790 }
kenjiArai 0:5b88d5760320 9791
kenjiArai 0:5b88d5760320 9792 /* Loop as long as no application data record is available */
kenjiArai 0:5b88d5760320 9793 while( ssl->in_offt == NULL )
kenjiArai 0:5b88d5760320 9794 {
kenjiArai 0:5b88d5760320 9795 /* Start timer if not already running */
kenjiArai 0:5b88d5760320 9796 if( ssl->f_get_timer != NULL &&
kenjiArai 0:5b88d5760320 9797 ssl->f_get_timer( ssl->p_timer ) == -1 )
kenjiArai 0:5b88d5760320 9798 {
kenjiArai 0:5b88d5760320 9799 ssl_set_timer( ssl, ssl->conf->read_timeout );
kenjiArai 0:5b88d5760320 9800 }
kenjiArai 0:5b88d5760320 9801
kenjiArai 0:5b88d5760320 9802 if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 9803 {
kenjiArai 0:5b88d5760320 9804 if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
kenjiArai 0:5b88d5760320 9805 return( 0 );
kenjiArai 0:5b88d5760320 9806
kenjiArai 0:5b88d5760320 9807 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
kenjiArai 0:5b88d5760320 9808 return( ret );
kenjiArai 0:5b88d5760320 9809 }
kenjiArai 0:5b88d5760320 9810
kenjiArai 0:5b88d5760320 9811 if( ssl->in_msglen == 0 &&
kenjiArai 0:5b88d5760320 9812 ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
kenjiArai 0:5b88d5760320 9813 {
kenjiArai 0:5b88d5760320 9814 /*
kenjiArai 0:5b88d5760320 9815 * OpenSSL sends empty messages to randomize the IV
kenjiArai 0:5b88d5760320 9816 */
kenjiArai 0:5b88d5760320 9817 if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
kenjiArai 0:5b88d5760320 9818 {
kenjiArai 0:5b88d5760320 9819 if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
kenjiArai 0:5b88d5760320 9820 return( 0 );
kenjiArai 0:5b88d5760320 9821
kenjiArai 0:5b88d5760320 9822 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
kenjiArai 0:5b88d5760320 9823 return( ret );
kenjiArai 0:5b88d5760320 9824 }
kenjiArai 0:5b88d5760320 9825 }
kenjiArai 0:5b88d5760320 9826
kenjiArai 0:5b88d5760320 9827 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
kenjiArai 0:5b88d5760320 9828 {
kenjiArai 0:5b88d5760320 9829 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
kenjiArai 0:5b88d5760320 9830
kenjiArai 0:5b88d5760320 9831 /*
kenjiArai 0:5b88d5760320 9832 * - For client-side, expect SERVER_HELLO_REQUEST.
kenjiArai 0:5b88d5760320 9833 * - For server-side, expect CLIENT_HELLO.
kenjiArai 0:5b88d5760320 9834 * - Fail (TLS) or silently drop record (DTLS) in other cases.
kenjiArai 0:5b88d5760320 9835 */
kenjiArai 0:5b88d5760320 9836
kenjiArai 0:5b88d5760320 9837 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 9838 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
kenjiArai 0:5b88d5760320 9839 ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
kenjiArai 0:5b88d5760320 9840 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
kenjiArai 0:5b88d5760320 9841 {
kenjiArai 0:5b88d5760320 9842 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
kenjiArai 0:5b88d5760320 9843
kenjiArai 0:5b88d5760320 9844 /* With DTLS, drop the packet (probably from last handshake) */
kenjiArai 0:5b88d5760320 9845 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9846 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 9847 {
kenjiArai 0:5b88d5760320 9848 continue;
kenjiArai 0:5b88d5760320 9849 }
kenjiArai 0:5b88d5760320 9850 #endif
kenjiArai 0:5b88d5760320 9851 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 9852 }
kenjiArai 0:5b88d5760320 9853 #endif /* MBEDTLS_SSL_CLI_C */
kenjiArai 0:5b88d5760320 9854
kenjiArai 0:5b88d5760320 9855 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 9856 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
kenjiArai 0:5b88d5760320 9857 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
kenjiArai 0:5b88d5760320 9858 {
kenjiArai 0:5b88d5760320 9859 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
kenjiArai 0:5b88d5760320 9860
kenjiArai 0:5b88d5760320 9861 /* With DTLS, drop the packet (probably from last handshake) */
kenjiArai 0:5b88d5760320 9862 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9863 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 9864 {
kenjiArai 0:5b88d5760320 9865 continue;
kenjiArai 0:5b88d5760320 9866 }
kenjiArai 0:5b88d5760320 9867 #endif
kenjiArai 0:5b88d5760320 9868 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 9869 }
kenjiArai 0:5b88d5760320 9870 #endif /* MBEDTLS_SSL_SRV_C */
kenjiArai 0:5b88d5760320 9871
kenjiArai 0:5b88d5760320 9872 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 9873 /* Determine whether renegotiation attempt should be accepted */
kenjiArai 0:5b88d5760320 9874 if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
kenjiArai 0:5b88d5760320 9875 ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
kenjiArai 0:5b88d5760320 9876 ssl->conf->allow_legacy_renegotiation ==
kenjiArai 0:5b88d5760320 9877 MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
kenjiArai 0:5b88d5760320 9878 {
kenjiArai 0:5b88d5760320 9879 /*
kenjiArai 0:5b88d5760320 9880 * Accept renegotiation request
kenjiArai 0:5b88d5760320 9881 */
kenjiArai 0:5b88d5760320 9882
kenjiArai 0:5b88d5760320 9883 /* DTLS clients need to know renego is server-initiated */
kenjiArai 0:5b88d5760320 9884 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9885 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
kenjiArai 0:5b88d5760320 9886 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 9887 {
kenjiArai 0:5b88d5760320 9888 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
kenjiArai 0:5b88d5760320 9889 }
kenjiArai 0:5b88d5760320 9890 #endif
kenjiArai 0:5b88d5760320 9891 ret = ssl_start_renegotiation( ssl );
kenjiArai 0:5b88d5760320 9892 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
kenjiArai 0:5b88d5760320 9893 ret != 0 )
kenjiArai 0:5b88d5760320 9894 {
kenjiArai 0:5b88d5760320 9895 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
kenjiArai 0:5b88d5760320 9896 return( ret );
kenjiArai 0:5b88d5760320 9897 }
kenjiArai 0:5b88d5760320 9898 }
kenjiArai 0:5b88d5760320 9899 else
kenjiArai 0:5b88d5760320 9900 #endif /* MBEDTLS_SSL_RENEGOTIATION */
kenjiArai 0:5b88d5760320 9901 {
kenjiArai 0:5b88d5760320 9902 /*
kenjiArai 0:5b88d5760320 9903 * Refuse renegotiation
kenjiArai 0:5b88d5760320 9904 */
kenjiArai 0:5b88d5760320 9905
kenjiArai 0:5b88d5760320 9906 MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
kenjiArai 0:5b88d5760320 9907
kenjiArai 0:5b88d5760320 9908 #if defined(MBEDTLS_SSL_PROTO_SSL3)
kenjiArai 0:5b88d5760320 9909 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
kenjiArai 0:5b88d5760320 9910 {
kenjiArai 0:5b88d5760320 9911 /* SSLv3 does not have a "no_renegotiation" warning, so
kenjiArai 0:5b88d5760320 9912 we send a fatal alert and abort the connection. */
kenjiArai 0:5b88d5760320 9913 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 9914 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 9915 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 9916 }
kenjiArai 0:5b88d5760320 9917 else
kenjiArai 0:5b88d5760320 9918 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
kenjiArai 0:5b88d5760320 9919 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 9920 defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 9921 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
kenjiArai 0:5b88d5760320 9922 {
kenjiArai 0:5b88d5760320 9923 if( ( ret = mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 9924 MBEDTLS_SSL_ALERT_LEVEL_WARNING,
kenjiArai 0:5b88d5760320 9925 MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
kenjiArai 0:5b88d5760320 9926 {
kenjiArai 0:5b88d5760320 9927 return( ret );
kenjiArai 0:5b88d5760320 9928 }
kenjiArai 0:5b88d5760320 9929 }
kenjiArai 0:5b88d5760320 9930 else
kenjiArai 0:5b88d5760320 9931 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
kenjiArai 0:5b88d5760320 9932 MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 9933 {
kenjiArai 0:5b88d5760320 9934 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
kenjiArai 0:5b88d5760320 9935 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 9936 }
kenjiArai 0:5b88d5760320 9937 }
kenjiArai 0:5b88d5760320 9938
kenjiArai 0:5b88d5760320 9939 /* At this point, we don't know whether the renegotiation has been
kenjiArai 0:5b88d5760320 9940 * completed or not. The cases to consider are the following:
kenjiArai 0:5b88d5760320 9941 * 1) The renegotiation is complete. In this case, no new record
kenjiArai 0:5b88d5760320 9942 * has been read yet.
kenjiArai 0:5b88d5760320 9943 * 2) The renegotiation is incomplete because the client received
kenjiArai 0:5b88d5760320 9944 * an application data record while awaiting the ServerHello.
kenjiArai 0:5b88d5760320 9945 * 3) The renegotiation is incomplete because the client received
kenjiArai 0:5b88d5760320 9946 * a non-handshake, non-application data message while awaiting
kenjiArai 0:5b88d5760320 9947 * the ServerHello.
kenjiArai 0:5b88d5760320 9948 * In each of these case, looping will be the proper action:
kenjiArai 0:5b88d5760320 9949 * - For 1), the next iteration will read a new record and check
kenjiArai 0:5b88d5760320 9950 * if it's application data.
kenjiArai 0:5b88d5760320 9951 * - For 2), the loop condition isn't satisfied as application data
kenjiArai 0:5b88d5760320 9952 * is present, hence continue is the same as break
kenjiArai 0:5b88d5760320 9953 * - For 3), the loop condition is satisfied and read_record
kenjiArai 0:5b88d5760320 9954 * will re-deliver the message that was held back by the client
kenjiArai 0:5b88d5760320 9955 * when expecting the ServerHello.
kenjiArai 0:5b88d5760320 9956 */
kenjiArai 0:5b88d5760320 9957 continue;
kenjiArai 0:5b88d5760320 9958 }
kenjiArai 0:5b88d5760320 9959 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 9960 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
kenjiArai 0:5b88d5760320 9961 {
kenjiArai 0:5b88d5760320 9962 if( ssl->conf->renego_max_records >= 0 )
kenjiArai 0:5b88d5760320 9963 {
kenjiArai 0:5b88d5760320 9964 if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
kenjiArai 0:5b88d5760320 9965 {
kenjiArai 0:5b88d5760320 9966 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
kenjiArai 0:5b88d5760320 9967 "but not honored by client" ) );
kenjiArai 0:5b88d5760320 9968 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 9969 }
kenjiArai 0:5b88d5760320 9970 }
kenjiArai 0:5b88d5760320 9971 }
kenjiArai 0:5b88d5760320 9972 #endif /* MBEDTLS_SSL_RENEGOTIATION */
kenjiArai 0:5b88d5760320 9973
kenjiArai 0:5b88d5760320 9974 /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
kenjiArai 0:5b88d5760320 9975 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
kenjiArai 0:5b88d5760320 9976 {
kenjiArai 0:5b88d5760320 9977 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
kenjiArai 0:5b88d5760320 9978 return( MBEDTLS_ERR_SSL_WANT_READ );
kenjiArai 0:5b88d5760320 9979 }
kenjiArai 0:5b88d5760320 9980
kenjiArai 0:5b88d5760320 9981 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
kenjiArai 0:5b88d5760320 9982 {
kenjiArai 0:5b88d5760320 9983 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
kenjiArai 0:5b88d5760320 9984 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
kenjiArai 0:5b88d5760320 9985 }
kenjiArai 0:5b88d5760320 9986
kenjiArai 0:5b88d5760320 9987 ssl->in_offt = ssl->in_msg;
kenjiArai 0:5b88d5760320 9988
kenjiArai 0:5b88d5760320 9989 /* We're going to return something now, cancel timer,
kenjiArai 0:5b88d5760320 9990 * except if handshake (renegotiation) is in progress */
kenjiArai 0:5b88d5760320 9991 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 9992 ssl_set_timer( ssl, 0 );
kenjiArai 0:5b88d5760320 9993
kenjiArai 0:5b88d5760320 9994 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 9995 /* If we requested renego but received AppData, resend HelloRequest.
kenjiArai 0:5b88d5760320 9996 * Do it now, after setting in_offt, to avoid taking this branch
kenjiArai 0:5b88d5760320 9997 * again if ssl_write_hello_request() returns WANT_WRITE */
kenjiArai 0:5b88d5760320 9998 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 9999 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
kenjiArai 0:5b88d5760320 10000 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
kenjiArai 0:5b88d5760320 10001 {
kenjiArai 0:5b88d5760320 10002 if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 10003 {
kenjiArai 0:5b88d5760320 10004 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
kenjiArai 0:5b88d5760320 10005 return( ret );
kenjiArai 0:5b88d5760320 10006 }
kenjiArai 0:5b88d5760320 10007 }
kenjiArai 0:5b88d5760320 10008 #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
kenjiArai 0:5b88d5760320 10009 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 10010 }
kenjiArai 0:5b88d5760320 10011
kenjiArai 0:5b88d5760320 10012 n = ( len < ssl->in_msglen )
kenjiArai 0:5b88d5760320 10013 ? len : ssl->in_msglen;
kenjiArai 0:5b88d5760320 10014
kenjiArai 0:5b88d5760320 10015 memcpy( buf, ssl->in_offt, n );
kenjiArai 0:5b88d5760320 10016 ssl->in_msglen -= n;
kenjiArai 0:5b88d5760320 10017
kenjiArai 0:5b88d5760320 10018 if( ssl->in_msglen == 0 )
kenjiArai 0:5b88d5760320 10019 {
kenjiArai 0:5b88d5760320 10020 /* all bytes consumed */
kenjiArai 0:5b88d5760320 10021 ssl->in_offt = NULL;
kenjiArai 0:5b88d5760320 10022 ssl->keep_current_message = 0;
kenjiArai 0:5b88d5760320 10023 }
kenjiArai 0:5b88d5760320 10024 else
kenjiArai 0:5b88d5760320 10025 {
kenjiArai 0:5b88d5760320 10026 /* more data available */
kenjiArai 0:5b88d5760320 10027 ssl->in_offt += n;
kenjiArai 0:5b88d5760320 10028 }
kenjiArai 0:5b88d5760320 10029
kenjiArai 0:5b88d5760320 10030 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
kenjiArai 0:5b88d5760320 10031
kenjiArai 0:5b88d5760320 10032 return( (int) n );
kenjiArai 0:5b88d5760320 10033 }
kenjiArai 0:5b88d5760320 10034
kenjiArai 0:5b88d5760320 10035 /*
kenjiArai 0:5b88d5760320 10036 * Send application data to be encrypted by the SSL layer, taking care of max
kenjiArai 0:5b88d5760320 10037 * fragment length and buffer size.
kenjiArai 0:5b88d5760320 10038 *
kenjiArai 0:5b88d5760320 10039 * According to RFC 5246 Section 6.2.1:
kenjiArai 0:5b88d5760320 10040 *
kenjiArai 0:5b88d5760320 10041 * Zero-length fragments of Application data MAY be sent as they are
kenjiArai 0:5b88d5760320 10042 * potentially useful as a traffic analysis countermeasure.
kenjiArai 0:5b88d5760320 10043 *
kenjiArai 0:5b88d5760320 10044 * Therefore, it is possible that the input message length is 0 and the
kenjiArai 0:5b88d5760320 10045 * corresponding return code is 0 on success.
kenjiArai 0:5b88d5760320 10046 */
kenjiArai 0:5b88d5760320 10047 static int ssl_write_real( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 10048 const unsigned char *buf, size_t len )
kenjiArai 0:5b88d5760320 10049 {
kenjiArai 0:5b88d5760320 10050 int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
kenjiArai 0:5b88d5760320 10051 const size_t max_len = (size_t) ret;
kenjiArai 0:5b88d5760320 10052
kenjiArai 0:5b88d5760320 10053 if( ret < 0 )
kenjiArai 0:5b88d5760320 10054 {
kenjiArai 0:5b88d5760320 10055 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret );
kenjiArai 0:5b88d5760320 10056 return( ret );
kenjiArai 0:5b88d5760320 10057 }
kenjiArai 0:5b88d5760320 10058
kenjiArai 0:5b88d5760320 10059 if( len > max_len )
kenjiArai 0:5b88d5760320 10060 {
kenjiArai 0:5b88d5760320 10061 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 10062 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 10063 {
kenjiArai 0:5b88d5760320 10064 MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
kenjiArai 0:5b88d5760320 10065 "maximum fragment length: %d > %d",
kenjiArai 0:5b88d5760320 10066 len, max_len ) );
kenjiArai 0:5b88d5760320 10067 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 10068 }
kenjiArai 0:5b88d5760320 10069 else
kenjiArai 0:5b88d5760320 10070 #endif
kenjiArai 0:5b88d5760320 10071 len = max_len;
kenjiArai 0:5b88d5760320 10072 }
kenjiArai 0:5b88d5760320 10073
kenjiArai 0:5b88d5760320 10074 if( ssl->out_left != 0 )
kenjiArai 0:5b88d5760320 10075 {
kenjiArai 0:5b88d5760320 10076 /*
kenjiArai 0:5b88d5760320 10077 * The user has previously tried to send the data and
kenjiArai 0:5b88d5760320 10078 * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
kenjiArai 0:5b88d5760320 10079 * written. In this case, we expect the high-level write function
kenjiArai 0:5b88d5760320 10080 * (e.g. mbedtls_ssl_write()) to be called with the same parameters
kenjiArai 0:5b88d5760320 10081 */
kenjiArai 0:5b88d5760320 10082 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 10083 {
kenjiArai 0:5b88d5760320 10084 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
kenjiArai 0:5b88d5760320 10085 return( ret );
kenjiArai 0:5b88d5760320 10086 }
kenjiArai 0:5b88d5760320 10087 }
kenjiArai 0:5b88d5760320 10088 else
kenjiArai 0:5b88d5760320 10089 {
kenjiArai 0:5b88d5760320 10090 /*
kenjiArai 0:5b88d5760320 10091 * The user is trying to send a message the first time, so we need to
kenjiArai 0:5b88d5760320 10092 * copy the data into the internal buffers and setup the data structure
kenjiArai 0:5b88d5760320 10093 * to keep track of partial writes
kenjiArai 0:5b88d5760320 10094 */
kenjiArai 0:5b88d5760320 10095 ssl->out_msglen = len;
kenjiArai 0:5b88d5760320 10096 ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
kenjiArai 0:5b88d5760320 10097 memcpy( ssl->out_msg, buf, len );
kenjiArai 0:5b88d5760320 10098
kenjiArai 0:5b88d5760320 10099 if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
kenjiArai 0:5b88d5760320 10100 {
kenjiArai 0:5b88d5760320 10101 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
kenjiArai 0:5b88d5760320 10102 return( ret );
kenjiArai 0:5b88d5760320 10103 }
kenjiArai 0:5b88d5760320 10104 }
kenjiArai 0:5b88d5760320 10105
kenjiArai 0:5b88d5760320 10106 return( (int) len );
kenjiArai 0:5b88d5760320 10107 }
kenjiArai 0:5b88d5760320 10108
kenjiArai 0:5b88d5760320 10109 /*
kenjiArai 0:5b88d5760320 10110 * Write application data, doing 1/n-1 splitting if necessary.
kenjiArai 0:5b88d5760320 10111 *
kenjiArai 0:5b88d5760320 10112 * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
kenjiArai 0:5b88d5760320 10113 * then the caller will call us again with the same arguments, so
kenjiArai 0:5b88d5760320 10114 * remember whether we already did the split or not.
kenjiArai 0:5b88d5760320 10115 */
kenjiArai 0:5b88d5760320 10116 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
kenjiArai 0:5b88d5760320 10117 static int ssl_write_split( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 10118 const unsigned char *buf, size_t len )
kenjiArai 0:5b88d5760320 10119 {
kenjiArai 0:5b88d5760320 10120 int ret;
kenjiArai 0:5b88d5760320 10121
kenjiArai 0:5b88d5760320 10122 if( ssl->conf->cbc_record_splitting ==
kenjiArai 0:5b88d5760320 10123 MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
kenjiArai 0:5b88d5760320 10124 len <= 1 ||
kenjiArai 0:5b88d5760320 10125 ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
kenjiArai 0:5b88d5760320 10126 mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
kenjiArai 0:5b88d5760320 10127 != MBEDTLS_MODE_CBC )
kenjiArai 0:5b88d5760320 10128 {
kenjiArai 0:5b88d5760320 10129 return( ssl_write_real( ssl, buf, len ) );
kenjiArai 0:5b88d5760320 10130 }
kenjiArai 0:5b88d5760320 10131
kenjiArai 0:5b88d5760320 10132 if( ssl->split_done == 0 )
kenjiArai 0:5b88d5760320 10133 {
kenjiArai 0:5b88d5760320 10134 if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
kenjiArai 0:5b88d5760320 10135 return( ret );
kenjiArai 0:5b88d5760320 10136 ssl->split_done = 1;
kenjiArai 0:5b88d5760320 10137 }
kenjiArai 0:5b88d5760320 10138
kenjiArai 0:5b88d5760320 10139 if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
kenjiArai 0:5b88d5760320 10140 return( ret );
kenjiArai 0:5b88d5760320 10141 ssl->split_done = 0;
kenjiArai 0:5b88d5760320 10142
kenjiArai 0:5b88d5760320 10143 return( ret + 1 );
kenjiArai 0:5b88d5760320 10144 }
kenjiArai 0:5b88d5760320 10145 #endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
kenjiArai 0:5b88d5760320 10146
kenjiArai 0:5b88d5760320 10147 /*
kenjiArai 0:5b88d5760320 10148 * Write application data (public-facing wrapper)
kenjiArai 0:5b88d5760320 10149 */
kenjiArai 0:5b88d5760320 10150 int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
kenjiArai 0:5b88d5760320 10151 {
kenjiArai 0:5b88d5760320 10152 int ret;
kenjiArai 0:5b88d5760320 10153
kenjiArai 0:5b88d5760320 10154 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
kenjiArai 0:5b88d5760320 10155
kenjiArai 0:5b88d5760320 10156 if( ssl == NULL || ssl->conf == NULL )
kenjiArai 0:5b88d5760320 10157 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 10158
kenjiArai 0:5b88d5760320 10159 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 10160 if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 10161 {
kenjiArai 0:5b88d5760320 10162 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
kenjiArai 0:5b88d5760320 10163 return( ret );
kenjiArai 0:5b88d5760320 10164 }
kenjiArai 0:5b88d5760320 10165 #endif
kenjiArai 0:5b88d5760320 10166
kenjiArai 0:5b88d5760320 10167 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 10168 {
kenjiArai 0:5b88d5760320 10169 if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
kenjiArai 0:5b88d5760320 10170 {
kenjiArai 0:5b88d5760320 10171 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
kenjiArai 0:5b88d5760320 10172 return( ret );
kenjiArai 0:5b88d5760320 10173 }
kenjiArai 0:5b88d5760320 10174 }
kenjiArai 0:5b88d5760320 10175
kenjiArai 0:5b88d5760320 10176 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
kenjiArai 0:5b88d5760320 10177 ret = ssl_write_split( ssl, buf, len );
kenjiArai 0:5b88d5760320 10178 #else
kenjiArai 0:5b88d5760320 10179 ret = ssl_write_real( ssl, buf, len );
kenjiArai 0:5b88d5760320 10180 #endif
kenjiArai 0:5b88d5760320 10181
kenjiArai 0:5b88d5760320 10182 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
kenjiArai 0:5b88d5760320 10183
kenjiArai 0:5b88d5760320 10184 return( ret );
kenjiArai 0:5b88d5760320 10185 }
kenjiArai 0:5b88d5760320 10186
kenjiArai 0:5b88d5760320 10187 /*
kenjiArai 0:5b88d5760320 10188 * Notify the peer that the connection is being closed
kenjiArai 0:5b88d5760320 10189 */
kenjiArai 0:5b88d5760320 10190 int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 10191 {
kenjiArai 0:5b88d5760320 10192 int ret;
kenjiArai 0:5b88d5760320 10193
kenjiArai 0:5b88d5760320 10194 if( ssl == NULL || ssl->conf == NULL )
kenjiArai 0:5b88d5760320 10195 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 10196
kenjiArai 0:5b88d5760320 10197 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
kenjiArai 0:5b88d5760320 10198
kenjiArai 0:5b88d5760320 10199 if( ssl->out_left != 0 )
kenjiArai 0:5b88d5760320 10200 return( mbedtls_ssl_flush_output( ssl ) );
kenjiArai 0:5b88d5760320 10201
kenjiArai 0:5b88d5760320 10202 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
kenjiArai 0:5b88d5760320 10203 {
kenjiArai 0:5b88d5760320 10204 if( ( ret = mbedtls_ssl_send_alert_message( ssl,
kenjiArai 0:5b88d5760320 10205 MBEDTLS_SSL_ALERT_LEVEL_WARNING,
kenjiArai 0:5b88d5760320 10206 MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
kenjiArai 0:5b88d5760320 10207 {
kenjiArai 0:5b88d5760320 10208 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
kenjiArai 0:5b88d5760320 10209 return( ret );
kenjiArai 0:5b88d5760320 10210 }
kenjiArai 0:5b88d5760320 10211 }
kenjiArai 0:5b88d5760320 10212
kenjiArai 0:5b88d5760320 10213 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
kenjiArai 0:5b88d5760320 10214
kenjiArai 0:5b88d5760320 10215 return( 0 );
kenjiArai 0:5b88d5760320 10216 }
kenjiArai 0:5b88d5760320 10217
kenjiArai 0:5b88d5760320 10218 void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
kenjiArai 0:5b88d5760320 10219 {
kenjiArai 0:5b88d5760320 10220 if( transform == NULL )
kenjiArai 0:5b88d5760320 10221 return;
kenjiArai 0:5b88d5760320 10222
kenjiArai 0:5b88d5760320 10223 #if defined(MBEDTLS_ZLIB_SUPPORT)
kenjiArai 0:5b88d5760320 10224 deflateEnd( &transform->ctx_deflate );
kenjiArai 0:5b88d5760320 10225 inflateEnd( &transform->ctx_inflate );
kenjiArai 0:5b88d5760320 10226 #endif
kenjiArai 0:5b88d5760320 10227
kenjiArai 0:5b88d5760320 10228 mbedtls_cipher_free( &transform->cipher_ctx_enc );
kenjiArai 0:5b88d5760320 10229 mbedtls_cipher_free( &transform->cipher_ctx_dec );
kenjiArai 0:5b88d5760320 10230
kenjiArai 0:5b88d5760320 10231 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
kenjiArai 0:5b88d5760320 10232 mbedtls_md_free( &transform->md_ctx_enc );
kenjiArai 0:5b88d5760320 10233 mbedtls_md_free( &transform->md_ctx_dec );
kenjiArai 0:5b88d5760320 10234 #endif
kenjiArai 0:5b88d5760320 10235
kenjiArai 0:5b88d5760320 10236 mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
kenjiArai 0:5b88d5760320 10237 }
kenjiArai 0:5b88d5760320 10238
kenjiArai 0:5b88d5760320 10239 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 10240 static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
kenjiArai 0:5b88d5760320 10241 {
kenjiArai 0:5b88d5760320 10242 mbedtls_ssl_key_cert *cur = key_cert, *next;
kenjiArai 0:5b88d5760320 10243
kenjiArai 0:5b88d5760320 10244 while( cur != NULL )
kenjiArai 0:5b88d5760320 10245 {
kenjiArai 0:5b88d5760320 10246 next = cur->next;
kenjiArai 0:5b88d5760320 10247 mbedtls_free( cur );
kenjiArai 0:5b88d5760320 10248 cur = next;
kenjiArai 0:5b88d5760320 10249 }
kenjiArai 0:5b88d5760320 10250 }
kenjiArai 0:5b88d5760320 10251 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 10252
kenjiArai 0:5b88d5760320 10253 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 10254
kenjiArai 0:5b88d5760320 10255 static void ssl_buffering_free( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 10256 {
kenjiArai 0:5b88d5760320 10257 unsigned offset;
kenjiArai 0:5b88d5760320 10258 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 10259
kenjiArai 0:5b88d5760320 10260 if( hs == NULL )
kenjiArai 0:5b88d5760320 10261 return;
kenjiArai 0:5b88d5760320 10262
kenjiArai 0:5b88d5760320 10263 ssl_free_buffered_record( ssl );
kenjiArai 0:5b88d5760320 10264
kenjiArai 0:5b88d5760320 10265 for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
kenjiArai 0:5b88d5760320 10266 ssl_buffering_free_slot( ssl, offset );
kenjiArai 0:5b88d5760320 10267 }
kenjiArai 0:5b88d5760320 10268
kenjiArai 0:5b88d5760320 10269 static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 10270 uint8_t slot )
kenjiArai 0:5b88d5760320 10271 {
kenjiArai 0:5b88d5760320 10272 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
kenjiArai 0:5b88d5760320 10273 mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
kenjiArai 0:5b88d5760320 10274
kenjiArai 0:5b88d5760320 10275 if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS )
kenjiArai 0:5b88d5760320 10276 return;
kenjiArai 0:5b88d5760320 10277
kenjiArai 0:5b88d5760320 10278 if( hs_buf->is_valid == 1 )
kenjiArai 0:5b88d5760320 10279 {
kenjiArai 0:5b88d5760320 10280 hs->buffering.total_bytes_buffered -= hs_buf->data_len;
kenjiArai 0:5b88d5760320 10281 mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len );
kenjiArai 0:5b88d5760320 10282 mbedtls_free( hs_buf->data );
kenjiArai 0:5b88d5760320 10283 memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
kenjiArai 0:5b88d5760320 10284 }
kenjiArai 0:5b88d5760320 10285 }
kenjiArai 0:5b88d5760320 10286
kenjiArai 0:5b88d5760320 10287 #endif /* MBEDTLS_SSL_PROTO_DTLS */
kenjiArai 0:5b88d5760320 10288
kenjiArai 0:5b88d5760320 10289 void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 10290 {
kenjiArai 0:5b88d5760320 10291 mbedtls_ssl_handshake_params *handshake = ssl->handshake;
kenjiArai 0:5b88d5760320 10292
kenjiArai 0:5b88d5760320 10293 if( handshake == NULL )
kenjiArai 0:5b88d5760320 10294 return;
kenjiArai 0:5b88d5760320 10295
kenjiArai 0:5b88d5760320 10296 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
kenjiArai 0:5b88d5760320 10297 if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
kenjiArai 0:5b88d5760320 10298 {
kenjiArai 0:5b88d5760320 10299 ssl->conf->f_async_cancel( ssl );
kenjiArai 0:5b88d5760320 10300 handshake->async_in_progress = 0;
kenjiArai 0:5b88d5760320 10301 }
kenjiArai 0:5b88d5760320 10302 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
kenjiArai 0:5b88d5760320 10303
kenjiArai 0:5b88d5760320 10304 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 10305 defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 10306 mbedtls_md5_free( &handshake->fin_md5 );
kenjiArai 0:5b88d5760320 10307 mbedtls_sha1_free( &handshake->fin_sha1 );
kenjiArai 0:5b88d5760320 10308 #endif
kenjiArai 0:5b88d5760320 10309 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 10310 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 10311 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 10312 psa_hash_abort( &handshake->fin_sha256_psa );
kenjiArai 0:5b88d5760320 10313 #else
kenjiArai 0:5b88d5760320 10314 mbedtls_sha256_free( &handshake->fin_sha256 );
kenjiArai 0:5b88d5760320 10315 #endif
kenjiArai 0:5b88d5760320 10316 #endif
kenjiArai 0:5b88d5760320 10317 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 10318 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 10319 psa_hash_abort( &handshake->fin_sha384_psa );
kenjiArai 0:5b88d5760320 10320 #else
kenjiArai 0:5b88d5760320 10321 mbedtls_sha512_free( &handshake->fin_sha512 );
kenjiArai 0:5b88d5760320 10322 #endif
kenjiArai 0:5b88d5760320 10323 #endif
kenjiArai 0:5b88d5760320 10324 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 10325
kenjiArai 0:5b88d5760320 10326 #if defined(MBEDTLS_DHM_C)
kenjiArai 0:5b88d5760320 10327 mbedtls_dhm_free( &handshake->dhm_ctx );
kenjiArai 0:5b88d5760320 10328 #endif
kenjiArai 0:5b88d5760320 10329 #if defined(MBEDTLS_ECDH_C)
kenjiArai 0:5b88d5760320 10330 mbedtls_ecdh_free( &handshake->ecdh_ctx );
kenjiArai 0:5b88d5760320 10331 #endif
kenjiArai 0:5b88d5760320 10332 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
kenjiArai 0:5b88d5760320 10333 mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
kenjiArai 0:5b88d5760320 10334 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 10335 mbedtls_free( handshake->ecjpake_cache );
kenjiArai 0:5b88d5760320 10336 handshake->ecjpake_cache = NULL;
kenjiArai 0:5b88d5760320 10337 handshake->ecjpake_cache_len = 0;
kenjiArai 0:5b88d5760320 10338 #endif
kenjiArai 0:5b88d5760320 10339 #endif
kenjiArai 0:5b88d5760320 10340
kenjiArai 0:5b88d5760320 10341 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
kenjiArai 0:5b88d5760320 10342 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
kenjiArai 0:5b88d5760320 10343 /* explicit void pointer cast for buggy MS compiler */
kenjiArai 0:5b88d5760320 10344 mbedtls_free( (void *) handshake->curves );
kenjiArai 0:5b88d5760320 10345 #endif
kenjiArai 0:5b88d5760320 10346
kenjiArai 0:5b88d5760320 10347 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
kenjiArai 0:5b88d5760320 10348 if( handshake->psk != NULL )
kenjiArai 0:5b88d5760320 10349 {
kenjiArai 0:5b88d5760320 10350 mbedtls_platform_zeroize( handshake->psk, handshake->psk_len );
kenjiArai 0:5b88d5760320 10351 mbedtls_free( handshake->psk );
kenjiArai 0:5b88d5760320 10352 }
kenjiArai 0:5b88d5760320 10353 #endif
kenjiArai 0:5b88d5760320 10354
kenjiArai 0:5b88d5760320 10355 #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
kenjiArai 0:5b88d5760320 10356 defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
kenjiArai 0:5b88d5760320 10357 /*
kenjiArai 0:5b88d5760320 10358 * Free only the linked list wrapper, not the keys themselves
kenjiArai 0:5b88d5760320 10359 * since the belong to the SNI callback
kenjiArai 0:5b88d5760320 10360 */
kenjiArai 0:5b88d5760320 10361 if( handshake->sni_key_cert != NULL )
kenjiArai 0:5b88d5760320 10362 {
kenjiArai 0:5b88d5760320 10363 mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
kenjiArai 0:5b88d5760320 10364
kenjiArai 0:5b88d5760320 10365 while( cur != NULL )
kenjiArai 0:5b88d5760320 10366 {
kenjiArai 0:5b88d5760320 10367 next = cur->next;
kenjiArai 0:5b88d5760320 10368 mbedtls_free( cur );
kenjiArai 0:5b88d5760320 10369 cur = next;
kenjiArai 0:5b88d5760320 10370 }
kenjiArai 0:5b88d5760320 10371 }
kenjiArai 0:5b88d5760320 10372 #endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
kenjiArai 0:5b88d5760320 10373
kenjiArai 0:5b88d5760320 10374 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 10375 mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx );
kenjiArai 0:5b88d5760320 10376 if( handshake->ecrs_peer_cert != NULL )
kenjiArai 0:5b88d5760320 10377 {
kenjiArai 0:5b88d5760320 10378 mbedtls_x509_crt_free( handshake->ecrs_peer_cert );
kenjiArai 0:5b88d5760320 10379 mbedtls_free( handshake->ecrs_peer_cert );
kenjiArai 0:5b88d5760320 10380 }
kenjiArai 0:5b88d5760320 10381 #endif
kenjiArai 0:5b88d5760320 10382
kenjiArai 0:5b88d5760320 10383 #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
kenjiArai 0:5b88d5760320 10384 !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
kenjiArai 0:5b88d5760320 10385 mbedtls_pk_free( &handshake->peer_pubkey );
kenjiArai 0:5b88d5760320 10386 #endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
kenjiArai 0:5b88d5760320 10387
kenjiArai 0:5b88d5760320 10388 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 10389 mbedtls_free( handshake->verify_cookie );
kenjiArai 0:5b88d5760320 10390 ssl_flight_free( handshake->flight );
kenjiArai 0:5b88d5760320 10391 ssl_buffering_free( ssl );
kenjiArai 0:5b88d5760320 10392 #endif
kenjiArai 0:5b88d5760320 10393
kenjiArai 0:5b88d5760320 10394 #if defined(MBEDTLS_ECDH_C) && \
kenjiArai 0:5b88d5760320 10395 defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 10396 psa_destroy_key( handshake->ecdh_psa_privkey );
kenjiArai 0:5b88d5760320 10397 #endif /* MBEDTLS_ECDH_C && MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 10398
kenjiArai 0:5b88d5760320 10399 mbedtls_platform_zeroize( handshake,
kenjiArai 0:5b88d5760320 10400 sizeof( mbedtls_ssl_handshake_params ) );
kenjiArai 0:5b88d5760320 10401 }
kenjiArai 0:5b88d5760320 10402
kenjiArai 0:5b88d5760320 10403 void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
kenjiArai 0:5b88d5760320 10404 {
kenjiArai 0:5b88d5760320 10405 if( session == NULL )
kenjiArai 0:5b88d5760320 10406 return;
kenjiArai 0:5b88d5760320 10407
kenjiArai 0:5b88d5760320 10408 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 10409 ssl_clear_peer_cert( session );
kenjiArai 0:5b88d5760320 10410 #endif
kenjiArai 0:5b88d5760320 10411
kenjiArai 0:5b88d5760320 10412 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 10413 mbedtls_free( session->ticket );
kenjiArai 0:5b88d5760320 10414 #endif
kenjiArai 0:5b88d5760320 10415
kenjiArai 0:5b88d5760320 10416 mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) );
kenjiArai 0:5b88d5760320 10417 }
kenjiArai 0:5b88d5760320 10418
kenjiArai 0:5b88d5760320 10419 /*
kenjiArai 0:5b88d5760320 10420 * Free an SSL context
kenjiArai 0:5b88d5760320 10421 */
kenjiArai 0:5b88d5760320 10422 void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
kenjiArai 0:5b88d5760320 10423 {
kenjiArai 0:5b88d5760320 10424 if( ssl == NULL )
kenjiArai 0:5b88d5760320 10425 return;
kenjiArai 0:5b88d5760320 10426
kenjiArai 0:5b88d5760320 10427 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) );
kenjiArai 0:5b88d5760320 10428
kenjiArai 0:5b88d5760320 10429 if( ssl->out_buf != NULL )
kenjiArai 0:5b88d5760320 10430 {
kenjiArai 0:5b88d5760320 10431 mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN );
kenjiArai 0:5b88d5760320 10432 mbedtls_free( ssl->out_buf );
kenjiArai 0:5b88d5760320 10433 }
kenjiArai 0:5b88d5760320 10434
kenjiArai 0:5b88d5760320 10435 if( ssl->in_buf != NULL )
kenjiArai 0:5b88d5760320 10436 {
kenjiArai 0:5b88d5760320 10437 mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN );
kenjiArai 0:5b88d5760320 10438 mbedtls_free( ssl->in_buf );
kenjiArai 0:5b88d5760320 10439 }
kenjiArai 0:5b88d5760320 10440
kenjiArai 0:5b88d5760320 10441 #if defined(MBEDTLS_ZLIB_SUPPORT)
kenjiArai 0:5b88d5760320 10442 if( ssl->compress_buf != NULL )
kenjiArai 0:5b88d5760320 10443 {
kenjiArai 0:5b88d5760320 10444 mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
kenjiArai 0:5b88d5760320 10445 mbedtls_free( ssl->compress_buf );
kenjiArai 0:5b88d5760320 10446 }
kenjiArai 0:5b88d5760320 10447 #endif
kenjiArai 0:5b88d5760320 10448
kenjiArai 0:5b88d5760320 10449 if( ssl->transform )
kenjiArai 0:5b88d5760320 10450 {
kenjiArai 0:5b88d5760320 10451 mbedtls_ssl_transform_free( ssl->transform );
kenjiArai 0:5b88d5760320 10452 mbedtls_free( ssl->transform );
kenjiArai 0:5b88d5760320 10453 }
kenjiArai 0:5b88d5760320 10454
kenjiArai 0:5b88d5760320 10455 if( ssl->handshake )
kenjiArai 0:5b88d5760320 10456 {
kenjiArai 0:5b88d5760320 10457 mbedtls_ssl_handshake_free( ssl );
kenjiArai 0:5b88d5760320 10458 mbedtls_ssl_transform_free( ssl->transform_negotiate );
kenjiArai 0:5b88d5760320 10459 mbedtls_ssl_session_free( ssl->session_negotiate );
kenjiArai 0:5b88d5760320 10460
kenjiArai 0:5b88d5760320 10461 mbedtls_free( ssl->handshake );
kenjiArai 0:5b88d5760320 10462 mbedtls_free( ssl->transform_negotiate );
kenjiArai 0:5b88d5760320 10463 mbedtls_free( ssl->session_negotiate );
kenjiArai 0:5b88d5760320 10464 }
kenjiArai 0:5b88d5760320 10465
kenjiArai 0:5b88d5760320 10466 if( ssl->session )
kenjiArai 0:5b88d5760320 10467 {
kenjiArai 0:5b88d5760320 10468 mbedtls_ssl_session_free( ssl->session );
kenjiArai 0:5b88d5760320 10469 mbedtls_free( ssl->session );
kenjiArai 0:5b88d5760320 10470 }
kenjiArai 0:5b88d5760320 10471
kenjiArai 0:5b88d5760320 10472 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 10473 if( ssl->hostname != NULL )
kenjiArai 0:5b88d5760320 10474 {
kenjiArai 0:5b88d5760320 10475 mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) );
kenjiArai 0:5b88d5760320 10476 mbedtls_free( ssl->hostname );
kenjiArai 0:5b88d5760320 10477 }
kenjiArai 0:5b88d5760320 10478 #endif
kenjiArai 0:5b88d5760320 10479
kenjiArai 0:5b88d5760320 10480 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
kenjiArai 0:5b88d5760320 10481 if( mbedtls_ssl_hw_record_finish != NULL )
kenjiArai 0:5b88d5760320 10482 {
kenjiArai 0:5b88d5760320 10483 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_finish()" ) );
kenjiArai 0:5b88d5760320 10484 mbedtls_ssl_hw_record_finish( ssl );
kenjiArai 0:5b88d5760320 10485 }
kenjiArai 0:5b88d5760320 10486 #endif
kenjiArai 0:5b88d5760320 10487
kenjiArai 0:5b88d5760320 10488 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 10489 mbedtls_free( ssl->cli_id );
kenjiArai 0:5b88d5760320 10490 #endif
kenjiArai 0:5b88d5760320 10491
kenjiArai 0:5b88d5760320 10492 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) );
kenjiArai 0:5b88d5760320 10493
kenjiArai 0:5b88d5760320 10494 /* Actually clear after last debug message */
kenjiArai 0:5b88d5760320 10495 mbedtls_platform_zeroize( ssl, sizeof( mbedtls_ssl_context ) );
kenjiArai 0:5b88d5760320 10496 }
kenjiArai 0:5b88d5760320 10497
kenjiArai 0:5b88d5760320 10498 /*
kenjiArai 0:5b88d5760320 10499 * Initialze mbedtls_ssl_config
kenjiArai 0:5b88d5760320 10500 */
kenjiArai 0:5b88d5760320 10501 void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
kenjiArai 0:5b88d5760320 10502 {
kenjiArai 0:5b88d5760320 10503 memset( conf, 0, sizeof( mbedtls_ssl_config ) );
kenjiArai 0:5b88d5760320 10504 }
kenjiArai 0:5b88d5760320 10505
kenjiArai 0:5b88d5760320 10506 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 10507 static int ssl_preset_default_hashes[] = {
kenjiArai 0:5b88d5760320 10508 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 10509 MBEDTLS_MD_SHA512,
kenjiArai 0:5b88d5760320 10510 MBEDTLS_MD_SHA384,
kenjiArai 0:5b88d5760320 10511 #endif
kenjiArai 0:5b88d5760320 10512 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 10513 MBEDTLS_MD_SHA256,
kenjiArai 0:5b88d5760320 10514 MBEDTLS_MD_SHA224,
kenjiArai 0:5b88d5760320 10515 #endif
kenjiArai 0:5b88d5760320 10516 #if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE)
kenjiArai 0:5b88d5760320 10517 MBEDTLS_MD_SHA1,
kenjiArai 0:5b88d5760320 10518 #endif
kenjiArai 0:5b88d5760320 10519 MBEDTLS_MD_NONE
kenjiArai 0:5b88d5760320 10520 };
kenjiArai 0:5b88d5760320 10521 #endif
kenjiArai 0:5b88d5760320 10522
kenjiArai 0:5b88d5760320 10523 static int ssl_preset_suiteb_ciphersuites[] = {
kenjiArai 0:5b88d5760320 10524 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
kenjiArai 0:5b88d5760320 10525 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
kenjiArai 0:5b88d5760320 10526 0
kenjiArai 0:5b88d5760320 10527 };
kenjiArai 0:5b88d5760320 10528
kenjiArai 0:5b88d5760320 10529 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 10530 static int ssl_preset_suiteb_hashes[] = {
kenjiArai 0:5b88d5760320 10531 MBEDTLS_MD_SHA256,
kenjiArai 0:5b88d5760320 10532 MBEDTLS_MD_SHA384,
kenjiArai 0:5b88d5760320 10533 MBEDTLS_MD_NONE
kenjiArai 0:5b88d5760320 10534 };
kenjiArai 0:5b88d5760320 10535 #endif
kenjiArai 0:5b88d5760320 10536
kenjiArai 0:5b88d5760320 10537 #if defined(MBEDTLS_ECP_C)
kenjiArai 0:5b88d5760320 10538 static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = {
kenjiArai 0:5b88d5760320 10539 MBEDTLS_ECP_DP_SECP256R1,
kenjiArai 0:5b88d5760320 10540 MBEDTLS_ECP_DP_SECP384R1,
kenjiArai 0:5b88d5760320 10541 MBEDTLS_ECP_DP_NONE
kenjiArai 0:5b88d5760320 10542 };
kenjiArai 0:5b88d5760320 10543 #endif
kenjiArai 0:5b88d5760320 10544
kenjiArai 0:5b88d5760320 10545 /*
kenjiArai 0:5b88d5760320 10546 * Load default in mbedtls_ssl_config
kenjiArai 0:5b88d5760320 10547 */
kenjiArai 0:5b88d5760320 10548 int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
kenjiArai 0:5b88d5760320 10549 int endpoint, int transport, int preset )
kenjiArai 0:5b88d5760320 10550 {
kenjiArai 0:5b88d5760320 10551 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 10552 int ret;
kenjiArai 0:5b88d5760320 10553 #endif
kenjiArai 0:5b88d5760320 10554
kenjiArai 0:5b88d5760320 10555 /* Use the functions here so that they are covered in tests,
kenjiArai 0:5b88d5760320 10556 * but otherwise access member directly for efficiency */
kenjiArai 0:5b88d5760320 10557 mbedtls_ssl_conf_endpoint( conf, endpoint );
kenjiArai 0:5b88d5760320 10558 mbedtls_ssl_conf_transport( conf, transport );
kenjiArai 0:5b88d5760320 10559
kenjiArai 0:5b88d5760320 10560 /*
kenjiArai 0:5b88d5760320 10561 * Things that are common to all presets
kenjiArai 0:5b88d5760320 10562 */
kenjiArai 0:5b88d5760320 10563 #if defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 10564 if( endpoint == MBEDTLS_SSL_IS_CLIENT )
kenjiArai 0:5b88d5760320 10565 {
kenjiArai 0:5b88d5760320 10566 conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
kenjiArai 0:5b88d5760320 10567 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
kenjiArai 0:5b88d5760320 10568 conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
kenjiArai 0:5b88d5760320 10569 #endif
kenjiArai 0:5b88d5760320 10570 }
kenjiArai 0:5b88d5760320 10571 #endif
kenjiArai 0:5b88d5760320 10572
kenjiArai 0:5b88d5760320 10573 #if defined(MBEDTLS_ARC4_C)
kenjiArai 0:5b88d5760320 10574 conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED;
kenjiArai 0:5b88d5760320 10575 #endif
kenjiArai 0:5b88d5760320 10576
kenjiArai 0:5b88d5760320 10577 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
kenjiArai 0:5b88d5760320 10578 conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
kenjiArai 0:5b88d5760320 10579 #endif
kenjiArai 0:5b88d5760320 10580
kenjiArai 0:5b88d5760320 10581 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
kenjiArai 0:5b88d5760320 10582 conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
kenjiArai 0:5b88d5760320 10583 #endif
kenjiArai 0:5b88d5760320 10584
kenjiArai 0:5b88d5760320 10585 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
kenjiArai 0:5b88d5760320 10586 conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED;
kenjiArai 0:5b88d5760320 10587 #endif
kenjiArai 0:5b88d5760320 10588
kenjiArai 0:5b88d5760320 10589 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 10590 conf->f_cookie_write = ssl_cookie_write_dummy;
kenjiArai 0:5b88d5760320 10591 conf->f_cookie_check = ssl_cookie_check_dummy;
kenjiArai 0:5b88d5760320 10592 #endif
kenjiArai 0:5b88d5760320 10593
kenjiArai 0:5b88d5760320 10594 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
kenjiArai 0:5b88d5760320 10595 conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED;
kenjiArai 0:5b88d5760320 10596 #endif
kenjiArai 0:5b88d5760320 10597
kenjiArai 0:5b88d5760320 10598 #if defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 10599 conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
kenjiArai 0:5b88d5760320 10600 #endif
kenjiArai 0:5b88d5760320 10601
kenjiArai 0:5b88d5760320 10602 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 10603 conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
kenjiArai 0:5b88d5760320 10604 conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
kenjiArai 0:5b88d5760320 10605 #endif
kenjiArai 0:5b88d5760320 10606
kenjiArai 0:5b88d5760320 10607 #if defined(MBEDTLS_SSL_RENEGOTIATION)
kenjiArai 0:5b88d5760320 10608 conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT;
kenjiArai 0:5b88d5760320 10609 memset( conf->renego_period, 0x00, 2 );
kenjiArai 0:5b88d5760320 10610 memset( conf->renego_period + 2, 0xFF, 6 );
kenjiArai 0:5b88d5760320 10611 #endif
kenjiArai 0:5b88d5760320 10612
kenjiArai 0:5b88d5760320 10613 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
kenjiArai 0:5b88d5760320 10614 if( endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 10615 {
kenjiArai 0:5b88d5760320 10616 const unsigned char dhm_p[] =
kenjiArai 0:5b88d5760320 10617 MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
kenjiArai 0:5b88d5760320 10618 const unsigned char dhm_g[] =
kenjiArai 0:5b88d5760320 10619 MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
kenjiArai 0:5b88d5760320 10620
kenjiArai 0:5b88d5760320 10621 if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf,
kenjiArai 0:5b88d5760320 10622 dhm_p, sizeof( dhm_p ),
kenjiArai 0:5b88d5760320 10623 dhm_g, sizeof( dhm_g ) ) ) != 0 )
kenjiArai 0:5b88d5760320 10624 {
kenjiArai 0:5b88d5760320 10625 return( ret );
kenjiArai 0:5b88d5760320 10626 }
kenjiArai 0:5b88d5760320 10627 }
kenjiArai 0:5b88d5760320 10628 #endif
kenjiArai 0:5b88d5760320 10629
kenjiArai 0:5b88d5760320 10630 /*
kenjiArai 0:5b88d5760320 10631 * Preset-specific defaults
kenjiArai 0:5b88d5760320 10632 */
kenjiArai 0:5b88d5760320 10633 switch( preset )
kenjiArai 0:5b88d5760320 10634 {
kenjiArai 0:5b88d5760320 10635 /*
kenjiArai 0:5b88d5760320 10636 * NSA Suite B
kenjiArai 0:5b88d5760320 10637 */
kenjiArai 0:5b88d5760320 10638 case MBEDTLS_SSL_PRESET_SUITEB:
kenjiArai 0:5b88d5760320 10639 conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
kenjiArai 0:5b88d5760320 10640 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
kenjiArai 0:5b88d5760320 10641 conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
kenjiArai 0:5b88d5760320 10642 conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
kenjiArai 0:5b88d5760320 10643
kenjiArai 0:5b88d5760320 10644 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
kenjiArai 0:5b88d5760320 10645 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
kenjiArai 0:5b88d5760320 10646 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
kenjiArai 0:5b88d5760320 10647 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
kenjiArai 0:5b88d5760320 10648 ssl_preset_suiteb_ciphersuites;
kenjiArai 0:5b88d5760320 10649
kenjiArai 0:5b88d5760320 10650 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 10651 conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
kenjiArai 0:5b88d5760320 10652 #endif
kenjiArai 0:5b88d5760320 10653
kenjiArai 0:5b88d5760320 10654 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 10655 conf->sig_hashes = ssl_preset_suiteb_hashes;
kenjiArai 0:5b88d5760320 10656 #endif
kenjiArai 0:5b88d5760320 10657
kenjiArai 0:5b88d5760320 10658 #if defined(MBEDTLS_ECP_C)
kenjiArai 0:5b88d5760320 10659 conf->curve_list = ssl_preset_suiteb_curves;
kenjiArai 0:5b88d5760320 10660 #endif
kenjiArai 0:5b88d5760320 10661 break;
kenjiArai 0:5b88d5760320 10662
kenjiArai 0:5b88d5760320 10663 /*
kenjiArai 0:5b88d5760320 10664 * Default
kenjiArai 0:5b88d5760320 10665 */
kenjiArai 0:5b88d5760320 10666 default:
kenjiArai 0:5b88d5760320 10667 conf->min_major_ver = ( MBEDTLS_SSL_MIN_MAJOR_VERSION >
kenjiArai 0:5b88d5760320 10668 MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION ) ?
kenjiArai 0:5b88d5760320 10669 MBEDTLS_SSL_MIN_MAJOR_VERSION :
kenjiArai 0:5b88d5760320 10670 MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION;
kenjiArai 0:5b88d5760320 10671 conf->min_minor_ver = ( MBEDTLS_SSL_MIN_MINOR_VERSION >
kenjiArai 0:5b88d5760320 10672 MBEDTLS_SSL_MIN_VALID_MINOR_VERSION ) ?
kenjiArai 0:5b88d5760320 10673 MBEDTLS_SSL_MIN_MINOR_VERSION :
kenjiArai 0:5b88d5760320 10674 MBEDTLS_SSL_MIN_VALID_MINOR_VERSION;
kenjiArai 0:5b88d5760320 10675 conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
kenjiArai 0:5b88d5760320 10676 conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
kenjiArai 0:5b88d5760320 10677
kenjiArai 0:5b88d5760320 10678 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 10679 if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 10680 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
kenjiArai 0:5b88d5760320 10681 #endif
kenjiArai 0:5b88d5760320 10682
kenjiArai 0:5b88d5760320 10683 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
kenjiArai 0:5b88d5760320 10684 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
kenjiArai 0:5b88d5760320 10685 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
kenjiArai 0:5b88d5760320 10686 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
kenjiArai 0:5b88d5760320 10687 mbedtls_ssl_list_ciphersuites();
kenjiArai 0:5b88d5760320 10688
kenjiArai 0:5b88d5760320 10689 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 10690 conf->cert_profile = &mbedtls_x509_crt_profile_default;
kenjiArai 0:5b88d5760320 10691 #endif
kenjiArai 0:5b88d5760320 10692
kenjiArai 0:5b88d5760320 10693 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 10694 conf->sig_hashes = ssl_preset_default_hashes;
kenjiArai 0:5b88d5760320 10695 #endif
kenjiArai 0:5b88d5760320 10696
kenjiArai 0:5b88d5760320 10697 #if defined(MBEDTLS_ECP_C)
kenjiArai 0:5b88d5760320 10698 conf->curve_list = mbedtls_ecp_grp_id_list();
kenjiArai 0:5b88d5760320 10699 #endif
kenjiArai 0:5b88d5760320 10700
kenjiArai 0:5b88d5760320 10701 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
kenjiArai 0:5b88d5760320 10702 conf->dhm_min_bitlen = 1024;
kenjiArai 0:5b88d5760320 10703 #endif
kenjiArai 0:5b88d5760320 10704 }
kenjiArai 0:5b88d5760320 10705
kenjiArai 0:5b88d5760320 10706 return( 0 );
kenjiArai 0:5b88d5760320 10707 }
kenjiArai 0:5b88d5760320 10708
kenjiArai 0:5b88d5760320 10709 /*
kenjiArai 0:5b88d5760320 10710 * Free mbedtls_ssl_config
kenjiArai 0:5b88d5760320 10711 */
kenjiArai 0:5b88d5760320 10712 void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
kenjiArai 0:5b88d5760320 10713 {
kenjiArai 0:5b88d5760320 10714 #if defined(MBEDTLS_DHM_C)
kenjiArai 0:5b88d5760320 10715 mbedtls_mpi_free( &conf->dhm_P );
kenjiArai 0:5b88d5760320 10716 mbedtls_mpi_free( &conf->dhm_G );
kenjiArai 0:5b88d5760320 10717 #endif
kenjiArai 0:5b88d5760320 10718
kenjiArai 0:5b88d5760320 10719 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
kenjiArai 0:5b88d5760320 10720 if( conf->psk != NULL )
kenjiArai 0:5b88d5760320 10721 {
kenjiArai 0:5b88d5760320 10722 mbedtls_platform_zeroize( conf->psk, conf->psk_len );
kenjiArai 0:5b88d5760320 10723 mbedtls_free( conf->psk );
kenjiArai 0:5b88d5760320 10724 conf->psk = NULL;
kenjiArai 0:5b88d5760320 10725 conf->psk_len = 0;
kenjiArai 0:5b88d5760320 10726 }
kenjiArai 0:5b88d5760320 10727
kenjiArai 0:5b88d5760320 10728 if( conf->psk_identity != NULL )
kenjiArai 0:5b88d5760320 10729 {
kenjiArai 0:5b88d5760320 10730 mbedtls_platform_zeroize( conf->psk_identity, conf->psk_identity_len );
kenjiArai 0:5b88d5760320 10731 mbedtls_free( conf->psk_identity );
kenjiArai 0:5b88d5760320 10732 conf->psk_identity = NULL;
kenjiArai 0:5b88d5760320 10733 conf->psk_identity_len = 0;
kenjiArai 0:5b88d5760320 10734 }
kenjiArai 0:5b88d5760320 10735 #endif
kenjiArai 0:5b88d5760320 10736
kenjiArai 0:5b88d5760320 10737 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 10738 ssl_key_cert_free( conf->key_cert );
kenjiArai 0:5b88d5760320 10739 #endif
kenjiArai 0:5b88d5760320 10740
kenjiArai 0:5b88d5760320 10741 mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) );
kenjiArai 0:5b88d5760320 10742 }
kenjiArai 0:5b88d5760320 10743
kenjiArai 0:5b88d5760320 10744 #if defined(MBEDTLS_PK_C) && \
kenjiArai 0:5b88d5760320 10745 ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) )
kenjiArai 0:5b88d5760320 10746 /*
kenjiArai 0:5b88d5760320 10747 * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
kenjiArai 0:5b88d5760320 10748 */
kenjiArai 0:5b88d5760320 10749 unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk )
kenjiArai 0:5b88d5760320 10750 {
kenjiArai 0:5b88d5760320 10751 #if defined(MBEDTLS_RSA_C)
kenjiArai 0:5b88d5760320 10752 if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) )
kenjiArai 0:5b88d5760320 10753 return( MBEDTLS_SSL_SIG_RSA );
kenjiArai 0:5b88d5760320 10754 #endif
kenjiArai 0:5b88d5760320 10755 #if defined(MBEDTLS_ECDSA_C)
kenjiArai 0:5b88d5760320 10756 if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) )
kenjiArai 0:5b88d5760320 10757 return( MBEDTLS_SSL_SIG_ECDSA );
kenjiArai 0:5b88d5760320 10758 #endif
kenjiArai 0:5b88d5760320 10759 return( MBEDTLS_SSL_SIG_ANON );
kenjiArai 0:5b88d5760320 10760 }
kenjiArai 0:5b88d5760320 10761
kenjiArai 0:5b88d5760320 10762 unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type )
kenjiArai 0:5b88d5760320 10763 {
kenjiArai 0:5b88d5760320 10764 switch( type ) {
kenjiArai 0:5b88d5760320 10765 case MBEDTLS_PK_RSA:
kenjiArai 0:5b88d5760320 10766 return( MBEDTLS_SSL_SIG_RSA );
kenjiArai 0:5b88d5760320 10767 case MBEDTLS_PK_ECDSA:
kenjiArai 0:5b88d5760320 10768 case MBEDTLS_PK_ECKEY:
kenjiArai 0:5b88d5760320 10769 return( MBEDTLS_SSL_SIG_ECDSA );
kenjiArai 0:5b88d5760320 10770 default:
kenjiArai 0:5b88d5760320 10771 return( MBEDTLS_SSL_SIG_ANON );
kenjiArai 0:5b88d5760320 10772 }
kenjiArai 0:5b88d5760320 10773 }
kenjiArai 0:5b88d5760320 10774
kenjiArai 0:5b88d5760320 10775 mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
kenjiArai 0:5b88d5760320 10776 {
kenjiArai 0:5b88d5760320 10777 switch( sig )
kenjiArai 0:5b88d5760320 10778 {
kenjiArai 0:5b88d5760320 10779 #if defined(MBEDTLS_RSA_C)
kenjiArai 0:5b88d5760320 10780 case MBEDTLS_SSL_SIG_RSA:
kenjiArai 0:5b88d5760320 10781 return( MBEDTLS_PK_RSA );
kenjiArai 0:5b88d5760320 10782 #endif
kenjiArai 0:5b88d5760320 10783 #if defined(MBEDTLS_ECDSA_C)
kenjiArai 0:5b88d5760320 10784 case MBEDTLS_SSL_SIG_ECDSA:
kenjiArai 0:5b88d5760320 10785 return( MBEDTLS_PK_ECDSA );
kenjiArai 0:5b88d5760320 10786 #endif
kenjiArai 0:5b88d5760320 10787 default:
kenjiArai 0:5b88d5760320 10788 return( MBEDTLS_PK_NONE );
kenjiArai 0:5b88d5760320 10789 }
kenjiArai 0:5b88d5760320 10790 }
kenjiArai 0:5b88d5760320 10791 #endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
kenjiArai 0:5b88d5760320 10792
kenjiArai 0:5b88d5760320 10793 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
kenjiArai 0:5b88d5760320 10794 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 10795
kenjiArai 0:5b88d5760320 10796 /* Find an entry in a signature-hash set matching a given hash algorithm. */
kenjiArai 0:5b88d5760320 10797 mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
kenjiArai 0:5b88d5760320 10798 mbedtls_pk_type_t sig_alg )
kenjiArai 0:5b88d5760320 10799 {
kenjiArai 0:5b88d5760320 10800 switch( sig_alg )
kenjiArai 0:5b88d5760320 10801 {
kenjiArai 0:5b88d5760320 10802 case MBEDTLS_PK_RSA:
kenjiArai 0:5b88d5760320 10803 return( set->rsa );
kenjiArai 0:5b88d5760320 10804 case MBEDTLS_PK_ECDSA:
kenjiArai 0:5b88d5760320 10805 return( set->ecdsa );
kenjiArai 0:5b88d5760320 10806 default:
kenjiArai 0:5b88d5760320 10807 return( MBEDTLS_MD_NONE );
kenjiArai 0:5b88d5760320 10808 }
kenjiArai 0:5b88d5760320 10809 }
kenjiArai 0:5b88d5760320 10810
kenjiArai 0:5b88d5760320 10811 /* Add a signature-hash-pair to a signature-hash set */
kenjiArai 0:5b88d5760320 10812 void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
kenjiArai 0:5b88d5760320 10813 mbedtls_pk_type_t sig_alg,
kenjiArai 0:5b88d5760320 10814 mbedtls_md_type_t md_alg )
kenjiArai 0:5b88d5760320 10815 {
kenjiArai 0:5b88d5760320 10816 switch( sig_alg )
kenjiArai 0:5b88d5760320 10817 {
kenjiArai 0:5b88d5760320 10818 case MBEDTLS_PK_RSA:
kenjiArai 0:5b88d5760320 10819 if( set->rsa == MBEDTLS_MD_NONE )
kenjiArai 0:5b88d5760320 10820 set->rsa = md_alg;
kenjiArai 0:5b88d5760320 10821 break;
kenjiArai 0:5b88d5760320 10822
kenjiArai 0:5b88d5760320 10823 case MBEDTLS_PK_ECDSA:
kenjiArai 0:5b88d5760320 10824 if( set->ecdsa == MBEDTLS_MD_NONE )
kenjiArai 0:5b88d5760320 10825 set->ecdsa = md_alg;
kenjiArai 0:5b88d5760320 10826 break;
kenjiArai 0:5b88d5760320 10827
kenjiArai 0:5b88d5760320 10828 default:
kenjiArai 0:5b88d5760320 10829 break;
kenjiArai 0:5b88d5760320 10830 }
kenjiArai 0:5b88d5760320 10831 }
kenjiArai 0:5b88d5760320 10832
kenjiArai 0:5b88d5760320 10833 /* Allow exactly one hash algorithm for each signature. */
kenjiArai 0:5b88d5760320 10834 void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
kenjiArai 0:5b88d5760320 10835 mbedtls_md_type_t md_alg )
kenjiArai 0:5b88d5760320 10836 {
kenjiArai 0:5b88d5760320 10837 set->rsa = md_alg;
kenjiArai 0:5b88d5760320 10838 set->ecdsa = md_alg;
kenjiArai 0:5b88d5760320 10839 }
kenjiArai 0:5b88d5760320 10840
kenjiArai 0:5b88d5760320 10841 #endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
kenjiArai 0:5b88d5760320 10842 MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
kenjiArai 0:5b88d5760320 10843
kenjiArai 0:5b88d5760320 10844 /*
kenjiArai 0:5b88d5760320 10845 * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
kenjiArai 0:5b88d5760320 10846 */
kenjiArai 0:5b88d5760320 10847 mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash )
kenjiArai 0:5b88d5760320 10848 {
kenjiArai 0:5b88d5760320 10849 switch( hash )
kenjiArai 0:5b88d5760320 10850 {
kenjiArai 0:5b88d5760320 10851 #if defined(MBEDTLS_MD5_C)
kenjiArai 0:5b88d5760320 10852 case MBEDTLS_SSL_HASH_MD5:
kenjiArai 0:5b88d5760320 10853 return( MBEDTLS_MD_MD5 );
kenjiArai 0:5b88d5760320 10854 #endif
kenjiArai 0:5b88d5760320 10855 #if defined(MBEDTLS_SHA1_C)
kenjiArai 0:5b88d5760320 10856 case MBEDTLS_SSL_HASH_SHA1:
kenjiArai 0:5b88d5760320 10857 return( MBEDTLS_MD_SHA1 );
kenjiArai 0:5b88d5760320 10858 #endif
kenjiArai 0:5b88d5760320 10859 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 10860 case MBEDTLS_SSL_HASH_SHA224:
kenjiArai 0:5b88d5760320 10861 return( MBEDTLS_MD_SHA224 );
kenjiArai 0:5b88d5760320 10862 case MBEDTLS_SSL_HASH_SHA256:
kenjiArai 0:5b88d5760320 10863 return( MBEDTLS_MD_SHA256 );
kenjiArai 0:5b88d5760320 10864 #endif
kenjiArai 0:5b88d5760320 10865 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 10866 case MBEDTLS_SSL_HASH_SHA384:
kenjiArai 0:5b88d5760320 10867 return( MBEDTLS_MD_SHA384 );
kenjiArai 0:5b88d5760320 10868 case MBEDTLS_SSL_HASH_SHA512:
kenjiArai 0:5b88d5760320 10869 return( MBEDTLS_MD_SHA512 );
kenjiArai 0:5b88d5760320 10870 #endif
kenjiArai 0:5b88d5760320 10871 default:
kenjiArai 0:5b88d5760320 10872 return( MBEDTLS_MD_NONE );
kenjiArai 0:5b88d5760320 10873 }
kenjiArai 0:5b88d5760320 10874 }
kenjiArai 0:5b88d5760320 10875
kenjiArai 0:5b88d5760320 10876 /*
kenjiArai 0:5b88d5760320 10877 * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX
kenjiArai 0:5b88d5760320 10878 */
kenjiArai 0:5b88d5760320 10879 unsigned char mbedtls_ssl_hash_from_md_alg( int md )
kenjiArai 0:5b88d5760320 10880 {
kenjiArai 0:5b88d5760320 10881 switch( md )
kenjiArai 0:5b88d5760320 10882 {
kenjiArai 0:5b88d5760320 10883 #if defined(MBEDTLS_MD5_C)
kenjiArai 0:5b88d5760320 10884 case MBEDTLS_MD_MD5:
kenjiArai 0:5b88d5760320 10885 return( MBEDTLS_SSL_HASH_MD5 );
kenjiArai 0:5b88d5760320 10886 #endif
kenjiArai 0:5b88d5760320 10887 #if defined(MBEDTLS_SHA1_C)
kenjiArai 0:5b88d5760320 10888 case MBEDTLS_MD_SHA1:
kenjiArai 0:5b88d5760320 10889 return( MBEDTLS_SSL_HASH_SHA1 );
kenjiArai 0:5b88d5760320 10890 #endif
kenjiArai 0:5b88d5760320 10891 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 10892 case MBEDTLS_MD_SHA224:
kenjiArai 0:5b88d5760320 10893 return( MBEDTLS_SSL_HASH_SHA224 );
kenjiArai 0:5b88d5760320 10894 case MBEDTLS_MD_SHA256:
kenjiArai 0:5b88d5760320 10895 return( MBEDTLS_SSL_HASH_SHA256 );
kenjiArai 0:5b88d5760320 10896 #endif
kenjiArai 0:5b88d5760320 10897 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 10898 case MBEDTLS_MD_SHA384:
kenjiArai 0:5b88d5760320 10899 return( MBEDTLS_SSL_HASH_SHA384 );
kenjiArai 0:5b88d5760320 10900 case MBEDTLS_MD_SHA512:
kenjiArai 0:5b88d5760320 10901 return( MBEDTLS_SSL_HASH_SHA512 );
kenjiArai 0:5b88d5760320 10902 #endif
kenjiArai 0:5b88d5760320 10903 default:
kenjiArai 0:5b88d5760320 10904 return( MBEDTLS_SSL_HASH_NONE );
kenjiArai 0:5b88d5760320 10905 }
kenjiArai 0:5b88d5760320 10906 }
kenjiArai 0:5b88d5760320 10907
kenjiArai 0:5b88d5760320 10908 #if defined(MBEDTLS_ECP_C)
kenjiArai 0:5b88d5760320 10909 /*
kenjiArai 0:5b88d5760320 10910 * Check if a curve proposed by the peer is in our list.
kenjiArai 0:5b88d5760320 10911 * Return 0 if we're willing to use it, -1 otherwise.
kenjiArai 0:5b88d5760320 10912 */
kenjiArai 0:5b88d5760320 10913 int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id )
kenjiArai 0:5b88d5760320 10914 {
kenjiArai 0:5b88d5760320 10915 const mbedtls_ecp_group_id *gid;
kenjiArai 0:5b88d5760320 10916
kenjiArai 0:5b88d5760320 10917 if( ssl->conf->curve_list == NULL )
kenjiArai 0:5b88d5760320 10918 return( -1 );
kenjiArai 0:5b88d5760320 10919
kenjiArai 0:5b88d5760320 10920 for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
kenjiArai 0:5b88d5760320 10921 if( *gid == grp_id )
kenjiArai 0:5b88d5760320 10922 return( 0 );
kenjiArai 0:5b88d5760320 10923
kenjiArai 0:5b88d5760320 10924 return( -1 );
kenjiArai 0:5b88d5760320 10925 }
kenjiArai 0:5b88d5760320 10926 #endif /* MBEDTLS_ECP_C */
kenjiArai 0:5b88d5760320 10927
kenjiArai 0:5b88d5760320 10928 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
kenjiArai 0:5b88d5760320 10929 /*
kenjiArai 0:5b88d5760320 10930 * Check if a hash proposed by the peer is in our list.
kenjiArai 0:5b88d5760320 10931 * Return 0 if we're willing to use it, -1 otherwise.
kenjiArai 0:5b88d5760320 10932 */
kenjiArai 0:5b88d5760320 10933 int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 10934 mbedtls_md_type_t md )
kenjiArai 0:5b88d5760320 10935 {
kenjiArai 0:5b88d5760320 10936 const int *cur;
kenjiArai 0:5b88d5760320 10937
kenjiArai 0:5b88d5760320 10938 if( ssl->conf->sig_hashes == NULL )
kenjiArai 0:5b88d5760320 10939 return( -1 );
kenjiArai 0:5b88d5760320 10940
kenjiArai 0:5b88d5760320 10941 for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
kenjiArai 0:5b88d5760320 10942 if( *cur == (int) md )
kenjiArai 0:5b88d5760320 10943 return( 0 );
kenjiArai 0:5b88d5760320 10944
kenjiArai 0:5b88d5760320 10945 return( -1 );
kenjiArai 0:5b88d5760320 10946 }
kenjiArai 0:5b88d5760320 10947 #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
kenjiArai 0:5b88d5760320 10948
kenjiArai 0:5b88d5760320 10949 #if defined(MBEDTLS_X509_CRT_PARSE_C)
kenjiArai 0:5b88d5760320 10950 int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
kenjiArai 0:5b88d5760320 10951 const mbedtls_ssl_ciphersuite_t *ciphersuite,
kenjiArai 0:5b88d5760320 10952 int cert_endpoint,
kenjiArai 0:5b88d5760320 10953 uint32_t *flags )
kenjiArai 0:5b88d5760320 10954 {
kenjiArai 0:5b88d5760320 10955 int ret = 0;
kenjiArai 0:5b88d5760320 10956 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
kenjiArai 0:5b88d5760320 10957 int usage = 0;
kenjiArai 0:5b88d5760320 10958 #endif
kenjiArai 0:5b88d5760320 10959 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
kenjiArai 0:5b88d5760320 10960 const char *ext_oid;
kenjiArai 0:5b88d5760320 10961 size_t ext_len;
kenjiArai 0:5b88d5760320 10962 #endif
kenjiArai 0:5b88d5760320 10963
kenjiArai 0:5b88d5760320 10964 #if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \
kenjiArai 0:5b88d5760320 10965 !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
kenjiArai 0:5b88d5760320 10966 ((void) cert);
kenjiArai 0:5b88d5760320 10967 ((void) cert_endpoint);
kenjiArai 0:5b88d5760320 10968 ((void) flags);
kenjiArai 0:5b88d5760320 10969 #endif
kenjiArai 0:5b88d5760320 10970
kenjiArai 0:5b88d5760320 10971 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
kenjiArai 0:5b88d5760320 10972 if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 10973 {
kenjiArai 0:5b88d5760320 10974 /* Server part of the key exchange */
kenjiArai 0:5b88d5760320 10975 switch( ciphersuite->key_exchange )
kenjiArai 0:5b88d5760320 10976 {
kenjiArai 0:5b88d5760320 10977 case MBEDTLS_KEY_EXCHANGE_RSA:
kenjiArai 0:5b88d5760320 10978 case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
kenjiArai 0:5b88d5760320 10979 usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
kenjiArai 0:5b88d5760320 10980 break;
kenjiArai 0:5b88d5760320 10981
kenjiArai 0:5b88d5760320 10982 case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
kenjiArai 0:5b88d5760320 10983 case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
kenjiArai 0:5b88d5760320 10984 case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
kenjiArai 0:5b88d5760320 10985 usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
kenjiArai 0:5b88d5760320 10986 break;
kenjiArai 0:5b88d5760320 10987
kenjiArai 0:5b88d5760320 10988 case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
kenjiArai 0:5b88d5760320 10989 case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
kenjiArai 0:5b88d5760320 10990 usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
kenjiArai 0:5b88d5760320 10991 break;
kenjiArai 0:5b88d5760320 10992
kenjiArai 0:5b88d5760320 10993 /* Don't use default: we want warnings when adding new values */
kenjiArai 0:5b88d5760320 10994 case MBEDTLS_KEY_EXCHANGE_NONE:
kenjiArai 0:5b88d5760320 10995 case MBEDTLS_KEY_EXCHANGE_PSK:
kenjiArai 0:5b88d5760320 10996 case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
kenjiArai 0:5b88d5760320 10997 case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
kenjiArai 0:5b88d5760320 10998 case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
kenjiArai 0:5b88d5760320 10999 usage = 0;
kenjiArai 0:5b88d5760320 11000 }
kenjiArai 0:5b88d5760320 11001 }
kenjiArai 0:5b88d5760320 11002 else
kenjiArai 0:5b88d5760320 11003 {
kenjiArai 0:5b88d5760320 11004 /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
kenjiArai 0:5b88d5760320 11005 usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
kenjiArai 0:5b88d5760320 11006 }
kenjiArai 0:5b88d5760320 11007
kenjiArai 0:5b88d5760320 11008 if( mbedtls_x509_crt_check_key_usage( cert, usage ) != 0 )
kenjiArai 0:5b88d5760320 11009 {
kenjiArai 0:5b88d5760320 11010 *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
kenjiArai 0:5b88d5760320 11011 ret = -1;
kenjiArai 0:5b88d5760320 11012 }
kenjiArai 0:5b88d5760320 11013 #else
kenjiArai 0:5b88d5760320 11014 ((void) ciphersuite);
kenjiArai 0:5b88d5760320 11015 #endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
kenjiArai 0:5b88d5760320 11016
kenjiArai 0:5b88d5760320 11017 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
kenjiArai 0:5b88d5760320 11018 if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
kenjiArai 0:5b88d5760320 11019 {
kenjiArai 0:5b88d5760320 11020 ext_oid = MBEDTLS_OID_SERVER_AUTH;
kenjiArai 0:5b88d5760320 11021 ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH );
kenjiArai 0:5b88d5760320 11022 }
kenjiArai 0:5b88d5760320 11023 else
kenjiArai 0:5b88d5760320 11024 {
kenjiArai 0:5b88d5760320 11025 ext_oid = MBEDTLS_OID_CLIENT_AUTH;
kenjiArai 0:5b88d5760320 11026 ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH );
kenjiArai 0:5b88d5760320 11027 }
kenjiArai 0:5b88d5760320 11028
kenjiArai 0:5b88d5760320 11029 if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 )
kenjiArai 0:5b88d5760320 11030 {
kenjiArai 0:5b88d5760320 11031 *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
kenjiArai 0:5b88d5760320 11032 ret = -1;
kenjiArai 0:5b88d5760320 11033 }
kenjiArai 0:5b88d5760320 11034 #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
kenjiArai 0:5b88d5760320 11035
kenjiArai 0:5b88d5760320 11036 return( ret );
kenjiArai 0:5b88d5760320 11037 }
kenjiArai 0:5b88d5760320 11038 #endif /* MBEDTLS_X509_CRT_PARSE_C */
kenjiArai 0:5b88d5760320 11039
kenjiArai 0:5b88d5760320 11040 /*
kenjiArai 0:5b88d5760320 11041 * Convert version numbers to/from wire format
kenjiArai 0:5b88d5760320 11042 * and, for DTLS, to/from TLS equivalent.
kenjiArai 0:5b88d5760320 11043 *
kenjiArai 0:5b88d5760320 11044 * For TLS this is the identity.
kenjiArai 0:5b88d5760320 11045 * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
kenjiArai 0:5b88d5760320 11046 * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1)
kenjiArai 0:5b88d5760320 11047 * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
kenjiArai 0:5b88d5760320 11048 */
kenjiArai 0:5b88d5760320 11049 void mbedtls_ssl_write_version( int major, int minor, int transport,
kenjiArai 0:5b88d5760320 11050 unsigned char ver[2] )
kenjiArai 0:5b88d5760320 11051 {
kenjiArai 0:5b88d5760320 11052 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 11053 if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 11054 {
kenjiArai 0:5b88d5760320 11055 if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
kenjiArai 0:5b88d5760320 11056 --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
kenjiArai 0:5b88d5760320 11057
kenjiArai 0:5b88d5760320 11058 ver[0] = (unsigned char)( 255 - ( major - 2 ) );
kenjiArai 0:5b88d5760320 11059 ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
kenjiArai 0:5b88d5760320 11060 }
kenjiArai 0:5b88d5760320 11061 else
kenjiArai 0:5b88d5760320 11062 #else
kenjiArai 0:5b88d5760320 11063 ((void) transport);
kenjiArai 0:5b88d5760320 11064 #endif
kenjiArai 0:5b88d5760320 11065 {
kenjiArai 0:5b88d5760320 11066 ver[0] = (unsigned char) major;
kenjiArai 0:5b88d5760320 11067 ver[1] = (unsigned char) minor;
kenjiArai 0:5b88d5760320 11068 }
kenjiArai 0:5b88d5760320 11069 }
kenjiArai 0:5b88d5760320 11070
kenjiArai 0:5b88d5760320 11071 void mbedtls_ssl_read_version( int *major, int *minor, int transport,
kenjiArai 0:5b88d5760320 11072 const unsigned char ver[2] )
kenjiArai 0:5b88d5760320 11073 {
kenjiArai 0:5b88d5760320 11074 #if defined(MBEDTLS_SSL_PROTO_DTLS)
kenjiArai 0:5b88d5760320 11075 if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
kenjiArai 0:5b88d5760320 11076 {
kenjiArai 0:5b88d5760320 11077 *major = 255 - ver[0] + 2;
kenjiArai 0:5b88d5760320 11078 *minor = 255 - ver[1] + 1;
kenjiArai 0:5b88d5760320 11079
kenjiArai 0:5b88d5760320 11080 if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
kenjiArai 0:5b88d5760320 11081 ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
kenjiArai 0:5b88d5760320 11082 }
kenjiArai 0:5b88d5760320 11083 else
kenjiArai 0:5b88d5760320 11084 #else
kenjiArai 0:5b88d5760320 11085 ((void) transport);
kenjiArai 0:5b88d5760320 11086 #endif
kenjiArai 0:5b88d5760320 11087 {
kenjiArai 0:5b88d5760320 11088 *major = ver[0];
kenjiArai 0:5b88d5760320 11089 *minor = ver[1];
kenjiArai 0:5b88d5760320 11090 }
kenjiArai 0:5b88d5760320 11091 }
kenjiArai 0:5b88d5760320 11092
kenjiArai 0:5b88d5760320 11093 int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
kenjiArai 0:5b88d5760320 11094 {
kenjiArai 0:5b88d5760320 11095 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 11096 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
kenjiArai 0:5b88d5760320 11097 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
kenjiArai 0:5b88d5760320 11098
kenjiArai 0:5b88d5760320 11099 switch( md )
kenjiArai 0:5b88d5760320 11100 {
kenjiArai 0:5b88d5760320 11101 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 11102 #if defined(MBEDTLS_MD5_C)
kenjiArai 0:5b88d5760320 11103 case MBEDTLS_SSL_HASH_MD5:
kenjiArai 0:5b88d5760320 11104 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
kenjiArai 0:5b88d5760320 11105 #endif
kenjiArai 0:5b88d5760320 11106 #if defined(MBEDTLS_SHA1_C)
kenjiArai 0:5b88d5760320 11107 case MBEDTLS_SSL_HASH_SHA1:
kenjiArai 0:5b88d5760320 11108 ssl->handshake->calc_verify = ssl_calc_verify_tls;
kenjiArai 0:5b88d5760320 11109 break;
kenjiArai 0:5b88d5760320 11110 #endif
kenjiArai 0:5b88d5760320 11111 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
kenjiArai 0:5b88d5760320 11112 #if defined(MBEDTLS_SHA512_C)
kenjiArai 0:5b88d5760320 11113 case MBEDTLS_SSL_HASH_SHA384:
kenjiArai 0:5b88d5760320 11114 ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
kenjiArai 0:5b88d5760320 11115 break;
kenjiArai 0:5b88d5760320 11116 #endif
kenjiArai 0:5b88d5760320 11117 #if defined(MBEDTLS_SHA256_C)
kenjiArai 0:5b88d5760320 11118 case MBEDTLS_SSL_HASH_SHA256:
kenjiArai 0:5b88d5760320 11119 ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256;
kenjiArai 0:5b88d5760320 11120 break;
kenjiArai 0:5b88d5760320 11121 #endif
kenjiArai 0:5b88d5760320 11122 default:
kenjiArai 0:5b88d5760320 11123 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
kenjiArai 0:5b88d5760320 11124 }
kenjiArai 0:5b88d5760320 11125
kenjiArai 0:5b88d5760320 11126 return 0;
kenjiArai 0:5b88d5760320 11127 #else /* !MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 11128 (void) ssl;
kenjiArai 0:5b88d5760320 11129 (void) md;
kenjiArai 0:5b88d5760320 11130
kenjiArai 0:5b88d5760320 11131 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
kenjiArai 0:5b88d5760320 11132 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 11133 }
kenjiArai 0:5b88d5760320 11134
kenjiArai 0:5b88d5760320 11135 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
kenjiArai 0:5b88d5760320 11136 defined(MBEDTLS_SSL_PROTO_TLS1_1)
kenjiArai 0:5b88d5760320 11137 int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 11138 unsigned char *output,
kenjiArai 0:5b88d5760320 11139 unsigned char *data, size_t data_len )
kenjiArai 0:5b88d5760320 11140 {
kenjiArai 0:5b88d5760320 11141 int ret = 0;
kenjiArai 0:5b88d5760320 11142 mbedtls_md5_context mbedtls_md5;
kenjiArai 0:5b88d5760320 11143 mbedtls_sha1_context mbedtls_sha1;
kenjiArai 0:5b88d5760320 11144
kenjiArai 0:5b88d5760320 11145 mbedtls_md5_init( &mbedtls_md5 );
kenjiArai 0:5b88d5760320 11146 mbedtls_sha1_init( &mbedtls_sha1 );
kenjiArai 0:5b88d5760320 11147
kenjiArai 0:5b88d5760320 11148 /*
kenjiArai 0:5b88d5760320 11149 * digitally-signed struct {
kenjiArai 0:5b88d5760320 11150 * opaque md5_hash[16];
kenjiArai 0:5b88d5760320 11151 * opaque sha_hash[20];
kenjiArai 0:5b88d5760320 11152 * };
kenjiArai 0:5b88d5760320 11153 *
kenjiArai 0:5b88d5760320 11154 * md5_hash
kenjiArai 0:5b88d5760320 11155 * MD5(ClientHello.random + ServerHello.random
kenjiArai 0:5b88d5760320 11156 * + ServerParams);
kenjiArai 0:5b88d5760320 11157 * sha_hash
kenjiArai 0:5b88d5760320 11158 * SHA(ClientHello.random + ServerHello.random
kenjiArai 0:5b88d5760320 11159 * + ServerParams);
kenjiArai 0:5b88d5760320 11160 */
kenjiArai 0:5b88d5760320 11161 if( ( ret = mbedtls_md5_starts_ret( &mbedtls_md5 ) ) != 0 )
kenjiArai 0:5b88d5760320 11162 {
kenjiArai 0:5b88d5760320 11163 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_starts_ret", ret );
kenjiArai 0:5b88d5760320 11164 goto exit;
kenjiArai 0:5b88d5760320 11165 }
kenjiArai 0:5b88d5760320 11166 if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5,
kenjiArai 0:5b88d5760320 11167 ssl->handshake->randbytes, 64 ) ) != 0 )
kenjiArai 0:5b88d5760320 11168 {
kenjiArai 0:5b88d5760320 11169 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret );
kenjiArai 0:5b88d5760320 11170 goto exit;
kenjiArai 0:5b88d5760320 11171 }
kenjiArai 0:5b88d5760320 11172 if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, data, data_len ) ) != 0 )
kenjiArai 0:5b88d5760320 11173 {
kenjiArai 0:5b88d5760320 11174 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret );
kenjiArai 0:5b88d5760320 11175 goto exit;
kenjiArai 0:5b88d5760320 11176 }
kenjiArai 0:5b88d5760320 11177 if( ( ret = mbedtls_md5_finish_ret( &mbedtls_md5, output ) ) != 0 )
kenjiArai 0:5b88d5760320 11178 {
kenjiArai 0:5b88d5760320 11179 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_finish_ret", ret );
kenjiArai 0:5b88d5760320 11180 goto exit;
kenjiArai 0:5b88d5760320 11181 }
kenjiArai 0:5b88d5760320 11182
kenjiArai 0:5b88d5760320 11183 if( ( ret = mbedtls_sha1_starts_ret( &mbedtls_sha1 ) ) != 0 )
kenjiArai 0:5b88d5760320 11184 {
kenjiArai 0:5b88d5760320 11185 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_starts_ret", ret );
kenjiArai 0:5b88d5760320 11186 goto exit;
kenjiArai 0:5b88d5760320 11187 }
kenjiArai 0:5b88d5760320 11188 if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1,
kenjiArai 0:5b88d5760320 11189 ssl->handshake->randbytes, 64 ) ) != 0 )
kenjiArai 0:5b88d5760320 11190 {
kenjiArai 0:5b88d5760320 11191 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret );
kenjiArai 0:5b88d5760320 11192 goto exit;
kenjiArai 0:5b88d5760320 11193 }
kenjiArai 0:5b88d5760320 11194 if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, data,
kenjiArai 0:5b88d5760320 11195 data_len ) ) != 0 )
kenjiArai 0:5b88d5760320 11196 {
kenjiArai 0:5b88d5760320 11197 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret );
kenjiArai 0:5b88d5760320 11198 goto exit;
kenjiArai 0:5b88d5760320 11199 }
kenjiArai 0:5b88d5760320 11200 if( ( ret = mbedtls_sha1_finish_ret( &mbedtls_sha1,
kenjiArai 0:5b88d5760320 11201 output + 16 ) ) != 0 )
kenjiArai 0:5b88d5760320 11202 {
kenjiArai 0:5b88d5760320 11203 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_finish_ret", ret );
kenjiArai 0:5b88d5760320 11204 goto exit;
kenjiArai 0:5b88d5760320 11205 }
kenjiArai 0:5b88d5760320 11206
kenjiArai 0:5b88d5760320 11207 exit:
kenjiArai 0:5b88d5760320 11208 mbedtls_md5_free( &mbedtls_md5 );
kenjiArai 0:5b88d5760320 11209 mbedtls_sha1_free( &mbedtls_sha1 );
kenjiArai 0:5b88d5760320 11210
kenjiArai 0:5b88d5760320 11211 if( ret != 0 )
kenjiArai 0:5b88d5760320 11212 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 11213 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 11214
kenjiArai 0:5b88d5760320 11215 return( ret );
kenjiArai 0:5b88d5760320 11216
kenjiArai 0:5b88d5760320 11217 }
kenjiArai 0:5b88d5760320 11218 #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
kenjiArai 0:5b88d5760320 11219 MBEDTLS_SSL_PROTO_TLS1_1 */
kenjiArai 0:5b88d5760320 11220
kenjiArai 0:5b88d5760320 11221 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
kenjiArai 0:5b88d5760320 11222 defined(MBEDTLS_SSL_PROTO_TLS1_2)
kenjiArai 0:5b88d5760320 11223
kenjiArai 0:5b88d5760320 11224 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 11225 int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 11226 unsigned char *hash, size_t *hashlen,
kenjiArai 0:5b88d5760320 11227 unsigned char *data, size_t data_len,
kenjiArai 0:5b88d5760320 11228 mbedtls_md_type_t md_alg )
kenjiArai 0:5b88d5760320 11229 {
kenjiArai 0:5b88d5760320 11230 psa_status_t status;
kenjiArai 0:5b88d5760320 11231 psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
kenjiArai 0:5b88d5760320 11232 psa_algorithm_t hash_alg = mbedtls_psa_translate_md( md_alg );
kenjiArai 0:5b88d5760320 11233
kenjiArai 0:5b88d5760320 11234 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) );
kenjiArai 0:5b88d5760320 11235
kenjiArai 0:5b88d5760320 11236 if( ( status = psa_hash_setup( &hash_operation,
kenjiArai 0:5b88d5760320 11237 hash_alg ) ) != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 11238 {
kenjiArai 0:5b88d5760320 11239 MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_setup", status );
kenjiArai 0:5b88d5760320 11240 goto exit;
kenjiArai 0:5b88d5760320 11241 }
kenjiArai 0:5b88d5760320 11242
kenjiArai 0:5b88d5760320 11243 if( ( status = psa_hash_update( &hash_operation, ssl->handshake->randbytes,
kenjiArai 0:5b88d5760320 11244 64 ) ) != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 11245 {
kenjiArai 0:5b88d5760320 11246 MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
kenjiArai 0:5b88d5760320 11247 goto exit;
kenjiArai 0:5b88d5760320 11248 }
kenjiArai 0:5b88d5760320 11249
kenjiArai 0:5b88d5760320 11250 if( ( status = psa_hash_update( &hash_operation,
kenjiArai 0:5b88d5760320 11251 data, data_len ) ) != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 11252 {
kenjiArai 0:5b88d5760320 11253 MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
kenjiArai 0:5b88d5760320 11254 goto exit;
kenjiArai 0:5b88d5760320 11255 }
kenjiArai 0:5b88d5760320 11256
kenjiArai 0:5b88d5760320 11257 if( ( status = psa_hash_finish( &hash_operation, hash, MBEDTLS_MD_MAX_SIZE,
kenjiArai 0:5b88d5760320 11258 hashlen ) ) != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 11259 {
kenjiArai 0:5b88d5760320 11260 MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_finish", status );
kenjiArai 0:5b88d5760320 11261 goto exit;
kenjiArai 0:5b88d5760320 11262 }
kenjiArai 0:5b88d5760320 11263
kenjiArai 0:5b88d5760320 11264 exit:
kenjiArai 0:5b88d5760320 11265 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 11266 {
kenjiArai 0:5b88d5760320 11267 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 11268 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 11269 switch( status )
kenjiArai 0:5b88d5760320 11270 {
kenjiArai 0:5b88d5760320 11271 case PSA_ERROR_NOT_SUPPORTED:
kenjiArai 0:5b88d5760320 11272 return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
kenjiArai 0:5b88d5760320 11273 case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
kenjiArai 0:5b88d5760320 11274 case PSA_ERROR_BUFFER_TOO_SMALL:
kenjiArai 0:5b88d5760320 11275 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 11276 case PSA_ERROR_INSUFFICIENT_MEMORY:
kenjiArai 0:5b88d5760320 11277 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
kenjiArai 0:5b88d5760320 11278 default:
kenjiArai 0:5b88d5760320 11279 return( MBEDTLS_ERR_MD_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 11280 }
kenjiArai 0:5b88d5760320 11281 }
kenjiArai 0:5b88d5760320 11282 return( 0 );
kenjiArai 0:5b88d5760320 11283 }
kenjiArai 0:5b88d5760320 11284
kenjiArai 0:5b88d5760320 11285 #else
kenjiArai 0:5b88d5760320 11286
kenjiArai 0:5b88d5760320 11287 int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
kenjiArai 0:5b88d5760320 11288 unsigned char *hash, size_t *hashlen,
kenjiArai 0:5b88d5760320 11289 unsigned char *data, size_t data_len,
kenjiArai 0:5b88d5760320 11290 mbedtls_md_type_t md_alg )
kenjiArai 0:5b88d5760320 11291 {
kenjiArai 0:5b88d5760320 11292 int ret = 0;
kenjiArai 0:5b88d5760320 11293 mbedtls_md_context_t ctx;
kenjiArai 0:5b88d5760320 11294 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
kenjiArai 0:5b88d5760320 11295 *hashlen = mbedtls_md_get_size( md_info );
kenjiArai 0:5b88d5760320 11296
kenjiArai 0:5b88d5760320 11297 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) );
kenjiArai 0:5b88d5760320 11298
kenjiArai 0:5b88d5760320 11299 mbedtls_md_init( &ctx );
kenjiArai 0:5b88d5760320 11300
kenjiArai 0:5b88d5760320 11301 /*
kenjiArai 0:5b88d5760320 11302 * digitally-signed struct {
kenjiArai 0:5b88d5760320 11303 * opaque client_random[32];
kenjiArai 0:5b88d5760320 11304 * opaque server_random[32];
kenjiArai 0:5b88d5760320 11305 * ServerDHParams params;
kenjiArai 0:5b88d5760320 11306 * };
kenjiArai 0:5b88d5760320 11307 */
kenjiArai 0:5b88d5760320 11308 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
kenjiArai 0:5b88d5760320 11309 {
kenjiArai 0:5b88d5760320 11310 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
kenjiArai 0:5b88d5760320 11311 goto exit;
kenjiArai 0:5b88d5760320 11312 }
kenjiArai 0:5b88d5760320 11313 if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
kenjiArai 0:5b88d5760320 11314 {
kenjiArai 0:5b88d5760320 11315 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret );
kenjiArai 0:5b88d5760320 11316 goto exit;
kenjiArai 0:5b88d5760320 11317 }
kenjiArai 0:5b88d5760320 11318 if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 )
kenjiArai 0:5b88d5760320 11319 {
kenjiArai 0:5b88d5760320 11320 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
kenjiArai 0:5b88d5760320 11321 goto exit;
kenjiArai 0:5b88d5760320 11322 }
kenjiArai 0:5b88d5760320 11323 if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 )
kenjiArai 0:5b88d5760320 11324 {
kenjiArai 0:5b88d5760320 11325 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
kenjiArai 0:5b88d5760320 11326 goto exit;
kenjiArai 0:5b88d5760320 11327 }
kenjiArai 0:5b88d5760320 11328 if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 )
kenjiArai 0:5b88d5760320 11329 {
kenjiArai 0:5b88d5760320 11330 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
kenjiArai 0:5b88d5760320 11331 goto exit;
kenjiArai 0:5b88d5760320 11332 }
kenjiArai 0:5b88d5760320 11333
kenjiArai 0:5b88d5760320 11334 exit:
kenjiArai 0:5b88d5760320 11335 mbedtls_md_free( &ctx );
kenjiArai 0:5b88d5760320 11336
kenjiArai 0:5b88d5760320 11337 if( ret != 0 )
kenjiArai 0:5b88d5760320 11338 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
kenjiArai 0:5b88d5760320 11339 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
kenjiArai 0:5b88d5760320 11340
kenjiArai 0:5b88d5760320 11341 return( ret );
kenjiArai 0:5b88d5760320 11342 }
kenjiArai 0:5b88d5760320 11343 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 11344
kenjiArai 0:5b88d5760320 11345 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
kenjiArai 0:5b88d5760320 11346 MBEDTLS_SSL_PROTO_TLS1_2 */
kenjiArai 0:5b88d5760320 11347
kenjiArai 0:5b88d5760320 11348 #endif /* MBEDTLS_SSL_TLS_C */