Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Committer:
HannesTschofenig
Date:
Thu Sep 27 06:34:22 2018 +0000
Revision:
0:796d0f61a05b
Example AES-GCM test program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HannesTschofenig 0:796d0f61a05b 1 /*
HannesTschofenig 0:796d0f61a05b 2 * SSLv3/TLSv1 shared functions
HannesTschofenig 0:796d0f61a05b 3 *
HannesTschofenig 0:796d0f61a05b 4 * Copyright (C) 2006-2014, Brainspark B.V.
HannesTschofenig 0:796d0f61a05b 5 *
HannesTschofenig 0:796d0f61a05b 6 * This file is part of PolarSSL (http://www.polarssl.org)
HannesTschofenig 0:796d0f61a05b 7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
HannesTschofenig 0:796d0f61a05b 8 *
HannesTschofenig 0:796d0f61a05b 9 * All rights reserved.
HannesTschofenig 0:796d0f61a05b 10 *
HannesTschofenig 0:796d0f61a05b 11 * This program is free software; you can redistribute it and/or modify
HannesTschofenig 0:796d0f61a05b 12 * it under the terms of the GNU General Public License as published by
HannesTschofenig 0:796d0f61a05b 13 * the Free Software Foundation; either version 2 of the License, or
HannesTschofenig 0:796d0f61a05b 14 * (at your option) any later version.
HannesTschofenig 0:796d0f61a05b 15 *
HannesTschofenig 0:796d0f61a05b 16 * This program is distributed in the hope that it will be useful,
HannesTschofenig 0:796d0f61a05b 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
HannesTschofenig 0:796d0f61a05b 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
HannesTschofenig 0:796d0f61a05b 19 * GNU General Public License for more details.
HannesTschofenig 0:796d0f61a05b 20 *
HannesTschofenig 0:796d0f61a05b 21 * You should have received a copy of the GNU General Public License along
HannesTschofenig 0:796d0f61a05b 22 * with this program; if not, write to the Free Software Foundation, Inc.,
HannesTschofenig 0:796d0f61a05b 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
HannesTschofenig 0:796d0f61a05b 24 */
HannesTschofenig 0:796d0f61a05b 25 /*
HannesTschofenig 0:796d0f61a05b 26 * The SSL 3.0 specification was drafted by Netscape in 1996,
HannesTschofenig 0:796d0f61a05b 27 * and became an IETF standard in 1999.
HannesTschofenig 0:796d0f61a05b 28 *
HannesTschofenig 0:796d0f61a05b 29 * http://wp.netscape.com/eng/ssl3/
HannesTschofenig 0:796d0f61a05b 30 * http://www.ietf.org/rfc/rfc2246.txt
HannesTschofenig 0:796d0f61a05b 31 * http://www.ietf.org/rfc/rfc4346.txt
HannesTschofenig 0:796d0f61a05b 32 */
HannesTschofenig 0:796d0f61a05b 33
HannesTschofenig 0:796d0f61a05b 34 #if !defined(POLARSSL_CONFIG_FILE)
HannesTschofenig 0:796d0f61a05b 35 #include "polarssl/config.h"
HannesTschofenig 0:796d0f61a05b 36 #else
HannesTschofenig 0:796d0f61a05b 37 #include POLARSSL_CONFIG_FILE
HannesTschofenig 0:796d0f61a05b 38 #endif
HannesTschofenig 0:796d0f61a05b 39
HannesTschofenig 0:796d0f61a05b 40 #if defined(POLARSSL_SSL_TLS_C)
HannesTschofenig 0:796d0f61a05b 41
HannesTschofenig 0:796d0f61a05b 42 #include "polarssl/debug.h"
HannesTschofenig 0:796d0f61a05b 43 #include "polarssl/ssl.h"
HannesTschofenig 0:796d0f61a05b 44
HannesTschofenig 0:796d0f61a05b 45 #if defined(POLARSSL_X509_CRT_PARSE_C) && \
HannesTschofenig 0:796d0f61a05b 46 defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
HannesTschofenig 0:796d0f61a05b 47 #include "polarssl/oid.h"
HannesTschofenig 0:796d0f61a05b 48 #endif
HannesTschofenig 0:796d0f61a05b 49
HannesTschofenig 0:796d0f61a05b 50 #if defined(POLARSSL_PLATFORM_C)
HannesTschofenig 0:796d0f61a05b 51 #include "polarssl/platform.h"
HannesTschofenig 0:796d0f61a05b 52 #else
HannesTschofenig 0:796d0f61a05b 53 #define polarssl_malloc malloc
HannesTschofenig 0:796d0f61a05b 54 #define polarssl_free free
HannesTschofenig 0:796d0f61a05b 55 #endif
HannesTschofenig 0:796d0f61a05b 56
HannesTschofenig 0:796d0f61a05b 57 #include <stdlib.h>
HannesTschofenig 0:796d0f61a05b 58
HannesTschofenig 0:796d0f61a05b 59 #if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \
HannesTschofenig 0:796d0f61a05b 60 !defined(EFI32)
HannesTschofenig 0:796d0f61a05b 61 #define strcasecmp _stricmp
HannesTschofenig 0:796d0f61a05b 62 #endif
HannesTschofenig 0:796d0f61a05b 63
HannesTschofenig 0:796d0f61a05b 64 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
HannesTschofenig 0:796d0f61a05b 65 /*
HannesTschofenig 0:796d0f61a05b 66 * Convert max_fragment_length codes to length.
HannesTschofenig 0:796d0f61a05b 67 * RFC 6066 says:
HannesTschofenig 0:796d0f61a05b 68 * enum{
HannesTschofenig 0:796d0f61a05b 69 * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
HannesTschofenig 0:796d0f61a05b 70 * } MaxFragmentLength;
HannesTschofenig 0:796d0f61a05b 71 * and we add 0 -> extension unused
HannesTschofenig 0:796d0f61a05b 72 */
HannesTschofenig 0:796d0f61a05b 73 static unsigned int mfl_code_to_length[SSL_MAX_FRAG_LEN_INVALID] =
HannesTschofenig 0:796d0f61a05b 74 {
HannesTschofenig 0:796d0f61a05b 75 SSL_MAX_CONTENT_LEN, /* SSL_MAX_FRAG_LEN_NONE */
HannesTschofenig 0:796d0f61a05b 76 512, /* SSL_MAX_FRAG_LEN_512 */
HannesTschofenig 0:796d0f61a05b 77 1024, /* SSL_MAX_FRAG_LEN_1024 */
HannesTschofenig 0:796d0f61a05b 78 2048, /* SSL_MAX_FRAG_LEN_2048 */
HannesTschofenig 0:796d0f61a05b 79 4096, /* SSL_MAX_FRAG_LEN_4096 */
HannesTschofenig 0:796d0f61a05b 80 };
HannesTschofenig 0:796d0f61a05b 81 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
HannesTschofenig 0:796d0f61a05b 82
HannesTschofenig 0:796d0f61a05b 83 static int ssl_session_copy( ssl_session *dst, const ssl_session *src )
HannesTschofenig 0:796d0f61a05b 84 {
HannesTschofenig 0:796d0f61a05b 85 ssl_session_free( dst );
HannesTschofenig 0:796d0f61a05b 86 memcpy( dst, src, sizeof( ssl_session ) );
HannesTschofenig 0:796d0f61a05b 87
HannesTschofenig 0:796d0f61a05b 88 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 89 if( src->peer_cert != NULL )
HannesTschofenig 0:796d0f61a05b 90 {
HannesTschofenig 0:796d0f61a05b 91 int ret;
HannesTschofenig 0:796d0f61a05b 92
HannesTschofenig 0:796d0f61a05b 93 dst->peer_cert = (x509_crt *) polarssl_malloc( sizeof(x509_crt) );
HannesTschofenig 0:796d0f61a05b 94 if( dst->peer_cert == NULL )
HannesTschofenig 0:796d0f61a05b 95 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 96
HannesTschofenig 0:796d0f61a05b 97 x509_crt_init( dst->peer_cert );
HannesTschofenig 0:796d0f61a05b 98
HannesTschofenig 0:796d0f61a05b 99 if( ( ret = x509_crt_parse( dst->peer_cert, src->peer_cert->raw.p,
HannesTschofenig 0:796d0f61a05b 100 src->peer_cert->raw.len ) != 0 ) )
HannesTschofenig 0:796d0f61a05b 101 {
HannesTschofenig 0:796d0f61a05b 102 polarssl_free( dst->peer_cert );
HannesTschofenig 0:796d0f61a05b 103 dst->peer_cert = NULL;
HannesTschofenig 0:796d0f61a05b 104 return( ret );
HannesTschofenig 0:796d0f61a05b 105 }
HannesTschofenig 0:796d0f61a05b 106 }
HannesTschofenig 0:796d0f61a05b 107 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 108
HannesTschofenig 0:796d0f61a05b 109 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 110 if( src->ticket != NULL )
HannesTschofenig 0:796d0f61a05b 111 {
HannesTschofenig 0:796d0f61a05b 112 dst->ticket = (unsigned char *) polarssl_malloc( src->ticket_len );
HannesTschofenig 0:796d0f61a05b 113 if( dst->ticket == NULL )
HannesTschofenig 0:796d0f61a05b 114 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 115
HannesTschofenig 0:796d0f61a05b 116 memcpy( dst->ticket, src->ticket, src->ticket_len );
HannesTschofenig 0:796d0f61a05b 117 }
HannesTschofenig 0:796d0f61a05b 118 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 119
HannesTschofenig 0:796d0f61a05b 120 return( 0 );
HannesTschofenig 0:796d0f61a05b 121 }
HannesTschofenig 0:796d0f61a05b 122
HannesTschofenig 0:796d0f61a05b 123 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
HannesTschofenig 0:796d0f61a05b 124 int (*ssl_hw_record_init)(ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 125 const unsigned char *key_enc, const unsigned char *key_dec,
HannesTschofenig 0:796d0f61a05b 126 size_t keylen,
HannesTschofenig 0:796d0f61a05b 127 const unsigned char *iv_enc, const unsigned char *iv_dec,
HannesTschofenig 0:796d0f61a05b 128 size_t ivlen,
HannesTschofenig 0:796d0f61a05b 129 const unsigned char *mac_enc, const unsigned char *mac_dec,
HannesTschofenig 0:796d0f61a05b 130 size_t maclen) = NULL;
HannesTschofenig 0:796d0f61a05b 131 int (*ssl_hw_record_activate)(ssl_context *ssl, int direction) = NULL;
HannesTschofenig 0:796d0f61a05b 132 int (*ssl_hw_record_reset)(ssl_context *ssl) = NULL;
HannesTschofenig 0:796d0f61a05b 133 int (*ssl_hw_record_write)(ssl_context *ssl) = NULL;
HannesTschofenig 0:796d0f61a05b 134 int (*ssl_hw_record_read)(ssl_context *ssl) = NULL;
HannesTschofenig 0:796d0f61a05b 135 int (*ssl_hw_record_finish)(ssl_context *ssl) = NULL;
HannesTschofenig 0:796d0f61a05b 136 #endif /* POLARSSL_SSL_HW_RECORD_ACCEL */
HannesTschofenig 0:796d0f61a05b 137
HannesTschofenig 0:796d0f61a05b 138 /*
HannesTschofenig 0:796d0f61a05b 139 * Key material generation
HannesTschofenig 0:796d0f61a05b 140 */
HannesTschofenig 0:796d0f61a05b 141 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 142 static int ssl3_prf( const unsigned char *secret, size_t slen,
HannesTschofenig 0:796d0f61a05b 143 const char *label,
HannesTschofenig 0:796d0f61a05b 144 const unsigned char *random, size_t rlen,
HannesTschofenig 0:796d0f61a05b 145 unsigned char *dstbuf, size_t dlen )
HannesTschofenig 0:796d0f61a05b 146 {
HannesTschofenig 0:796d0f61a05b 147 size_t i;
HannesTschofenig 0:796d0f61a05b 148 md5_context md5;
HannesTschofenig 0:796d0f61a05b 149 sha1_context sha1;
HannesTschofenig 0:796d0f61a05b 150 unsigned char padding[16];
HannesTschofenig 0:796d0f61a05b 151 unsigned char sha1sum[20];
HannesTschofenig 0:796d0f61a05b 152 ((void)label);
HannesTschofenig 0:796d0f61a05b 153
HannesTschofenig 0:796d0f61a05b 154 /*
HannesTschofenig 0:796d0f61a05b 155 * SSLv3:
HannesTschofenig 0:796d0f61a05b 156 * block =
HannesTschofenig 0:796d0f61a05b 157 * MD5( secret + SHA1( 'A' + secret + random ) ) +
HannesTschofenig 0:796d0f61a05b 158 * MD5( secret + SHA1( 'BB' + secret + random ) ) +
HannesTschofenig 0:796d0f61a05b 159 * MD5( secret + SHA1( 'CCC' + secret + random ) ) +
HannesTschofenig 0:796d0f61a05b 160 * ...
HannesTschofenig 0:796d0f61a05b 161 */
HannesTschofenig 0:796d0f61a05b 162 for( i = 0; i < dlen / 16; i++ )
HannesTschofenig 0:796d0f61a05b 163 {
HannesTschofenig 0:796d0f61a05b 164 memset( padding, (unsigned char) ('A' + i), 1 + i );
HannesTschofenig 0:796d0f61a05b 165
HannesTschofenig 0:796d0f61a05b 166 sha1_starts( &sha1 );
HannesTschofenig 0:796d0f61a05b 167 sha1_update( &sha1, padding, 1 + i );
HannesTschofenig 0:796d0f61a05b 168 sha1_update( &sha1, secret, slen );
HannesTschofenig 0:796d0f61a05b 169 sha1_update( &sha1, random, rlen );
HannesTschofenig 0:796d0f61a05b 170 sha1_finish( &sha1, sha1sum );
HannesTschofenig 0:796d0f61a05b 171
HannesTschofenig 0:796d0f61a05b 172 md5_starts( &md5 );
HannesTschofenig 0:796d0f61a05b 173 md5_update( &md5, secret, slen );
HannesTschofenig 0:796d0f61a05b 174 md5_update( &md5, sha1sum, 20 );
HannesTschofenig 0:796d0f61a05b 175 md5_finish( &md5, dstbuf + i * 16 );
HannesTschofenig 0:796d0f61a05b 176 }
HannesTschofenig 0:796d0f61a05b 177
HannesTschofenig 0:796d0f61a05b 178 memset( &md5, 0, sizeof( md5 ) );
HannesTschofenig 0:796d0f61a05b 179 memset( &sha1, 0, sizeof( sha1 ) );
HannesTschofenig 0:796d0f61a05b 180
HannesTschofenig 0:796d0f61a05b 181 memset( padding, 0, sizeof( padding ) );
HannesTschofenig 0:796d0f61a05b 182 memset( sha1sum, 0, sizeof( sha1sum ) );
HannesTschofenig 0:796d0f61a05b 183
HannesTschofenig 0:796d0f61a05b 184 return( 0 );
HannesTschofenig 0:796d0f61a05b 185 }
HannesTschofenig 0:796d0f61a05b 186 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 187
HannesTschofenig 0:796d0f61a05b 188 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 189 static int tls1_prf( const unsigned char *secret, size_t slen,
HannesTschofenig 0:796d0f61a05b 190 const char *label,
HannesTschofenig 0:796d0f61a05b 191 const unsigned char *random, size_t rlen,
HannesTschofenig 0:796d0f61a05b 192 unsigned char *dstbuf, size_t dlen )
HannesTschofenig 0:796d0f61a05b 193 {
HannesTschofenig 0:796d0f61a05b 194 size_t nb, hs;
HannesTschofenig 0:796d0f61a05b 195 size_t i, j, k;
HannesTschofenig 0:796d0f61a05b 196 const unsigned char *S1, *S2;
HannesTschofenig 0:796d0f61a05b 197 unsigned char tmp[128];
HannesTschofenig 0:796d0f61a05b 198 unsigned char h_i[20];
HannesTschofenig 0:796d0f61a05b 199
HannesTschofenig 0:796d0f61a05b 200 if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
HannesTschofenig 0:796d0f61a05b 201 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 202
HannesTschofenig 0:796d0f61a05b 203 hs = ( slen + 1 ) / 2;
HannesTschofenig 0:796d0f61a05b 204 S1 = secret;
HannesTschofenig 0:796d0f61a05b 205 S2 = secret + slen - hs;
HannesTschofenig 0:796d0f61a05b 206
HannesTschofenig 0:796d0f61a05b 207 nb = strlen( label );
HannesTschofenig 0:796d0f61a05b 208 memcpy( tmp + 20, label, nb );
HannesTschofenig 0:796d0f61a05b 209 memcpy( tmp + 20 + nb, random, rlen );
HannesTschofenig 0:796d0f61a05b 210 nb += rlen;
HannesTschofenig 0:796d0f61a05b 211
HannesTschofenig 0:796d0f61a05b 212 /*
HannesTschofenig 0:796d0f61a05b 213 * First compute P_md5(secret,label+random)[0..dlen]
HannesTschofenig 0:796d0f61a05b 214 */
HannesTschofenig 0:796d0f61a05b 215 md5_hmac( S1, hs, tmp + 20, nb, 4 + tmp );
HannesTschofenig 0:796d0f61a05b 216
HannesTschofenig 0:796d0f61a05b 217 for( i = 0; i < dlen; i += 16 )
HannesTschofenig 0:796d0f61a05b 218 {
HannesTschofenig 0:796d0f61a05b 219 md5_hmac( S1, hs, 4 + tmp, 16 + nb, h_i );
HannesTschofenig 0:796d0f61a05b 220 md5_hmac( S1, hs, 4 + tmp, 16, 4 + tmp );
HannesTschofenig 0:796d0f61a05b 221
HannesTschofenig 0:796d0f61a05b 222 k = ( i + 16 > dlen ) ? dlen % 16 : 16;
HannesTschofenig 0:796d0f61a05b 223
HannesTschofenig 0:796d0f61a05b 224 for( j = 0; j < k; j++ )
HannesTschofenig 0:796d0f61a05b 225 dstbuf[i + j] = h_i[j];
HannesTschofenig 0:796d0f61a05b 226 }
HannesTschofenig 0:796d0f61a05b 227
HannesTschofenig 0:796d0f61a05b 228 /*
HannesTschofenig 0:796d0f61a05b 229 * XOR out with P_sha1(secret,label+random)[0..dlen]
HannesTschofenig 0:796d0f61a05b 230 */
HannesTschofenig 0:796d0f61a05b 231 sha1_hmac( S2, hs, tmp + 20, nb, tmp );
HannesTschofenig 0:796d0f61a05b 232
HannesTschofenig 0:796d0f61a05b 233 for( i = 0; i < dlen; i += 20 )
HannesTschofenig 0:796d0f61a05b 234 {
HannesTschofenig 0:796d0f61a05b 235 sha1_hmac( S2, hs, tmp, 20 + nb, h_i );
HannesTschofenig 0:796d0f61a05b 236 sha1_hmac( S2, hs, tmp, 20, tmp );
HannesTschofenig 0:796d0f61a05b 237
HannesTschofenig 0:796d0f61a05b 238 k = ( i + 20 > dlen ) ? dlen % 20 : 20;
HannesTschofenig 0:796d0f61a05b 239
HannesTschofenig 0:796d0f61a05b 240 for( j = 0; j < k; j++ )
HannesTschofenig 0:796d0f61a05b 241 dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
HannesTschofenig 0:796d0f61a05b 242 }
HannesTschofenig 0:796d0f61a05b 243
HannesTschofenig 0:796d0f61a05b 244 memset( tmp, 0, sizeof( tmp ) );
HannesTschofenig 0:796d0f61a05b 245 memset( h_i, 0, sizeof( h_i ) );
HannesTschofenig 0:796d0f61a05b 246
HannesTschofenig 0:796d0f61a05b 247 return( 0 );
HannesTschofenig 0:796d0f61a05b 248 }
HannesTschofenig 0:796d0f61a05b 249 #endif /* POLARSSL_SSL_PROTO_TLS1) || POLARSSL_SSL_PROTO_TLS1_1 */
HannesTschofenig 0:796d0f61a05b 250
HannesTschofenig 0:796d0f61a05b 251 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 252 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 253 static int tls_prf_sha256( const unsigned char *secret, size_t slen,
HannesTschofenig 0:796d0f61a05b 254 const char *label,
HannesTschofenig 0:796d0f61a05b 255 const unsigned char *random, size_t rlen,
HannesTschofenig 0:796d0f61a05b 256 unsigned char *dstbuf, size_t dlen )
HannesTschofenig 0:796d0f61a05b 257 {
HannesTschofenig 0:796d0f61a05b 258 size_t nb;
HannesTschofenig 0:796d0f61a05b 259 size_t i, j, k;
HannesTschofenig 0:796d0f61a05b 260 unsigned char tmp[128];
HannesTschofenig 0:796d0f61a05b 261 unsigned char h_i[32];
HannesTschofenig 0:796d0f61a05b 262
HannesTschofenig 0:796d0f61a05b 263 if( sizeof( tmp ) < 32 + strlen( label ) + rlen )
HannesTschofenig 0:796d0f61a05b 264 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 265
HannesTschofenig 0:796d0f61a05b 266 nb = strlen( label );
HannesTschofenig 0:796d0f61a05b 267 memcpy( tmp + 32, label, nb );
HannesTschofenig 0:796d0f61a05b 268 memcpy( tmp + 32 + nb, random, rlen );
HannesTschofenig 0:796d0f61a05b 269 nb += rlen;
HannesTschofenig 0:796d0f61a05b 270
HannesTschofenig 0:796d0f61a05b 271 /*
HannesTschofenig 0:796d0f61a05b 272 * Compute P_<hash>(secret, label + random)[0..dlen]
HannesTschofenig 0:796d0f61a05b 273 */
HannesTschofenig 0:796d0f61a05b 274 sha256_hmac( secret, slen, tmp + 32, nb, tmp, 0 );
HannesTschofenig 0:796d0f61a05b 275
HannesTschofenig 0:796d0f61a05b 276 for( i = 0; i < dlen; i += 32 )
HannesTschofenig 0:796d0f61a05b 277 {
HannesTschofenig 0:796d0f61a05b 278 sha256_hmac( secret, slen, tmp, 32 + nb, h_i, 0 );
HannesTschofenig 0:796d0f61a05b 279 sha256_hmac( secret, slen, tmp, 32, tmp, 0 );
HannesTschofenig 0:796d0f61a05b 280
HannesTschofenig 0:796d0f61a05b 281 k = ( i + 32 > dlen ) ? dlen % 32 : 32;
HannesTschofenig 0:796d0f61a05b 282
HannesTschofenig 0:796d0f61a05b 283 for( j = 0; j < k; j++ )
HannesTschofenig 0:796d0f61a05b 284 dstbuf[i + j] = h_i[j];
HannesTschofenig 0:796d0f61a05b 285 }
HannesTschofenig 0:796d0f61a05b 286
HannesTschofenig 0:796d0f61a05b 287 memset( tmp, 0, sizeof( tmp ) );
HannesTschofenig 0:796d0f61a05b 288 memset( h_i, 0, sizeof( h_i ) );
HannesTschofenig 0:796d0f61a05b 289
HannesTschofenig 0:796d0f61a05b 290 return( 0 );
HannesTschofenig 0:796d0f61a05b 291 }
HannesTschofenig 0:796d0f61a05b 292 #endif /* POLARSSL_SHA256_C */
HannesTschofenig 0:796d0f61a05b 293
HannesTschofenig 0:796d0f61a05b 294 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 295 static int tls_prf_sha384( const unsigned char *secret, size_t slen,
HannesTschofenig 0:796d0f61a05b 296 const char *label,
HannesTschofenig 0:796d0f61a05b 297 const unsigned char *random, size_t rlen,
HannesTschofenig 0:796d0f61a05b 298 unsigned char *dstbuf, size_t dlen )
HannesTschofenig 0:796d0f61a05b 299 {
HannesTschofenig 0:796d0f61a05b 300 size_t nb;
HannesTschofenig 0:796d0f61a05b 301 size_t i, j, k;
HannesTschofenig 0:796d0f61a05b 302 unsigned char tmp[128];
HannesTschofenig 0:796d0f61a05b 303 unsigned char h_i[48];
HannesTschofenig 0:796d0f61a05b 304
HannesTschofenig 0:796d0f61a05b 305 if( sizeof( tmp ) < 48 + strlen( label ) + rlen )
HannesTschofenig 0:796d0f61a05b 306 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 307
HannesTschofenig 0:796d0f61a05b 308 nb = strlen( label );
HannesTschofenig 0:796d0f61a05b 309 memcpy( tmp + 48, label, nb );
HannesTschofenig 0:796d0f61a05b 310 memcpy( tmp + 48 + nb, random, rlen );
HannesTschofenig 0:796d0f61a05b 311 nb += rlen;
HannesTschofenig 0:796d0f61a05b 312
HannesTschofenig 0:796d0f61a05b 313 /*
HannesTschofenig 0:796d0f61a05b 314 * Compute P_<hash>(secret, label + random)[0..dlen]
HannesTschofenig 0:796d0f61a05b 315 */
HannesTschofenig 0:796d0f61a05b 316 sha512_hmac( secret, slen, tmp + 48, nb, tmp, 1 );
HannesTschofenig 0:796d0f61a05b 317
HannesTschofenig 0:796d0f61a05b 318 for( i = 0; i < dlen; i += 48 )
HannesTschofenig 0:796d0f61a05b 319 {
HannesTschofenig 0:796d0f61a05b 320 sha512_hmac( secret, slen, tmp, 48 + nb, h_i, 1 );
HannesTschofenig 0:796d0f61a05b 321 sha512_hmac( secret, slen, tmp, 48, tmp, 1 );
HannesTschofenig 0:796d0f61a05b 322
HannesTschofenig 0:796d0f61a05b 323 k = ( i + 48 > dlen ) ? dlen % 48 : 48;
HannesTschofenig 0:796d0f61a05b 324
HannesTschofenig 0:796d0f61a05b 325 for( j = 0; j < k; j++ )
HannesTschofenig 0:796d0f61a05b 326 dstbuf[i + j] = h_i[j];
HannesTschofenig 0:796d0f61a05b 327 }
HannesTschofenig 0:796d0f61a05b 328
HannesTschofenig 0:796d0f61a05b 329 memset( tmp, 0, sizeof( tmp ) );
HannesTschofenig 0:796d0f61a05b 330 memset( h_i, 0, sizeof( h_i ) );
HannesTschofenig 0:796d0f61a05b 331
HannesTschofenig 0:796d0f61a05b 332 return( 0 );
HannesTschofenig 0:796d0f61a05b 333 }
HannesTschofenig 0:796d0f61a05b 334 #endif /* POLARSSL_SHA512_C */
HannesTschofenig 0:796d0f61a05b 335 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 336
HannesTschofenig 0:796d0f61a05b 337 static void ssl_update_checksum_start(ssl_context *, const unsigned char *, size_t);
HannesTschofenig 0:796d0f61a05b 338
HannesTschofenig 0:796d0f61a05b 339 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
HannesTschofenig 0:796d0f61a05b 340 defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 341 static void ssl_update_checksum_md5sha1(ssl_context *, const unsigned char *, size_t);
HannesTschofenig 0:796d0f61a05b 342 #endif
HannesTschofenig 0:796d0f61a05b 343
HannesTschofenig 0:796d0f61a05b 344 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 345 static void ssl_calc_verify_ssl(ssl_context *,unsigned char *);
HannesTschofenig 0:796d0f61a05b 346 static void ssl_calc_finished_ssl(ssl_context *,unsigned char *,int);
HannesTschofenig 0:796d0f61a05b 347 #endif
HannesTschofenig 0:796d0f61a05b 348
HannesTschofenig 0:796d0f61a05b 349 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 350 static void ssl_calc_verify_tls(ssl_context *,unsigned char *);
HannesTschofenig 0:796d0f61a05b 351 static void ssl_calc_finished_tls(ssl_context *,unsigned char *,int);
HannesTschofenig 0:796d0f61a05b 352 #endif
HannesTschofenig 0:796d0f61a05b 353
HannesTschofenig 0:796d0f61a05b 354 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 355 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 356 static void ssl_update_checksum_sha256(ssl_context *, const unsigned char *, size_t);
HannesTschofenig 0:796d0f61a05b 357 static void ssl_calc_verify_tls_sha256(ssl_context *,unsigned char *);
HannesTschofenig 0:796d0f61a05b 358 static void ssl_calc_finished_tls_sha256(ssl_context *,unsigned char *,int);
HannesTschofenig 0:796d0f61a05b 359 #endif
HannesTschofenig 0:796d0f61a05b 360
HannesTschofenig 0:796d0f61a05b 361 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 362 static void ssl_update_checksum_sha384(ssl_context *, const unsigned char *, size_t);
HannesTschofenig 0:796d0f61a05b 363 static void ssl_calc_verify_tls_sha384(ssl_context *,unsigned char *);
HannesTschofenig 0:796d0f61a05b 364 static void ssl_calc_finished_tls_sha384(ssl_context *,unsigned char *,int);
HannesTschofenig 0:796d0f61a05b 365 #endif
HannesTschofenig 0:796d0f61a05b 366 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 367
HannesTschofenig 0:796d0f61a05b 368 int ssl_derive_keys( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 369 {
HannesTschofenig 0:796d0f61a05b 370 int ret = 0;
HannesTschofenig 0:796d0f61a05b 371 unsigned char tmp[64];
HannesTschofenig 0:796d0f61a05b 372 unsigned char keyblk[256];
HannesTschofenig 0:796d0f61a05b 373 unsigned char *key1;
HannesTschofenig 0:796d0f61a05b 374 unsigned char *key2;
HannesTschofenig 0:796d0f61a05b 375 unsigned char *mac_enc;
HannesTschofenig 0:796d0f61a05b 376 unsigned char *mac_dec;
HannesTschofenig 0:796d0f61a05b 377 size_t iv_copy_len;
HannesTschofenig 0:796d0f61a05b 378 const cipher_info_t *cipher_info;
HannesTschofenig 0:796d0f61a05b 379 const md_info_t *md_info;
HannesTschofenig 0:796d0f61a05b 380
HannesTschofenig 0:796d0f61a05b 381 ssl_session *session = ssl->session_negotiate;
HannesTschofenig 0:796d0f61a05b 382 ssl_transform *transform = ssl->transform_negotiate;
HannesTschofenig 0:796d0f61a05b 383 ssl_handshake_params *handshake = ssl->handshake;
HannesTschofenig 0:796d0f61a05b 384
HannesTschofenig 0:796d0f61a05b 385 SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
HannesTschofenig 0:796d0f61a05b 386
HannesTschofenig 0:796d0f61a05b 387 cipher_info = cipher_info_from_type( transform->ciphersuite_info->cipher );
HannesTschofenig 0:796d0f61a05b 388 if( cipher_info == NULL )
HannesTschofenig 0:796d0f61a05b 389 {
HannesTschofenig 0:796d0f61a05b 390 SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
HannesTschofenig 0:796d0f61a05b 391 transform->ciphersuite_info->cipher ) );
HannesTschofenig 0:796d0f61a05b 392 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 393 }
HannesTschofenig 0:796d0f61a05b 394
HannesTschofenig 0:796d0f61a05b 395 md_info = md_info_from_type( transform->ciphersuite_info->mac );
HannesTschofenig 0:796d0f61a05b 396 if( md_info == NULL )
HannesTschofenig 0:796d0f61a05b 397 {
HannesTschofenig 0:796d0f61a05b 398 SSL_DEBUG_MSG( 1, ( "md info for %d not found",
HannesTschofenig 0:796d0f61a05b 399 transform->ciphersuite_info->mac ) );
HannesTschofenig 0:796d0f61a05b 400 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 401 }
HannesTschofenig 0:796d0f61a05b 402
HannesTschofenig 0:796d0f61a05b 403 /*
HannesTschofenig 0:796d0f61a05b 404 * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
HannesTschofenig 0:796d0f61a05b 405 */
HannesTschofenig 0:796d0f61a05b 406 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 407 if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 408 {
HannesTschofenig 0:796d0f61a05b 409 handshake->tls_prf = ssl3_prf;
HannesTschofenig 0:796d0f61a05b 410 handshake->calc_verify = ssl_calc_verify_ssl;
HannesTschofenig 0:796d0f61a05b 411 handshake->calc_finished = ssl_calc_finished_ssl;
HannesTschofenig 0:796d0f61a05b 412 }
HannesTschofenig 0:796d0f61a05b 413 else
HannesTschofenig 0:796d0f61a05b 414 #endif
HannesTschofenig 0:796d0f61a05b 415 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 416 if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 417 {
HannesTschofenig 0:796d0f61a05b 418 handshake->tls_prf = tls1_prf;
HannesTschofenig 0:796d0f61a05b 419 handshake->calc_verify = ssl_calc_verify_tls;
HannesTschofenig 0:796d0f61a05b 420 handshake->calc_finished = ssl_calc_finished_tls;
HannesTschofenig 0:796d0f61a05b 421 }
HannesTschofenig 0:796d0f61a05b 422 else
HannesTschofenig 0:796d0f61a05b 423 #endif
HannesTschofenig 0:796d0f61a05b 424 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 425 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 426 if( ssl->minor_ver == SSL_MINOR_VERSION_3 &&
HannesTschofenig 0:796d0f61a05b 427 transform->ciphersuite_info->mac == POLARSSL_MD_SHA384 )
HannesTschofenig 0:796d0f61a05b 428 {
HannesTschofenig 0:796d0f61a05b 429 handshake->tls_prf = tls_prf_sha384;
HannesTschofenig 0:796d0f61a05b 430 handshake->calc_verify = ssl_calc_verify_tls_sha384;
HannesTschofenig 0:796d0f61a05b 431 handshake->calc_finished = ssl_calc_finished_tls_sha384;
HannesTschofenig 0:796d0f61a05b 432 }
HannesTschofenig 0:796d0f61a05b 433 else
HannesTschofenig 0:796d0f61a05b 434 #endif
HannesTschofenig 0:796d0f61a05b 435 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 436 if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 437 {
HannesTschofenig 0:796d0f61a05b 438 handshake->tls_prf = tls_prf_sha256;
HannesTschofenig 0:796d0f61a05b 439 handshake->calc_verify = ssl_calc_verify_tls_sha256;
HannesTschofenig 0:796d0f61a05b 440 handshake->calc_finished = ssl_calc_finished_tls_sha256;
HannesTschofenig 0:796d0f61a05b 441 }
HannesTschofenig 0:796d0f61a05b 442 else
HannesTschofenig 0:796d0f61a05b 443 #endif
HannesTschofenig 0:796d0f61a05b 444 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 445 {
HannesTschofenig 0:796d0f61a05b 446 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 447 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 448 }
HannesTschofenig 0:796d0f61a05b 449
HannesTschofenig 0:796d0f61a05b 450 /*
HannesTschofenig 0:796d0f61a05b 451 * SSLv3:
HannesTschofenig 0:796d0f61a05b 452 * master =
HannesTschofenig 0:796d0f61a05b 453 * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) +
HannesTschofenig 0:796d0f61a05b 454 * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) +
HannesTschofenig 0:796d0f61a05b 455 * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
HannesTschofenig 0:796d0f61a05b 456 *
HannesTschofenig 0:796d0f61a05b 457 * TLSv1+:
HannesTschofenig 0:796d0f61a05b 458 * master = PRF( premaster, "master secret", randbytes )[0..47]
HannesTschofenig 0:796d0f61a05b 459 */
HannesTschofenig 0:796d0f61a05b 460 if( handshake->resume == 0 )
HannesTschofenig 0:796d0f61a05b 461 {
HannesTschofenig 0:796d0f61a05b 462 SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
HannesTschofenig 0:796d0f61a05b 463 handshake->pmslen );
HannesTschofenig 0:796d0f61a05b 464
HannesTschofenig 0:796d0f61a05b 465 handshake->tls_prf( handshake->premaster, handshake->pmslen,
HannesTschofenig 0:796d0f61a05b 466 "master secret",
HannesTschofenig 0:796d0f61a05b 467 handshake->randbytes, 64, session->master, 48 );
HannesTschofenig 0:796d0f61a05b 468
HannesTschofenig 0:796d0f61a05b 469 memset( handshake->premaster, 0, sizeof( handshake->premaster ) );
HannesTschofenig 0:796d0f61a05b 470 }
HannesTschofenig 0:796d0f61a05b 471 else
HannesTschofenig 0:796d0f61a05b 472 SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
HannesTschofenig 0:796d0f61a05b 473
HannesTschofenig 0:796d0f61a05b 474 /*
HannesTschofenig 0:796d0f61a05b 475 * Swap the client and server random values.
HannesTschofenig 0:796d0f61a05b 476 */
HannesTschofenig 0:796d0f61a05b 477 memcpy( tmp, handshake->randbytes, 64 );
HannesTschofenig 0:796d0f61a05b 478 memcpy( handshake->randbytes, tmp + 32, 32 );
HannesTschofenig 0:796d0f61a05b 479 memcpy( handshake->randbytes + 32, tmp, 32 );
HannesTschofenig 0:796d0f61a05b 480 memset( tmp, 0, sizeof( tmp ) );
HannesTschofenig 0:796d0f61a05b 481
HannesTschofenig 0:796d0f61a05b 482 /*
HannesTschofenig 0:796d0f61a05b 483 * SSLv3:
HannesTschofenig 0:796d0f61a05b 484 * key block =
HannesTschofenig 0:796d0f61a05b 485 * MD5( master + SHA1( 'A' + master + randbytes ) ) +
HannesTschofenig 0:796d0f61a05b 486 * MD5( master + SHA1( 'BB' + master + randbytes ) ) +
HannesTschofenig 0:796d0f61a05b 487 * MD5( master + SHA1( 'CCC' + master + randbytes ) ) +
HannesTschofenig 0:796d0f61a05b 488 * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
HannesTschofenig 0:796d0f61a05b 489 * ...
HannesTschofenig 0:796d0f61a05b 490 *
HannesTschofenig 0:796d0f61a05b 491 * TLSv1:
HannesTschofenig 0:796d0f61a05b 492 * key block = PRF( master, "key expansion", randbytes )
HannesTschofenig 0:796d0f61a05b 493 */
HannesTschofenig 0:796d0f61a05b 494 handshake->tls_prf( session->master, 48, "key expansion",
HannesTschofenig 0:796d0f61a05b 495 handshake->randbytes, 64, keyblk, 256 );
HannesTschofenig 0:796d0f61a05b 496
HannesTschofenig 0:796d0f61a05b 497 SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
HannesTschofenig 0:796d0f61a05b 498 ssl_get_ciphersuite_name( session->ciphersuite ) ) );
HannesTschofenig 0:796d0f61a05b 499 SSL_DEBUG_BUF( 3, "master secret", session->master, 48 );
HannesTschofenig 0:796d0f61a05b 500 SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
HannesTschofenig 0:796d0f61a05b 501 SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
HannesTschofenig 0:796d0f61a05b 502
HannesTschofenig 0:796d0f61a05b 503 memset( handshake->randbytes, 0, sizeof( handshake->randbytes ) );
HannesTschofenig 0:796d0f61a05b 504
HannesTschofenig 0:796d0f61a05b 505 /*
HannesTschofenig 0:796d0f61a05b 506 * Determine the appropriate key, IV and MAC length.
HannesTschofenig 0:796d0f61a05b 507 */
HannesTschofenig 0:796d0f61a05b 508
HannesTschofenig 0:796d0f61a05b 509 if( cipher_info->mode == POLARSSL_MODE_GCM )
HannesTschofenig 0:796d0f61a05b 510 {
HannesTschofenig 0:796d0f61a05b 511 transform->keylen = cipher_info->key_length;
HannesTschofenig 0:796d0f61a05b 512 transform->keylen /= 8;
HannesTschofenig 0:796d0f61a05b 513 transform->minlen = 1;
HannesTschofenig 0:796d0f61a05b 514 transform->ivlen = 12;
HannesTschofenig 0:796d0f61a05b 515 transform->fixed_ivlen = 4;
HannesTschofenig 0:796d0f61a05b 516 transform->maclen = 0;
HannesTschofenig 0:796d0f61a05b 517 }
HannesTschofenig 0:796d0f61a05b 518 else
HannesTschofenig 0:796d0f61a05b 519 {
HannesTschofenig 0:796d0f61a05b 520 if( md_info->type != POLARSSL_MD_NONE )
HannesTschofenig 0:796d0f61a05b 521 {
HannesTschofenig 0:796d0f61a05b 522 int ret;
HannesTschofenig 0:796d0f61a05b 523
HannesTschofenig 0:796d0f61a05b 524 if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 525 {
HannesTschofenig 0:796d0f61a05b 526 SSL_DEBUG_RET( 1, "md_init_ctx", ret );
HannesTschofenig 0:796d0f61a05b 527 return( ret );
HannesTschofenig 0:796d0f61a05b 528 }
HannesTschofenig 0:796d0f61a05b 529
HannesTschofenig 0:796d0f61a05b 530 if( ( ret = md_init_ctx( &transform->md_ctx_dec, md_info ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 531 {
HannesTschofenig 0:796d0f61a05b 532 SSL_DEBUG_RET( 1, "md_init_ctx", ret );
HannesTschofenig 0:796d0f61a05b 533 return( ret );
HannesTschofenig 0:796d0f61a05b 534 }
HannesTschofenig 0:796d0f61a05b 535
HannesTschofenig 0:796d0f61a05b 536 transform->maclen = md_get_size( md_info );
HannesTschofenig 0:796d0f61a05b 537
HannesTschofenig 0:796d0f61a05b 538 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
HannesTschofenig 0:796d0f61a05b 539 /*
HannesTschofenig 0:796d0f61a05b 540 * If HMAC is to be truncated, we shall keep the leftmost bytes,
HannesTschofenig 0:796d0f61a05b 541 * (rfc 6066 page 13 or rfc 2104 section 4),
HannesTschofenig 0:796d0f61a05b 542 * so we only need to adjust the length here.
HannesTschofenig 0:796d0f61a05b 543 */
HannesTschofenig 0:796d0f61a05b 544 if( session->trunc_hmac == SSL_TRUNC_HMAC_ENABLED )
HannesTschofenig 0:796d0f61a05b 545 transform->maclen = SSL_TRUNCATED_HMAC_LEN;
HannesTschofenig 0:796d0f61a05b 546 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
HannesTschofenig 0:796d0f61a05b 547 }
HannesTschofenig 0:796d0f61a05b 548
HannesTschofenig 0:796d0f61a05b 549 transform->keylen = cipher_info->key_length;
HannesTschofenig 0:796d0f61a05b 550 transform->keylen /= 8;
HannesTschofenig 0:796d0f61a05b 551 transform->ivlen = cipher_info->iv_size;
HannesTschofenig 0:796d0f61a05b 552
HannesTschofenig 0:796d0f61a05b 553 transform->minlen = transform->keylen;
HannesTschofenig 0:796d0f61a05b 554 if( transform->minlen < transform->maclen )
HannesTschofenig 0:796d0f61a05b 555 {
HannesTschofenig 0:796d0f61a05b 556 if( cipher_info->mode == POLARSSL_MODE_STREAM )
HannesTschofenig 0:796d0f61a05b 557 transform->minlen = transform->maclen;
HannesTschofenig 0:796d0f61a05b 558 else
HannesTschofenig 0:796d0f61a05b 559 transform->minlen += transform->keylen;
HannesTschofenig 0:796d0f61a05b 560 }
HannesTschofenig 0:796d0f61a05b 561 }
HannesTschofenig 0:796d0f61a05b 562
HannesTschofenig 0:796d0f61a05b 563 SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
HannesTschofenig 0:796d0f61a05b 564 transform->keylen, transform->minlen, transform->ivlen,
HannesTschofenig 0:796d0f61a05b 565 transform->maclen ) );
HannesTschofenig 0:796d0f61a05b 566
HannesTschofenig 0:796d0f61a05b 567 /*
HannesTschofenig 0:796d0f61a05b 568 * Finally setup the cipher contexts, IVs and MAC secrets.
HannesTschofenig 0:796d0f61a05b 569 */
HannesTschofenig 0:796d0f61a05b 570 if( ssl->endpoint == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 571 {
HannesTschofenig 0:796d0f61a05b 572 key1 = keyblk + transform->maclen * 2;
HannesTschofenig 0:796d0f61a05b 573 key2 = keyblk + transform->maclen * 2 + transform->keylen;
HannesTschofenig 0:796d0f61a05b 574
HannesTschofenig 0:796d0f61a05b 575 mac_enc = keyblk;
HannesTschofenig 0:796d0f61a05b 576 mac_dec = keyblk + transform->maclen;
HannesTschofenig 0:796d0f61a05b 577
HannesTschofenig 0:796d0f61a05b 578 /*
HannesTschofenig 0:796d0f61a05b 579 * This is not used in TLS v1.1.
HannesTschofenig 0:796d0f61a05b 580 */
HannesTschofenig 0:796d0f61a05b 581 iv_copy_len = ( transform->fixed_ivlen ) ?
HannesTschofenig 0:796d0f61a05b 582 transform->fixed_ivlen : transform->ivlen;
HannesTschofenig 0:796d0f61a05b 583 memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len );
HannesTschofenig 0:796d0f61a05b 584 memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len,
HannesTschofenig 0:796d0f61a05b 585 iv_copy_len );
HannesTschofenig 0:796d0f61a05b 586 }
HannesTschofenig 0:796d0f61a05b 587 else
HannesTschofenig 0:796d0f61a05b 588 {
HannesTschofenig 0:796d0f61a05b 589 key1 = keyblk + transform->maclen * 2 + transform->keylen;
HannesTschofenig 0:796d0f61a05b 590 key2 = keyblk + transform->maclen * 2;
HannesTschofenig 0:796d0f61a05b 591
HannesTschofenig 0:796d0f61a05b 592 mac_enc = keyblk + transform->maclen;
HannesTschofenig 0:796d0f61a05b 593 mac_dec = keyblk;
HannesTschofenig 0:796d0f61a05b 594
HannesTschofenig 0:796d0f61a05b 595 /*
HannesTschofenig 0:796d0f61a05b 596 * This is not used in TLS v1.1.
HannesTschofenig 0:796d0f61a05b 597 */
HannesTschofenig 0:796d0f61a05b 598 iv_copy_len = ( transform->fixed_ivlen ) ?
HannesTschofenig 0:796d0f61a05b 599 transform->fixed_ivlen : transform->ivlen;
HannesTschofenig 0:796d0f61a05b 600 memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len );
HannesTschofenig 0:796d0f61a05b 601 memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len,
HannesTschofenig 0:796d0f61a05b 602 iv_copy_len );
HannesTschofenig 0:796d0f61a05b 603 }
HannesTschofenig 0:796d0f61a05b 604
HannesTschofenig 0:796d0f61a05b 605 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 606 if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 607 {
HannesTschofenig 0:796d0f61a05b 608 if( transform->maclen > sizeof transform->mac_enc )
HannesTschofenig 0:796d0f61a05b 609 {
HannesTschofenig 0:796d0f61a05b 610 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 611 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 612 }
HannesTschofenig 0:796d0f61a05b 613
HannesTschofenig 0:796d0f61a05b 614 memcpy( transform->mac_enc, mac_enc, transform->maclen );
HannesTschofenig 0:796d0f61a05b 615 memcpy( transform->mac_dec, mac_dec, transform->maclen );
HannesTschofenig 0:796d0f61a05b 616 }
HannesTschofenig 0:796d0f61a05b 617 else
HannesTschofenig 0:796d0f61a05b 618 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 619 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 620 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 621 if( ssl->minor_ver >= SSL_MINOR_VERSION_1 )
HannesTschofenig 0:796d0f61a05b 622 {
HannesTschofenig 0:796d0f61a05b 623 md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen );
HannesTschofenig 0:796d0f61a05b 624 md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen );
HannesTschofenig 0:796d0f61a05b 625 }
HannesTschofenig 0:796d0f61a05b 626 else
HannesTschofenig 0:796d0f61a05b 627 #endif
HannesTschofenig 0:796d0f61a05b 628 {
HannesTschofenig 0:796d0f61a05b 629 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 630 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 631 }
HannesTschofenig 0:796d0f61a05b 632
HannesTschofenig 0:796d0f61a05b 633 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
HannesTschofenig 0:796d0f61a05b 634 if( ssl_hw_record_init != NULL)
HannesTschofenig 0:796d0f61a05b 635 {
HannesTschofenig 0:796d0f61a05b 636 int ret = 0;
HannesTschofenig 0:796d0f61a05b 637
HannesTschofenig 0:796d0f61a05b 638 SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_init()" ) );
HannesTschofenig 0:796d0f61a05b 639
HannesTschofenig 0:796d0f61a05b 640 if( ( ret = ssl_hw_record_init( ssl, key1, key2, transform->keylen,
HannesTschofenig 0:796d0f61a05b 641 transform->iv_enc, transform->iv_dec,
HannesTschofenig 0:796d0f61a05b 642 iv_copy_len,
HannesTschofenig 0:796d0f61a05b 643 mac_enc, mac_dec,
HannesTschofenig 0:796d0f61a05b 644 transform->maclen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 645 {
HannesTschofenig 0:796d0f61a05b 646 SSL_DEBUG_RET( 1, "ssl_hw_record_init", ret );
HannesTschofenig 0:796d0f61a05b 647 return POLARSSL_ERR_SSL_HW_ACCEL_FAILED;
HannesTschofenig 0:796d0f61a05b 648 }
HannesTschofenig 0:796d0f61a05b 649 }
HannesTschofenig 0:796d0f61a05b 650 #endif /* POLARSSL_SSL_HW_RECORD_ACCEL */
HannesTschofenig 0:796d0f61a05b 651
HannesTschofenig 0:796d0f61a05b 652 if( ( ret = cipher_init_ctx( &transform->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 653 cipher_info ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 654 {
HannesTschofenig 0:796d0f61a05b 655 SSL_DEBUG_RET( 1, "cipher_init_ctx", ret );
HannesTschofenig 0:796d0f61a05b 656 return( ret );
HannesTschofenig 0:796d0f61a05b 657 }
HannesTschofenig 0:796d0f61a05b 658
HannesTschofenig 0:796d0f61a05b 659 if( ( ret = cipher_init_ctx( &transform->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 660 cipher_info ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 661 {
HannesTschofenig 0:796d0f61a05b 662 SSL_DEBUG_RET( 1, "cipher_init_ctx", ret );
HannesTschofenig 0:796d0f61a05b 663 return( ret );
HannesTschofenig 0:796d0f61a05b 664 }
HannesTschofenig 0:796d0f61a05b 665
HannesTschofenig 0:796d0f61a05b 666 if( ( ret = cipher_setkey( &transform->cipher_ctx_enc, key1,
HannesTschofenig 0:796d0f61a05b 667 cipher_info->key_length,
HannesTschofenig 0:796d0f61a05b 668 POLARSSL_ENCRYPT ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 669 {
HannesTschofenig 0:796d0f61a05b 670 SSL_DEBUG_RET( 1, "cipher_setkey", ret );
HannesTschofenig 0:796d0f61a05b 671 return( ret );
HannesTschofenig 0:796d0f61a05b 672 }
HannesTschofenig 0:796d0f61a05b 673
HannesTschofenig 0:796d0f61a05b 674 if( ( ret = cipher_setkey( &transform->cipher_ctx_dec, key2,
HannesTschofenig 0:796d0f61a05b 675 cipher_info->key_length,
HannesTschofenig 0:796d0f61a05b 676 POLARSSL_DECRYPT ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 677 {
HannesTschofenig 0:796d0f61a05b 678 SSL_DEBUG_RET( 1, "cipher_setkey", ret );
HannesTschofenig 0:796d0f61a05b 679 return( ret );
HannesTschofenig 0:796d0f61a05b 680 }
HannesTschofenig 0:796d0f61a05b 681
HannesTschofenig 0:796d0f61a05b 682 #if defined(POLARSSL_CIPHER_MODE_CBC)
HannesTschofenig 0:796d0f61a05b 683 if( cipher_info->mode == POLARSSL_MODE_CBC )
HannesTschofenig 0:796d0f61a05b 684 {
HannesTschofenig 0:796d0f61a05b 685 if( ( ret = cipher_set_padding_mode( &transform->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 686 POLARSSL_PADDING_NONE ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 687 {
HannesTschofenig 0:796d0f61a05b 688 SSL_DEBUG_RET( 1, "cipher_set_padding_mode", ret );
HannesTschofenig 0:796d0f61a05b 689 return( ret );
HannesTschofenig 0:796d0f61a05b 690 }
HannesTschofenig 0:796d0f61a05b 691
HannesTschofenig 0:796d0f61a05b 692 if( ( ret = cipher_set_padding_mode( &transform->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 693 POLARSSL_PADDING_NONE ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 694 {
HannesTschofenig 0:796d0f61a05b 695 SSL_DEBUG_RET( 1, "cipher_set_padding_mode", ret );
HannesTschofenig 0:796d0f61a05b 696 return( ret );
HannesTschofenig 0:796d0f61a05b 697 }
HannesTschofenig 0:796d0f61a05b 698 }
HannesTschofenig 0:796d0f61a05b 699 #endif /* POLARSSL_CIPHER_MODE_CBC */
HannesTschofenig 0:796d0f61a05b 700
HannesTschofenig 0:796d0f61a05b 701 memset( keyblk, 0, sizeof( keyblk ) );
HannesTschofenig 0:796d0f61a05b 702
HannesTschofenig 0:796d0f61a05b 703 #if defined(POLARSSL_ZLIB_SUPPORT)
HannesTschofenig 0:796d0f61a05b 704 // Initialize compression
HannesTschofenig 0:796d0f61a05b 705 //
HannesTschofenig 0:796d0f61a05b 706 if( session->compression == SSL_COMPRESS_DEFLATE )
HannesTschofenig 0:796d0f61a05b 707 {
HannesTschofenig 0:796d0f61a05b 708 if( ssl->compress_buf == NULL )
HannesTschofenig 0:796d0f61a05b 709 {
HannesTschofenig 0:796d0f61a05b 710 SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
HannesTschofenig 0:796d0f61a05b 711 ssl->compress_buf = polarssl_malloc( SSL_BUFFER_LEN );
HannesTschofenig 0:796d0f61a05b 712 if( ssl->compress_buf == NULL )
HannesTschofenig 0:796d0f61a05b 713 {
HannesTschofenig 0:796d0f61a05b 714 SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed",
HannesTschofenig 0:796d0f61a05b 715 SSL_BUFFER_LEN ) );
HannesTschofenig 0:796d0f61a05b 716 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 717 }
HannesTschofenig 0:796d0f61a05b 718 }
HannesTschofenig 0:796d0f61a05b 719
HannesTschofenig 0:796d0f61a05b 720 SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) );
HannesTschofenig 0:796d0f61a05b 721
HannesTschofenig 0:796d0f61a05b 722 memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) );
HannesTschofenig 0:796d0f61a05b 723 memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) );
HannesTschofenig 0:796d0f61a05b 724
HannesTschofenig 0:796d0f61a05b 725 if( deflateInit( &transform->ctx_deflate,
HannesTschofenig 0:796d0f61a05b 726 Z_DEFAULT_COMPRESSION ) != Z_OK ||
HannesTschofenig 0:796d0f61a05b 727 inflateInit( &transform->ctx_inflate ) != Z_OK )
HannesTschofenig 0:796d0f61a05b 728 {
HannesTschofenig 0:796d0f61a05b 729 SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
HannesTschofenig 0:796d0f61a05b 730 return( POLARSSL_ERR_SSL_COMPRESSION_FAILED );
HannesTschofenig 0:796d0f61a05b 731 }
HannesTschofenig 0:796d0f61a05b 732 }
HannesTschofenig 0:796d0f61a05b 733 #endif /* POLARSSL_ZLIB_SUPPORT */
HannesTschofenig 0:796d0f61a05b 734
HannesTschofenig 0:796d0f61a05b 735 SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
HannesTschofenig 0:796d0f61a05b 736
HannesTschofenig 0:796d0f61a05b 737 return( 0 );
HannesTschofenig 0:796d0f61a05b 738 }
HannesTschofenig 0:796d0f61a05b 739
HannesTschofenig 0:796d0f61a05b 740 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 741 void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] )
HannesTschofenig 0:796d0f61a05b 742 {
HannesTschofenig 0:796d0f61a05b 743 md5_context md5;
HannesTschofenig 0:796d0f61a05b 744 sha1_context sha1;
HannesTschofenig 0:796d0f61a05b 745 unsigned char pad_1[48];
HannesTschofenig 0:796d0f61a05b 746 unsigned char pad_2[48];
HannesTschofenig 0:796d0f61a05b 747
HannesTschofenig 0:796d0f61a05b 748 SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) );
HannesTschofenig 0:796d0f61a05b 749
HannesTschofenig 0:796d0f61a05b 750 memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) );
HannesTschofenig 0:796d0f61a05b 751 memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) );
HannesTschofenig 0:796d0f61a05b 752
HannesTschofenig 0:796d0f61a05b 753 memset( pad_1, 0x36, 48 );
HannesTschofenig 0:796d0f61a05b 754 memset( pad_2, 0x5C, 48 );
HannesTschofenig 0:796d0f61a05b 755
HannesTschofenig 0:796d0f61a05b 756 md5_update( &md5, ssl->session_negotiate->master, 48 );
HannesTschofenig 0:796d0f61a05b 757 md5_update( &md5, pad_1, 48 );
HannesTschofenig 0:796d0f61a05b 758 md5_finish( &md5, hash );
HannesTschofenig 0:796d0f61a05b 759
HannesTschofenig 0:796d0f61a05b 760 md5_starts( &md5 );
HannesTschofenig 0:796d0f61a05b 761 md5_update( &md5, ssl->session_negotiate->master, 48 );
HannesTschofenig 0:796d0f61a05b 762 md5_update( &md5, pad_2, 48 );
HannesTschofenig 0:796d0f61a05b 763 md5_update( &md5, hash, 16 );
HannesTschofenig 0:796d0f61a05b 764 md5_finish( &md5, hash );
HannesTschofenig 0:796d0f61a05b 765
HannesTschofenig 0:796d0f61a05b 766 sha1_update( &sha1, ssl->session_negotiate->master, 48 );
HannesTschofenig 0:796d0f61a05b 767 sha1_update( &sha1, pad_1, 40 );
HannesTschofenig 0:796d0f61a05b 768 sha1_finish( &sha1, hash + 16 );
HannesTschofenig 0:796d0f61a05b 769
HannesTschofenig 0:796d0f61a05b 770 sha1_starts( &sha1 );
HannesTschofenig 0:796d0f61a05b 771 sha1_update( &sha1, ssl->session_negotiate->master, 48 );
HannesTschofenig 0:796d0f61a05b 772 sha1_update( &sha1, pad_2, 40 );
HannesTschofenig 0:796d0f61a05b 773 sha1_update( &sha1, hash + 16, 20 );
HannesTschofenig 0:796d0f61a05b 774 sha1_finish( &sha1, hash + 16 );
HannesTschofenig 0:796d0f61a05b 775
HannesTschofenig 0:796d0f61a05b 776 SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
HannesTschofenig 0:796d0f61a05b 777 SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
HannesTschofenig 0:796d0f61a05b 778
HannesTschofenig 0:796d0f61a05b 779 return;
HannesTschofenig 0:796d0f61a05b 780 }
HannesTschofenig 0:796d0f61a05b 781 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 782
HannesTschofenig 0:796d0f61a05b 783 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 784 void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] )
HannesTschofenig 0:796d0f61a05b 785 {
HannesTschofenig 0:796d0f61a05b 786 md5_context md5;
HannesTschofenig 0:796d0f61a05b 787 sha1_context sha1;
HannesTschofenig 0:796d0f61a05b 788
HannesTschofenig 0:796d0f61a05b 789 SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) );
HannesTschofenig 0:796d0f61a05b 790
HannesTschofenig 0:796d0f61a05b 791 memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) );
HannesTschofenig 0:796d0f61a05b 792 memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) );
HannesTschofenig 0:796d0f61a05b 793
HannesTschofenig 0:796d0f61a05b 794 md5_finish( &md5, hash );
HannesTschofenig 0:796d0f61a05b 795 sha1_finish( &sha1, hash + 16 );
HannesTschofenig 0:796d0f61a05b 796
HannesTschofenig 0:796d0f61a05b 797 SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
HannesTschofenig 0:796d0f61a05b 798 SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
HannesTschofenig 0:796d0f61a05b 799
HannesTschofenig 0:796d0f61a05b 800 return;
HannesTschofenig 0:796d0f61a05b 801 }
HannesTschofenig 0:796d0f61a05b 802 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */
HannesTschofenig 0:796d0f61a05b 803
HannesTschofenig 0:796d0f61a05b 804 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 805 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 806 void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] )
HannesTschofenig 0:796d0f61a05b 807 {
HannesTschofenig 0:796d0f61a05b 808 sha256_context sha256;
HannesTschofenig 0:796d0f61a05b 809
HannesTschofenig 0:796d0f61a05b 810 SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
HannesTschofenig 0:796d0f61a05b 811
HannesTschofenig 0:796d0f61a05b 812 memcpy( &sha256, &ssl->handshake->fin_sha256, sizeof(sha256_context) );
HannesTschofenig 0:796d0f61a05b 813 sha256_finish( &sha256, hash );
HannesTschofenig 0:796d0f61a05b 814
HannesTschofenig 0:796d0f61a05b 815 SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
HannesTschofenig 0:796d0f61a05b 816 SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
HannesTschofenig 0:796d0f61a05b 817
HannesTschofenig 0:796d0f61a05b 818 return;
HannesTschofenig 0:796d0f61a05b 819 }
HannesTschofenig 0:796d0f61a05b 820 #endif /* POLARSSL_SHA256_C */
HannesTschofenig 0:796d0f61a05b 821
HannesTschofenig 0:796d0f61a05b 822 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 823 void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] )
HannesTschofenig 0:796d0f61a05b 824 {
HannesTschofenig 0:796d0f61a05b 825 sha512_context sha512;
HannesTschofenig 0:796d0f61a05b 826
HannesTschofenig 0:796d0f61a05b 827 SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
HannesTschofenig 0:796d0f61a05b 828
HannesTschofenig 0:796d0f61a05b 829 memcpy( &sha512, &ssl->handshake->fin_sha512, sizeof(sha512_context) );
HannesTschofenig 0:796d0f61a05b 830 sha512_finish( &sha512, hash );
HannesTschofenig 0:796d0f61a05b 831
HannesTschofenig 0:796d0f61a05b 832 SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
HannesTschofenig 0:796d0f61a05b 833 SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
HannesTschofenig 0:796d0f61a05b 834
HannesTschofenig 0:796d0f61a05b 835 return;
HannesTschofenig 0:796d0f61a05b 836 }
HannesTschofenig 0:796d0f61a05b 837 #endif /* POLARSSL_SHA512_C */
HannesTschofenig 0:796d0f61a05b 838 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 839
HannesTschofenig 0:796d0f61a05b 840 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 841 int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex )
HannesTschofenig 0:796d0f61a05b 842 {
HannesTschofenig 0:796d0f61a05b 843 unsigned char *p = ssl->handshake->premaster;
HannesTschofenig 0:796d0f61a05b 844 unsigned char *end = p + sizeof( ssl->handshake->premaster );
HannesTschofenig 0:796d0f61a05b 845
HannesTschofenig 0:796d0f61a05b 846 /*
HannesTschofenig 0:796d0f61a05b 847 * PMS = struct {
HannesTschofenig 0:796d0f61a05b 848 * opaque other_secret<0..2^16-1>;
HannesTschofenig 0:796d0f61a05b 849 * opaque psk<0..2^16-1>;
HannesTschofenig 0:796d0f61a05b 850 * };
HannesTschofenig 0:796d0f61a05b 851 * with "other_secret" depending on the particular key exchange
HannesTschofenig 0:796d0f61a05b 852 */
HannesTschofenig 0:796d0f61a05b 853 #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 854 if( key_ex == POLARSSL_KEY_EXCHANGE_PSK )
HannesTschofenig 0:796d0f61a05b 855 {
HannesTschofenig 0:796d0f61a05b 856 if( end - p < 2 + (int) ssl->psk_len )
HannesTschofenig 0:796d0f61a05b 857 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 858
HannesTschofenig 0:796d0f61a05b 859 *(p++) = (unsigned char)( ssl->psk_len >> 8 );
HannesTschofenig 0:796d0f61a05b 860 *(p++) = (unsigned char)( ssl->psk_len );
HannesTschofenig 0:796d0f61a05b 861 p += ssl->psk_len;
HannesTschofenig 0:796d0f61a05b 862 }
HannesTschofenig 0:796d0f61a05b 863 else
HannesTschofenig 0:796d0f61a05b 864 #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 865 #if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 866 if( key_ex == POLARSSL_KEY_EXCHANGE_RSA_PSK )
HannesTschofenig 0:796d0f61a05b 867 {
HannesTschofenig 0:796d0f61a05b 868 /*
HannesTschofenig 0:796d0f61a05b 869 * other_secret already set by the ClientKeyExchange message,
HannesTschofenig 0:796d0f61a05b 870 * and is 48 bytes long
HannesTschofenig 0:796d0f61a05b 871 */
HannesTschofenig 0:796d0f61a05b 872 *p++ = 0;
HannesTschofenig 0:796d0f61a05b 873 *p++ = 48;
HannesTschofenig 0:796d0f61a05b 874 p += 48;
HannesTschofenig 0:796d0f61a05b 875 }
HannesTschofenig 0:796d0f61a05b 876 else
HannesTschofenig 0:796d0f61a05b 877 #endif /* POLARSSL_KEY_EXCHANGE_RSA_PKS_ENABLED */
HannesTschofenig 0:796d0f61a05b 878 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 879 if( key_ex == POLARSSL_KEY_EXCHANGE_DHE_PSK )
HannesTschofenig 0:796d0f61a05b 880 {
HannesTschofenig 0:796d0f61a05b 881 int ret;
HannesTschofenig 0:796d0f61a05b 882 size_t len = ssl->handshake->dhm_ctx.len;
HannesTschofenig 0:796d0f61a05b 883
HannesTschofenig 0:796d0f61a05b 884 if( end - p < 2 + (int) len )
HannesTschofenig 0:796d0f61a05b 885 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 886
HannesTschofenig 0:796d0f61a05b 887 *(p++) = (unsigned char)( len >> 8 );
HannesTschofenig 0:796d0f61a05b 888 *(p++) = (unsigned char)( len );
HannesTschofenig 0:796d0f61a05b 889 if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
HannesTschofenig 0:796d0f61a05b 890 p, &len, ssl->f_rng, ssl->p_rng ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 891 {
HannesTschofenig 0:796d0f61a05b 892 SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
HannesTschofenig 0:796d0f61a05b 893 return( ret );
HannesTschofenig 0:796d0f61a05b 894 }
HannesTschofenig 0:796d0f61a05b 895 p += len;
HannesTschofenig 0:796d0f61a05b 896
HannesTschofenig 0:796d0f61a05b 897 SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
HannesTschofenig 0:796d0f61a05b 898 }
HannesTschofenig 0:796d0f61a05b 899 else
HannesTschofenig 0:796d0f61a05b 900 #endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 901 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 902 if( key_ex == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 903 {
HannesTschofenig 0:796d0f61a05b 904 int ret;
HannesTschofenig 0:796d0f61a05b 905 size_t zlen;
HannesTschofenig 0:796d0f61a05b 906
HannesTschofenig 0:796d0f61a05b 907 if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
HannesTschofenig 0:796d0f61a05b 908 p + 2, end - (p + 2),
HannesTschofenig 0:796d0f61a05b 909 ssl->f_rng, ssl->p_rng ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 910 {
HannesTschofenig 0:796d0f61a05b 911 SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
HannesTschofenig 0:796d0f61a05b 912 return( ret );
HannesTschofenig 0:796d0f61a05b 913 }
HannesTschofenig 0:796d0f61a05b 914
HannesTschofenig 0:796d0f61a05b 915 *(p++) = (unsigned char)( zlen >> 8 );
HannesTschofenig 0:796d0f61a05b 916 *(p++) = (unsigned char)( zlen );
HannesTschofenig 0:796d0f61a05b 917 p += zlen;
HannesTschofenig 0:796d0f61a05b 918
HannesTschofenig 0:796d0f61a05b 919 SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
HannesTschofenig 0:796d0f61a05b 920 }
HannesTschofenig 0:796d0f61a05b 921 else
HannesTschofenig 0:796d0f61a05b 922 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 923 {
HannesTschofenig 0:796d0f61a05b 924 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 925 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 926 }
HannesTschofenig 0:796d0f61a05b 927
HannesTschofenig 0:796d0f61a05b 928 /* opaque psk<0..2^16-1>; */
HannesTschofenig 0:796d0f61a05b 929 if( end - p < 2 + (int) ssl->psk_len )
HannesTschofenig 0:796d0f61a05b 930 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 931
HannesTschofenig 0:796d0f61a05b 932 *(p++) = (unsigned char)( ssl->psk_len >> 8 );
HannesTschofenig 0:796d0f61a05b 933 *(p++) = (unsigned char)( ssl->psk_len );
HannesTschofenig 0:796d0f61a05b 934 memcpy( p, ssl->psk, ssl->psk_len );
HannesTschofenig 0:796d0f61a05b 935 p += ssl->psk_len;
HannesTschofenig 0:796d0f61a05b 936
HannesTschofenig 0:796d0f61a05b 937 ssl->handshake->pmslen = p - ssl->handshake->premaster;
HannesTschofenig 0:796d0f61a05b 938
HannesTschofenig 0:796d0f61a05b 939 return( 0 );
HannesTschofenig 0:796d0f61a05b 940 }
HannesTschofenig 0:796d0f61a05b 941 #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 942
HannesTschofenig 0:796d0f61a05b 943 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 944 /*
HannesTschofenig 0:796d0f61a05b 945 * SSLv3.0 MAC functions
HannesTschofenig 0:796d0f61a05b 946 */
HannesTschofenig 0:796d0f61a05b 947 static void ssl_mac( md_context_t *md_ctx, unsigned char *secret,
HannesTschofenig 0:796d0f61a05b 948 unsigned char *buf, size_t len,
HannesTschofenig 0:796d0f61a05b 949 unsigned char *ctr, int type )
HannesTschofenig 0:796d0f61a05b 950 {
HannesTschofenig 0:796d0f61a05b 951 unsigned char header[11];
HannesTschofenig 0:796d0f61a05b 952 unsigned char padding[48];
HannesTschofenig 0:796d0f61a05b 953 int padlen = 0;
HannesTschofenig 0:796d0f61a05b 954 int md_size = md_get_size( md_ctx->md_info );
HannesTschofenig 0:796d0f61a05b 955 int md_type = md_get_type( md_ctx->md_info );
HannesTschofenig 0:796d0f61a05b 956
HannesTschofenig 0:796d0f61a05b 957 if( md_type == POLARSSL_MD_MD5 )
HannesTschofenig 0:796d0f61a05b 958 padlen = 48;
HannesTschofenig 0:796d0f61a05b 959 else if( md_type == POLARSSL_MD_SHA1 )
HannesTschofenig 0:796d0f61a05b 960 padlen = 40;
HannesTschofenig 0:796d0f61a05b 961 else if( md_type == POLARSSL_MD_SHA256 )
HannesTschofenig 0:796d0f61a05b 962 padlen = 32;
HannesTschofenig 0:796d0f61a05b 963 else if( md_type == POLARSSL_MD_SHA384 )
HannesTschofenig 0:796d0f61a05b 964 padlen = 16;
HannesTschofenig 0:796d0f61a05b 965
HannesTschofenig 0:796d0f61a05b 966 memcpy( header, ctr, 8 );
HannesTschofenig 0:796d0f61a05b 967 header[ 8] = (unsigned char) type;
HannesTschofenig 0:796d0f61a05b 968 header[ 9] = (unsigned char)( len >> 8 );
HannesTschofenig 0:796d0f61a05b 969 header[10] = (unsigned char)( len );
HannesTschofenig 0:796d0f61a05b 970
HannesTschofenig 0:796d0f61a05b 971 memset( padding, 0x36, padlen );
HannesTschofenig 0:796d0f61a05b 972 md_starts( md_ctx );
HannesTschofenig 0:796d0f61a05b 973 md_update( md_ctx, secret, md_size );
HannesTschofenig 0:796d0f61a05b 974 md_update( md_ctx, padding, padlen );
HannesTschofenig 0:796d0f61a05b 975 md_update( md_ctx, header, 11 );
HannesTschofenig 0:796d0f61a05b 976 md_update( md_ctx, buf, len );
HannesTschofenig 0:796d0f61a05b 977 md_finish( md_ctx, buf + len );
HannesTschofenig 0:796d0f61a05b 978
HannesTschofenig 0:796d0f61a05b 979 memset( padding, 0x5C, padlen );
HannesTschofenig 0:796d0f61a05b 980 md_starts( md_ctx );
HannesTschofenig 0:796d0f61a05b 981 md_update( md_ctx, secret, md_size );
HannesTschofenig 0:796d0f61a05b 982 md_update( md_ctx, padding, padlen );
HannesTschofenig 0:796d0f61a05b 983 md_update( md_ctx, buf + len, md_size );
HannesTschofenig 0:796d0f61a05b 984 md_finish( md_ctx, buf + len );
HannesTschofenig 0:796d0f61a05b 985 }
HannesTschofenig 0:796d0f61a05b 986 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 987
HannesTschofenig 0:796d0f61a05b 988 /*
HannesTschofenig 0:796d0f61a05b 989 * Encryption/decryption functions
HannesTschofenig 0:796d0f61a05b 990 */
HannesTschofenig 0:796d0f61a05b 991 static int ssl_encrypt_buf( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 992 {
HannesTschofenig 0:796d0f61a05b 993 size_t i;
HannesTschofenig 0:796d0f61a05b 994
HannesTschofenig 0:796d0f61a05b 995 SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
HannesTschofenig 0:796d0f61a05b 996
HannesTschofenig 0:796d0f61a05b 997 /*
HannesTschofenig 0:796d0f61a05b 998 * Add MAC before encrypt, except for GCM
HannesTschofenig 0:796d0f61a05b 999 */
HannesTschofenig 0:796d0f61a05b 1000 #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \
HannesTschofenig 0:796d0f61a05b 1001 ( defined(POLARSSL_CIPHER_MODE_CBC) && \
HannesTschofenig 0:796d0f61a05b 1002 ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) )
HannesTschofenig 0:796d0f61a05b 1003 if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode !=
HannesTschofenig 0:796d0f61a05b 1004 POLARSSL_MODE_GCM )
HannesTschofenig 0:796d0f61a05b 1005 {
HannesTschofenig 0:796d0f61a05b 1006 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 1007 if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 1008 {
HannesTschofenig 0:796d0f61a05b 1009 ssl_mac( &ssl->transform_out->md_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1010 ssl->transform_out->mac_enc,
HannesTschofenig 0:796d0f61a05b 1011 ssl->out_msg, ssl->out_msglen,
HannesTschofenig 0:796d0f61a05b 1012 ssl->out_ctr, ssl->out_msgtype );
HannesTschofenig 0:796d0f61a05b 1013 }
HannesTschofenig 0:796d0f61a05b 1014 else
HannesTschofenig 0:796d0f61a05b 1015 #endif
HannesTschofenig 0:796d0f61a05b 1016 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 1017 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 1018 if( ssl->minor_ver >= SSL_MINOR_VERSION_1 )
HannesTschofenig 0:796d0f61a05b 1019 {
HannesTschofenig 0:796d0f61a05b 1020 md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 13 );
HannesTschofenig 0:796d0f61a05b 1021 md_hmac_update( &ssl->transform_out->md_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1022 ssl->out_msg, ssl->out_msglen );
HannesTschofenig 0:796d0f61a05b 1023 md_hmac_finish( &ssl->transform_out->md_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1024 ssl->out_msg + ssl->out_msglen );
HannesTschofenig 0:796d0f61a05b 1025 md_hmac_reset( &ssl->transform_out->md_ctx_enc );
HannesTschofenig 0:796d0f61a05b 1026 }
HannesTschofenig 0:796d0f61a05b 1027 else
HannesTschofenig 0:796d0f61a05b 1028 #endif
HannesTschofenig 0:796d0f61a05b 1029 {
HannesTschofenig 0:796d0f61a05b 1030 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 1031 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 1032 }
HannesTschofenig 0:796d0f61a05b 1033
HannesTschofenig 0:796d0f61a05b 1034 SSL_DEBUG_BUF( 4, "computed mac",
HannesTschofenig 0:796d0f61a05b 1035 ssl->out_msg + ssl->out_msglen,
HannesTschofenig 0:796d0f61a05b 1036 ssl->transform_out->maclen );
HannesTschofenig 0:796d0f61a05b 1037
HannesTschofenig 0:796d0f61a05b 1038 ssl->out_msglen += ssl->transform_out->maclen;
HannesTschofenig 0:796d0f61a05b 1039 }
HannesTschofenig 0:796d0f61a05b 1040 #endif /* GCM not the only option */
HannesTschofenig 0:796d0f61a05b 1041
HannesTschofenig 0:796d0f61a05b 1042 /*
HannesTschofenig 0:796d0f61a05b 1043 * Encrypt
HannesTschofenig 0:796d0f61a05b 1044 */
HannesTschofenig 0:796d0f61a05b 1045 #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER)
HannesTschofenig 0:796d0f61a05b 1046 if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode ==
HannesTschofenig 0:796d0f61a05b 1047 POLARSSL_MODE_STREAM )
HannesTschofenig 0:796d0f61a05b 1048 {
HannesTschofenig 0:796d0f61a05b 1049 int ret;
HannesTschofenig 0:796d0f61a05b 1050 size_t olen = 0;
HannesTschofenig 0:796d0f61a05b 1051
HannesTschofenig 0:796d0f61a05b 1052 SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
HannesTschofenig 0:796d0f61a05b 1053 "including %d bytes of padding",
HannesTschofenig 0:796d0f61a05b 1054 ssl->out_msglen, 0 ) );
HannesTschofenig 0:796d0f61a05b 1055
HannesTschofenig 0:796d0f61a05b 1056 SSL_DEBUG_BUF( 4, "before encrypt: output payload",
HannesTschofenig 0:796d0f61a05b 1057 ssl->out_msg, ssl->out_msglen );
HannesTschofenig 0:796d0f61a05b 1058
HannesTschofenig 0:796d0f61a05b 1059 if( ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1060 {
HannesTschofenig 0:796d0f61a05b 1061 SSL_DEBUG_RET( 1, "cipher_reset", ret );
HannesTschofenig 0:796d0f61a05b 1062 return( ret );
HannesTschofenig 0:796d0f61a05b 1063 }
HannesTschofenig 0:796d0f61a05b 1064
HannesTschofenig 0:796d0f61a05b 1065 if( ( ret = cipher_set_iv( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1066 ssl->transform_out->iv_enc,
HannesTschofenig 0:796d0f61a05b 1067 ssl->transform_out->ivlen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1068 {
HannesTschofenig 0:796d0f61a05b 1069 SSL_DEBUG_RET( 1, "cipher_set_iv", ret );
HannesTschofenig 0:796d0f61a05b 1070 return( ret );
HannesTschofenig 0:796d0f61a05b 1071 }
HannesTschofenig 0:796d0f61a05b 1072
HannesTschofenig 0:796d0f61a05b 1073 if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1074 ssl->out_msg, ssl->out_msglen, ssl->out_msg,
HannesTschofenig 0:796d0f61a05b 1075 &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1076 {
HannesTschofenig 0:796d0f61a05b 1077 SSL_DEBUG_RET( 1, "cipher_update", ret );
HannesTschofenig 0:796d0f61a05b 1078 return( ret );
HannesTschofenig 0:796d0f61a05b 1079 }
HannesTschofenig 0:796d0f61a05b 1080
HannesTschofenig 0:796d0f61a05b 1081 if( ssl->out_msglen != olen )
HannesTschofenig 0:796d0f61a05b 1082 {
HannesTschofenig 0:796d0f61a05b 1083 SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
HannesTschofenig 0:796d0f61a05b 1084 ssl->out_msglen, olen ) );
HannesTschofenig 0:796d0f61a05b 1085 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
HannesTschofenig 0:796d0f61a05b 1086 }
HannesTschofenig 0:796d0f61a05b 1087
HannesTschofenig 0:796d0f61a05b 1088 if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1089 ssl->out_msg + olen, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1090 {
HannesTschofenig 0:796d0f61a05b 1091 SSL_DEBUG_RET( 1, "cipher_finish", ret );
HannesTschofenig 0:796d0f61a05b 1092 return( ret );
HannesTschofenig 0:796d0f61a05b 1093 }
HannesTschofenig 0:796d0f61a05b 1094
HannesTschofenig 0:796d0f61a05b 1095 if( 0 != olen )
HannesTschofenig 0:796d0f61a05b 1096 {
HannesTschofenig 0:796d0f61a05b 1097 SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
HannesTschofenig 0:796d0f61a05b 1098 0, olen ) );
HannesTschofenig 0:796d0f61a05b 1099 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
HannesTschofenig 0:796d0f61a05b 1100 }
HannesTschofenig 0:796d0f61a05b 1101 }
HannesTschofenig 0:796d0f61a05b 1102 else
HannesTschofenig 0:796d0f61a05b 1103 #endif /* POLARSSL_ARC4_C || POLARSSL_CIPHER_NULL_CIPHER */
HannesTschofenig 0:796d0f61a05b 1104 #if defined(POLARSSL_GCM_C)
HannesTschofenig 0:796d0f61a05b 1105 if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode ==
HannesTschofenig 0:796d0f61a05b 1106 POLARSSL_MODE_GCM )
HannesTschofenig 0:796d0f61a05b 1107 {
HannesTschofenig 0:796d0f61a05b 1108 size_t enc_msglen, olen, totlen;
HannesTschofenig 0:796d0f61a05b 1109 unsigned char *enc_msg;
HannesTschofenig 0:796d0f61a05b 1110 unsigned char add_data[13];
HannesTschofenig 0:796d0f61a05b 1111 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 1112
HannesTschofenig 0:796d0f61a05b 1113 memcpy( add_data, ssl->out_ctr, 8 );
HannesTschofenig 0:796d0f61a05b 1114 add_data[8] = ssl->out_msgtype;
HannesTschofenig 0:796d0f61a05b 1115 add_data[9] = ssl->major_ver;
HannesTschofenig 0:796d0f61a05b 1116 add_data[10] = ssl->minor_ver;
HannesTschofenig 0:796d0f61a05b 1117 add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF;
HannesTschofenig 0:796d0f61a05b 1118 add_data[12] = ssl->out_msglen & 0xFF;
HannesTschofenig 0:796d0f61a05b 1119
HannesTschofenig 0:796d0f61a05b 1120 SSL_DEBUG_BUF( 4, "additional data used for AEAD",
HannesTschofenig 0:796d0f61a05b 1121 add_data, 13 );
HannesTschofenig 0:796d0f61a05b 1122
HannesTschofenig 0:796d0f61a05b 1123 /*
HannesTschofenig 0:796d0f61a05b 1124 * Generate IV
HannesTschofenig 0:796d0f61a05b 1125 */
HannesTschofenig 0:796d0f61a05b 1126 ret = ssl->f_rng( ssl->p_rng,
HannesTschofenig 0:796d0f61a05b 1127 ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
HannesTschofenig 0:796d0f61a05b 1128 ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
HannesTschofenig 0:796d0f61a05b 1129 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1130 return( ret );
HannesTschofenig 0:796d0f61a05b 1131
HannesTschofenig 0:796d0f61a05b 1132 memcpy( ssl->out_iv,
HannesTschofenig 0:796d0f61a05b 1133 ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
HannesTschofenig 0:796d0f61a05b 1134 ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
HannesTschofenig 0:796d0f61a05b 1135
HannesTschofenig 0:796d0f61a05b 1136 SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv,
HannesTschofenig 0:796d0f61a05b 1137 ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
HannesTschofenig 0:796d0f61a05b 1138
HannesTschofenig 0:796d0f61a05b 1139 /*
HannesTschofenig 0:796d0f61a05b 1140 * Fix pointer positions and message length with added IV
HannesTschofenig 0:796d0f61a05b 1141 */
HannesTschofenig 0:796d0f61a05b 1142 enc_msg = ssl->out_msg;
HannesTschofenig 0:796d0f61a05b 1143 enc_msglen = ssl->out_msglen;
HannesTschofenig 0:796d0f61a05b 1144 ssl->out_msglen += ssl->transform_out->ivlen -
HannesTschofenig 0:796d0f61a05b 1145 ssl->transform_out->fixed_ivlen;
HannesTschofenig 0:796d0f61a05b 1146
HannesTschofenig 0:796d0f61a05b 1147 SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
HannesTschofenig 0:796d0f61a05b 1148 "including %d bytes of padding",
HannesTschofenig 0:796d0f61a05b 1149 ssl->out_msglen, 0 ) );
HannesTschofenig 0:796d0f61a05b 1150
HannesTschofenig 0:796d0f61a05b 1151 SSL_DEBUG_BUF( 4, "before encrypt: output payload",
HannesTschofenig 0:796d0f61a05b 1152 ssl->out_msg, ssl->out_msglen );
HannesTschofenig 0:796d0f61a05b 1153
HannesTschofenig 0:796d0f61a05b 1154 /*
HannesTschofenig 0:796d0f61a05b 1155 * Encrypt
HannesTschofenig 0:796d0f61a05b 1156 */
HannesTschofenig 0:796d0f61a05b 1157 if( ( ret = cipher_set_iv( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1158 ssl->transform_out->iv_enc,
HannesTschofenig 0:796d0f61a05b 1159 ssl->transform_out->ivlen ) ) != 0 ||
HannesTschofenig 0:796d0f61a05b 1160 ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1161 {
HannesTschofenig 0:796d0f61a05b 1162 return( ret );
HannesTschofenig 0:796d0f61a05b 1163 }
HannesTschofenig 0:796d0f61a05b 1164
HannesTschofenig 0:796d0f61a05b 1165 if( ( ret = cipher_update_ad( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1166 add_data, 13 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1167 {
HannesTschofenig 0:796d0f61a05b 1168 return( ret );
HannesTschofenig 0:796d0f61a05b 1169 }
HannesTschofenig 0:796d0f61a05b 1170
HannesTschofenig 0:796d0f61a05b 1171 if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1172 enc_msg, enc_msglen,
HannesTschofenig 0:796d0f61a05b 1173 enc_msg, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1174 {
HannesTschofenig 0:796d0f61a05b 1175 return( ret );
HannesTschofenig 0:796d0f61a05b 1176 }
HannesTschofenig 0:796d0f61a05b 1177 totlen = olen;
HannesTschofenig 0:796d0f61a05b 1178
HannesTschofenig 0:796d0f61a05b 1179 if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1180 enc_msg + olen, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1181 {
HannesTschofenig 0:796d0f61a05b 1182 return( ret );
HannesTschofenig 0:796d0f61a05b 1183 }
HannesTschofenig 0:796d0f61a05b 1184 totlen += olen;
HannesTschofenig 0:796d0f61a05b 1185
HannesTschofenig 0:796d0f61a05b 1186 if( totlen != enc_msglen )
HannesTschofenig 0:796d0f61a05b 1187 {
HannesTschofenig 0:796d0f61a05b 1188 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 1189 return( -1 );
HannesTschofenig 0:796d0f61a05b 1190 }
HannesTschofenig 0:796d0f61a05b 1191
HannesTschofenig 0:796d0f61a05b 1192 /*
HannesTschofenig 0:796d0f61a05b 1193 * Authenticate
HannesTschofenig 0:796d0f61a05b 1194 */
HannesTschofenig 0:796d0f61a05b 1195 ssl->out_msglen += 16;
HannesTschofenig 0:796d0f61a05b 1196
HannesTschofenig 0:796d0f61a05b 1197 if( ( ret = cipher_write_tag( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1198 enc_msg + enc_msglen, 16 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1199 {
HannesTschofenig 0:796d0f61a05b 1200 return( ret );
HannesTschofenig 0:796d0f61a05b 1201 }
HannesTschofenig 0:796d0f61a05b 1202
HannesTschofenig 0:796d0f61a05b 1203 SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, 16 );
HannesTschofenig 0:796d0f61a05b 1204 }
HannesTschofenig 0:796d0f61a05b 1205 else
HannesTschofenig 0:796d0f61a05b 1206 #endif /* POLARSSL_GCM_C */
HannesTschofenig 0:796d0f61a05b 1207 #if defined(POLARSSL_CIPHER_MODE_CBC) && \
HannesTschofenig 0:796d0f61a05b 1208 ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) )
HannesTschofenig 0:796d0f61a05b 1209 if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode ==
HannesTschofenig 0:796d0f61a05b 1210 POLARSSL_MODE_CBC )
HannesTschofenig 0:796d0f61a05b 1211 {
HannesTschofenig 0:796d0f61a05b 1212 int ret;
HannesTschofenig 0:796d0f61a05b 1213 unsigned char *enc_msg;
HannesTschofenig 0:796d0f61a05b 1214 size_t enc_msglen, padlen, olen = 0;
HannesTschofenig 0:796d0f61a05b 1215
HannesTschofenig 0:796d0f61a05b 1216 padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) %
HannesTschofenig 0:796d0f61a05b 1217 ssl->transform_out->ivlen;
HannesTschofenig 0:796d0f61a05b 1218 if( padlen == ssl->transform_out->ivlen )
HannesTschofenig 0:796d0f61a05b 1219 padlen = 0;
HannesTschofenig 0:796d0f61a05b 1220
HannesTschofenig 0:796d0f61a05b 1221 for( i = 0; i <= padlen; i++ )
HannesTschofenig 0:796d0f61a05b 1222 ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen;
HannesTschofenig 0:796d0f61a05b 1223
HannesTschofenig 0:796d0f61a05b 1224 ssl->out_msglen += padlen + 1;
HannesTschofenig 0:796d0f61a05b 1225
HannesTschofenig 0:796d0f61a05b 1226 enc_msglen = ssl->out_msglen;
HannesTschofenig 0:796d0f61a05b 1227 enc_msg = ssl->out_msg;
HannesTschofenig 0:796d0f61a05b 1228
HannesTschofenig 0:796d0f61a05b 1229 #if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 1230 /*
HannesTschofenig 0:796d0f61a05b 1231 * Prepend per-record IV for block cipher in TLS v1.1 and up as per
HannesTschofenig 0:796d0f61a05b 1232 * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
HannesTschofenig 0:796d0f61a05b 1233 */
HannesTschofenig 0:796d0f61a05b 1234 if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
HannesTschofenig 0:796d0f61a05b 1235 {
HannesTschofenig 0:796d0f61a05b 1236 /*
HannesTschofenig 0:796d0f61a05b 1237 * Generate IV
HannesTschofenig 0:796d0f61a05b 1238 */
HannesTschofenig 0:796d0f61a05b 1239 int ret = ssl->f_rng( ssl->p_rng, ssl->transform_out->iv_enc,
HannesTschofenig 0:796d0f61a05b 1240 ssl->transform_out->ivlen );
HannesTschofenig 0:796d0f61a05b 1241 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1242 return( ret );
HannesTschofenig 0:796d0f61a05b 1243
HannesTschofenig 0:796d0f61a05b 1244 memcpy( ssl->out_iv, ssl->transform_out->iv_enc,
HannesTschofenig 0:796d0f61a05b 1245 ssl->transform_out->ivlen );
HannesTschofenig 0:796d0f61a05b 1246
HannesTschofenig 0:796d0f61a05b 1247 /*
HannesTschofenig 0:796d0f61a05b 1248 * Fix pointer positions and message length with added IV
HannesTschofenig 0:796d0f61a05b 1249 */
HannesTschofenig 0:796d0f61a05b 1250 enc_msg = ssl->out_msg;
HannesTschofenig 0:796d0f61a05b 1251 enc_msglen = ssl->out_msglen;
HannesTschofenig 0:796d0f61a05b 1252 ssl->out_msglen += ssl->transform_out->ivlen;
HannesTschofenig 0:796d0f61a05b 1253 }
HannesTschofenig 0:796d0f61a05b 1254 #endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 1255
HannesTschofenig 0:796d0f61a05b 1256 SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
HannesTschofenig 0:796d0f61a05b 1257 "including %d bytes of IV and %d bytes of padding",
HannesTschofenig 0:796d0f61a05b 1258 ssl->out_msglen, ssl->transform_out->ivlen,
HannesTschofenig 0:796d0f61a05b 1259 padlen + 1 ) );
HannesTschofenig 0:796d0f61a05b 1260
HannesTschofenig 0:796d0f61a05b 1261 SSL_DEBUG_BUF( 4, "before encrypt: output payload",
HannesTschofenig 0:796d0f61a05b 1262 ssl->out_iv, ssl->out_msglen );
HannesTschofenig 0:796d0f61a05b 1263
HannesTschofenig 0:796d0f61a05b 1264 if( ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1265 {
HannesTschofenig 0:796d0f61a05b 1266 SSL_DEBUG_RET( 1, "cipher_reset", ret );
HannesTschofenig 0:796d0f61a05b 1267 return( ret );
HannesTschofenig 0:796d0f61a05b 1268 }
HannesTschofenig 0:796d0f61a05b 1269
HannesTschofenig 0:796d0f61a05b 1270 if( ( ret = cipher_set_iv( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1271 ssl->transform_out->iv_enc,
HannesTschofenig 0:796d0f61a05b 1272 ssl->transform_out->ivlen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1273 {
HannesTschofenig 0:796d0f61a05b 1274 SSL_DEBUG_RET( 1, "cipher_set_iv", ret );
HannesTschofenig 0:796d0f61a05b 1275 return( ret );
HannesTschofenig 0:796d0f61a05b 1276 }
HannesTschofenig 0:796d0f61a05b 1277
HannesTschofenig 0:796d0f61a05b 1278 if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1279 enc_msg, enc_msglen, enc_msg,
HannesTschofenig 0:796d0f61a05b 1280 &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1281 {
HannesTschofenig 0:796d0f61a05b 1282 SSL_DEBUG_RET( 1, "cipher_update", ret );
HannesTschofenig 0:796d0f61a05b 1283 return( ret );
HannesTschofenig 0:796d0f61a05b 1284 }
HannesTschofenig 0:796d0f61a05b 1285
HannesTschofenig 0:796d0f61a05b 1286 enc_msglen -= olen;
HannesTschofenig 0:796d0f61a05b 1287
HannesTschofenig 0:796d0f61a05b 1288 if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc,
HannesTschofenig 0:796d0f61a05b 1289 enc_msg + olen, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1290 {
HannesTschofenig 0:796d0f61a05b 1291 SSL_DEBUG_RET( 1, "cipher_finish", ret );
HannesTschofenig 0:796d0f61a05b 1292 return( ret );
HannesTschofenig 0:796d0f61a05b 1293 }
HannesTschofenig 0:796d0f61a05b 1294
HannesTschofenig 0:796d0f61a05b 1295 if( enc_msglen != olen )
HannesTschofenig 0:796d0f61a05b 1296 {
HannesTschofenig 0:796d0f61a05b 1297 SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
HannesTschofenig 0:796d0f61a05b 1298 enc_msglen, olen ) );
HannesTschofenig 0:796d0f61a05b 1299 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
HannesTschofenig 0:796d0f61a05b 1300 }
HannesTschofenig 0:796d0f61a05b 1301
HannesTschofenig 0:796d0f61a05b 1302 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1)
HannesTschofenig 0:796d0f61a05b 1303 if( ssl->minor_ver < SSL_MINOR_VERSION_2 )
HannesTschofenig 0:796d0f61a05b 1304 {
HannesTschofenig 0:796d0f61a05b 1305 /*
HannesTschofenig 0:796d0f61a05b 1306 * Save IV in SSL3 and TLS1
HannesTschofenig 0:796d0f61a05b 1307 */
HannesTschofenig 0:796d0f61a05b 1308 memcpy( ssl->transform_out->iv_enc,
HannesTschofenig 0:796d0f61a05b 1309 ssl->transform_out->cipher_ctx_enc.iv,
HannesTschofenig 0:796d0f61a05b 1310 ssl->transform_out->ivlen );
HannesTschofenig 0:796d0f61a05b 1311 }
HannesTschofenig 0:796d0f61a05b 1312 #endif
HannesTschofenig 0:796d0f61a05b 1313 }
HannesTschofenig 0:796d0f61a05b 1314 else
HannesTschofenig 0:796d0f61a05b 1315 #endif /* POLARSSL_CIPHER_MODE_CBC &&
HannesTschofenig 0:796d0f61a05b 1316 ( POLARSSL_AES_C || POLARSSL_CAMELLIA_C ) */
HannesTschofenig 0:796d0f61a05b 1317 {
HannesTschofenig 0:796d0f61a05b 1318 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 1319 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 1320 }
HannesTschofenig 0:796d0f61a05b 1321
HannesTschofenig 0:796d0f61a05b 1322 for( i = 8; i > 0; i-- )
HannesTschofenig 0:796d0f61a05b 1323 if( ++ssl->out_ctr[i - 1] != 0 )
HannesTschofenig 0:796d0f61a05b 1324 break;
HannesTschofenig 0:796d0f61a05b 1325
HannesTschofenig 0:796d0f61a05b 1326 /* The loops goes to its end iff the counter is wrapping */
HannesTschofenig 0:796d0f61a05b 1327 if( i == 0 )
HannesTschofenig 0:796d0f61a05b 1328 {
HannesTschofenig 0:796d0f61a05b 1329 SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
HannesTschofenig 0:796d0f61a05b 1330 return( POLARSSL_ERR_SSL_COUNTER_WRAPPING );
HannesTschofenig 0:796d0f61a05b 1331 }
HannesTschofenig 0:796d0f61a05b 1332
HannesTschofenig 0:796d0f61a05b 1333 SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
HannesTschofenig 0:796d0f61a05b 1334
HannesTschofenig 0:796d0f61a05b 1335 return( 0 );
HannesTschofenig 0:796d0f61a05b 1336 }
HannesTschofenig 0:796d0f61a05b 1337
HannesTschofenig 0:796d0f61a05b 1338 #define POLARSSL_SSL_MAX_MAC_SIZE 48
HannesTschofenig 0:796d0f61a05b 1339
HannesTschofenig 0:796d0f61a05b 1340 static int ssl_decrypt_buf( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1341 {
HannesTschofenig 0:796d0f61a05b 1342 size_t i;
HannesTschofenig 0:796d0f61a05b 1343 #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \
HannesTschofenig 0:796d0f61a05b 1344 ( defined(POLARSSL_CIPHER_MODE_CBC) && \
HannesTschofenig 0:796d0f61a05b 1345 ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) )
HannesTschofenig 0:796d0f61a05b 1346 size_t padlen = 0, correct = 1;
HannesTschofenig 0:796d0f61a05b 1347 #endif
HannesTschofenig 0:796d0f61a05b 1348
HannesTschofenig 0:796d0f61a05b 1349 SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
HannesTschofenig 0:796d0f61a05b 1350
HannesTschofenig 0:796d0f61a05b 1351 if( ssl->in_msglen < ssl->transform_in->minlen )
HannesTschofenig 0:796d0f61a05b 1352 {
HannesTschofenig 0:796d0f61a05b 1353 SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)",
HannesTschofenig 0:796d0f61a05b 1354 ssl->in_msglen, ssl->transform_in->minlen ) );
HannesTschofenig 0:796d0f61a05b 1355 return( POLARSSL_ERR_SSL_INVALID_MAC );
HannesTschofenig 0:796d0f61a05b 1356 }
HannesTschofenig 0:796d0f61a05b 1357
HannesTschofenig 0:796d0f61a05b 1358 #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER)
HannesTschofenig 0:796d0f61a05b 1359 if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode ==
HannesTschofenig 0:796d0f61a05b 1360 POLARSSL_MODE_STREAM )
HannesTschofenig 0:796d0f61a05b 1361 {
HannesTschofenig 0:796d0f61a05b 1362 int ret;
HannesTschofenig 0:796d0f61a05b 1363 size_t olen = 0;
HannesTschofenig 0:796d0f61a05b 1364
HannesTschofenig 0:796d0f61a05b 1365 padlen = 0;
HannesTschofenig 0:796d0f61a05b 1366
HannesTschofenig 0:796d0f61a05b 1367 if( ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1368 {
HannesTschofenig 0:796d0f61a05b 1369 SSL_DEBUG_RET( 1, "cipher_reset", ret );
HannesTschofenig 0:796d0f61a05b 1370 return( ret );
HannesTschofenig 0:796d0f61a05b 1371 }
HannesTschofenig 0:796d0f61a05b 1372
HannesTschofenig 0:796d0f61a05b 1373 if( ( ret = cipher_set_iv( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1374 ssl->transform_in->iv_dec,
HannesTschofenig 0:796d0f61a05b 1375 ssl->transform_in->ivlen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1376 {
HannesTschofenig 0:796d0f61a05b 1377 SSL_DEBUG_RET( 1, "cipher_set_iv", ret );
HannesTschofenig 0:796d0f61a05b 1378 return( ret );
HannesTschofenig 0:796d0f61a05b 1379 }
HannesTschofenig 0:796d0f61a05b 1380
HannesTschofenig 0:796d0f61a05b 1381 if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1382 ssl->in_msg, ssl->in_msglen, ssl->in_msg,
HannesTschofenig 0:796d0f61a05b 1383 &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1384 {
HannesTschofenig 0:796d0f61a05b 1385 SSL_DEBUG_RET( 1, "cipher_update", ret );
HannesTschofenig 0:796d0f61a05b 1386 return( ret );
HannesTschofenig 0:796d0f61a05b 1387 }
HannesTschofenig 0:796d0f61a05b 1388
HannesTschofenig 0:796d0f61a05b 1389 if( ssl->in_msglen != olen )
HannesTschofenig 0:796d0f61a05b 1390 {
HannesTschofenig 0:796d0f61a05b 1391 SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) );
HannesTschofenig 0:796d0f61a05b 1392 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
HannesTschofenig 0:796d0f61a05b 1393 }
HannesTschofenig 0:796d0f61a05b 1394
HannesTschofenig 0:796d0f61a05b 1395 if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1396 ssl->in_msg + olen, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1397 {
HannesTschofenig 0:796d0f61a05b 1398 SSL_DEBUG_RET( 1, "cipher_finish", ret );
HannesTschofenig 0:796d0f61a05b 1399 return( ret );
HannesTschofenig 0:796d0f61a05b 1400 }
HannesTschofenig 0:796d0f61a05b 1401
HannesTschofenig 0:796d0f61a05b 1402 if( 0 != olen )
HannesTschofenig 0:796d0f61a05b 1403 {
HannesTschofenig 0:796d0f61a05b 1404 SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) );
HannesTschofenig 0:796d0f61a05b 1405 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
HannesTschofenig 0:796d0f61a05b 1406 }
HannesTschofenig 0:796d0f61a05b 1407 }
HannesTschofenig 0:796d0f61a05b 1408 else
HannesTschofenig 0:796d0f61a05b 1409 #endif /* POLARSSL_ARC4_C || POLARSSL_CIPHER_NULL_CIPHER */
HannesTschofenig 0:796d0f61a05b 1410 #if defined(POLARSSL_GCM_C)
HannesTschofenig 0:796d0f61a05b 1411 if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode ==
HannesTschofenig 0:796d0f61a05b 1412 POLARSSL_MODE_GCM )
HannesTschofenig 0:796d0f61a05b 1413 {
HannesTschofenig 0:796d0f61a05b 1414 unsigned char *dec_msg;
HannesTschofenig 0:796d0f61a05b 1415 unsigned char *dec_msg_result;
HannesTschofenig 0:796d0f61a05b 1416 size_t dec_msglen, olen, totlen;
HannesTschofenig 0:796d0f61a05b 1417 unsigned char add_data[13];
HannesTschofenig 0:796d0f61a05b 1418 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 1419
HannesTschofenig 0:796d0f61a05b 1420 dec_msglen = ssl->in_msglen - ( ssl->transform_in->ivlen -
HannesTschofenig 0:796d0f61a05b 1421 ssl->transform_in->fixed_ivlen );
HannesTschofenig 0:796d0f61a05b 1422 dec_msglen -= 16;
HannesTschofenig 0:796d0f61a05b 1423 dec_msg = ssl->in_msg;
HannesTschofenig 0:796d0f61a05b 1424 dec_msg_result = ssl->in_msg;
HannesTschofenig 0:796d0f61a05b 1425 ssl->in_msglen = dec_msglen;
HannesTschofenig 0:796d0f61a05b 1426
HannesTschofenig 0:796d0f61a05b 1427 memcpy( add_data, ssl->in_ctr, 8 );
HannesTschofenig 0:796d0f61a05b 1428 add_data[8] = ssl->in_msgtype;
HannesTschofenig 0:796d0f61a05b 1429 add_data[9] = ssl->major_ver;
HannesTschofenig 0:796d0f61a05b 1430 add_data[10] = ssl->minor_ver;
HannesTschofenig 0:796d0f61a05b 1431 add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
HannesTschofenig 0:796d0f61a05b 1432 add_data[12] = ssl->in_msglen & 0xFF;
HannesTschofenig 0:796d0f61a05b 1433
HannesTschofenig 0:796d0f61a05b 1434 SSL_DEBUG_BUF( 4, "additional data used for AEAD",
HannesTschofenig 0:796d0f61a05b 1435 add_data, 13 );
HannesTschofenig 0:796d0f61a05b 1436
HannesTschofenig 0:796d0f61a05b 1437 memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
HannesTschofenig 0:796d0f61a05b 1438 ssl->in_iv,
HannesTschofenig 0:796d0f61a05b 1439 ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
HannesTschofenig 0:796d0f61a05b 1440
HannesTschofenig 0:796d0f61a05b 1441 SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec,
HannesTschofenig 0:796d0f61a05b 1442 ssl->transform_in->ivlen );
HannesTschofenig 0:796d0f61a05b 1443 SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, 16 );
HannesTschofenig 0:796d0f61a05b 1444
HannesTschofenig 0:796d0f61a05b 1445 /*
HannesTschofenig 0:796d0f61a05b 1446 * Decrypt
HannesTschofenig 0:796d0f61a05b 1447 */
HannesTschofenig 0:796d0f61a05b 1448 if( ( ret = cipher_set_iv( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1449 ssl->transform_in->iv_dec,
HannesTschofenig 0:796d0f61a05b 1450 ssl->transform_in->ivlen ) ) != 0 ||
HannesTschofenig 0:796d0f61a05b 1451 ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1452 {
HannesTschofenig 0:796d0f61a05b 1453 return( ret );
HannesTschofenig 0:796d0f61a05b 1454 }
HannesTschofenig 0:796d0f61a05b 1455
HannesTschofenig 0:796d0f61a05b 1456 if( ( ret = cipher_update_ad( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1457 add_data, 13 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1458 {
HannesTschofenig 0:796d0f61a05b 1459 return( ret );
HannesTschofenig 0:796d0f61a05b 1460 }
HannesTschofenig 0:796d0f61a05b 1461
HannesTschofenig 0:796d0f61a05b 1462 if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1463 dec_msg, dec_msglen,
HannesTschofenig 0:796d0f61a05b 1464 dec_msg_result, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1465 {
HannesTschofenig 0:796d0f61a05b 1466 return( ret );
HannesTschofenig 0:796d0f61a05b 1467 }
HannesTschofenig 0:796d0f61a05b 1468 totlen = olen;
HannesTschofenig 0:796d0f61a05b 1469
HannesTschofenig 0:796d0f61a05b 1470 if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1471 dec_msg_result + olen, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1472 {
HannesTschofenig 0:796d0f61a05b 1473 return( ret );
HannesTschofenig 0:796d0f61a05b 1474 }
HannesTschofenig 0:796d0f61a05b 1475 totlen += olen;
HannesTschofenig 0:796d0f61a05b 1476
HannesTschofenig 0:796d0f61a05b 1477 if( totlen != dec_msglen )
HannesTschofenig 0:796d0f61a05b 1478 {
HannesTschofenig 0:796d0f61a05b 1479 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 1480 return( -1 );
HannesTschofenig 0:796d0f61a05b 1481 }
HannesTschofenig 0:796d0f61a05b 1482
HannesTschofenig 0:796d0f61a05b 1483 /*
HannesTschofenig 0:796d0f61a05b 1484 * Authenticate
HannesTschofenig 0:796d0f61a05b 1485 */
HannesTschofenig 0:796d0f61a05b 1486 if( ( ret = cipher_check_tag( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1487 dec_msg + dec_msglen, 16 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1488 {
HannesTschofenig 0:796d0f61a05b 1489 SSL_DEBUG_RET( 1, "cipher_check_tag", ret );
HannesTschofenig 0:796d0f61a05b 1490 return( POLARSSL_ERR_SSL_INVALID_MAC );
HannesTschofenig 0:796d0f61a05b 1491 }
HannesTschofenig 0:796d0f61a05b 1492
HannesTschofenig 0:796d0f61a05b 1493 }
HannesTschofenig 0:796d0f61a05b 1494 else
HannesTschofenig 0:796d0f61a05b 1495 #endif /* POLARSSL_GCM_C */
HannesTschofenig 0:796d0f61a05b 1496 #if defined(POLARSSL_CIPHER_MODE_CBC) && \
HannesTschofenig 0:796d0f61a05b 1497 ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) )
HannesTschofenig 0:796d0f61a05b 1498 if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode ==
HannesTschofenig 0:796d0f61a05b 1499 POLARSSL_MODE_CBC )
HannesTschofenig 0:796d0f61a05b 1500 {
HannesTschofenig 0:796d0f61a05b 1501 /*
HannesTschofenig 0:796d0f61a05b 1502 * Decrypt and check the padding
HannesTschofenig 0:796d0f61a05b 1503 */
HannesTschofenig 0:796d0f61a05b 1504 int ret;
HannesTschofenig 0:796d0f61a05b 1505 unsigned char *dec_msg;
HannesTschofenig 0:796d0f61a05b 1506 unsigned char *dec_msg_result;
HannesTschofenig 0:796d0f61a05b 1507 size_t dec_msglen;
HannesTschofenig 0:796d0f61a05b 1508 size_t minlen = 0;
HannesTschofenig 0:796d0f61a05b 1509 size_t olen = 0;
HannesTschofenig 0:796d0f61a05b 1510
HannesTschofenig 0:796d0f61a05b 1511 /*
HannesTschofenig 0:796d0f61a05b 1512 * Check immediate ciphertext sanity
HannesTschofenig 0:796d0f61a05b 1513 */
HannesTschofenig 0:796d0f61a05b 1514 if( ssl->in_msglen % ssl->transform_in->ivlen != 0 )
HannesTschofenig 0:796d0f61a05b 1515 {
HannesTschofenig 0:796d0f61a05b 1516 SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
HannesTschofenig 0:796d0f61a05b 1517 ssl->in_msglen, ssl->transform_in->ivlen ) );
HannesTschofenig 0:796d0f61a05b 1518 return( POLARSSL_ERR_SSL_INVALID_MAC );
HannesTschofenig 0:796d0f61a05b 1519 }
HannesTschofenig 0:796d0f61a05b 1520
HannesTschofenig 0:796d0f61a05b 1521 #if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 1522 if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
HannesTschofenig 0:796d0f61a05b 1523 minlen += ssl->transform_in->ivlen;
HannesTschofenig 0:796d0f61a05b 1524 #endif
HannesTschofenig 0:796d0f61a05b 1525
HannesTschofenig 0:796d0f61a05b 1526 if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
HannesTschofenig 0:796d0f61a05b 1527 ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
HannesTschofenig 0:796d0f61a05b 1528 {
HannesTschofenig 0:796d0f61a05b 1529 SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) "
HannesTschofenig 0:796d0f61a05b 1530 "+ 1 ) ( + expl IV )", ssl->in_msglen,
HannesTschofenig 0:796d0f61a05b 1531 ssl->transform_in->ivlen,
HannesTschofenig 0:796d0f61a05b 1532 ssl->transform_in->maclen ) );
HannesTschofenig 0:796d0f61a05b 1533 return( POLARSSL_ERR_SSL_INVALID_MAC );
HannesTschofenig 0:796d0f61a05b 1534 }
HannesTschofenig 0:796d0f61a05b 1535
HannesTschofenig 0:796d0f61a05b 1536 dec_msglen = ssl->in_msglen;
HannesTschofenig 0:796d0f61a05b 1537 dec_msg = ssl->in_msg;
HannesTschofenig 0:796d0f61a05b 1538 dec_msg_result = ssl->in_msg;
HannesTschofenig 0:796d0f61a05b 1539
HannesTschofenig 0:796d0f61a05b 1540 #if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 1541 /*
HannesTschofenig 0:796d0f61a05b 1542 * Initialize for prepended IV for block cipher in TLS v1.1 and up
HannesTschofenig 0:796d0f61a05b 1543 */
HannesTschofenig 0:796d0f61a05b 1544 if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
HannesTschofenig 0:796d0f61a05b 1545 {
HannesTschofenig 0:796d0f61a05b 1546 dec_msglen -= ssl->transform_in->ivlen;
HannesTschofenig 0:796d0f61a05b 1547 ssl->in_msglen -= ssl->transform_in->ivlen;
HannesTschofenig 0:796d0f61a05b 1548
HannesTschofenig 0:796d0f61a05b 1549 for( i = 0; i < ssl->transform_in->ivlen; i++ )
HannesTschofenig 0:796d0f61a05b 1550 ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
HannesTschofenig 0:796d0f61a05b 1551 }
HannesTschofenig 0:796d0f61a05b 1552 #endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 1553
HannesTschofenig 0:796d0f61a05b 1554 if( ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1555 {
HannesTschofenig 0:796d0f61a05b 1556 SSL_DEBUG_RET( 1, "cipher_reset", ret );
HannesTschofenig 0:796d0f61a05b 1557 return( ret );
HannesTschofenig 0:796d0f61a05b 1558 }
HannesTschofenig 0:796d0f61a05b 1559
HannesTschofenig 0:796d0f61a05b 1560 if( ( ret = cipher_set_iv( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1561 ssl->transform_in->iv_dec,
HannesTschofenig 0:796d0f61a05b 1562 ssl->transform_in->ivlen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1563 {
HannesTschofenig 0:796d0f61a05b 1564 SSL_DEBUG_RET( 1, "cipher_set_iv", ret );
HannesTschofenig 0:796d0f61a05b 1565 return( ret );
HannesTschofenig 0:796d0f61a05b 1566 }
HannesTschofenig 0:796d0f61a05b 1567
HannesTschofenig 0:796d0f61a05b 1568 if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1569 dec_msg, dec_msglen, dec_msg_result,
HannesTschofenig 0:796d0f61a05b 1570 &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1571 {
HannesTschofenig 0:796d0f61a05b 1572 SSL_DEBUG_RET( 1, "cipher_update", ret );
HannesTschofenig 0:796d0f61a05b 1573 return( ret );
HannesTschofenig 0:796d0f61a05b 1574 }
HannesTschofenig 0:796d0f61a05b 1575
HannesTschofenig 0:796d0f61a05b 1576 dec_msglen -= olen;
HannesTschofenig 0:796d0f61a05b 1577 if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1578 dec_msg_result + olen, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1579 {
HannesTschofenig 0:796d0f61a05b 1580 SSL_DEBUG_RET( 1, "cipher_finish", ret );
HannesTschofenig 0:796d0f61a05b 1581 return( ret );
HannesTschofenig 0:796d0f61a05b 1582 }
HannesTschofenig 0:796d0f61a05b 1583
HannesTschofenig 0:796d0f61a05b 1584 if( dec_msglen != olen )
HannesTschofenig 0:796d0f61a05b 1585 {
HannesTschofenig 0:796d0f61a05b 1586 SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) );
HannesTschofenig 0:796d0f61a05b 1587 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
HannesTschofenig 0:796d0f61a05b 1588 }
HannesTschofenig 0:796d0f61a05b 1589
HannesTschofenig 0:796d0f61a05b 1590 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1)
HannesTschofenig 0:796d0f61a05b 1591 if( ssl->minor_ver < SSL_MINOR_VERSION_2 )
HannesTschofenig 0:796d0f61a05b 1592 {
HannesTschofenig 0:796d0f61a05b 1593 /*
HannesTschofenig 0:796d0f61a05b 1594 * Save IV in SSL3 and TLS1
HannesTschofenig 0:796d0f61a05b 1595 */
HannesTschofenig 0:796d0f61a05b 1596 memcpy( ssl->transform_in->iv_dec,
HannesTschofenig 0:796d0f61a05b 1597 ssl->transform_in->cipher_ctx_dec.iv,
HannesTschofenig 0:796d0f61a05b 1598 ssl->transform_in->ivlen );
HannesTschofenig 0:796d0f61a05b 1599 }
HannesTschofenig 0:796d0f61a05b 1600 #endif
HannesTschofenig 0:796d0f61a05b 1601
HannesTschofenig 0:796d0f61a05b 1602 padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
HannesTschofenig 0:796d0f61a05b 1603
HannesTschofenig 0:796d0f61a05b 1604 if( ssl->in_msglen < ssl->transform_in->maclen + padlen )
HannesTschofenig 0:796d0f61a05b 1605 {
HannesTschofenig 0:796d0f61a05b 1606 #if defined(POLARSSL_SSL_DEBUG_ALL)
HannesTschofenig 0:796d0f61a05b 1607 SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
HannesTschofenig 0:796d0f61a05b 1608 ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
HannesTschofenig 0:796d0f61a05b 1609 #endif
HannesTschofenig 0:796d0f61a05b 1610 padlen = 0;
HannesTschofenig 0:796d0f61a05b 1611 correct = 0;
HannesTschofenig 0:796d0f61a05b 1612 }
HannesTschofenig 0:796d0f61a05b 1613
HannesTschofenig 0:796d0f61a05b 1614 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 1615 if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 1616 {
HannesTschofenig 0:796d0f61a05b 1617 if( padlen > ssl->transform_in->ivlen )
HannesTschofenig 0:796d0f61a05b 1618 {
HannesTschofenig 0:796d0f61a05b 1619 #if defined(POLARSSL_SSL_DEBUG_ALL)
HannesTschofenig 0:796d0f61a05b 1620 SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
HannesTschofenig 0:796d0f61a05b 1621 "should be no more than %d",
HannesTschofenig 0:796d0f61a05b 1622 padlen, ssl->transform_in->ivlen ) );
HannesTschofenig 0:796d0f61a05b 1623 #endif
HannesTschofenig 0:796d0f61a05b 1624 correct = 0;
HannesTschofenig 0:796d0f61a05b 1625 }
HannesTschofenig 0:796d0f61a05b 1626 }
HannesTschofenig 0:796d0f61a05b 1627 else
HannesTschofenig 0:796d0f61a05b 1628 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 1629 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 1630 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 1631 if( ssl->minor_ver > SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 1632 {
HannesTschofenig 0:796d0f61a05b 1633 /*
HannesTschofenig 0:796d0f61a05b 1634 * TLSv1+: always check the padding up to the first failure
HannesTschofenig 0:796d0f61a05b 1635 * and fake check up to 256 bytes of padding
HannesTschofenig 0:796d0f61a05b 1636 */
HannesTschofenig 0:796d0f61a05b 1637 size_t pad_count = 0, real_count = 1;
HannesTschofenig 0:796d0f61a05b 1638 size_t padding_idx = ssl->in_msglen - padlen - 1;
HannesTschofenig 0:796d0f61a05b 1639
HannesTschofenig 0:796d0f61a05b 1640 /*
HannesTschofenig 0:796d0f61a05b 1641 * Padding is guaranteed to be incorrect if:
HannesTschofenig 0:796d0f61a05b 1642 * 1. padlen >= ssl->in_msglen
HannesTschofenig 0:796d0f61a05b 1643 *
HannesTschofenig 0:796d0f61a05b 1644 * 2. padding_idx >= SSL_MAX_CONTENT_LEN +
HannesTschofenig 0:796d0f61a05b 1645 * ssl->transform_in->maclen
HannesTschofenig 0:796d0f61a05b 1646 *
HannesTschofenig 0:796d0f61a05b 1647 * In both cases we reset padding_idx to a safe value (0) to
HannesTschofenig 0:796d0f61a05b 1648 * prevent out-of-buffer reads.
HannesTschofenig 0:796d0f61a05b 1649 */
HannesTschofenig 0:796d0f61a05b 1650 correct &= ( ssl->in_msglen >= padlen + 1 );
HannesTschofenig 0:796d0f61a05b 1651 correct &= ( padding_idx < SSL_MAX_CONTENT_LEN +
HannesTschofenig 0:796d0f61a05b 1652 ssl->transform_in->maclen );
HannesTschofenig 0:796d0f61a05b 1653
HannesTschofenig 0:796d0f61a05b 1654 padding_idx *= correct;
HannesTschofenig 0:796d0f61a05b 1655
HannesTschofenig 0:796d0f61a05b 1656 for( i = 1; i <= 256; i++ )
HannesTschofenig 0:796d0f61a05b 1657 {
HannesTschofenig 0:796d0f61a05b 1658 real_count &= ( i <= padlen );
HannesTschofenig 0:796d0f61a05b 1659 pad_count += real_count *
HannesTschofenig 0:796d0f61a05b 1660 ( ssl->in_msg[padding_idx + i] == padlen - 1 );
HannesTschofenig 0:796d0f61a05b 1661 }
HannesTschofenig 0:796d0f61a05b 1662
HannesTschofenig 0:796d0f61a05b 1663 correct &= ( pad_count == padlen ); /* Only 1 on correct padding */
HannesTschofenig 0:796d0f61a05b 1664
HannesTschofenig 0:796d0f61a05b 1665 #if defined(POLARSSL_SSL_DEBUG_ALL)
HannesTschofenig 0:796d0f61a05b 1666 if( padlen > 0 && correct == 0)
HannesTschofenig 0:796d0f61a05b 1667 SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
HannesTschofenig 0:796d0f61a05b 1668 #endif
HannesTschofenig 0:796d0f61a05b 1669 padlen &= correct * 0x1FF;
HannesTschofenig 0:796d0f61a05b 1670 }
HannesTschofenig 0:796d0f61a05b 1671 else
HannesTschofenig 0:796d0f61a05b 1672 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
HannesTschofenig 0:796d0f61a05b 1673 POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 1674 {
HannesTschofenig 0:796d0f61a05b 1675 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 1676 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 1677 }
HannesTschofenig 0:796d0f61a05b 1678 }
HannesTschofenig 0:796d0f61a05b 1679 else
HannesTschofenig 0:796d0f61a05b 1680 #endif /* POLARSSL_CIPHER_MODE_CBC &&
HannesTschofenig 0:796d0f61a05b 1681 ( POLARSSL_AES_C || POLARSSL_CAMELLIA_C ) */
HannesTschofenig 0:796d0f61a05b 1682 {
HannesTschofenig 0:796d0f61a05b 1683 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 1684 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 1685 }
HannesTschofenig 0:796d0f61a05b 1686
HannesTschofenig 0:796d0f61a05b 1687 SSL_DEBUG_BUF( 4, "raw buffer after decryption",
HannesTschofenig 0:796d0f61a05b 1688 ssl->in_msg, ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 1689
HannesTschofenig 0:796d0f61a05b 1690 /*
HannesTschofenig 0:796d0f61a05b 1691 * Always compute the MAC (RFC4346, CBCTIME), except for GCM of course
HannesTschofenig 0:796d0f61a05b 1692 */
HannesTschofenig 0:796d0f61a05b 1693 #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \
HannesTschofenig 0:796d0f61a05b 1694 ( defined(POLARSSL_CIPHER_MODE_CBC) && \
HannesTschofenig 0:796d0f61a05b 1695 ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) )
HannesTschofenig 0:796d0f61a05b 1696 if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode !=
HannesTschofenig 0:796d0f61a05b 1697 POLARSSL_MODE_GCM )
HannesTschofenig 0:796d0f61a05b 1698 {
HannesTschofenig 0:796d0f61a05b 1699 unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE];
HannesTschofenig 0:796d0f61a05b 1700
HannesTschofenig 0:796d0f61a05b 1701 ssl->in_msglen -= ( ssl->transform_in->maclen + padlen );
HannesTschofenig 0:796d0f61a05b 1702
HannesTschofenig 0:796d0f61a05b 1703 ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 );
HannesTschofenig 0:796d0f61a05b 1704 ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 1705
HannesTschofenig 0:796d0f61a05b 1706 memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen );
HannesTschofenig 0:796d0f61a05b 1707
HannesTschofenig 0:796d0f61a05b 1708 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 1709 if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 1710 {
HannesTschofenig 0:796d0f61a05b 1711 ssl_mac( &ssl->transform_in->md_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1712 ssl->transform_in->mac_dec,
HannesTschofenig 0:796d0f61a05b 1713 ssl->in_msg, ssl->in_msglen,
HannesTschofenig 0:796d0f61a05b 1714 ssl->in_ctr, ssl->in_msgtype );
HannesTschofenig 0:796d0f61a05b 1715 }
HannesTschofenig 0:796d0f61a05b 1716 else
HannesTschofenig 0:796d0f61a05b 1717 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 1718 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 1719 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 1720 if( ssl->minor_ver > SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 1721 {
HannesTschofenig 0:796d0f61a05b 1722 /*
HannesTschofenig 0:796d0f61a05b 1723 * Process MAC and always update for padlen afterwards to make
HannesTschofenig 0:796d0f61a05b 1724 * total time independent of padlen
HannesTschofenig 0:796d0f61a05b 1725 *
HannesTschofenig 0:796d0f61a05b 1726 * extra_run compensates MAC check for padlen
HannesTschofenig 0:796d0f61a05b 1727 *
HannesTschofenig 0:796d0f61a05b 1728 * Known timing attacks:
HannesTschofenig 0:796d0f61a05b 1729 * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
HannesTschofenig 0:796d0f61a05b 1730 *
HannesTschofenig 0:796d0f61a05b 1731 * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values
HannesTschofenig 0:796d0f61a05b 1732 * correctly. (We round down instead of up, so -56 is the correct
HannesTschofenig 0:796d0f61a05b 1733 * value for our calculations instead of -55)
HannesTschofenig 0:796d0f61a05b 1734 */
HannesTschofenig 0:796d0f61a05b 1735 size_t j, extra_run = 0;
HannesTschofenig 0:796d0f61a05b 1736 extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
HannesTschofenig 0:796d0f61a05b 1737 ( 13 + ssl->in_msglen + 8 ) / 64;
HannesTschofenig 0:796d0f61a05b 1738
HannesTschofenig 0:796d0f61a05b 1739 extra_run &= correct * 0xFF;
HannesTschofenig 0:796d0f61a05b 1740
HannesTschofenig 0:796d0f61a05b 1741 md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 13 );
HannesTschofenig 0:796d0f61a05b 1742 md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
HannesTschofenig 0:796d0f61a05b 1743 ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 1744 md_hmac_finish( &ssl->transform_in->md_ctx_dec,
HannesTschofenig 0:796d0f61a05b 1745 ssl->in_msg + ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 1746 for( j = 0; j < extra_run; j++ )
HannesTschofenig 0:796d0f61a05b 1747 md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
HannesTschofenig 0:796d0f61a05b 1748
HannesTschofenig 0:796d0f61a05b 1749 md_hmac_reset( &ssl->transform_in->md_ctx_dec );
HannesTschofenig 0:796d0f61a05b 1750 }
HannesTschofenig 0:796d0f61a05b 1751 else
HannesTschofenig 0:796d0f61a05b 1752 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
HannesTschofenig 0:796d0f61a05b 1753 POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 1754 {
HannesTschofenig 0:796d0f61a05b 1755 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 1756 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 1757 }
HannesTschofenig 0:796d0f61a05b 1758
HannesTschofenig 0:796d0f61a05b 1759 SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen );
HannesTschofenig 0:796d0f61a05b 1760 SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen,
HannesTschofenig 0:796d0f61a05b 1761 ssl->transform_in->maclen );
HannesTschofenig 0:796d0f61a05b 1762
HannesTschofenig 0:796d0f61a05b 1763 if( safer_memcmp( tmp, ssl->in_msg + ssl->in_msglen,
HannesTschofenig 0:796d0f61a05b 1764 ssl->transform_in->maclen ) != 0 )
HannesTschofenig 0:796d0f61a05b 1765 {
HannesTschofenig 0:796d0f61a05b 1766 #if defined(POLARSSL_SSL_DEBUG_ALL)
HannesTschofenig 0:796d0f61a05b 1767 SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
HannesTschofenig 0:796d0f61a05b 1768 #endif
HannesTschofenig 0:796d0f61a05b 1769 correct = 0;
HannesTschofenig 0:796d0f61a05b 1770 }
HannesTschofenig 0:796d0f61a05b 1771
HannesTschofenig 0:796d0f61a05b 1772 /*
HannesTschofenig 0:796d0f61a05b 1773 * Finally check the correct flag
HannesTschofenig 0:796d0f61a05b 1774 */
HannesTschofenig 0:796d0f61a05b 1775 if( correct == 0 )
HannesTschofenig 0:796d0f61a05b 1776 return( POLARSSL_ERR_SSL_INVALID_MAC );
HannesTschofenig 0:796d0f61a05b 1777 }
HannesTschofenig 0:796d0f61a05b 1778 #endif /* GCM not the only option */
HannesTschofenig 0:796d0f61a05b 1779
HannesTschofenig 0:796d0f61a05b 1780 if( ssl->in_msglen == 0 )
HannesTschofenig 0:796d0f61a05b 1781 {
HannesTschofenig 0:796d0f61a05b 1782 ssl->nb_zero++;
HannesTschofenig 0:796d0f61a05b 1783
HannesTschofenig 0:796d0f61a05b 1784 /*
HannesTschofenig 0:796d0f61a05b 1785 * Three or more empty messages may be a DoS attack
HannesTschofenig 0:796d0f61a05b 1786 * (excessive CPU consumption).
HannesTschofenig 0:796d0f61a05b 1787 */
HannesTschofenig 0:796d0f61a05b 1788 if( ssl->nb_zero > 3 )
HannesTschofenig 0:796d0f61a05b 1789 {
HannesTschofenig 0:796d0f61a05b 1790 SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
HannesTschofenig 0:796d0f61a05b 1791 "messages, possible DoS attack" ) );
HannesTschofenig 0:796d0f61a05b 1792 return( POLARSSL_ERR_SSL_INVALID_MAC );
HannesTschofenig 0:796d0f61a05b 1793 }
HannesTschofenig 0:796d0f61a05b 1794 }
HannesTschofenig 0:796d0f61a05b 1795 else
HannesTschofenig 0:796d0f61a05b 1796 ssl->nb_zero = 0;
HannesTschofenig 0:796d0f61a05b 1797
HannesTschofenig 0:796d0f61a05b 1798 for( i = 8; i > 0; i-- )
HannesTschofenig 0:796d0f61a05b 1799 if( ++ssl->in_ctr[i - 1] != 0 )
HannesTschofenig 0:796d0f61a05b 1800 break;
HannesTschofenig 0:796d0f61a05b 1801
HannesTschofenig 0:796d0f61a05b 1802 /* The loops goes to its end iff the counter is wrapping */
HannesTschofenig 0:796d0f61a05b 1803 if( i == 0 )
HannesTschofenig 0:796d0f61a05b 1804 {
HannesTschofenig 0:796d0f61a05b 1805 SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
HannesTschofenig 0:796d0f61a05b 1806 return( POLARSSL_ERR_SSL_COUNTER_WRAPPING );
HannesTschofenig 0:796d0f61a05b 1807 }
HannesTschofenig 0:796d0f61a05b 1808
HannesTschofenig 0:796d0f61a05b 1809 SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
HannesTschofenig 0:796d0f61a05b 1810
HannesTschofenig 0:796d0f61a05b 1811 return( 0 );
HannesTschofenig 0:796d0f61a05b 1812 }
HannesTschofenig 0:796d0f61a05b 1813
HannesTschofenig 0:796d0f61a05b 1814 #if defined(POLARSSL_ZLIB_SUPPORT)
HannesTschofenig 0:796d0f61a05b 1815 /*
HannesTschofenig 0:796d0f61a05b 1816 * Compression/decompression functions
HannesTschofenig 0:796d0f61a05b 1817 */
HannesTschofenig 0:796d0f61a05b 1818 static int ssl_compress_buf( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1819 {
HannesTschofenig 0:796d0f61a05b 1820 int ret;
HannesTschofenig 0:796d0f61a05b 1821 unsigned char *msg_post = ssl->out_msg;
HannesTschofenig 0:796d0f61a05b 1822 size_t len_pre = ssl->out_msglen;
HannesTschofenig 0:796d0f61a05b 1823 unsigned char *msg_pre = ssl->compress_buf;
HannesTschofenig 0:796d0f61a05b 1824
HannesTschofenig 0:796d0f61a05b 1825 SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
HannesTschofenig 0:796d0f61a05b 1826
HannesTschofenig 0:796d0f61a05b 1827 if( len_pre == 0 )
HannesTschofenig 0:796d0f61a05b 1828 return( 0 );
HannesTschofenig 0:796d0f61a05b 1829
HannesTschofenig 0:796d0f61a05b 1830 memcpy( msg_pre, ssl->out_msg, len_pre );
HannesTschofenig 0:796d0f61a05b 1831
HannesTschofenig 0:796d0f61a05b 1832 SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ",
HannesTschofenig 0:796d0f61a05b 1833 ssl->out_msglen ) );
HannesTschofenig 0:796d0f61a05b 1834
HannesTschofenig 0:796d0f61a05b 1835 SSL_DEBUG_BUF( 4, "before compression: output payload",
HannesTschofenig 0:796d0f61a05b 1836 ssl->out_msg, ssl->out_msglen );
HannesTschofenig 0:796d0f61a05b 1837
HannesTschofenig 0:796d0f61a05b 1838 ssl->transform_out->ctx_deflate.next_in = msg_pre;
HannesTschofenig 0:796d0f61a05b 1839 ssl->transform_out->ctx_deflate.avail_in = len_pre;
HannesTschofenig 0:796d0f61a05b 1840 ssl->transform_out->ctx_deflate.next_out = msg_post;
HannesTschofenig 0:796d0f61a05b 1841 ssl->transform_out->ctx_deflate.avail_out = SSL_BUFFER_LEN;
HannesTschofenig 0:796d0f61a05b 1842
HannesTschofenig 0:796d0f61a05b 1843 ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
HannesTschofenig 0:796d0f61a05b 1844 if( ret != Z_OK )
HannesTschofenig 0:796d0f61a05b 1845 {
HannesTschofenig 0:796d0f61a05b 1846 SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
HannesTschofenig 0:796d0f61a05b 1847 return( POLARSSL_ERR_SSL_COMPRESSION_FAILED );
HannesTschofenig 0:796d0f61a05b 1848 }
HannesTschofenig 0:796d0f61a05b 1849
HannesTschofenig 0:796d0f61a05b 1850 ssl->out_msglen = SSL_BUFFER_LEN -
HannesTschofenig 0:796d0f61a05b 1851 ssl->transform_out->ctx_deflate.avail_out;
HannesTschofenig 0:796d0f61a05b 1852
HannesTschofenig 0:796d0f61a05b 1853 SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
HannesTschofenig 0:796d0f61a05b 1854 ssl->out_msglen ) );
HannesTschofenig 0:796d0f61a05b 1855
HannesTschofenig 0:796d0f61a05b 1856 SSL_DEBUG_BUF( 4, "after compression: output payload",
HannesTschofenig 0:796d0f61a05b 1857 ssl->out_msg, ssl->out_msglen );
HannesTschofenig 0:796d0f61a05b 1858
HannesTschofenig 0:796d0f61a05b 1859 SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
HannesTschofenig 0:796d0f61a05b 1860
HannesTschofenig 0:796d0f61a05b 1861 return( 0 );
HannesTschofenig 0:796d0f61a05b 1862 }
HannesTschofenig 0:796d0f61a05b 1863
HannesTschofenig 0:796d0f61a05b 1864 static int ssl_decompress_buf( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1865 {
HannesTschofenig 0:796d0f61a05b 1866 int ret;
HannesTschofenig 0:796d0f61a05b 1867 unsigned char *msg_post = ssl->in_msg;
HannesTschofenig 0:796d0f61a05b 1868 size_t len_pre = ssl->in_msglen;
HannesTschofenig 0:796d0f61a05b 1869 unsigned char *msg_pre = ssl->compress_buf;
HannesTschofenig 0:796d0f61a05b 1870
HannesTschofenig 0:796d0f61a05b 1871 SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
HannesTschofenig 0:796d0f61a05b 1872
HannesTschofenig 0:796d0f61a05b 1873 if( len_pre == 0 )
HannesTschofenig 0:796d0f61a05b 1874 return( 0 );
HannesTschofenig 0:796d0f61a05b 1875
HannesTschofenig 0:796d0f61a05b 1876 memcpy( msg_pre, ssl->in_msg, len_pre );
HannesTschofenig 0:796d0f61a05b 1877
HannesTschofenig 0:796d0f61a05b 1878 SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ",
HannesTschofenig 0:796d0f61a05b 1879 ssl->in_msglen ) );
HannesTschofenig 0:796d0f61a05b 1880
HannesTschofenig 0:796d0f61a05b 1881 SSL_DEBUG_BUF( 4, "before decompression: input payload",
HannesTschofenig 0:796d0f61a05b 1882 ssl->in_msg, ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 1883
HannesTschofenig 0:796d0f61a05b 1884 ssl->transform_in->ctx_inflate.next_in = msg_pre;
HannesTschofenig 0:796d0f61a05b 1885 ssl->transform_in->ctx_inflate.avail_in = len_pre;
HannesTschofenig 0:796d0f61a05b 1886 ssl->transform_in->ctx_inflate.next_out = msg_post;
HannesTschofenig 0:796d0f61a05b 1887 ssl->transform_in->ctx_inflate.avail_out = SSL_MAX_CONTENT_LEN;
HannesTschofenig 0:796d0f61a05b 1888
HannesTschofenig 0:796d0f61a05b 1889 ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
HannesTschofenig 0:796d0f61a05b 1890 if( ret != Z_OK )
HannesTschofenig 0:796d0f61a05b 1891 {
HannesTschofenig 0:796d0f61a05b 1892 SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
HannesTschofenig 0:796d0f61a05b 1893 return( POLARSSL_ERR_SSL_COMPRESSION_FAILED );
HannesTschofenig 0:796d0f61a05b 1894 }
HannesTschofenig 0:796d0f61a05b 1895
HannesTschofenig 0:796d0f61a05b 1896 ssl->in_msglen = SSL_MAX_CONTENT_LEN -
HannesTschofenig 0:796d0f61a05b 1897 ssl->transform_in->ctx_inflate.avail_out;
HannesTschofenig 0:796d0f61a05b 1898
HannesTschofenig 0:796d0f61a05b 1899 SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
HannesTschofenig 0:796d0f61a05b 1900 ssl->in_msglen ) );
HannesTschofenig 0:796d0f61a05b 1901
HannesTschofenig 0:796d0f61a05b 1902 SSL_DEBUG_BUF( 4, "after decompression: input payload",
HannesTschofenig 0:796d0f61a05b 1903 ssl->in_msg, ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 1904
HannesTschofenig 0:796d0f61a05b 1905 SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
HannesTschofenig 0:796d0f61a05b 1906
HannesTschofenig 0:796d0f61a05b 1907 return( 0 );
HannesTschofenig 0:796d0f61a05b 1908 }
HannesTschofenig 0:796d0f61a05b 1909 #endif /* POLARSSL_ZLIB_SUPPORT */
HannesTschofenig 0:796d0f61a05b 1910
HannesTschofenig 0:796d0f61a05b 1911 /*
HannesTschofenig 0:796d0f61a05b 1912 * Fill the input message buffer
HannesTschofenig 0:796d0f61a05b 1913 */
HannesTschofenig 0:796d0f61a05b 1914 int ssl_fetch_input( ssl_context *ssl, size_t nb_want )
HannesTschofenig 0:796d0f61a05b 1915 {
HannesTschofenig 0:796d0f61a05b 1916 int ret;
HannesTschofenig 0:796d0f61a05b 1917 size_t len;
HannesTschofenig 0:796d0f61a05b 1918
HannesTschofenig 0:796d0f61a05b 1919 SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
HannesTschofenig 0:796d0f61a05b 1920
HannesTschofenig 0:796d0f61a05b 1921 if( nb_want > SSL_BUFFER_LEN - 8 )
HannesTschofenig 0:796d0f61a05b 1922 {
HannesTschofenig 0:796d0f61a05b 1923 SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
HannesTschofenig 0:796d0f61a05b 1924 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 1925 }
HannesTschofenig 0:796d0f61a05b 1926
HannesTschofenig 0:796d0f61a05b 1927 while( ssl->in_left < nb_want )
HannesTschofenig 0:796d0f61a05b 1928 {
HannesTschofenig 0:796d0f61a05b 1929 len = nb_want - ssl->in_left;
HannesTschofenig 0:796d0f61a05b 1930 ret = ssl->f_recv( ssl->p_recv, ssl->in_hdr + ssl->in_left, len );
HannesTschofenig 0:796d0f61a05b 1931
HannesTschofenig 0:796d0f61a05b 1932 SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
HannesTschofenig 0:796d0f61a05b 1933 ssl->in_left, nb_want ) );
HannesTschofenig 0:796d0f61a05b 1934 SSL_DEBUG_RET( 2, "ssl->f_recv", ret );
HannesTschofenig 0:796d0f61a05b 1935
HannesTschofenig 0:796d0f61a05b 1936 if( ret == 0 )
HannesTschofenig 0:796d0f61a05b 1937 return( POLARSSL_ERR_SSL_CONN_EOF );
HannesTschofenig 0:796d0f61a05b 1938
HannesTschofenig 0:796d0f61a05b 1939 if( ret < 0 )
HannesTschofenig 0:796d0f61a05b 1940 return( ret );
HannesTschofenig 0:796d0f61a05b 1941
HannesTschofenig 0:796d0f61a05b 1942 ssl->in_left += ret;
HannesTschofenig 0:796d0f61a05b 1943 }
HannesTschofenig 0:796d0f61a05b 1944
HannesTschofenig 0:796d0f61a05b 1945 SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
HannesTschofenig 0:796d0f61a05b 1946
HannesTschofenig 0:796d0f61a05b 1947 return( 0 );
HannesTschofenig 0:796d0f61a05b 1948 }
HannesTschofenig 0:796d0f61a05b 1949
HannesTschofenig 0:796d0f61a05b 1950 /*
HannesTschofenig 0:796d0f61a05b 1951 * Flush any data not yet written
HannesTschofenig 0:796d0f61a05b 1952 */
HannesTschofenig 0:796d0f61a05b 1953 int ssl_flush_output( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1954 {
HannesTschofenig 0:796d0f61a05b 1955 int ret;
HannesTschofenig 0:796d0f61a05b 1956 unsigned char *buf;
HannesTschofenig 0:796d0f61a05b 1957
HannesTschofenig 0:796d0f61a05b 1958 SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
HannesTschofenig 0:796d0f61a05b 1959
HannesTschofenig 0:796d0f61a05b 1960 while( ssl->out_left > 0 )
HannesTschofenig 0:796d0f61a05b 1961 {
HannesTschofenig 0:796d0f61a05b 1962 SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
HannesTschofenig 0:796d0f61a05b 1963 5 + ssl->out_msglen, ssl->out_left ) );
HannesTschofenig 0:796d0f61a05b 1964
HannesTschofenig 0:796d0f61a05b 1965 buf = ssl->out_hdr + 5 + ssl->out_msglen - ssl->out_left;
HannesTschofenig 0:796d0f61a05b 1966 ret = ssl->f_send( ssl->p_send, buf, ssl->out_left );
HannesTschofenig 0:796d0f61a05b 1967
HannesTschofenig 0:796d0f61a05b 1968 SSL_DEBUG_RET( 2, "ssl->f_send", ret );
HannesTschofenig 0:796d0f61a05b 1969
HannesTschofenig 0:796d0f61a05b 1970 if( ret <= 0 )
HannesTschofenig 0:796d0f61a05b 1971 return( ret );
HannesTschofenig 0:796d0f61a05b 1972
HannesTschofenig 0:796d0f61a05b 1973 ssl->out_left -= ret;
HannesTschofenig 0:796d0f61a05b 1974 }
HannesTschofenig 0:796d0f61a05b 1975
HannesTschofenig 0:796d0f61a05b 1976 SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
HannesTschofenig 0:796d0f61a05b 1977
HannesTschofenig 0:796d0f61a05b 1978 return( 0 );
HannesTschofenig 0:796d0f61a05b 1979 }
HannesTschofenig 0:796d0f61a05b 1980
HannesTschofenig 0:796d0f61a05b 1981 /*
HannesTschofenig 0:796d0f61a05b 1982 * Record layer functions
HannesTschofenig 0:796d0f61a05b 1983 */
HannesTschofenig 0:796d0f61a05b 1984 int ssl_write_record( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1985 {
HannesTschofenig 0:796d0f61a05b 1986 int ret, done = 0;
HannesTschofenig 0:796d0f61a05b 1987 size_t len = ssl->out_msglen;
HannesTschofenig 0:796d0f61a05b 1988
HannesTschofenig 0:796d0f61a05b 1989 SSL_DEBUG_MSG( 2, ( "=> write record" ) );
HannesTschofenig 0:796d0f61a05b 1990
HannesTschofenig 0:796d0f61a05b 1991 if( ssl->out_msgtype == SSL_MSG_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 1992 {
HannesTschofenig 0:796d0f61a05b 1993 ssl->out_msg[1] = (unsigned char)( ( len - 4 ) >> 16 );
HannesTschofenig 0:796d0f61a05b 1994 ssl->out_msg[2] = (unsigned char)( ( len - 4 ) >> 8 );
HannesTschofenig 0:796d0f61a05b 1995 ssl->out_msg[3] = (unsigned char)( ( len - 4 ) );
HannesTschofenig 0:796d0f61a05b 1996
HannesTschofenig 0:796d0f61a05b 1997 if( ssl->out_msg[0] != SSL_HS_HELLO_REQUEST )
HannesTschofenig 0:796d0f61a05b 1998 ssl->handshake->update_checksum( ssl, ssl->out_msg, len );
HannesTschofenig 0:796d0f61a05b 1999 }
HannesTschofenig 0:796d0f61a05b 2000
HannesTschofenig 0:796d0f61a05b 2001 #if defined(POLARSSL_ZLIB_SUPPORT)
HannesTschofenig 0:796d0f61a05b 2002 if( ssl->transform_out != NULL &&
HannesTschofenig 0:796d0f61a05b 2003 ssl->session_out->compression == SSL_COMPRESS_DEFLATE )
HannesTschofenig 0:796d0f61a05b 2004 {
HannesTschofenig 0:796d0f61a05b 2005 if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2006 {
HannesTschofenig 0:796d0f61a05b 2007 SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
HannesTschofenig 0:796d0f61a05b 2008 return( ret );
HannesTschofenig 0:796d0f61a05b 2009 }
HannesTschofenig 0:796d0f61a05b 2010
HannesTschofenig 0:796d0f61a05b 2011 len = ssl->out_msglen;
HannesTschofenig 0:796d0f61a05b 2012 }
HannesTschofenig 0:796d0f61a05b 2013 #endif /*POLARSSL_ZLIB_SUPPORT */
HannesTschofenig 0:796d0f61a05b 2014
HannesTschofenig 0:796d0f61a05b 2015 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
HannesTschofenig 0:796d0f61a05b 2016 if( ssl_hw_record_write != NULL)
HannesTschofenig 0:796d0f61a05b 2017 {
HannesTschofenig 0:796d0f61a05b 2018 SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_write()" ) );
HannesTschofenig 0:796d0f61a05b 2019
HannesTschofenig 0:796d0f61a05b 2020 ret = ssl_hw_record_write( ssl );
HannesTschofenig 0:796d0f61a05b 2021 if( ret != 0 && ret != POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH )
HannesTschofenig 0:796d0f61a05b 2022 {
HannesTschofenig 0:796d0f61a05b 2023 SSL_DEBUG_RET( 1, "ssl_hw_record_write", ret );
HannesTschofenig 0:796d0f61a05b 2024 return POLARSSL_ERR_SSL_HW_ACCEL_FAILED;
HannesTschofenig 0:796d0f61a05b 2025 }
HannesTschofenig 0:796d0f61a05b 2026
HannesTschofenig 0:796d0f61a05b 2027 if( ret == 0 )
HannesTschofenig 0:796d0f61a05b 2028 done = 1;
HannesTschofenig 0:796d0f61a05b 2029 }
HannesTschofenig 0:796d0f61a05b 2030 #endif /* POLARSSL_SSL_HW_RECORD_ACCEL */
HannesTschofenig 0:796d0f61a05b 2031 if( !done )
HannesTschofenig 0:796d0f61a05b 2032 {
HannesTschofenig 0:796d0f61a05b 2033 ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
HannesTschofenig 0:796d0f61a05b 2034 ssl->out_hdr[1] = (unsigned char) ssl->major_ver;
HannesTschofenig 0:796d0f61a05b 2035 ssl->out_hdr[2] = (unsigned char) ssl->minor_ver;
HannesTschofenig 0:796d0f61a05b 2036 ssl->out_hdr[3] = (unsigned char)( len >> 8 );
HannesTschofenig 0:796d0f61a05b 2037 ssl->out_hdr[4] = (unsigned char)( len );
HannesTschofenig 0:796d0f61a05b 2038
HannesTschofenig 0:796d0f61a05b 2039 if( ssl->transform_out != NULL )
HannesTschofenig 0:796d0f61a05b 2040 {
HannesTschofenig 0:796d0f61a05b 2041 if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2042 {
HannesTschofenig 0:796d0f61a05b 2043 SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
HannesTschofenig 0:796d0f61a05b 2044 return( ret );
HannesTschofenig 0:796d0f61a05b 2045 }
HannesTschofenig 0:796d0f61a05b 2046
HannesTschofenig 0:796d0f61a05b 2047 len = ssl->out_msglen;
HannesTschofenig 0:796d0f61a05b 2048 ssl->out_hdr[3] = (unsigned char)( len >> 8 );
HannesTschofenig 0:796d0f61a05b 2049 ssl->out_hdr[4] = (unsigned char)( len );
HannesTschofenig 0:796d0f61a05b 2050 }
HannesTschofenig 0:796d0f61a05b 2051
HannesTschofenig 0:796d0f61a05b 2052 ssl->out_left = 5 + ssl->out_msglen;
HannesTschofenig 0:796d0f61a05b 2053
HannesTschofenig 0:796d0f61a05b 2054 SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
HannesTschofenig 0:796d0f61a05b 2055 "version = [%d:%d], msglen = %d",
HannesTschofenig 0:796d0f61a05b 2056 ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2],
HannesTschofenig 0:796d0f61a05b 2057 ( ssl->out_hdr[3] << 8 ) | ssl->out_hdr[4] ) );
HannesTschofenig 0:796d0f61a05b 2058
HannesTschofenig 0:796d0f61a05b 2059 SSL_DEBUG_BUF( 4, "output record sent to network",
HannesTschofenig 0:796d0f61a05b 2060 ssl->out_hdr, 5 + ssl->out_msglen );
HannesTschofenig 0:796d0f61a05b 2061 }
HannesTschofenig 0:796d0f61a05b 2062
HannesTschofenig 0:796d0f61a05b 2063 if( ( ret = ssl_flush_output( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2064 {
HannesTschofenig 0:796d0f61a05b 2065 SSL_DEBUG_RET( 1, "ssl_flush_output", ret );
HannesTschofenig 0:796d0f61a05b 2066 return( ret );
HannesTschofenig 0:796d0f61a05b 2067 }
HannesTschofenig 0:796d0f61a05b 2068
HannesTschofenig 0:796d0f61a05b 2069 SSL_DEBUG_MSG( 2, ( "<= write record" ) );
HannesTschofenig 0:796d0f61a05b 2070
HannesTschofenig 0:796d0f61a05b 2071 return( 0 );
HannesTschofenig 0:796d0f61a05b 2072 }
HannesTschofenig 0:796d0f61a05b 2073
HannesTschofenig 0:796d0f61a05b 2074 int ssl_read_record( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2075 {
HannesTschofenig 0:796d0f61a05b 2076 int ret, done = 0;
HannesTschofenig 0:796d0f61a05b 2077
HannesTschofenig 0:796d0f61a05b 2078 SSL_DEBUG_MSG( 2, ( "=> read record" ) );
HannesTschofenig 0:796d0f61a05b 2079
HannesTschofenig 0:796d0f61a05b 2080 SSL_DEBUG_BUF( 4, "input record from network",
HannesTschofenig 0:796d0f61a05b 2081 ssl->in_hdr, 5 + ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 2082
HannesTschofenig 0:796d0f61a05b 2083 if( ssl->in_hslen != 0 &&
HannesTschofenig 0:796d0f61a05b 2084 ssl->in_hslen < ssl->in_msglen )
HannesTschofenig 0:796d0f61a05b 2085 {
HannesTschofenig 0:796d0f61a05b 2086 /*
HannesTschofenig 0:796d0f61a05b 2087 * Get next Handshake message in the current record
HannesTschofenig 0:796d0f61a05b 2088 */
HannesTschofenig 0:796d0f61a05b 2089 ssl->in_msglen -= ssl->in_hslen;
HannesTschofenig 0:796d0f61a05b 2090
HannesTschofenig 0:796d0f61a05b 2091 memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
HannesTschofenig 0:796d0f61a05b 2092 ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 2093
HannesTschofenig 0:796d0f61a05b 2094 ssl->in_hslen = 4;
HannesTschofenig 0:796d0f61a05b 2095 ssl->in_hslen += ( ssl->in_msg[2] << 8 ) | ssl->in_msg[3];
HannesTschofenig 0:796d0f61a05b 2096
HannesTschofenig 0:796d0f61a05b 2097 SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
HannesTschofenig 0:796d0f61a05b 2098 " %d, type = %d, hslen = %d",
HannesTschofenig 0:796d0f61a05b 2099 ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
HannesTschofenig 0:796d0f61a05b 2100
HannesTschofenig 0:796d0f61a05b 2101 if( ssl->in_msglen < 4 || ssl->in_msg[1] != 0 )
HannesTschofenig 0:796d0f61a05b 2102 {
HannesTschofenig 0:796d0f61a05b 2103 SSL_DEBUG_MSG( 1, ( "bad handshake length" ) );
HannesTschofenig 0:796d0f61a05b 2104 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2105 }
HannesTschofenig 0:796d0f61a05b 2106
HannesTschofenig 0:796d0f61a05b 2107 if( ssl->in_msglen < ssl->in_hslen )
HannesTschofenig 0:796d0f61a05b 2108 {
HannesTschofenig 0:796d0f61a05b 2109 SSL_DEBUG_MSG( 1, ( "bad handshake length" ) );
HannesTschofenig 0:796d0f61a05b 2110 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2111 }
HannesTschofenig 0:796d0f61a05b 2112
HannesTschofenig 0:796d0f61a05b 2113 if( ssl->state != SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 2114 ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
HannesTschofenig 0:796d0f61a05b 2115
HannesTschofenig 0:796d0f61a05b 2116 return( 0 );
HannesTschofenig 0:796d0f61a05b 2117 }
HannesTschofenig 0:796d0f61a05b 2118
HannesTschofenig 0:796d0f61a05b 2119 ssl->in_hslen = 0;
HannesTschofenig 0:796d0f61a05b 2120
HannesTschofenig 0:796d0f61a05b 2121 /*
HannesTschofenig 0:796d0f61a05b 2122 * Read the record header and validate it
HannesTschofenig 0:796d0f61a05b 2123 */
HannesTschofenig 0:796d0f61a05b 2124 if( ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2125 {
HannesTschofenig 0:796d0f61a05b 2126 SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
HannesTschofenig 0:796d0f61a05b 2127 return( ret );
HannesTschofenig 0:796d0f61a05b 2128 }
HannesTschofenig 0:796d0f61a05b 2129
HannesTschofenig 0:796d0f61a05b 2130 ssl->in_msgtype = ssl->in_hdr[0];
HannesTschofenig 0:796d0f61a05b 2131 ssl->in_msglen = ( ssl->in_hdr[3] << 8 ) | ssl->in_hdr[4];
HannesTschofenig 0:796d0f61a05b 2132
HannesTschofenig 0:796d0f61a05b 2133 SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
HannesTschofenig 0:796d0f61a05b 2134 "version = [%d:%d], msglen = %d",
HannesTschofenig 0:796d0f61a05b 2135 ssl->in_hdr[0], ssl->in_hdr[1], ssl->in_hdr[2],
HannesTschofenig 0:796d0f61a05b 2136 ( ssl->in_hdr[3] << 8 ) | ssl->in_hdr[4] ) );
HannesTschofenig 0:796d0f61a05b 2137
HannesTschofenig 0:796d0f61a05b 2138 if( ssl->in_hdr[1] != ssl->major_ver )
HannesTschofenig 0:796d0f61a05b 2139 {
HannesTschofenig 0:796d0f61a05b 2140 SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
HannesTschofenig 0:796d0f61a05b 2141 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2142 }
HannesTschofenig 0:796d0f61a05b 2143
HannesTschofenig 0:796d0f61a05b 2144 if( ssl->in_hdr[2] > ssl->max_minor_ver )
HannesTschofenig 0:796d0f61a05b 2145 {
HannesTschofenig 0:796d0f61a05b 2146 SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
HannesTschofenig 0:796d0f61a05b 2147 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2148 }
HannesTschofenig 0:796d0f61a05b 2149
HannesTschofenig 0:796d0f61a05b 2150 /* Sanity check (outer boundaries) */
HannesTschofenig 0:796d0f61a05b 2151 if( ssl->in_msglen < 1 || ssl->in_msglen > SSL_BUFFER_LEN - 13 )
HannesTschofenig 0:796d0f61a05b 2152 {
HannesTschofenig 0:796d0f61a05b 2153 SSL_DEBUG_MSG( 1, ( "bad message length" ) );
HannesTschofenig 0:796d0f61a05b 2154 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2155 }
HannesTschofenig 0:796d0f61a05b 2156
HannesTschofenig 0:796d0f61a05b 2157 /*
HannesTschofenig 0:796d0f61a05b 2158 * Make sure the message length is acceptable for the current transform
HannesTschofenig 0:796d0f61a05b 2159 * and protocol version.
HannesTschofenig 0:796d0f61a05b 2160 */
HannesTschofenig 0:796d0f61a05b 2161 if( ssl->transform_in == NULL )
HannesTschofenig 0:796d0f61a05b 2162 {
HannesTschofenig 0:796d0f61a05b 2163 if( ssl->in_msglen > SSL_MAX_CONTENT_LEN )
HannesTschofenig 0:796d0f61a05b 2164 {
HannesTschofenig 0:796d0f61a05b 2165 SSL_DEBUG_MSG( 1, ( "bad message length" ) );
HannesTschofenig 0:796d0f61a05b 2166 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2167 }
HannesTschofenig 0:796d0f61a05b 2168 }
HannesTschofenig 0:796d0f61a05b 2169 else
HannesTschofenig 0:796d0f61a05b 2170 {
HannesTschofenig 0:796d0f61a05b 2171 if( ssl->in_msglen < ssl->transform_in->minlen )
HannesTschofenig 0:796d0f61a05b 2172 {
HannesTschofenig 0:796d0f61a05b 2173 SSL_DEBUG_MSG( 1, ( "bad message length" ) );
HannesTschofenig 0:796d0f61a05b 2174 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2175 }
HannesTschofenig 0:796d0f61a05b 2176
HannesTschofenig 0:796d0f61a05b 2177 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 2178 if( ssl->minor_ver == SSL_MINOR_VERSION_0 &&
HannesTschofenig 0:796d0f61a05b 2179 ssl->in_msglen > ssl->transform_in->minlen + SSL_MAX_CONTENT_LEN )
HannesTschofenig 0:796d0f61a05b 2180 {
HannesTschofenig 0:796d0f61a05b 2181 SSL_DEBUG_MSG( 1, ( "bad message length" ) );
HannesTschofenig 0:796d0f61a05b 2182 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2183 }
HannesTschofenig 0:796d0f61a05b 2184 #endif
HannesTschofenig 0:796d0f61a05b 2185
HannesTschofenig 0:796d0f61a05b 2186 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 2187 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2188 /*
HannesTschofenig 0:796d0f61a05b 2189 * TLS encrypted messages can have up to 256 bytes of padding
HannesTschofenig 0:796d0f61a05b 2190 */
HannesTschofenig 0:796d0f61a05b 2191 if( ssl->minor_ver >= SSL_MINOR_VERSION_1 &&
HannesTschofenig 0:796d0f61a05b 2192 ssl->in_msglen > ssl->transform_in->minlen +
HannesTschofenig 0:796d0f61a05b 2193 SSL_MAX_CONTENT_LEN + 256 )
HannesTschofenig 0:796d0f61a05b 2194 {
HannesTschofenig 0:796d0f61a05b 2195 SSL_DEBUG_MSG( 1, ( "bad message length" ) );
HannesTschofenig 0:796d0f61a05b 2196 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2197 }
HannesTschofenig 0:796d0f61a05b 2198 #endif
HannesTschofenig 0:796d0f61a05b 2199 }
HannesTschofenig 0:796d0f61a05b 2200
HannesTschofenig 0:796d0f61a05b 2201 /*
HannesTschofenig 0:796d0f61a05b 2202 * Read and optionally decrypt the message contents
HannesTschofenig 0:796d0f61a05b 2203 */
HannesTschofenig 0:796d0f61a05b 2204 if( ( ret = ssl_fetch_input( ssl, 5 + ssl->in_msglen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2205 {
HannesTschofenig 0:796d0f61a05b 2206 SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
HannesTschofenig 0:796d0f61a05b 2207 return( ret );
HannesTschofenig 0:796d0f61a05b 2208 }
HannesTschofenig 0:796d0f61a05b 2209
HannesTschofenig 0:796d0f61a05b 2210 SSL_DEBUG_BUF( 4, "input record from network",
HannesTschofenig 0:796d0f61a05b 2211 ssl->in_hdr, 5 + ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 2212
HannesTschofenig 0:796d0f61a05b 2213 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
HannesTschofenig 0:796d0f61a05b 2214 if( ssl_hw_record_read != NULL)
HannesTschofenig 0:796d0f61a05b 2215 {
HannesTschofenig 0:796d0f61a05b 2216 SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_read()" ) );
HannesTschofenig 0:796d0f61a05b 2217
HannesTschofenig 0:796d0f61a05b 2218 ret = ssl_hw_record_read( ssl );
HannesTschofenig 0:796d0f61a05b 2219 if( ret != 0 && ret != POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH )
HannesTschofenig 0:796d0f61a05b 2220 {
HannesTschofenig 0:796d0f61a05b 2221 SSL_DEBUG_RET( 1, "ssl_hw_record_read", ret );
HannesTschofenig 0:796d0f61a05b 2222 return POLARSSL_ERR_SSL_HW_ACCEL_FAILED;
HannesTschofenig 0:796d0f61a05b 2223 }
HannesTschofenig 0:796d0f61a05b 2224
HannesTschofenig 0:796d0f61a05b 2225 if( ret == 0 )
HannesTschofenig 0:796d0f61a05b 2226 done = 1;
HannesTschofenig 0:796d0f61a05b 2227 }
HannesTschofenig 0:796d0f61a05b 2228 #endif /* POLARSSL_SSL_HW_RECORD_ACCEL */
HannesTschofenig 0:796d0f61a05b 2229 if( !done && ssl->transform_in != NULL )
HannesTschofenig 0:796d0f61a05b 2230 {
HannesTschofenig 0:796d0f61a05b 2231 if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2232 {
HannesTschofenig 0:796d0f61a05b 2233 #if defined(POLARSSL_SSL_ALERT_MESSAGES)
HannesTschofenig 0:796d0f61a05b 2234 if( ret == POLARSSL_ERR_SSL_INVALID_MAC )
HannesTschofenig 0:796d0f61a05b 2235 {
HannesTschofenig 0:796d0f61a05b 2236 ssl_send_alert_message( ssl,
HannesTschofenig 0:796d0f61a05b 2237 SSL_ALERT_LEVEL_FATAL,
HannesTschofenig 0:796d0f61a05b 2238 SSL_ALERT_MSG_BAD_RECORD_MAC );
HannesTschofenig 0:796d0f61a05b 2239 }
HannesTschofenig 0:796d0f61a05b 2240 #endif
HannesTschofenig 0:796d0f61a05b 2241 SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
HannesTschofenig 0:796d0f61a05b 2242 return( ret );
HannesTschofenig 0:796d0f61a05b 2243 }
HannesTschofenig 0:796d0f61a05b 2244
HannesTschofenig 0:796d0f61a05b 2245 SSL_DEBUG_BUF( 4, "input payload after decrypt",
HannesTschofenig 0:796d0f61a05b 2246 ssl->in_msg, ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 2247
HannesTschofenig 0:796d0f61a05b 2248 if( ssl->in_msglen > SSL_MAX_CONTENT_LEN )
HannesTschofenig 0:796d0f61a05b 2249 {
HannesTschofenig 0:796d0f61a05b 2250 SSL_DEBUG_MSG( 1, ( "bad message length" ) );
HannesTschofenig 0:796d0f61a05b 2251 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2252 }
HannesTschofenig 0:796d0f61a05b 2253 }
HannesTschofenig 0:796d0f61a05b 2254
HannesTschofenig 0:796d0f61a05b 2255 #if defined(POLARSSL_ZLIB_SUPPORT)
HannesTschofenig 0:796d0f61a05b 2256 if( ssl->transform_in != NULL &&
HannesTschofenig 0:796d0f61a05b 2257 ssl->session_in->compression == SSL_COMPRESS_DEFLATE )
HannesTschofenig 0:796d0f61a05b 2258 {
HannesTschofenig 0:796d0f61a05b 2259 if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2260 {
HannesTschofenig 0:796d0f61a05b 2261 SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
HannesTschofenig 0:796d0f61a05b 2262 return( ret );
HannesTschofenig 0:796d0f61a05b 2263 }
HannesTschofenig 0:796d0f61a05b 2264
HannesTschofenig 0:796d0f61a05b 2265 ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 );
HannesTschofenig 0:796d0f61a05b 2266 ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 2267 }
HannesTschofenig 0:796d0f61a05b 2268 #endif /* POLARSSL_ZLIB_SUPPORT */
HannesTschofenig 0:796d0f61a05b 2269
HannesTschofenig 0:796d0f61a05b 2270 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE &&
HannesTschofenig 0:796d0f61a05b 2271 ssl->in_msgtype != SSL_MSG_ALERT &&
HannesTschofenig 0:796d0f61a05b 2272 ssl->in_msgtype != SSL_MSG_CHANGE_CIPHER_SPEC &&
HannesTschofenig 0:796d0f61a05b 2273 ssl->in_msgtype != SSL_MSG_APPLICATION_DATA )
HannesTschofenig 0:796d0f61a05b 2274 {
HannesTschofenig 0:796d0f61a05b 2275 SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
HannesTschofenig 0:796d0f61a05b 2276
HannesTschofenig 0:796d0f61a05b 2277 if( ( ret = ssl_send_alert_message( ssl,
HannesTschofenig 0:796d0f61a05b 2278 SSL_ALERT_LEVEL_FATAL,
HannesTschofenig 0:796d0f61a05b 2279 SSL_ALERT_MSG_UNEXPECTED_MESSAGE ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2280 {
HannesTschofenig 0:796d0f61a05b 2281 return( ret );
HannesTschofenig 0:796d0f61a05b 2282 }
HannesTschofenig 0:796d0f61a05b 2283
HannesTschofenig 0:796d0f61a05b 2284 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2285 }
HannesTschofenig 0:796d0f61a05b 2286
HannesTschofenig 0:796d0f61a05b 2287 if( ssl->in_msgtype == SSL_MSG_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 2288 {
HannesTschofenig 0:796d0f61a05b 2289 ssl->in_hslen = 4;
HannesTschofenig 0:796d0f61a05b 2290 ssl->in_hslen += ( ssl->in_msg[2] << 8 ) | ssl->in_msg[3];
HannesTschofenig 0:796d0f61a05b 2291
HannesTschofenig 0:796d0f61a05b 2292 SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
HannesTschofenig 0:796d0f61a05b 2293 " %d, type = %d, hslen = %d",
HannesTschofenig 0:796d0f61a05b 2294 ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
HannesTschofenig 0:796d0f61a05b 2295
HannesTschofenig 0:796d0f61a05b 2296 /*
HannesTschofenig 0:796d0f61a05b 2297 * Additional checks to validate the handshake header
HannesTschofenig 0:796d0f61a05b 2298 */
HannesTschofenig 0:796d0f61a05b 2299 if( ssl->in_msglen < 4 || ssl->in_msg[1] != 0 )
HannesTschofenig 0:796d0f61a05b 2300 {
HannesTschofenig 0:796d0f61a05b 2301 SSL_DEBUG_MSG( 1, ( "bad handshake length" ) );
HannesTschofenig 0:796d0f61a05b 2302 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2303 }
HannesTschofenig 0:796d0f61a05b 2304
HannesTschofenig 0:796d0f61a05b 2305 if( ssl->in_msglen < ssl->in_hslen )
HannesTschofenig 0:796d0f61a05b 2306 {
HannesTschofenig 0:796d0f61a05b 2307 SSL_DEBUG_MSG( 1, ( "bad handshake length" ) );
HannesTschofenig 0:796d0f61a05b 2308 return( POLARSSL_ERR_SSL_INVALID_RECORD );
HannesTschofenig 0:796d0f61a05b 2309 }
HannesTschofenig 0:796d0f61a05b 2310
HannesTschofenig 0:796d0f61a05b 2311 if( ssl->state != SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 2312 ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
HannesTschofenig 0:796d0f61a05b 2313 }
HannesTschofenig 0:796d0f61a05b 2314
HannesTschofenig 0:796d0f61a05b 2315 if( ssl->in_msgtype == SSL_MSG_ALERT )
HannesTschofenig 0:796d0f61a05b 2316 {
HannesTschofenig 0:796d0f61a05b 2317 SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
HannesTschofenig 0:796d0f61a05b 2318 ssl->in_msg[0], ssl->in_msg[1] ) );
HannesTschofenig 0:796d0f61a05b 2319
HannesTschofenig 0:796d0f61a05b 2320 /*
HannesTschofenig 0:796d0f61a05b 2321 * Ignore non-fatal alerts, except close_notify
HannesTschofenig 0:796d0f61a05b 2322 */
HannesTschofenig 0:796d0f61a05b 2323 if( ssl->in_msg[0] == SSL_ALERT_LEVEL_FATAL )
HannesTschofenig 0:796d0f61a05b 2324 {
HannesTschofenig 0:796d0f61a05b 2325 SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
HannesTschofenig 0:796d0f61a05b 2326 ssl->in_msg[1] ) );
HannesTschofenig 0:796d0f61a05b 2327 /**
HannesTschofenig 0:796d0f61a05b 2328 * Subtract from error code as ssl->in_msg[1] is 7-bit positive
HannesTschofenig 0:796d0f61a05b 2329 * error identifier.
HannesTschofenig 0:796d0f61a05b 2330 */
HannesTschofenig 0:796d0f61a05b 2331 return( POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE );
HannesTschofenig 0:796d0f61a05b 2332 }
HannesTschofenig 0:796d0f61a05b 2333
HannesTschofenig 0:796d0f61a05b 2334 if( ssl->in_msg[0] == SSL_ALERT_LEVEL_WARNING &&
HannesTschofenig 0:796d0f61a05b 2335 ssl->in_msg[1] == SSL_ALERT_MSG_CLOSE_NOTIFY )
HannesTschofenig 0:796d0f61a05b 2336 {
HannesTschofenig 0:796d0f61a05b 2337 SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
HannesTschofenig 0:796d0f61a05b 2338 return( POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY );
HannesTschofenig 0:796d0f61a05b 2339 }
HannesTschofenig 0:796d0f61a05b 2340 }
HannesTschofenig 0:796d0f61a05b 2341
HannesTschofenig 0:796d0f61a05b 2342 ssl->in_left = 0;
HannesTschofenig 0:796d0f61a05b 2343
HannesTschofenig 0:796d0f61a05b 2344 SSL_DEBUG_MSG( 2, ( "<= read record" ) );
HannesTschofenig 0:796d0f61a05b 2345
HannesTschofenig 0:796d0f61a05b 2346 return( 0 );
HannesTschofenig 0:796d0f61a05b 2347 }
HannesTschofenig 0:796d0f61a05b 2348
HannesTschofenig 0:796d0f61a05b 2349 int ssl_send_fatal_handshake_failure( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2350 {
HannesTschofenig 0:796d0f61a05b 2351 int ret;
HannesTschofenig 0:796d0f61a05b 2352
HannesTschofenig 0:796d0f61a05b 2353 if( ( ret = ssl_send_alert_message( ssl,
HannesTschofenig 0:796d0f61a05b 2354 SSL_ALERT_LEVEL_FATAL,
HannesTschofenig 0:796d0f61a05b 2355 SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2356 {
HannesTschofenig 0:796d0f61a05b 2357 return( ret );
HannesTschofenig 0:796d0f61a05b 2358 }
HannesTschofenig 0:796d0f61a05b 2359
HannesTschofenig 0:796d0f61a05b 2360 return( 0 );
HannesTschofenig 0:796d0f61a05b 2361 }
HannesTschofenig 0:796d0f61a05b 2362
HannesTschofenig 0:796d0f61a05b 2363 int ssl_send_alert_message( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 2364 unsigned char level,
HannesTschofenig 0:796d0f61a05b 2365 unsigned char message )
HannesTschofenig 0:796d0f61a05b 2366 {
HannesTschofenig 0:796d0f61a05b 2367 int ret;
HannesTschofenig 0:796d0f61a05b 2368
HannesTschofenig 0:796d0f61a05b 2369 SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
HannesTschofenig 0:796d0f61a05b 2370
HannesTschofenig 0:796d0f61a05b 2371 ssl->out_msgtype = SSL_MSG_ALERT;
HannesTschofenig 0:796d0f61a05b 2372 ssl->out_msglen = 2;
HannesTschofenig 0:796d0f61a05b 2373 ssl->out_msg[0] = level;
HannesTschofenig 0:796d0f61a05b 2374 ssl->out_msg[1] = message;
HannesTschofenig 0:796d0f61a05b 2375
HannesTschofenig 0:796d0f61a05b 2376 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2377 {
HannesTschofenig 0:796d0f61a05b 2378 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 2379 return( ret );
HannesTschofenig 0:796d0f61a05b 2380 }
HannesTschofenig 0:796d0f61a05b 2381
HannesTschofenig 0:796d0f61a05b 2382 SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
HannesTschofenig 0:796d0f61a05b 2383
HannesTschofenig 0:796d0f61a05b 2384 return( 0 );
HannesTschofenig 0:796d0f61a05b 2385 }
HannesTschofenig 0:796d0f61a05b 2386
HannesTschofenig 0:796d0f61a05b 2387 /*
HannesTschofenig 0:796d0f61a05b 2388 * Handshake functions
HannesTschofenig 0:796d0f61a05b 2389 */
HannesTschofenig 0:796d0f61a05b 2390 #if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2391 !defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2392 !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2393 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2394 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2395 !defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2396 !defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2397 int ssl_write_certificate( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2398 {
HannesTschofenig 0:796d0f61a05b 2399 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 2400 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2401
HannesTschofenig 0:796d0f61a05b 2402 SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
HannesTschofenig 0:796d0f61a05b 2403
HannesTschofenig 0:796d0f61a05b 2404 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 2405 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
HannesTschofenig 0:796d0f61a05b 2406 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 2407 {
HannesTschofenig 0:796d0f61a05b 2408 SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
HannesTschofenig 0:796d0f61a05b 2409 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2410 return( 0 );
HannesTschofenig 0:796d0f61a05b 2411 }
HannesTschofenig 0:796d0f61a05b 2412
HannesTschofenig 0:796d0f61a05b 2413 SSL_DEBUG_MSG( 1, ( "should not happen" ) );
HannesTschofenig 0:796d0f61a05b 2414 return( ret );
HannesTschofenig 0:796d0f61a05b 2415 }
HannesTschofenig 0:796d0f61a05b 2416
HannesTschofenig 0:796d0f61a05b 2417 int ssl_parse_certificate( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2418 {
HannesTschofenig 0:796d0f61a05b 2419 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 2420 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2421
HannesTschofenig 0:796d0f61a05b 2422 SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
HannesTschofenig 0:796d0f61a05b 2423
HannesTschofenig 0:796d0f61a05b 2424 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 2425 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
HannesTschofenig 0:796d0f61a05b 2426 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 2427 {
HannesTschofenig 0:796d0f61a05b 2428 SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
HannesTschofenig 0:796d0f61a05b 2429 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2430 return( 0 );
HannesTschofenig 0:796d0f61a05b 2431 }
HannesTschofenig 0:796d0f61a05b 2432
HannesTschofenig 0:796d0f61a05b 2433 SSL_DEBUG_MSG( 1, ( "should not happen" ) );
HannesTschofenig 0:796d0f61a05b 2434 return( ret );
HannesTschofenig 0:796d0f61a05b 2435 }
HannesTschofenig 0:796d0f61a05b 2436 #else
HannesTschofenig 0:796d0f61a05b 2437 int ssl_write_certificate( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2438 {
HannesTschofenig 0:796d0f61a05b 2439 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 2440 size_t i, n;
HannesTschofenig 0:796d0f61a05b 2441 const x509_crt *crt;
HannesTschofenig 0:796d0f61a05b 2442 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2443
HannesTschofenig 0:796d0f61a05b 2444 SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
HannesTschofenig 0:796d0f61a05b 2445
HannesTschofenig 0:796d0f61a05b 2446 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 2447 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
HannesTschofenig 0:796d0f61a05b 2448 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 2449 {
HannesTschofenig 0:796d0f61a05b 2450 SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
HannesTschofenig 0:796d0f61a05b 2451 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2452 return( 0 );
HannesTschofenig 0:796d0f61a05b 2453 }
HannesTschofenig 0:796d0f61a05b 2454
HannesTschofenig 0:796d0f61a05b 2455 if( ssl->endpoint == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 2456 {
HannesTschofenig 0:796d0f61a05b 2457 if( ssl->client_auth == 0 )
HannesTschofenig 0:796d0f61a05b 2458 {
HannesTschofenig 0:796d0f61a05b 2459 SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
HannesTschofenig 0:796d0f61a05b 2460 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2461 return( 0 );
HannesTschofenig 0:796d0f61a05b 2462 }
HannesTschofenig 0:796d0f61a05b 2463
HannesTschofenig 0:796d0f61a05b 2464 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 2465 /*
HannesTschofenig 0:796d0f61a05b 2466 * If using SSLv3 and got no cert, send an Alert message
HannesTschofenig 0:796d0f61a05b 2467 * (otherwise an empty Certificate message will be sent).
HannesTschofenig 0:796d0f61a05b 2468 */
HannesTschofenig 0:796d0f61a05b 2469 if( ssl_own_cert( ssl ) == NULL &&
HannesTschofenig 0:796d0f61a05b 2470 ssl->minor_ver == SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 2471 {
HannesTschofenig 0:796d0f61a05b 2472 ssl->out_msglen = 2;
HannesTschofenig 0:796d0f61a05b 2473 ssl->out_msgtype = SSL_MSG_ALERT;
HannesTschofenig 0:796d0f61a05b 2474 ssl->out_msg[0] = SSL_ALERT_LEVEL_WARNING;
HannesTschofenig 0:796d0f61a05b 2475 ssl->out_msg[1] = SSL_ALERT_MSG_NO_CERT;
HannesTschofenig 0:796d0f61a05b 2476
HannesTschofenig 0:796d0f61a05b 2477 SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) );
HannesTschofenig 0:796d0f61a05b 2478 goto write_msg;
HannesTschofenig 0:796d0f61a05b 2479 }
HannesTschofenig 0:796d0f61a05b 2480 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 2481 }
HannesTschofenig 0:796d0f61a05b 2482 else /* SSL_IS_SERVER */
HannesTschofenig 0:796d0f61a05b 2483 {
HannesTschofenig 0:796d0f61a05b 2484 if( ssl_own_cert( ssl ) == NULL )
HannesTschofenig 0:796d0f61a05b 2485 {
HannesTschofenig 0:796d0f61a05b 2486 SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) );
HannesTschofenig 0:796d0f61a05b 2487 return( POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED );
HannesTschofenig 0:796d0f61a05b 2488 }
HannesTschofenig 0:796d0f61a05b 2489 }
HannesTschofenig 0:796d0f61a05b 2490
HannesTschofenig 0:796d0f61a05b 2491 SSL_DEBUG_CRT( 3, "own certificate", ssl_own_cert( ssl ) );
HannesTschofenig 0:796d0f61a05b 2492
HannesTschofenig 0:796d0f61a05b 2493 /*
HannesTschofenig 0:796d0f61a05b 2494 * 0 . 0 handshake type
HannesTschofenig 0:796d0f61a05b 2495 * 1 . 3 handshake length
HannesTschofenig 0:796d0f61a05b 2496 * 4 . 6 length of all certs
HannesTschofenig 0:796d0f61a05b 2497 * 7 . 9 length of cert. 1
HannesTschofenig 0:796d0f61a05b 2498 * 10 . n-1 peer certificate
HannesTschofenig 0:796d0f61a05b 2499 * n . n+2 length of cert. 2
HannesTschofenig 0:796d0f61a05b 2500 * n+3 . ... upper level cert, etc.
HannesTschofenig 0:796d0f61a05b 2501 */
HannesTschofenig 0:796d0f61a05b 2502 i = 7;
HannesTschofenig 0:796d0f61a05b 2503 crt = ssl_own_cert( ssl );
HannesTschofenig 0:796d0f61a05b 2504
HannesTschofenig 0:796d0f61a05b 2505 while( crt != NULL )
HannesTschofenig 0:796d0f61a05b 2506 {
HannesTschofenig 0:796d0f61a05b 2507 n = crt->raw.len;
HannesTschofenig 0:796d0f61a05b 2508 if( n > SSL_MAX_CONTENT_LEN - 3 - i )
HannesTschofenig 0:796d0f61a05b 2509 {
HannesTschofenig 0:796d0f61a05b 2510 SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d",
HannesTschofenig 0:796d0f61a05b 2511 i + 3 + n, SSL_MAX_CONTENT_LEN ) );
HannesTschofenig 0:796d0f61a05b 2512 return( POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE );
HannesTschofenig 0:796d0f61a05b 2513 }
HannesTschofenig 0:796d0f61a05b 2514
HannesTschofenig 0:796d0f61a05b 2515 ssl->out_msg[i ] = (unsigned char)( n >> 16 );
HannesTschofenig 0:796d0f61a05b 2516 ssl->out_msg[i + 1] = (unsigned char)( n >> 8 );
HannesTschofenig 0:796d0f61a05b 2517 ssl->out_msg[i + 2] = (unsigned char)( n );
HannesTschofenig 0:796d0f61a05b 2518
HannesTschofenig 0:796d0f61a05b 2519 i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
HannesTschofenig 0:796d0f61a05b 2520 i += n; crt = crt->next;
HannesTschofenig 0:796d0f61a05b 2521 }
HannesTschofenig 0:796d0f61a05b 2522
HannesTschofenig 0:796d0f61a05b 2523 ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 );
HannesTschofenig 0:796d0f61a05b 2524 ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 );
HannesTschofenig 0:796d0f61a05b 2525 ssl->out_msg[6] = (unsigned char)( ( i - 7 ) );
HannesTschofenig 0:796d0f61a05b 2526
HannesTschofenig 0:796d0f61a05b 2527 ssl->out_msglen = i;
HannesTschofenig 0:796d0f61a05b 2528 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 2529 ssl->out_msg[0] = SSL_HS_CERTIFICATE;
HannesTschofenig 0:796d0f61a05b 2530
HannesTschofenig 0:796d0f61a05b 2531 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 2532 write_msg:
HannesTschofenig 0:796d0f61a05b 2533 #endif
HannesTschofenig 0:796d0f61a05b 2534
HannesTschofenig 0:796d0f61a05b 2535 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2536
HannesTschofenig 0:796d0f61a05b 2537 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2538 {
HannesTschofenig 0:796d0f61a05b 2539 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 2540 return( ret );
HannesTschofenig 0:796d0f61a05b 2541 }
HannesTschofenig 0:796d0f61a05b 2542
HannesTschofenig 0:796d0f61a05b 2543 SSL_DEBUG_MSG( 2, ( "<= write certificate" ) );
HannesTschofenig 0:796d0f61a05b 2544
HannesTschofenig 0:796d0f61a05b 2545 return( ret );
HannesTschofenig 0:796d0f61a05b 2546 }
HannesTschofenig 0:796d0f61a05b 2547
HannesTschofenig 0:796d0f61a05b 2548 int ssl_parse_certificate( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2549 {
HannesTschofenig 0:796d0f61a05b 2550 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 2551 size_t i, n;
HannesTschofenig 0:796d0f61a05b 2552 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2553
HannesTschofenig 0:796d0f61a05b 2554 SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
HannesTschofenig 0:796d0f61a05b 2555
HannesTschofenig 0:796d0f61a05b 2556 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 2557 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
HannesTschofenig 0:796d0f61a05b 2558 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 2559 {
HannesTschofenig 0:796d0f61a05b 2560 SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
HannesTschofenig 0:796d0f61a05b 2561 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2562 return( 0 );
HannesTschofenig 0:796d0f61a05b 2563 }
HannesTschofenig 0:796d0f61a05b 2564
HannesTschofenig 0:796d0f61a05b 2565 if( ssl->endpoint == SSL_IS_SERVER &&
HannesTschofenig 0:796d0f61a05b 2566 ( ssl->authmode == SSL_VERIFY_NONE ||
HannesTschofenig 0:796d0f61a05b 2567 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) )
HannesTschofenig 0:796d0f61a05b 2568 {
HannesTschofenig 0:796d0f61a05b 2569 ssl->session_negotiate->verify_result = BADCERT_SKIP_VERIFY;
HannesTschofenig 0:796d0f61a05b 2570 SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
HannesTschofenig 0:796d0f61a05b 2571 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2572 return( 0 );
HannesTschofenig 0:796d0f61a05b 2573 }
HannesTschofenig 0:796d0f61a05b 2574
HannesTschofenig 0:796d0f61a05b 2575 if( ( ret = ssl_read_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2576 {
HannesTschofenig 0:796d0f61a05b 2577 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
HannesTschofenig 0:796d0f61a05b 2578 return( ret );
HannesTschofenig 0:796d0f61a05b 2579 }
HannesTschofenig 0:796d0f61a05b 2580
HannesTschofenig 0:796d0f61a05b 2581 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2582
HannesTschofenig 0:796d0f61a05b 2583 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 2584 /*
HannesTschofenig 0:796d0f61a05b 2585 * Check if the client sent an empty certificate
HannesTschofenig 0:796d0f61a05b 2586 */
HannesTschofenig 0:796d0f61a05b 2587 if( ssl->endpoint == SSL_IS_SERVER &&
HannesTschofenig 0:796d0f61a05b 2588 ssl->minor_ver == SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 2589 {
HannesTschofenig 0:796d0f61a05b 2590 if( ssl->in_msglen == 2 &&
HannesTschofenig 0:796d0f61a05b 2591 ssl->in_msgtype == SSL_MSG_ALERT &&
HannesTschofenig 0:796d0f61a05b 2592 ssl->in_msg[0] == SSL_ALERT_LEVEL_WARNING &&
HannesTschofenig 0:796d0f61a05b 2593 ssl->in_msg[1] == SSL_ALERT_MSG_NO_CERT )
HannesTschofenig 0:796d0f61a05b 2594 {
HannesTschofenig 0:796d0f61a05b 2595 SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
HannesTschofenig 0:796d0f61a05b 2596
HannesTschofenig 0:796d0f61a05b 2597 ssl->session_negotiate->verify_result = BADCERT_MISSING;
HannesTschofenig 0:796d0f61a05b 2598 if( ssl->authmode == SSL_VERIFY_OPTIONAL )
HannesTschofenig 0:796d0f61a05b 2599 return( 0 );
HannesTschofenig 0:796d0f61a05b 2600 else
HannesTschofenig 0:796d0f61a05b 2601 return( POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE );
HannesTschofenig 0:796d0f61a05b 2602 }
HannesTschofenig 0:796d0f61a05b 2603 }
HannesTschofenig 0:796d0f61a05b 2604 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 2605
HannesTschofenig 0:796d0f61a05b 2606 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 2607 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2608 if( ssl->endpoint == SSL_IS_SERVER &&
HannesTschofenig 0:796d0f61a05b 2609 ssl->minor_ver != SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 2610 {
HannesTschofenig 0:796d0f61a05b 2611 if( ssl->in_hslen == 7 &&
HannesTschofenig 0:796d0f61a05b 2612 ssl->in_msgtype == SSL_MSG_HANDSHAKE &&
HannesTschofenig 0:796d0f61a05b 2613 ssl->in_msg[0] == SSL_HS_CERTIFICATE &&
HannesTschofenig 0:796d0f61a05b 2614 memcmp( ssl->in_msg + 4, "\0\0\0", 3 ) == 0 )
HannesTschofenig 0:796d0f61a05b 2615 {
HannesTschofenig 0:796d0f61a05b 2616 SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
HannesTschofenig 0:796d0f61a05b 2617
HannesTschofenig 0:796d0f61a05b 2618 ssl->session_negotiate->verify_result = BADCERT_MISSING;
HannesTschofenig 0:796d0f61a05b 2619 if( ssl->authmode == SSL_VERIFY_REQUIRED )
HannesTschofenig 0:796d0f61a05b 2620 return( POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE );
HannesTschofenig 0:796d0f61a05b 2621 else
HannesTschofenig 0:796d0f61a05b 2622 return( 0 );
HannesTschofenig 0:796d0f61a05b 2623 }
HannesTschofenig 0:796d0f61a05b 2624 }
HannesTschofenig 0:796d0f61a05b 2625 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
HannesTschofenig 0:796d0f61a05b 2626 POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 2627
HannesTschofenig 0:796d0f61a05b 2628 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 2629 {
HannesTschofenig 0:796d0f61a05b 2630 SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
HannesTschofenig 0:796d0f61a05b 2631 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
HannesTschofenig 0:796d0f61a05b 2632 }
HannesTschofenig 0:796d0f61a05b 2633
HannesTschofenig 0:796d0f61a05b 2634 if( ssl->in_msg[0] != SSL_HS_CERTIFICATE || ssl->in_hslen < 10 )
HannesTschofenig 0:796d0f61a05b 2635 {
HannesTschofenig 0:796d0f61a05b 2636 SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
HannesTschofenig 0:796d0f61a05b 2637 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
HannesTschofenig 0:796d0f61a05b 2638 }
HannesTschofenig 0:796d0f61a05b 2639
HannesTschofenig 0:796d0f61a05b 2640 /*
HannesTschofenig 0:796d0f61a05b 2641 * Same message structure as in ssl_write_certificate()
HannesTschofenig 0:796d0f61a05b 2642 */
HannesTschofenig 0:796d0f61a05b 2643 n = ( ssl->in_msg[5] << 8 ) | ssl->in_msg[6];
HannesTschofenig 0:796d0f61a05b 2644
HannesTschofenig 0:796d0f61a05b 2645 if( ssl->in_msg[4] != 0 || ssl->in_hslen != 7 + n )
HannesTschofenig 0:796d0f61a05b 2646 {
HannesTschofenig 0:796d0f61a05b 2647 SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
HannesTschofenig 0:796d0f61a05b 2648 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
HannesTschofenig 0:796d0f61a05b 2649 }
HannesTschofenig 0:796d0f61a05b 2650
HannesTschofenig 0:796d0f61a05b 2651 /* In case we tried to reuse a session but it failed */
HannesTschofenig 0:796d0f61a05b 2652 if( ssl->session_negotiate->peer_cert != NULL )
HannesTschofenig 0:796d0f61a05b 2653 {
HannesTschofenig 0:796d0f61a05b 2654 x509_crt_free( ssl->session_negotiate->peer_cert );
HannesTschofenig 0:796d0f61a05b 2655 polarssl_free( ssl->session_negotiate->peer_cert );
HannesTschofenig 0:796d0f61a05b 2656 }
HannesTschofenig 0:796d0f61a05b 2657
HannesTschofenig 0:796d0f61a05b 2658 if( ( ssl->session_negotiate->peer_cert = (x509_crt *) polarssl_malloc(
HannesTschofenig 0:796d0f61a05b 2659 sizeof( x509_crt ) ) ) == NULL )
HannesTschofenig 0:796d0f61a05b 2660 {
HannesTschofenig 0:796d0f61a05b 2661 SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed",
HannesTschofenig 0:796d0f61a05b 2662 sizeof( x509_crt ) ) );
HannesTschofenig 0:796d0f61a05b 2663 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 2664 }
HannesTschofenig 0:796d0f61a05b 2665
HannesTschofenig 0:796d0f61a05b 2666 x509_crt_init( ssl->session_negotiate->peer_cert );
HannesTschofenig 0:796d0f61a05b 2667
HannesTschofenig 0:796d0f61a05b 2668 i = 7;
HannesTschofenig 0:796d0f61a05b 2669
HannesTschofenig 0:796d0f61a05b 2670 while( i < ssl->in_hslen )
HannesTschofenig 0:796d0f61a05b 2671 {
HannesTschofenig 0:796d0f61a05b 2672 if( ssl->in_msg[i] != 0 )
HannesTschofenig 0:796d0f61a05b 2673 {
HannesTschofenig 0:796d0f61a05b 2674 SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
HannesTschofenig 0:796d0f61a05b 2675 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
HannesTschofenig 0:796d0f61a05b 2676 }
HannesTschofenig 0:796d0f61a05b 2677
HannesTschofenig 0:796d0f61a05b 2678 n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
HannesTschofenig 0:796d0f61a05b 2679 | (unsigned int) ssl->in_msg[i + 2];
HannesTschofenig 0:796d0f61a05b 2680 i += 3;
HannesTschofenig 0:796d0f61a05b 2681
HannesTschofenig 0:796d0f61a05b 2682 if( n < 128 || i + n > ssl->in_hslen )
HannesTschofenig 0:796d0f61a05b 2683 {
HannesTschofenig 0:796d0f61a05b 2684 SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
HannesTschofenig 0:796d0f61a05b 2685 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
HannesTschofenig 0:796d0f61a05b 2686 }
HannesTschofenig 0:796d0f61a05b 2687
HannesTschofenig 0:796d0f61a05b 2688 ret = x509_crt_parse_der( ssl->session_negotiate->peer_cert,
HannesTschofenig 0:796d0f61a05b 2689 ssl->in_msg + i, n );
HannesTschofenig 0:796d0f61a05b 2690 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 2691 {
HannesTschofenig 0:796d0f61a05b 2692 SSL_DEBUG_RET( 1, " x509_crt_parse_der", ret );
HannesTschofenig 0:796d0f61a05b 2693 return( ret );
HannesTschofenig 0:796d0f61a05b 2694 }
HannesTschofenig 0:796d0f61a05b 2695
HannesTschofenig 0:796d0f61a05b 2696 i += n;
HannesTschofenig 0:796d0f61a05b 2697 }
HannesTschofenig 0:796d0f61a05b 2698
HannesTschofenig 0:796d0f61a05b 2699 SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert );
HannesTschofenig 0:796d0f61a05b 2700
HannesTschofenig 0:796d0f61a05b 2701 /*
HannesTschofenig 0:796d0f61a05b 2702 * On client, make sure the server cert doesn't change during renego to
HannesTschofenig 0:796d0f61a05b 2703 * avoid "triple handshake" attack: https://secure-resumption.com/
HannesTschofenig 0:796d0f61a05b 2704 */
HannesTschofenig 0:796d0f61a05b 2705 if( ssl->endpoint == SSL_IS_CLIENT &&
HannesTschofenig 0:796d0f61a05b 2706 ssl->renegotiation == SSL_RENEGOTIATION )
HannesTschofenig 0:796d0f61a05b 2707 {
HannesTschofenig 0:796d0f61a05b 2708 if( ssl->session->peer_cert == NULL )
HannesTschofenig 0:796d0f61a05b 2709 {
HannesTschofenig 0:796d0f61a05b 2710 SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
HannesTschofenig 0:796d0f61a05b 2711 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
HannesTschofenig 0:796d0f61a05b 2712 }
HannesTschofenig 0:796d0f61a05b 2713
HannesTschofenig 0:796d0f61a05b 2714 if( ssl->session->peer_cert->raw.len !=
HannesTschofenig 0:796d0f61a05b 2715 ssl->session_negotiate->peer_cert->raw.len ||
HannesTschofenig 0:796d0f61a05b 2716 memcmp( ssl->session->peer_cert->raw.p,
HannesTschofenig 0:796d0f61a05b 2717 ssl->session_negotiate->peer_cert->raw.p,
HannesTschofenig 0:796d0f61a05b 2718 ssl->session->peer_cert->raw.len ) != 0 )
HannesTschofenig 0:796d0f61a05b 2719 {
HannesTschofenig 0:796d0f61a05b 2720 SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) );
HannesTschofenig 0:796d0f61a05b 2721 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
HannesTschofenig 0:796d0f61a05b 2722 }
HannesTschofenig 0:796d0f61a05b 2723 }
HannesTschofenig 0:796d0f61a05b 2724
HannesTschofenig 0:796d0f61a05b 2725 if( ssl->authmode != SSL_VERIFY_NONE )
HannesTschofenig 0:796d0f61a05b 2726 {
HannesTschofenig 0:796d0f61a05b 2727 if( ssl->ca_chain == NULL )
HannesTschofenig 0:796d0f61a05b 2728 {
HannesTschofenig 0:796d0f61a05b 2729 SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
HannesTschofenig 0:796d0f61a05b 2730 return( POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED );
HannesTschofenig 0:796d0f61a05b 2731 }
HannesTschofenig 0:796d0f61a05b 2732
HannesTschofenig 0:796d0f61a05b 2733 /*
HannesTschofenig 0:796d0f61a05b 2734 * Main check: verify certificate
HannesTschofenig 0:796d0f61a05b 2735 */
HannesTschofenig 0:796d0f61a05b 2736 ret = x509_crt_verify( ssl->session_negotiate->peer_cert,
HannesTschofenig 0:796d0f61a05b 2737 ssl->ca_chain, ssl->ca_crl, ssl->peer_cn,
HannesTschofenig 0:796d0f61a05b 2738 &ssl->session_negotiate->verify_result,
HannesTschofenig 0:796d0f61a05b 2739 ssl->f_vrfy, ssl->p_vrfy );
HannesTschofenig 0:796d0f61a05b 2740
HannesTschofenig 0:796d0f61a05b 2741 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 2742 {
HannesTschofenig 0:796d0f61a05b 2743 SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
HannesTschofenig 0:796d0f61a05b 2744 }
HannesTschofenig 0:796d0f61a05b 2745
HannesTschofenig 0:796d0f61a05b 2746 /*
HannesTschofenig 0:796d0f61a05b 2747 * Secondary checks: always done, but change 'ret' only if it was 0
HannesTschofenig 0:796d0f61a05b 2748 */
HannesTschofenig 0:796d0f61a05b 2749
HannesTschofenig 0:796d0f61a05b 2750 #if defined(POLARSSL_SSL_SET_CURVES)
HannesTschofenig 0:796d0f61a05b 2751 {
HannesTschofenig 0:796d0f61a05b 2752 pk_context *pk = &ssl->session_negotiate->peer_cert->pk;
HannesTschofenig 0:796d0f61a05b 2753
HannesTschofenig 0:796d0f61a05b 2754 /* If certificate uses an EC key, make sure the curve is OK */
HannesTschofenig 0:796d0f61a05b 2755 if( pk_can_do( pk, POLARSSL_PK_ECKEY ) &&
HannesTschofenig 0:796d0f61a05b 2756 ! ssl_curve_is_acceptable( ssl, pk_ec( *pk )->grp.id ) )
HannesTschofenig 0:796d0f61a05b 2757 {
HannesTschofenig 0:796d0f61a05b 2758 SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
HannesTschofenig 0:796d0f61a05b 2759 if( ret == 0 )
HannesTschofenig 0:796d0f61a05b 2760 ret = POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE;
HannesTschofenig 0:796d0f61a05b 2761 }
HannesTschofenig 0:796d0f61a05b 2762 }
HannesTschofenig 0:796d0f61a05b 2763 #endif /* POLARSSL_SSL_SET_CURVES */
HannesTschofenig 0:796d0f61a05b 2764
HannesTschofenig 0:796d0f61a05b 2765 if( ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
HannesTschofenig 0:796d0f61a05b 2766 ciphersuite_info,
HannesTschofenig 0:796d0f61a05b 2767 ! ssl->endpoint ) != 0 )
HannesTschofenig 0:796d0f61a05b 2768 {
HannesTschofenig 0:796d0f61a05b 2769 SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
HannesTschofenig 0:796d0f61a05b 2770 if( ret == 0 )
HannesTschofenig 0:796d0f61a05b 2771 ret = POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE;
HannesTschofenig 0:796d0f61a05b 2772 }
HannesTschofenig 0:796d0f61a05b 2773
HannesTschofenig 0:796d0f61a05b 2774 if( ssl->authmode != SSL_VERIFY_REQUIRED )
HannesTschofenig 0:796d0f61a05b 2775 ret = 0;
HannesTschofenig 0:796d0f61a05b 2776 }
HannesTschofenig 0:796d0f61a05b 2777
HannesTschofenig 0:796d0f61a05b 2778 SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
HannesTschofenig 0:796d0f61a05b 2779
HannesTschofenig 0:796d0f61a05b 2780 return( ret );
HannesTschofenig 0:796d0f61a05b 2781 }
HannesTschofenig 0:796d0f61a05b 2782 #endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED
HannesTschofenig 0:796d0f61a05b 2783 !POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED
HannesTschofenig 0:796d0f61a05b 2784 !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED
HannesTschofenig 0:796d0f61a05b 2785 !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED
HannesTschofenig 0:796d0f61a05b 2786 !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
HannesTschofenig 0:796d0f61a05b 2787 !POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED
HannesTschofenig 0:796d0f61a05b 2788 !POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
HannesTschofenig 0:796d0f61a05b 2789
HannesTschofenig 0:796d0f61a05b 2790 int ssl_write_change_cipher_spec( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2791 {
HannesTschofenig 0:796d0f61a05b 2792 int ret;
HannesTschofenig 0:796d0f61a05b 2793
HannesTschofenig 0:796d0f61a05b 2794 SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
HannesTschofenig 0:796d0f61a05b 2795
HannesTschofenig 0:796d0f61a05b 2796 ssl->out_msgtype = SSL_MSG_CHANGE_CIPHER_SPEC;
HannesTschofenig 0:796d0f61a05b 2797 ssl->out_msglen = 1;
HannesTschofenig 0:796d0f61a05b 2798 ssl->out_msg[0] = 1;
HannesTschofenig 0:796d0f61a05b 2799
HannesTschofenig 0:796d0f61a05b 2800 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2801
HannesTschofenig 0:796d0f61a05b 2802 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2803 {
HannesTschofenig 0:796d0f61a05b 2804 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 2805 return( ret );
HannesTschofenig 0:796d0f61a05b 2806 }
HannesTschofenig 0:796d0f61a05b 2807
HannesTschofenig 0:796d0f61a05b 2808 SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
HannesTschofenig 0:796d0f61a05b 2809
HannesTschofenig 0:796d0f61a05b 2810 return( 0 );
HannesTschofenig 0:796d0f61a05b 2811 }
HannesTschofenig 0:796d0f61a05b 2812
HannesTschofenig 0:796d0f61a05b 2813 int ssl_parse_change_cipher_spec( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2814 {
HannesTschofenig 0:796d0f61a05b 2815 int ret;
HannesTschofenig 0:796d0f61a05b 2816
HannesTschofenig 0:796d0f61a05b 2817 SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
HannesTschofenig 0:796d0f61a05b 2818
HannesTschofenig 0:796d0f61a05b 2819 if( ( ret = ssl_read_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2820 {
HannesTschofenig 0:796d0f61a05b 2821 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
HannesTschofenig 0:796d0f61a05b 2822 return( ret );
HannesTschofenig 0:796d0f61a05b 2823 }
HannesTschofenig 0:796d0f61a05b 2824
HannesTschofenig 0:796d0f61a05b 2825 if( ssl->in_msgtype != SSL_MSG_CHANGE_CIPHER_SPEC )
HannesTschofenig 0:796d0f61a05b 2826 {
HannesTschofenig 0:796d0f61a05b 2827 SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
HannesTschofenig 0:796d0f61a05b 2828 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
HannesTschofenig 0:796d0f61a05b 2829 }
HannesTschofenig 0:796d0f61a05b 2830
HannesTschofenig 0:796d0f61a05b 2831 if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 )
HannesTschofenig 0:796d0f61a05b 2832 {
HannesTschofenig 0:796d0f61a05b 2833 SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
HannesTschofenig 0:796d0f61a05b 2834 return( POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC );
HannesTschofenig 0:796d0f61a05b 2835 }
HannesTschofenig 0:796d0f61a05b 2836
HannesTschofenig 0:796d0f61a05b 2837 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2838
HannesTschofenig 0:796d0f61a05b 2839 SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
HannesTschofenig 0:796d0f61a05b 2840
HannesTschofenig 0:796d0f61a05b 2841 return( 0 );
HannesTschofenig 0:796d0f61a05b 2842 }
HannesTschofenig 0:796d0f61a05b 2843
HannesTschofenig 0:796d0f61a05b 2844 void ssl_optimize_checksum( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 2845 const ssl_ciphersuite_t *ciphersuite_info )
HannesTschofenig 0:796d0f61a05b 2846 {
HannesTschofenig 0:796d0f61a05b 2847 ((void) ciphersuite_info);
HannesTschofenig 0:796d0f61a05b 2848
HannesTschofenig 0:796d0f61a05b 2849 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
HannesTschofenig 0:796d0f61a05b 2850 defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 2851 if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 2852 ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
HannesTschofenig 0:796d0f61a05b 2853 else
HannesTschofenig 0:796d0f61a05b 2854 #endif
HannesTschofenig 0:796d0f61a05b 2855 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2856 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 2857 if( ciphersuite_info->mac == POLARSSL_MD_SHA384 )
HannesTschofenig 0:796d0f61a05b 2858 ssl->handshake->update_checksum = ssl_update_checksum_sha384;
HannesTschofenig 0:796d0f61a05b 2859 else
HannesTschofenig 0:796d0f61a05b 2860 #endif
HannesTschofenig 0:796d0f61a05b 2861 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 2862 if( ciphersuite_info->mac != POLARSSL_MD_SHA384 )
HannesTschofenig 0:796d0f61a05b 2863 ssl->handshake->update_checksum = ssl_update_checksum_sha256;
HannesTschofenig 0:796d0f61a05b 2864 else
HannesTschofenig 0:796d0f61a05b 2865 #endif
HannesTschofenig 0:796d0f61a05b 2866 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 2867 /* Should never happen */
HannesTschofenig 0:796d0f61a05b 2868 return;
HannesTschofenig 0:796d0f61a05b 2869 }
HannesTschofenig 0:796d0f61a05b 2870
HannesTschofenig 0:796d0f61a05b 2871 static void ssl_update_checksum_start( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 2872 const unsigned char *buf, size_t len )
HannesTschofenig 0:796d0f61a05b 2873 {
HannesTschofenig 0:796d0f61a05b 2874 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
HannesTschofenig 0:796d0f61a05b 2875 defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 2876 md5_update( &ssl->handshake->fin_md5 , buf, len );
HannesTschofenig 0:796d0f61a05b 2877 sha1_update( &ssl->handshake->fin_sha1, buf, len );
HannesTschofenig 0:796d0f61a05b 2878 #endif
HannesTschofenig 0:796d0f61a05b 2879 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2880 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 2881 sha256_update( &ssl->handshake->fin_sha256, buf, len );
HannesTschofenig 0:796d0f61a05b 2882 #endif
HannesTschofenig 0:796d0f61a05b 2883 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 2884 sha512_update( &ssl->handshake->fin_sha512, buf, len );
HannesTschofenig 0:796d0f61a05b 2885 #endif
HannesTschofenig 0:796d0f61a05b 2886 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 2887 }
HannesTschofenig 0:796d0f61a05b 2888
HannesTschofenig 0:796d0f61a05b 2889 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
HannesTschofenig 0:796d0f61a05b 2890 defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 2891 static void ssl_update_checksum_md5sha1( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 2892 const unsigned char *buf, size_t len )
HannesTschofenig 0:796d0f61a05b 2893 {
HannesTschofenig 0:796d0f61a05b 2894 md5_update( &ssl->handshake->fin_md5 , buf, len );
HannesTschofenig 0:796d0f61a05b 2895 sha1_update( &ssl->handshake->fin_sha1, buf, len );
HannesTschofenig 0:796d0f61a05b 2896 }
HannesTschofenig 0:796d0f61a05b 2897 #endif
HannesTschofenig 0:796d0f61a05b 2898
HannesTschofenig 0:796d0f61a05b 2899 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2900 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 2901 static void ssl_update_checksum_sha256( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 2902 const unsigned char *buf, size_t len )
HannesTschofenig 0:796d0f61a05b 2903 {
HannesTschofenig 0:796d0f61a05b 2904 sha256_update( &ssl->handshake->fin_sha256, buf, len );
HannesTschofenig 0:796d0f61a05b 2905 }
HannesTschofenig 0:796d0f61a05b 2906 #endif
HannesTschofenig 0:796d0f61a05b 2907
HannesTschofenig 0:796d0f61a05b 2908 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 2909 static void ssl_update_checksum_sha384( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 2910 const unsigned char *buf, size_t len )
HannesTschofenig 0:796d0f61a05b 2911 {
HannesTschofenig 0:796d0f61a05b 2912 sha512_update( &ssl->handshake->fin_sha512, buf, len );
HannesTschofenig 0:796d0f61a05b 2913 }
HannesTschofenig 0:796d0f61a05b 2914 #endif
HannesTschofenig 0:796d0f61a05b 2915 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 2916
HannesTschofenig 0:796d0f61a05b 2917 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 2918 static void ssl_calc_finished_ssl(
HannesTschofenig 0:796d0f61a05b 2919 ssl_context *ssl, unsigned char *buf, int from )
HannesTschofenig 0:796d0f61a05b 2920 {
HannesTschofenig 0:796d0f61a05b 2921 const char *sender;
HannesTschofenig 0:796d0f61a05b 2922 md5_context md5;
HannesTschofenig 0:796d0f61a05b 2923 sha1_context sha1;
HannesTschofenig 0:796d0f61a05b 2924
HannesTschofenig 0:796d0f61a05b 2925 unsigned char padbuf[48];
HannesTschofenig 0:796d0f61a05b 2926 unsigned char md5sum[16];
HannesTschofenig 0:796d0f61a05b 2927 unsigned char sha1sum[20];
HannesTschofenig 0:796d0f61a05b 2928
HannesTschofenig 0:796d0f61a05b 2929 ssl_session *session = ssl->session_negotiate;
HannesTschofenig 0:796d0f61a05b 2930 if( !session )
HannesTschofenig 0:796d0f61a05b 2931 session = ssl->session;
HannesTschofenig 0:796d0f61a05b 2932
HannesTschofenig 0:796d0f61a05b 2933 SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) );
HannesTschofenig 0:796d0f61a05b 2934
HannesTschofenig 0:796d0f61a05b 2935 memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) );
HannesTschofenig 0:796d0f61a05b 2936 memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) );
HannesTschofenig 0:796d0f61a05b 2937
HannesTschofenig 0:796d0f61a05b 2938 /*
HannesTschofenig 0:796d0f61a05b 2939 * SSLv3:
HannesTschofenig 0:796d0f61a05b 2940 * hash =
HannesTschofenig 0:796d0f61a05b 2941 * MD5( master + pad2 +
HannesTschofenig 0:796d0f61a05b 2942 * MD5( handshake + sender + master + pad1 ) )
HannesTschofenig 0:796d0f61a05b 2943 * + SHA1( master + pad2 +
HannesTschofenig 0:796d0f61a05b 2944 * SHA1( handshake + sender + master + pad1 ) )
HannesTschofenig 0:796d0f61a05b 2945 */
HannesTschofenig 0:796d0f61a05b 2946
HannesTschofenig 0:796d0f61a05b 2947 #if !defined(POLARSSL_MD5_ALT)
HannesTschofenig 0:796d0f61a05b 2948 SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
HannesTschofenig 0:796d0f61a05b 2949 md5.state, sizeof( md5.state ) );
HannesTschofenig 0:796d0f61a05b 2950 #endif
HannesTschofenig 0:796d0f61a05b 2951
HannesTschofenig 0:796d0f61a05b 2952 #if !defined(POLARSSL_SHA1_ALT)
HannesTschofenig 0:796d0f61a05b 2953 SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
HannesTschofenig 0:796d0f61a05b 2954 sha1.state, sizeof( sha1.state ) );
HannesTschofenig 0:796d0f61a05b 2955 #endif
HannesTschofenig 0:796d0f61a05b 2956
HannesTschofenig 0:796d0f61a05b 2957 sender = ( from == SSL_IS_CLIENT ) ? "CLNT"
HannesTschofenig 0:796d0f61a05b 2958 : "SRVR";
HannesTschofenig 0:796d0f61a05b 2959
HannesTschofenig 0:796d0f61a05b 2960 memset( padbuf, 0x36, 48 );
HannesTschofenig 0:796d0f61a05b 2961
HannesTschofenig 0:796d0f61a05b 2962 md5_update( &md5, (const unsigned char *) sender, 4 );
HannesTschofenig 0:796d0f61a05b 2963 md5_update( &md5, session->master, 48 );
HannesTschofenig 0:796d0f61a05b 2964 md5_update( &md5, padbuf, 48 );
HannesTschofenig 0:796d0f61a05b 2965 md5_finish( &md5, md5sum );
HannesTschofenig 0:796d0f61a05b 2966
HannesTschofenig 0:796d0f61a05b 2967 sha1_update( &sha1, (const unsigned char *) sender, 4 );
HannesTschofenig 0:796d0f61a05b 2968 sha1_update( &sha1, session->master, 48 );
HannesTschofenig 0:796d0f61a05b 2969 sha1_update( &sha1, padbuf, 40 );
HannesTschofenig 0:796d0f61a05b 2970 sha1_finish( &sha1, sha1sum );
HannesTschofenig 0:796d0f61a05b 2971
HannesTschofenig 0:796d0f61a05b 2972 memset( padbuf, 0x5C, 48 );
HannesTschofenig 0:796d0f61a05b 2973
HannesTschofenig 0:796d0f61a05b 2974 md5_starts( &md5 );
HannesTschofenig 0:796d0f61a05b 2975 md5_update( &md5, session->master, 48 );
HannesTschofenig 0:796d0f61a05b 2976 md5_update( &md5, padbuf, 48 );
HannesTschofenig 0:796d0f61a05b 2977 md5_update( &md5, md5sum, 16 );
HannesTschofenig 0:796d0f61a05b 2978 md5_finish( &md5, buf );
HannesTschofenig 0:796d0f61a05b 2979
HannesTschofenig 0:796d0f61a05b 2980 sha1_starts( &sha1 );
HannesTschofenig 0:796d0f61a05b 2981 sha1_update( &sha1, session->master, 48 );
HannesTschofenig 0:796d0f61a05b 2982 sha1_update( &sha1, padbuf , 40 );
HannesTschofenig 0:796d0f61a05b 2983 sha1_update( &sha1, sha1sum, 20 );
HannesTschofenig 0:796d0f61a05b 2984 sha1_finish( &sha1, buf + 16 );
HannesTschofenig 0:796d0f61a05b 2985
HannesTschofenig 0:796d0f61a05b 2986 SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
HannesTschofenig 0:796d0f61a05b 2987
HannesTschofenig 0:796d0f61a05b 2988 memset( &md5, 0, sizeof( md5_context ) );
HannesTschofenig 0:796d0f61a05b 2989 memset( &sha1, 0, sizeof( sha1_context ) );
HannesTschofenig 0:796d0f61a05b 2990
HannesTschofenig 0:796d0f61a05b 2991 memset( padbuf, 0, sizeof( padbuf ) );
HannesTschofenig 0:796d0f61a05b 2992 memset( md5sum, 0, sizeof( md5sum ) );
HannesTschofenig 0:796d0f61a05b 2993 memset( sha1sum, 0, sizeof( sha1sum ) );
HannesTschofenig 0:796d0f61a05b 2994
HannesTschofenig 0:796d0f61a05b 2995 SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
HannesTschofenig 0:796d0f61a05b 2996 }
HannesTschofenig 0:796d0f61a05b 2997 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 2998
HannesTschofenig 0:796d0f61a05b 2999 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 3000 static void ssl_calc_finished_tls(
HannesTschofenig 0:796d0f61a05b 3001 ssl_context *ssl, unsigned char *buf, int from )
HannesTschofenig 0:796d0f61a05b 3002 {
HannesTschofenig 0:796d0f61a05b 3003 int len = 12;
HannesTschofenig 0:796d0f61a05b 3004 const char *sender;
HannesTschofenig 0:796d0f61a05b 3005 md5_context md5;
HannesTschofenig 0:796d0f61a05b 3006 sha1_context sha1;
HannesTschofenig 0:796d0f61a05b 3007 unsigned char padbuf[36];
HannesTschofenig 0:796d0f61a05b 3008
HannesTschofenig 0:796d0f61a05b 3009 ssl_session *session = ssl->session_negotiate;
HannesTschofenig 0:796d0f61a05b 3010 if( !session )
HannesTschofenig 0:796d0f61a05b 3011 session = ssl->session;
HannesTschofenig 0:796d0f61a05b 3012
HannesTschofenig 0:796d0f61a05b 3013 SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) );
HannesTschofenig 0:796d0f61a05b 3014
HannesTschofenig 0:796d0f61a05b 3015 memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) );
HannesTschofenig 0:796d0f61a05b 3016 memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) );
HannesTschofenig 0:796d0f61a05b 3017
HannesTschofenig 0:796d0f61a05b 3018 /*
HannesTschofenig 0:796d0f61a05b 3019 * TLSv1:
HannesTschofenig 0:796d0f61a05b 3020 * hash = PRF( master, finished_label,
HannesTschofenig 0:796d0f61a05b 3021 * MD5( handshake ) + SHA1( handshake ) )[0..11]
HannesTschofenig 0:796d0f61a05b 3022 */
HannesTschofenig 0:796d0f61a05b 3023
HannesTschofenig 0:796d0f61a05b 3024 #if !defined(POLARSSL_MD5_ALT)
HannesTschofenig 0:796d0f61a05b 3025 SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
HannesTschofenig 0:796d0f61a05b 3026 md5.state, sizeof( md5.state ) );
HannesTschofenig 0:796d0f61a05b 3027 #endif
HannesTschofenig 0:796d0f61a05b 3028
HannesTschofenig 0:796d0f61a05b 3029 #if !defined(POLARSSL_SHA1_ALT)
HannesTschofenig 0:796d0f61a05b 3030 SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
HannesTschofenig 0:796d0f61a05b 3031 sha1.state, sizeof( sha1.state ) );
HannesTschofenig 0:796d0f61a05b 3032 #endif
HannesTschofenig 0:796d0f61a05b 3033
HannesTschofenig 0:796d0f61a05b 3034 sender = ( from == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 3035 ? "client finished"
HannesTschofenig 0:796d0f61a05b 3036 : "server finished";
HannesTschofenig 0:796d0f61a05b 3037
HannesTschofenig 0:796d0f61a05b 3038 md5_finish( &md5, padbuf );
HannesTschofenig 0:796d0f61a05b 3039 sha1_finish( &sha1, padbuf + 16 );
HannesTschofenig 0:796d0f61a05b 3040
HannesTschofenig 0:796d0f61a05b 3041 ssl->handshake->tls_prf( session->master, 48, sender,
HannesTschofenig 0:796d0f61a05b 3042 padbuf, 36, buf, len );
HannesTschofenig 0:796d0f61a05b 3043
HannesTschofenig 0:796d0f61a05b 3044 SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
HannesTschofenig 0:796d0f61a05b 3045
HannesTschofenig 0:796d0f61a05b 3046 memset( &md5, 0, sizeof( md5_context ) );
HannesTschofenig 0:796d0f61a05b 3047 memset( &sha1, 0, sizeof( sha1_context ) );
HannesTschofenig 0:796d0f61a05b 3048
HannesTschofenig 0:796d0f61a05b 3049 memset( padbuf, 0, sizeof( padbuf ) );
HannesTschofenig 0:796d0f61a05b 3050
HannesTschofenig 0:796d0f61a05b 3051 SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
HannesTschofenig 0:796d0f61a05b 3052 }
HannesTschofenig 0:796d0f61a05b 3053 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */
HannesTschofenig 0:796d0f61a05b 3054
HannesTschofenig 0:796d0f61a05b 3055 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 3056 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 3057 static void ssl_calc_finished_tls_sha256(
HannesTschofenig 0:796d0f61a05b 3058 ssl_context *ssl, unsigned char *buf, int from )
HannesTschofenig 0:796d0f61a05b 3059 {
HannesTschofenig 0:796d0f61a05b 3060 int len = 12;
HannesTschofenig 0:796d0f61a05b 3061 const char *sender;
HannesTschofenig 0:796d0f61a05b 3062 sha256_context sha256;
HannesTschofenig 0:796d0f61a05b 3063 unsigned char padbuf[32];
HannesTschofenig 0:796d0f61a05b 3064
HannesTschofenig 0:796d0f61a05b 3065 ssl_session *session = ssl->session_negotiate;
HannesTschofenig 0:796d0f61a05b 3066 if( !session )
HannesTschofenig 0:796d0f61a05b 3067 session = ssl->session;
HannesTschofenig 0:796d0f61a05b 3068
HannesTschofenig 0:796d0f61a05b 3069 SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) );
HannesTschofenig 0:796d0f61a05b 3070
HannesTschofenig 0:796d0f61a05b 3071 memcpy( &sha256, &ssl->handshake->fin_sha256, sizeof(sha256_context) );
HannesTschofenig 0:796d0f61a05b 3072
HannesTschofenig 0:796d0f61a05b 3073 /*
HannesTschofenig 0:796d0f61a05b 3074 * TLSv1.2:
HannesTschofenig 0:796d0f61a05b 3075 * hash = PRF( master, finished_label,
HannesTschofenig 0:796d0f61a05b 3076 * Hash( handshake ) )[0.11]
HannesTschofenig 0:796d0f61a05b 3077 */
HannesTschofenig 0:796d0f61a05b 3078
HannesTschofenig 0:796d0f61a05b 3079 #if !defined(POLARSSL_SHA256_ALT)
HannesTschofenig 0:796d0f61a05b 3080 SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
HannesTschofenig 0:796d0f61a05b 3081 sha256.state, sizeof( sha256.state ) );
HannesTschofenig 0:796d0f61a05b 3082 #endif
HannesTschofenig 0:796d0f61a05b 3083
HannesTschofenig 0:796d0f61a05b 3084 sender = ( from == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 3085 ? "client finished"
HannesTschofenig 0:796d0f61a05b 3086 : "server finished";
HannesTschofenig 0:796d0f61a05b 3087
HannesTschofenig 0:796d0f61a05b 3088 sha256_finish( &sha256, padbuf );
HannesTschofenig 0:796d0f61a05b 3089
HannesTschofenig 0:796d0f61a05b 3090 ssl->handshake->tls_prf( session->master, 48, sender,
HannesTschofenig 0:796d0f61a05b 3091 padbuf, 32, buf, len );
HannesTschofenig 0:796d0f61a05b 3092
HannesTschofenig 0:796d0f61a05b 3093 SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
HannesTschofenig 0:796d0f61a05b 3094
HannesTschofenig 0:796d0f61a05b 3095 memset( &sha256, 0, sizeof( sha256_context ) );
HannesTschofenig 0:796d0f61a05b 3096
HannesTschofenig 0:796d0f61a05b 3097 memset( padbuf, 0, sizeof( padbuf ) );
HannesTschofenig 0:796d0f61a05b 3098
HannesTschofenig 0:796d0f61a05b 3099 SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
HannesTschofenig 0:796d0f61a05b 3100 }
HannesTschofenig 0:796d0f61a05b 3101 #endif /* POLARSSL_SHA256_C */
HannesTschofenig 0:796d0f61a05b 3102
HannesTschofenig 0:796d0f61a05b 3103 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 3104 static void ssl_calc_finished_tls_sha384(
HannesTschofenig 0:796d0f61a05b 3105 ssl_context *ssl, unsigned char *buf, int from )
HannesTschofenig 0:796d0f61a05b 3106 {
HannesTschofenig 0:796d0f61a05b 3107 int len = 12;
HannesTschofenig 0:796d0f61a05b 3108 const char *sender;
HannesTschofenig 0:796d0f61a05b 3109 sha512_context sha512;
HannesTschofenig 0:796d0f61a05b 3110 unsigned char padbuf[48];
HannesTschofenig 0:796d0f61a05b 3111
HannesTschofenig 0:796d0f61a05b 3112 ssl_session *session = ssl->session_negotiate;
HannesTschofenig 0:796d0f61a05b 3113 if( !session )
HannesTschofenig 0:796d0f61a05b 3114 session = ssl->session;
HannesTschofenig 0:796d0f61a05b 3115
HannesTschofenig 0:796d0f61a05b 3116 SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) );
HannesTschofenig 0:796d0f61a05b 3117
HannesTschofenig 0:796d0f61a05b 3118 memcpy( &sha512, &ssl->handshake->fin_sha512, sizeof(sha512_context) );
HannesTschofenig 0:796d0f61a05b 3119
HannesTschofenig 0:796d0f61a05b 3120 /*
HannesTschofenig 0:796d0f61a05b 3121 * TLSv1.2:
HannesTschofenig 0:796d0f61a05b 3122 * hash = PRF( master, finished_label,
HannesTschofenig 0:796d0f61a05b 3123 * Hash( handshake ) )[0.11]
HannesTschofenig 0:796d0f61a05b 3124 */
HannesTschofenig 0:796d0f61a05b 3125
HannesTschofenig 0:796d0f61a05b 3126 #if !defined(POLARSSL_SHA512_ALT)
HannesTschofenig 0:796d0f61a05b 3127 SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
HannesTschofenig 0:796d0f61a05b 3128 sha512.state, sizeof( sha512.state ) );
HannesTschofenig 0:796d0f61a05b 3129 #endif
HannesTschofenig 0:796d0f61a05b 3130
HannesTschofenig 0:796d0f61a05b 3131 sender = ( from == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 3132 ? "client finished"
HannesTschofenig 0:796d0f61a05b 3133 : "server finished";
HannesTschofenig 0:796d0f61a05b 3134
HannesTschofenig 0:796d0f61a05b 3135 sha512_finish( &sha512, padbuf );
HannesTschofenig 0:796d0f61a05b 3136
HannesTschofenig 0:796d0f61a05b 3137 ssl->handshake->tls_prf( session->master, 48, sender,
HannesTschofenig 0:796d0f61a05b 3138 padbuf, 48, buf, len );
HannesTschofenig 0:796d0f61a05b 3139
HannesTschofenig 0:796d0f61a05b 3140 SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
HannesTschofenig 0:796d0f61a05b 3141
HannesTschofenig 0:796d0f61a05b 3142 memset( &sha512, 0, sizeof( sha512_context ) );
HannesTschofenig 0:796d0f61a05b 3143
HannesTschofenig 0:796d0f61a05b 3144 memset( padbuf, 0, sizeof( padbuf ) );
HannesTschofenig 0:796d0f61a05b 3145
HannesTschofenig 0:796d0f61a05b 3146 SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
HannesTschofenig 0:796d0f61a05b 3147 }
HannesTschofenig 0:796d0f61a05b 3148 #endif /* POLARSSL_SHA512_C */
HannesTschofenig 0:796d0f61a05b 3149 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 3150
HannesTschofenig 0:796d0f61a05b 3151 void ssl_handshake_wrapup( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3152 {
HannesTschofenig 0:796d0f61a05b 3153 int resume = ssl->handshake->resume;
HannesTschofenig 0:796d0f61a05b 3154
HannesTschofenig 0:796d0f61a05b 3155 SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
HannesTschofenig 0:796d0f61a05b 3156
HannesTschofenig 0:796d0f61a05b 3157 /*
HannesTschofenig 0:796d0f61a05b 3158 * Free our handshake params
HannesTschofenig 0:796d0f61a05b 3159 */
HannesTschofenig 0:796d0f61a05b 3160 ssl_handshake_free( ssl->handshake );
HannesTschofenig 0:796d0f61a05b 3161 polarssl_free( ssl->handshake );
HannesTschofenig 0:796d0f61a05b 3162 ssl->handshake = NULL;
HannesTschofenig 0:796d0f61a05b 3163
HannesTschofenig 0:796d0f61a05b 3164 if( ssl->renegotiation == SSL_RENEGOTIATION )
HannesTschofenig 0:796d0f61a05b 3165 ssl->renegotiation = SSL_RENEGOTIATION_DONE;
HannesTschofenig 0:796d0f61a05b 3166
HannesTschofenig 0:796d0f61a05b 3167 /*
HannesTschofenig 0:796d0f61a05b 3168 * Switch in our now active transform context
HannesTschofenig 0:796d0f61a05b 3169 */
HannesTschofenig 0:796d0f61a05b 3170 if( ssl->transform )
HannesTschofenig 0:796d0f61a05b 3171 {
HannesTschofenig 0:796d0f61a05b 3172 ssl_transform_free( ssl->transform );
HannesTschofenig 0:796d0f61a05b 3173 polarssl_free( ssl->transform );
HannesTschofenig 0:796d0f61a05b 3174 }
HannesTschofenig 0:796d0f61a05b 3175 ssl->transform = ssl->transform_negotiate;
HannesTschofenig 0:796d0f61a05b 3176 ssl->transform_negotiate = NULL;
HannesTschofenig 0:796d0f61a05b 3177
HannesTschofenig 0:796d0f61a05b 3178 if( ssl->session )
HannesTschofenig 0:796d0f61a05b 3179 {
HannesTschofenig 0:796d0f61a05b 3180 ssl_session_free( ssl->session );
HannesTschofenig 0:796d0f61a05b 3181 polarssl_free( ssl->session );
HannesTschofenig 0:796d0f61a05b 3182 }
HannesTschofenig 0:796d0f61a05b 3183 ssl->session = ssl->session_negotiate;
HannesTschofenig 0:796d0f61a05b 3184 ssl->session_negotiate = NULL;
HannesTschofenig 0:796d0f61a05b 3185
HannesTschofenig 0:796d0f61a05b 3186 /*
HannesTschofenig 0:796d0f61a05b 3187 * Add cache entry
HannesTschofenig 0:796d0f61a05b 3188 */
HannesTschofenig 0:796d0f61a05b 3189 if( ssl->f_set_cache != NULL &&
HannesTschofenig 0:796d0f61a05b 3190 ssl->session->length != 0 &&
HannesTschofenig 0:796d0f61a05b 3191 resume == 0 )
HannesTschofenig 0:796d0f61a05b 3192 {
HannesTschofenig 0:796d0f61a05b 3193 if( ssl->f_set_cache( ssl->p_set_cache, ssl->session ) != 0 )
HannesTschofenig 0:796d0f61a05b 3194 SSL_DEBUG_MSG( 1, ( "cache did not store session" ) );
HannesTschofenig 0:796d0f61a05b 3195 }
HannesTschofenig 0:796d0f61a05b 3196
HannesTschofenig 0:796d0f61a05b 3197 ssl->state++;
HannesTschofenig 0:796d0f61a05b 3198
HannesTschofenig 0:796d0f61a05b 3199 SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
HannesTschofenig 0:796d0f61a05b 3200 }
HannesTschofenig 0:796d0f61a05b 3201
HannesTschofenig 0:796d0f61a05b 3202 int ssl_write_finished( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3203 {
HannesTschofenig 0:796d0f61a05b 3204 int ret, hash_len;
HannesTschofenig 0:796d0f61a05b 3205
HannesTschofenig 0:796d0f61a05b 3206 SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
HannesTschofenig 0:796d0f61a05b 3207
HannesTschofenig 0:796d0f61a05b 3208 /*
HannesTschofenig 0:796d0f61a05b 3209 * Set the out_msg pointer to the correct location based on IV length
HannesTschofenig 0:796d0f61a05b 3210 */
HannesTschofenig 0:796d0f61a05b 3211 if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
HannesTschofenig 0:796d0f61a05b 3212 {
HannesTschofenig 0:796d0f61a05b 3213 ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen -
HannesTschofenig 0:796d0f61a05b 3214 ssl->transform_negotiate->fixed_ivlen;
HannesTschofenig 0:796d0f61a05b 3215 }
HannesTschofenig 0:796d0f61a05b 3216 else
HannesTschofenig 0:796d0f61a05b 3217 ssl->out_msg = ssl->out_iv;
HannesTschofenig 0:796d0f61a05b 3218
HannesTschofenig 0:796d0f61a05b 3219 ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->endpoint );
HannesTschofenig 0:796d0f61a05b 3220
HannesTschofenig 0:796d0f61a05b 3221 // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
HannesTschofenig 0:796d0f61a05b 3222 hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12;
HannesTschofenig 0:796d0f61a05b 3223
HannesTschofenig 0:796d0f61a05b 3224 ssl->verify_data_len = hash_len;
HannesTschofenig 0:796d0f61a05b 3225 memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
HannesTschofenig 0:796d0f61a05b 3226
HannesTschofenig 0:796d0f61a05b 3227 ssl->out_msglen = 4 + hash_len;
HannesTschofenig 0:796d0f61a05b 3228 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 3229 ssl->out_msg[0] = SSL_HS_FINISHED;
HannesTschofenig 0:796d0f61a05b 3230
HannesTschofenig 0:796d0f61a05b 3231 /*
HannesTschofenig 0:796d0f61a05b 3232 * In case of session resuming, invert the client and server
HannesTschofenig 0:796d0f61a05b 3233 * ChangeCipherSpec messages order.
HannesTschofenig 0:796d0f61a05b 3234 */
HannesTschofenig 0:796d0f61a05b 3235 if( ssl->handshake->resume != 0 )
HannesTschofenig 0:796d0f61a05b 3236 {
HannesTschofenig 0:796d0f61a05b 3237 if( ssl->endpoint == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 3238 ssl->state = SSL_HANDSHAKE_WRAPUP;
HannesTschofenig 0:796d0f61a05b 3239 else
HannesTschofenig 0:796d0f61a05b 3240 ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC;
HannesTschofenig 0:796d0f61a05b 3241 }
HannesTschofenig 0:796d0f61a05b 3242 else
HannesTschofenig 0:796d0f61a05b 3243 ssl->state++;
HannesTschofenig 0:796d0f61a05b 3244
HannesTschofenig 0:796d0f61a05b 3245 /*
HannesTschofenig 0:796d0f61a05b 3246 * Switch to our negotiated transform and session parameters for outbound
HannesTschofenig 0:796d0f61a05b 3247 * data.
HannesTschofenig 0:796d0f61a05b 3248 */
HannesTschofenig 0:796d0f61a05b 3249 SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
HannesTschofenig 0:796d0f61a05b 3250 ssl->transform_out = ssl->transform_negotiate;
HannesTschofenig 0:796d0f61a05b 3251 ssl->session_out = ssl->session_negotiate;
HannesTschofenig 0:796d0f61a05b 3252 memset( ssl->out_ctr, 0, 8 );
HannesTschofenig 0:796d0f61a05b 3253
HannesTschofenig 0:796d0f61a05b 3254 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
HannesTschofenig 0:796d0f61a05b 3255 if( ssl_hw_record_activate != NULL)
HannesTschofenig 0:796d0f61a05b 3256 {
HannesTschofenig 0:796d0f61a05b 3257 if( ( ret = ssl_hw_record_activate( ssl, SSL_CHANNEL_OUTBOUND ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3258 {
HannesTschofenig 0:796d0f61a05b 3259 SSL_DEBUG_RET( 1, "ssl_hw_record_activate", ret );
HannesTschofenig 0:796d0f61a05b 3260 return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED );
HannesTschofenig 0:796d0f61a05b 3261 }
HannesTschofenig 0:796d0f61a05b 3262 }
HannesTschofenig 0:796d0f61a05b 3263 #endif
HannesTschofenig 0:796d0f61a05b 3264
HannesTschofenig 0:796d0f61a05b 3265 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3266 {
HannesTschofenig 0:796d0f61a05b 3267 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 3268 return( ret );
HannesTschofenig 0:796d0f61a05b 3269 }
HannesTschofenig 0:796d0f61a05b 3270
HannesTschofenig 0:796d0f61a05b 3271 SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
HannesTschofenig 0:796d0f61a05b 3272
HannesTschofenig 0:796d0f61a05b 3273 return( 0 );
HannesTschofenig 0:796d0f61a05b 3274 }
HannesTschofenig 0:796d0f61a05b 3275
HannesTschofenig 0:796d0f61a05b 3276 int ssl_parse_finished( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3277 {
HannesTschofenig 0:796d0f61a05b 3278 int ret;
HannesTschofenig 0:796d0f61a05b 3279 unsigned int hash_len;
HannesTschofenig 0:796d0f61a05b 3280 unsigned char buf[36];
HannesTschofenig 0:796d0f61a05b 3281
HannesTschofenig 0:796d0f61a05b 3282 SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
HannesTschofenig 0:796d0f61a05b 3283
HannesTschofenig 0:796d0f61a05b 3284 ssl->handshake->calc_finished( ssl, buf, ssl->endpoint ^ 1 );
HannesTschofenig 0:796d0f61a05b 3285
HannesTschofenig 0:796d0f61a05b 3286 /*
HannesTschofenig 0:796d0f61a05b 3287 * Switch to our negotiated transform and session parameters for inbound
HannesTschofenig 0:796d0f61a05b 3288 * data.
HannesTschofenig 0:796d0f61a05b 3289 */
HannesTschofenig 0:796d0f61a05b 3290 SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
HannesTschofenig 0:796d0f61a05b 3291 ssl->transform_in = ssl->transform_negotiate;
HannesTschofenig 0:796d0f61a05b 3292 ssl->session_in = ssl->session_negotiate;
HannesTschofenig 0:796d0f61a05b 3293 memset( ssl->in_ctr, 0, 8 );
HannesTschofenig 0:796d0f61a05b 3294
HannesTschofenig 0:796d0f61a05b 3295 /*
HannesTschofenig 0:796d0f61a05b 3296 * Set the in_msg pointer to the correct location based on IV length
HannesTschofenig 0:796d0f61a05b 3297 */
HannesTschofenig 0:796d0f61a05b 3298 if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
HannesTschofenig 0:796d0f61a05b 3299 {
HannesTschofenig 0:796d0f61a05b 3300 ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen -
HannesTschofenig 0:796d0f61a05b 3301 ssl->transform_negotiate->fixed_ivlen;
HannesTschofenig 0:796d0f61a05b 3302 }
HannesTschofenig 0:796d0f61a05b 3303 else
HannesTschofenig 0:796d0f61a05b 3304 ssl->in_msg = ssl->in_iv;
HannesTschofenig 0:796d0f61a05b 3305
HannesTschofenig 0:796d0f61a05b 3306 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
HannesTschofenig 0:796d0f61a05b 3307 if( ssl_hw_record_activate != NULL)
HannesTschofenig 0:796d0f61a05b 3308 {
HannesTschofenig 0:796d0f61a05b 3309 if( ( ret = ssl_hw_record_activate( ssl, SSL_CHANNEL_INBOUND ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3310 {
HannesTschofenig 0:796d0f61a05b 3311 SSL_DEBUG_RET( 1, "ssl_hw_record_activate", ret );
HannesTschofenig 0:796d0f61a05b 3312 return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED );
HannesTschofenig 0:796d0f61a05b 3313 }
HannesTschofenig 0:796d0f61a05b 3314 }
HannesTschofenig 0:796d0f61a05b 3315 #endif
HannesTschofenig 0:796d0f61a05b 3316
HannesTschofenig 0:796d0f61a05b 3317 if( ( ret = ssl_read_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3318 {
HannesTschofenig 0:796d0f61a05b 3319 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
HannesTschofenig 0:796d0f61a05b 3320 return( ret );
HannesTschofenig 0:796d0f61a05b 3321 }
HannesTschofenig 0:796d0f61a05b 3322
HannesTschofenig 0:796d0f61a05b 3323 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 3324 {
HannesTschofenig 0:796d0f61a05b 3325 SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
HannesTschofenig 0:796d0f61a05b 3326 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
HannesTschofenig 0:796d0f61a05b 3327 }
HannesTschofenig 0:796d0f61a05b 3328
HannesTschofenig 0:796d0f61a05b 3329 // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
HannesTschofenig 0:796d0f61a05b 3330 hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12;
HannesTschofenig 0:796d0f61a05b 3331
HannesTschofenig 0:796d0f61a05b 3332 if( ssl->in_msg[0] != SSL_HS_FINISHED ||
HannesTschofenig 0:796d0f61a05b 3333 ssl->in_hslen != 4 + hash_len )
HannesTschofenig 0:796d0f61a05b 3334 {
HannesTschofenig 0:796d0f61a05b 3335 SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
HannesTschofenig 0:796d0f61a05b 3336 return( POLARSSL_ERR_SSL_BAD_HS_FINISHED );
HannesTschofenig 0:796d0f61a05b 3337 }
HannesTschofenig 0:796d0f61a05b 3338
HannesTschofenig 0:796d0f61a05b 3339 if( safer_memcmp( ssl->in_msg + 4, buf, hash_len ) != 0 )
HannesTschofenig 0:796d0f61a05b 3340 {
HannesTschofenig 0:796d0f61a05b 3341 SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
HannesTschofenig 0:796d0f61a05b 3342 return( POLARSSL_ERR_SSL_BAD_HS_FINISHED );
HannesTschofenig 0:796d0f61a05b 3343 }
HannesTschofenig 0:796d0f61a05b 3344
HannesTschofenig 0:796d0f61a05b 3345 ssl->verify_data_len = hash_len;
HannesTschofenig 0:796d0f61a05b 3346 memcpy( ssl->peer_verify_data, buf, hash_len );
HannesTschofenig 0:796d0f61a05b 3347
HannesTschofenig 0:796d0f61a05b 3348 if( ssl->handshake->resume != 0 )
HannesTschofenig 0:796d0f61a05b 3349 {
HannesTschofenig 0:796d0f61a05b 3350 if( ssl->endpoint == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 3351 ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC;
HannesTschofenig 0:796d0f61a05b 3352
HannesTschofenig 0:796d0f61a05b 3353 if( ssl->endpoint == SSL_IS_SERVER )
HannesTschofenig 0:796d0f61a05b 3354 ssl->state = SSL_HANDSHAKE_WRAPUP;
HannesTschofenig 0:796d0f61a05b 3355 }
HannesTschofenig 0:796d0f61a05b 3356 else
HannesTschofenig 0:796d0f61a05b 3357 ssl->state++;
HannesTschofenig 0:796d0f61a05b 3358
HannesTschofenig 0:796d0f61a05b 3359 SSL_DEBUG_MSG( 2, ( "<= parse finished" ) );
HannesTschofenig 0:796d0f61a05b 3360
HannesTschofenig 0:796d0f61a05b 3361 return( 0 );
HannesTschofenig 0:796d0f61a05b 3362 }
HannesTschofenig 0:796d0f61a05b 3363
HannesTschofenig 0:796d0f61a05b 3364 static int ssl_handshake_init( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3365 {
HannesTschofenig 0:796d0f61a05b 3366 if( ssl->transform_negotiate )
HannesTschofenig 0:796d0f61a05b 3367 ssl_transform_free( ssl->transform_negotiate );
HannesTschofenig 0:796d0f61a05b 3368 else
HannesTschofenig 0:796d0f61a05b 3369 {
HannesTschofenig 0:796d0f61a05b 3370 ssl->transform_negotiate =
HannesTschofenig 0:796d0f61a05b 3371 (ssl_transform *) polarssl_malloc( sizeof(ssl_transform) );
HannesTschofenig 0:796d0f61a05b 3372
HannesTschofenig 0:796d0f61a05b 3373 if( ssl->transform_negotiate != NULL )
HannesTschofenig 0:796d0f61a05b 3374 memset( ssl->transform_negotiate, 0, sizeof(ssl_transform) );
HannesTschofenig 0:796d0f61a05b 3375 }
HannesTschofenig 0:796d0f61a05b 3376
HannesTschofenig 0:796d0f61a05b 3377 if( ssl->session_negotiate )
HannesTschofenig 0:796d0f61a05b 3378 ssl_session_free( ssl->session_negotiate );
HannesTschofenig 0:796d0f61a05b 3379 else
HannesTschofenig 0:796d0f61a05b 3380 {
HannesTschofenig 0:796d0f61a05b 3381 ssl->session_negotiate =
HannesTschofenig 0:796d0f61a05b 3382 (ssl_session *) polarssl_malloc( sizeof(ssl_session) );
HannesTschofenig 0:796d0f61a05b 3383
HannesTschofenig 0:796d0f61a05b 3384 if( ssl->session_negotiate != NULL )
HannesTschofenig 0:796d0f61a05b 3385 memset( ssl->session_negotiate, 0, sizeof(ssl_session) );
HannesTschofenig 0:796d0f61a05b 3386 }
HannesTschofenig 0:796d0f61a05b 3387
HannesTschofenig 0:796d0f61a05b 3388 if( ssl->handshake )
HannesTschofenig 0:796d0f61a05b 3389 ssl_handshake_free( ssl->handshake );
HannesTschofenig 0:796d0f61a05b 3390 else
HannesTschofenig 0:796d0f61a05b 3391 {
HannesTschofenig 0:796d0f61a05b 3392 ssl->handshake = (ssl_handshake_params *)
HannesTschofenig 0:796d0f61a05b 3393 polarssl_malloc( sizeof(ssl_handshake_params) );
HannesTschofenig 0:796d0f61a05b 3394
HannesTschofenig 0:796d0f61a05b 3395 if( ssl->handshake != NULL )
HannesTschofenig 0:796d0f61a05b 3396 memset( ssl->handshake, 0, sizeof(ssl_handshake_params) );
HannesTschofenig 0:796d0f61a05b 3397 }
HannesTschofenig 0:796d0f61a05b 3398
HannesTschofenig 0:796d0f61a05b 3399 if( ssl->handshake == NULL ||
HannesTschofenig 0:796d0f61a05b 3400 ssl->transform_negotiate == NULL ||
HannesTschofenig 0:796d0f61a05b 3401 ssl->session_negotiate == NULL )
HannesTschofenig 0:796d0f61a05b 3402 {
HannesTschofenig 0:796d0f61a05b 3403 SSL_DEBUG_MSG( 1, ( "malloc() of ssl sub-contexts failed" ) );
HannesTschofenig 0:796d0f61a05b 3404 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3405 }
HannesTschofenig 0:796d0f61a05b 3406
HannesTschofenig 0:796d0f61a05b 3407 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
HannesTschofenig 0:796d0f61a05b 3408 defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 3409 md5_starts( &ssl->handshake->fin_md5 );
HannesTschofenig 0:796d0f61a05b 3410 sha1_starts( &ssl->handshake->fin_sha1 );
HannesTschofenig 0:796d0f61a05b 3411 #endif
HannesTschofenig 0:796d0f61a05b 3412 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 3413 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 3414 sha256_starts( &ssl->handshake->fin_sha256, 0 );
HannesTschofenig 0:796d0f61a05b 3415 #endif
HannesTschofenig 0:796d0f61a05b 3416 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 3417 sha512_starts( &ssl->handshake->fin_sha512, 1 );
HannesTschofenig 0:796d0f61a05b 3418 #endif
HannesTschofenig 0:796d0f61a05b 3419 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 3420
HannesTschofenig 0:796d0f61a05b 3421 ssl->handshake->update_checksum = ssl_update_checksum_start;
HannesTschofenig 0:796d0f61a05b 3422 ssl->handshake->sig_alg = SSL_HASH_SHA1;
HannesTschofenig 0:796d0f61a05b 3423
HannesTschofenig 0:796d0f61a05b 3424 #if defined(POLARSSL_ECDH_C)
HannesTschofenig 0:796d0f61a05b 3425 ecdh_init( &ssl->handshake->ecdh_ctx );
HannesTschofenig 0:796d0f61a05b 3426 #endif
HannesTschofenig 0:796d0f61a05b 3427
HannesTschofenig 0:796d0f61a05b 3428 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 3429 ssl->handshake->key_cert = ssl->key_cert;
HannesTschofenig 0:796d0f61a05b 3430 #endif
HannesTschofenig 0:796d0f61a05b 3431
HannesTschofenig 0:796d0f61a05b 3432 return( 0 );
HannesTschofenig 0:796d0f61a05b 3433 }
HannesTschofenig 0:796d0f61a05b 3434
HannesTschofenig 0:796d0f61a05b 3435 /*
HannesTschofenig 0:796d0f61a05b 3436 * Initialize an SSL context
HannesTschofenig 0:796d0f61a05b 3437 */
HannesTschofenig 0:796d0f61a05b 3438 int ssl_init( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3439 {
HannesTschofenig 0:796d0f61a05b 3440 int ret;
HannesTschofenig 0:796d0f61a05b 3441 int len = SSL_BUFFER_LEN;
HannesTschofenig 0:796d0f61a05b 3442
HannesTschofenig 0:796d0f61a05b 3443 void *sptr1 = ssl->f_dbg;
HannesTschofenig 0:796d0f61a05b 3444 void *sptr2 = ssl->f_rng;
HannesTschofenig 0:796d0f61a05b 3445
HannesTschofenig 0:796d0f61a05b 3446 // SSL_DEBUG_MSG( 1, ( "ssl_init" ) );
HannesTschofenig 0:796d0f61a05b 3447 memset( ssl, 0, sizeof( ssl_context ) );
HannesTschofenig 0:796d0f61a05b 3448
HannesTschofenig 0:796d0f61a05b 3449 ssl->f_dbg = sptr1;
HannesTschofenig 0:796d0f61a05b 3450 ssl->f_rng = sptr2;
HannesTschofenig 0:796d0f61a05b 3451
HannesTschofenig 0:796d0f61a05b 3452 /*
HannesTschofenig 0:796d0f61a05b 3453 * Sane defaults
HannesTschofenig 0:796d0f61a05b 3454 */
HannesTschofenig 0:796d0f61a05b 3455 ssl->min_major_ver = SSL_MIN_MAJOR_VERSION;
HannesTschofenig 0:796d0f61a05b 3456 ssl->min_minor_ver = SSL_MIN_MINOR_VERSION;
HannesTschofenig 0:796d0f61a05b 3457 ssl->max_major_ver = SSL_MAX_MAJOR_VERSION;
HannesTschofenig 0:796d0f61a05b 3458 ssl->max_minor_ver = SSL_MAX_MINOR_VERSION;
HannesTschofenig 0:796d0f61a05b 3459
HannesTschofenig 0:796d0f61a05b 3460 ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() );
HannesTschofenig 0:796d0f61a05b 3461
HannesTschofenig 0:796d0f61a05b 3462 #if defined(POLARSSL_DHM_C)
HannesTschofenig 0:796d0f61a05b 3463 if( ( ret = mpi_read_string( &ssl->dhm_P, 16,
HannesTschofenig 0:796d0f61a05b 3464 POLARSSL_DHM_RFC5114_MODP_1024_P) ) != 0 ||
HannesTschofenig 0:796d0f61a05b 3465 ( ret = mpi_read_string( &ssl->dhm_G, 16,
HannesTschofenig 0:796d0f61a05b 3466 POLARSSL_DHM_RFC5114_MODP_1024_G) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3467 {
HannesTschofenig 0:796d0f61a05b 3468 SSL_DEBUG_RET( 1, "mpi_read_string", ret );
HannesTschofenig 0:796d0f61a05b 3469 return( ret );
HannesTschofenig 0:796d0f61a05b 3470 }
HannesTschofenig 0:796d0f61a05b 3471 #endif
HannesTschofenig 0:796d0f61a05b 3472
HannesTschofenig 0:796d0f61a05b 3473 /*
HannesTschofenig 0:796d0f61a05b 3474 * Prepare base structures
HannesTschofenig 0:796d0f61a05b 3475 */
HannesTschofenig 0:796d0f61a05b 3476 ssl->in_ctr = (unsigned char *) polarssl_malloc( len );
HannesTschofenig 0:796d0f61a05b 3477 ssl->in_hdr = ssl->in_ctr + 8;
HannesTschofenig 0:796d0f61a05b 3478 ssl->in_iv = ssl->in_ctr + 13;
HannesTschofenig 0:796d0f61a05b 3479 ssl->in_msg = ssl->in_ctr + 13;
HannesTschofenig 0:796d0f61a05b 3480
HannesTschofenig 0:796d0f61a05b 3481 if( ssl->in_ctr == NULL )
HannesTschofenig 0:796d0f61a05b 3482 {
HannesTschofenig 0:796d0f61a05b 3483 SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) );
HannesTschofenig 0:796d0f61a05b 3484 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3485 }
HannesTschofenig 0:796d0f61a05b 3486
HannesTschofenig 0:796d0f61a05b 3487 ssl->out_ctr = (unsigned char *) polarssl_malloc( len );
HannesTschofenig 0:796d0f61a05b 3488 ssl->out_hdr = ssl->out_ctr + 8;
HannesTschofenig 0:796d0f61a05b 3489 ssl->out_iv = ssl->out_ctr + 13;
HannesTschofenig 0:796d0f61a05b 3490 ssl->out_msg = ssl->out_ctr + 13;
HannesTschofenig 0:796d0f61a05b 3491
HannesTschofenig 0:796d0f61a05b 3492 if( ssl->out_ctr == NULL )
HannesTschofenig 0:796d0f61a05b 3493 {
HannesTschofenig 0:796d0f61a05b 3494 SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) );
HannesTschofenig 0:796d0f61a05b 3495 polarssl_free( ssl->in_ctr );
HannesTschofenig 0:796d0f61a05b 3496 ssl->in_ctr = NULL;
HannesTschofenig 0:796d0f61a05b 3497 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3498 }
HannesTschofenig 0:796d0f61a05b 3499
HannesTschofenig 0:796d0f61a05b 3500 memset( ssl-> in_ctr, 0, SSL_BUFFER_LEN );
HannesTschofenig 0:796d0f61a05b 3501 memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
HannesTschofenig 0:796d0f61a05b 3502
HannesTschofenig 0:796d0f61a05b 3503 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 3504 ssl->ticket_lifetime = SSL_DEFAULT_TICKET_LIFETIME;
HannesTschofenig 0:796d0f61a05b 3505 #endif
HannesTschofenig 0:796d0f61a05b 3506
HannesTschofenig 0:796d0f61a05b 3507 #if defined(POLARSSL_SSL_SET_CURVES)
HannesTschofenig 0:796d0f61a05b 3508 ssl->curve_list = ecp_grp_id_list( );
HannesTschofenig 0:796d0f61a05b 3509 #endif
HannesTschofenig 0:796d0f61a05b 3510
HannesTschofenig 0:796d0f61a05b 3511 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3512 return( ret );
HannesTschofenig 0:796d0f61a05b 3513
HannesTschofenig 0:796d0f61a05b 3514 return( 0 );
HannesTschofenig 0:796d0f61a05b 3515 }
HannesTschofenig 0:796d0f61a05b 3516
HannesTschofenig 0:796d0f61a05b 3517 /*
HannesTschofenig 0:796d0f61a05b 3518 * Reset an initialized and used SSL context for re-use while retaining
HannesTschofenig 0:796d0f61a05b 3519 * all application-set variables, function pointers and data.
HannesTschofenig 0:796d0f61a05b 3520 */
HannesTschofenig 0:796d0f61a05b 3521 int ssl_session_reset( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3522 {
HannesTschofenig 0:796d0f61a05b 3523 int ret;
HannesTschofenig 0:796d0f61a05b 3524
HannesTschofenig 0:796d0f61a05b 3525 ssl->state = SSL_HELLO_REQUEST;
HannesTschofenig 0:796d0f61a05b 3526 ssl->renegotiation = SSL_INITIAL_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 3527 ssl->secure_renegotiation = SSL_LEGACY_RENEGOTIATION;
HannesTschofenig 0:796d0f61a05b 3528
HannesTschofenig 0:796d0f61a05b 3529 ssl->verify_data_len = 0;
HannesTschofenig 0:796d0f61a05b 3530 memset( ssl->own_verify_data, 0, 36 );
HannesTschofenig 0:796d0f61a05b 3531 memset( ssl->peer_verify_data, 0, 36 );
HannesTschofenig 0:796d0f61a05b 3532
HannesTschofenig 0:796d0f61a05b 3533 ssl->in_offt = NULL;
HannesTschofenig 0:796d0f61a05b 3534
HannesTschofenig 0:796d0f61a05b 3535 ssl->in_msg = ssl->in_ctr + 13;
HannesTschofenig 0:796d0f61a05b 3536 ssl->in_msgtype = 0;
HannesTschofenig 0:796d0f61a05b 3537 ssl->in_msglen = 0;
HannesTschofenig 0:796d0f61a05b 3538 ssl->in_left = 0;
HannesTschofenig 0:796d0f61a05b 3539
HannesTschofenig 0:796d0f61a05b 3540 ssl->in_hslen = 0;
HannesTschofenig 0:796d0f61a05b 3541 ssl->nb_zero = 0;
HannesTschofenig 0:796d0f61a05b 3542 ssl->record_read = 0;
HannesTschofenig 0:796d0f61a05b 3543
HannesTschofenig 0:796d0f61a05b 3544 ssl->out_msg = ssl->out_ctr + 13;
HannesTschofenig 0:796d0f61a05b 3545 ssl->out_msgtype = 0;
HannesTschofenig 0:796d0f61a05b 3546 ssl->out_msglen = 0;
HannesTschofenig 0:796d0f61a05b 3547 ssl->out_left = 0;
HannesTschofenig 0:796d0f61a05b 3548
HannesTschofenig 0:796d0f61a05b 3549 ssl->transform_in = NULL;
HannesTschofenig 0:796d0f61a05b 3550 ssl->transform_out = NULL;
HannesTschofenig 0:796d0f61a05b 3551
HannesTschofenig 0:796d0f61a05b 3552 memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
HannesTschofenig 0:796d0f61a05b 3553 memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
HannesTschofenig 0:796d0f61a05b 3554
HannesTschofenig 0:796d0f61a05b 3555 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
HannesTschofenig 0:796d0f61a05b 3556 if( ssl_hw_record_reset != NULL)
HannesTschofenig 0:796d0f61a05b 3557 {
HannesTschofenig 0:796d0f61a05b 3558 SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_reset()" ) );
HannesTschofenig 0:796d0f61a05b 3559 if( ( ret = ssl_hw_record_reset( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3560 {
HannesTschofenig 0:796d0f61a05b 3561 SSL_DEBUG_RET( 1, "ssl_hw_record_reset", ret );
HannesTschofenig 0:796d0f61a05b 3562 return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED );
HannesTschofenig 0:796d0f61a05b 3563 }
HannesTschofenig 0:796d0f61a05b 3564 }
HannesTschofenig 0:796d0f61a05b 3565 #endif
HannesTschofenig 0:796d0f61a05b 3566
HannesTschofenig 0:796d0f61a05b 3567 if( ssl->transform )
HannesTschofenig 0:796d0f61a05b 3568 {
HannesTschofenig 0:796d0f61a05b 3569 ssl_transform_free( ssl->transform );
HannesTschofenig 0:796d0f61a05b 3570 polarssl_free( ssl->transform );
HannesTschofenig 0:796d0f61a05b 3571 ssl->transform = NULL;
HannesTschofenig 0:796d0f61a05b 3572 }
HannesTschofenig 0:796d0f61a05b 3573
HannesTschofenig 0:796d0f61a05b 3574 if( ssl->session )
HannesTschofenig 0:796d0f61a05b 3575 {
HannesTschofenig 0:796d0f61a05b 3576 ssl_session_free( ssl->session );
HannesTschofenig 0:796d0f61a05b 3577 polarssl_free( ssl->session );
HannesTschofenig 0:796d0f61a05b 3578 ssl->session = NULL;
HannesTschofenig 0:796d0f61a05b 3579 }
HannesTschofenig 0:796d0f61a05b 3580
HannesTschofenig 0:796d0f61a05b 3581 #if defined(POLARSSL_SSL_ALPN)
HannesTschofenig 0:796d0f61a05b 3582 ssl->alpn_chosen = NULL;
HannesTschofenig 0:796d0f61a05b 3583 #endif
HannesTschofenig 0:796d0f61a05b 3584
HannesTschofenig 0:796d0f61a05b 3585 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3586 return( ret );
HannesTschofenig 0:796d0f61a05b 3587
HannesTschofenig 0:796d0f61a05b 3588 return( 0 );
HannesTschofenig 0:796d0f61a05b 3589 }
HannesTschofenig 0:796d0f61a05b 3590
HannesTschofenig 0:796d0f61a05b 3591 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 3592 /*
HannesTschofenig 0:796d0f61a05b 3593 * Allocate and initialize ticket keys
HannesTschofenig 0:796d0f61a05b 3594 */
HannesTschofenig 0:796d0f61a05b 3595 static int ssl_ticket_keys_init( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3596 {
HannesTschofenig 0:796d0f61a05b 3597 int ret;
HannesTschofenig 0:796d0f61a05b 3598 ssl_ticket_keys *tkeys;
HannesTschofenig 0:796d0f61a05b 3599 unsigned char buf[16];
HannesTschofenig 0:796d0f61a05b 3600
HannesTschofenig 0:796d0f61a05b 3601 if( ssl->ticket_keys != NULL )
HannesTschofenig 0:796d0f61a05b 3602 return( 0 );
HannesTschofenig 0:796d0f61a05b 3603
HannesTschofenig 0:796d0f61a05b 3604 tkeys = (ssl_ticket_keys *) polarssl_malloc( sizeof(ssl_ticket_keys) );
HannesTschofenig 0:796d0f61a05b 3605 if( tkeys == NULL )
HannesTschofenig 0:796d0f61a05b 3606 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3607
HannesTschofenig 0:796d0f61a05b 3608 if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->key_name, 16 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3609 {
HannesTschofenig 0:796d0f61a05b 3610 polarssl_free( tkeys );
HannesTschofenig 0:796d0f61a05b 3611 return( ret );
HannesTschofenig 0:796d0f61a05b 3612 }
HannesTschofenig 0:796d0f61a05b 3613
HannesTschofenig 0:796d0f61a05b 3614 if( ( ret = ssl->f_rng( ssl->p_rng, buf, 16 ) ) != 0 ||
HannesTschofenig 0:796d0f61a05b 3615 ( ret = aes_setkey_enc( &tkeys->enc, buf, 128 ) ) != 0 ||
HannesTschofenig 0:796d0f61a05b 3616 ( ret = aes_setkey_dec( &tkeys->dec, buf, 128 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3617 {
HannesTschofenig 0:796d0f61a05b 3618 polarssl_free( tkeys );
HannesTschofenig 0:796d0f61a05b 3619 return( ret );
HannesTschofenig 0:796d0f61a05b 3620 }
HannesTschofenig 0:796d0f61a05b 3621
HannesTschofenig 0:796d0f61a05b 3622 if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->mac_key, 16 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3623 {
HannesTschofenig 0:796d0f61a05b 3624 polarssl_free( tkeys );
HannesTschofenig 0:796d0f61a05b 3625 return( ret );
HannesTschofenig 0:796d0f61a05b 3626 }
HannesTschofenig 0:796d0f61a05b 3627
HannesTschofenig 0:796d0f61a05b 3628 ssl->ticket_keys = tkeys;
HannesTschofenig 0:796d0f61a05b 3629
HannesTschofenig 0:796d0f61a05b 3630 return( 0 );
HannesTschofenig 0:796d0f61a05b 3631 }
HannesTschofenig 0:796d0f61a05b 3632 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 3633
HannesTschofenig 0:796d0f61a05b 3634 /*
HannesTschofenig 0:796d0f61a05b 3635 * SSL set accessors
HannesTschofenig 0:796d0f61a05b 3636 */
HannesTschofenig 0:796d0f61a05b 3637 void ssl_set_endpoint( ssl_context *ssl, int endpoint )
HannesTschofenig 0:796d0f61a05b 3638 {
HannesTschofenig 0:796d0f61a05b 3639 ssl->endpoint = endpoint;
HannesTschofenig 0:796d0f61a05b 3640
HannesTschofenig 0:796d0f61a05b 3641 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 3642 if( endpoint == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 3643 ssl->session_tickets = SSL_SESSION_TICKETS_ENABLED;
HannesTschofenig 0:796d0f61a05b 3644 #endif
HannesTschofenig 0:796d0f61a05b 3645 }
HannesTschofenig 0:796d0f61a05b 3646
HannesTschofenig 0:796d0f61a05b 3647 void ssl_set_authmode( ssl_context *ssl, int authmode )
HannesTschofenig 0:796d0f61a05b 3648 {
HannesTschofenig 0:796d0f61a05b 3649 ssl->authmode = authmode;
HannesTschofenig 0:796d0f61a05b 3650 }
HannesTschofenig 0:796d0f61a05b 3651
HannesTschofenig 0:796d0f61a05b 3652 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 3653 void ssl_set_verify( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 3654 int (*f_vrfy)(void *, x509_crt *, int, int *),
HannesTschofenig 0:796d0f61a05b 3655 void *p_vrfy )
HannesTschofenig 0:796d0f61a05b 3656 {
HannesTschofenig 0:796d0f61a05b 3657 ssl->f_vrfy = f_vrfy;
HannesTschofenig 0:796d0f61a05b 3658 ssl->p_vrfy = p_vrfy;
HannesTschofenig 0:796d0f61a05b 3659 }
HannesTschofenig 0:796d0f61a05b 3660 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 3661
HannesTschofenig 0:796d0f61a05b 3662 void ssl_set_rng( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 3663 int (*f_rng)(void *, unsigned char *, size_t),
HannesTschofenig 0:796d0f61a05b 3664 void *p_rng )
HannesTschofenig 0:796d0f61a05b 3665 {
HannesTschofenig 0:796d0f61a05b 3666 ssl->f_rng = f_rng;
HannesTschofenig 0:796d0f61a05b 3667 ssl->p_rng = p_rng;
HannesTschofenig 0:796d0f61a05b 3668 }
HannesTschofenig 0:796d0f61a05b 3669
HannesTschofenig 0:796d0f61a05b 3670 void ssl_set_dbg( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 3671 void (*f_dbg)(void *, int, const char *),
HannesTschofenig 0:796d0f61a05b 3672 void *p_dbg )
HannesTschofenig 0:796d0f61a05b 3673 {
HannesTschofenig 0:796d0f61a05b 3674 ssl->f_dbg = f_dbg;
HannesTschofenig 0:796d0f61a05b 3675 ssl->p_dbg = p_dbg;
HannesTschofenig 0:796d0f61a05b 3676 }
HannesTschofenig 0:796d0f61a05b 3677
HannesTschofenig 0:796d0f61a05b 3678 void ssl_set_bio( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 3679 int (*f_recv)(void *, unsigned char *, size_t), void *p_recv,
HannesTschofenig 0:796d0f61a05b 3680 int (*f_send)(void *, const unsigned char *, size_t), void *p_send )
HannesTschofenig 0:796d0f61a05b 3681 {
HannesTschofenig 0:796d0f61a05b 3682 ssl->f_recv = f_recv;
HannesTschofenig 0:796d0f61a05b 3683 ssl->f_send = f_send;
HannesTschofenig 0:796d0f61a05b 3684 ssl->p_recv = p_recv;
HannesTschofenig 0:796d0f61a05b 3685 ssl->p_send = p_send;
HannesTschofenig 0:796d0f61a05b 3686 }
HannesTschofenig 0:796d0f61a05b 3687
HannesTschofenig 0:796d0f61a05b 3688 void ssl_set_session_cache( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 3689 int (*f_get_cache)(void *, ssl_session *), void *p_get_cache,
HannesTschofenig 0:796d0f61a05b 3690 int (*f_set_cache)(void *, const ssl_session *), void *p_set_cache )
HannesTschofenig 0:796d0f61a05b 3691 {
HannesTschofenig 0:796d0f61a05b 3692 ssl->f_get_cache = f_get_cache;
HannesTschofenig 0:796d0f61a05b 3693 ssl->p_get_cache = p_get_cache;
HannesTschofenig 0:796d0f61a05b 3694 ssl->f_set_cache = f_set_cache;
HannesTschofenig 0:796d0f61a05b 3695 ssl->p_set_cache = p_set_cache;
HannesTschofenig 0:796d0f61a05b 3696 }
HannesTschofenig 0:796d0f61a05b 3697
HannesTschofenig 0:796d0f61a05b 3698 int ssl_set_session( ssl_context *ssl, const ssl_session *session )
HannesTschofenig 0:796d0f61a05b 3699 {
HannesTschofenig 0:796d0f61a05b 3700 int ret;
HannesTschofenig 0:796d0f61a05b 3701
HannesTschofenig 0:796d0f61a05b 3702 if( ssl == NULL ||
HannesTschofenig 0:796d0f61a05b 3703 session == NULL ||
HannesTschofenig 0:796d0f61a05b 3704 ssl->session_negotiate == NULL ||
HannesTschofenig 0:796d0f61a05b 3705 ssl->endpoint != SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 3706 {
HannesTschofenig 0:796d0f61a05b 3707 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 3708 }
HannesTschofenig 0:796d0f61a05b 3709
HannesTschofenig 0:796d0f61a05b 3710 if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3711 return( ret );
HannesTschofenig 0:796d0f61a05b 3712
HannesTschofenig 0:796d0f61a05b 3713 ssl->handshake->resume = 1;
HannesTschofenig 0:796d0f61a05b 3714
HannesTschofenig 0:796d0f61a05b 3715 return( 0 );
HannesTschofenig 0:796d0f61a05b 3716 }
HannesTschofenig 0:796d0f61a05b 3717
HannesTschofenig 0:796d0f61a05b 3718 void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites )
HannesTschofenig 0:796d0f61a05b 3719 {
HannesTschofenig 0:796d0f61a05b 3720 ssl->ciphersuite_list[SSL_MINOR_VERSION_0] = ciphersuites;
HannesTschofenig 0:796d0f61a05b 3721 ssl->ciphersuite_list[SSL_MINOR_VERSION_1] = ciphersuites;
HannesTschofenig 0:796d0f61a05b 3722 ssl->ciphersuite_list[SSL_MINOR_VERSION_2] = ciphersuites;
HannesTschofenig 0:796d0f61a05b 3723 ssl->ciphersuite_list[SSL_MINOR_VERSION_3] = ciphersuites;
HannesTschofenig 0:796d0f61a05b 3724 }
HannesTschofenig 0:796d0f61a05b 3725
HannesTschofenig 0:796d0f61a05b 3726 void ssl_set_ciphersuites_for_version( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 3727 const int *ciphersuites,
HannesTschofenig 0:796d0f61a05b 3728 int major, int minor )
HannesTschofenig 0:796d0f61a05b 3729 {
HannesTschofenig 0:796d0f61a05b 3730 if( major != SSL_MAJOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 3731 return;
HannesTschofenig 0:796d0f61a05b 3732
HannesTschofenig 0:796d0f61a05b 3733 if( minor < SSL_MINOR_VERSION_0 || minor > SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 3734 return;
HannesTschofenig 0:796d0f61a05b 3735
HannesTschofenig 0:796d0f61a05b 3736 ssl->ciphersuite_list[minor] = ciphersuites;
HannesTschofenig 0:796d0f61a05b 3737 }
HannesTschofenig 0:796d0f61a05b 3738
HannesTschofenig 0:796d0f61a05b 3739 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 3740 /* Add a new (empty) key_cert entry an return a pointer to it */
HannesTschofenig 0:796d0f61a05b 3741 static ssl_key_cert *ssl_add_key_cert( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3742 {
HannesTschofenig 0:796d0f61a05b 3743 ssl_key_cert *key_cert, *last;
HannesTschofenig 0:796d0f61a05b 3744
HannesTschofenig 0:796d0f61a05b 3745 key_cert = (ssl_key_cert *) polarssl_malloc( sizeof(ssl_key_cert) );
HannesTschofenig 0:796d0f61a05b 3746 if( key_cert == NULL )
HannesTschofenig 0:796d0f61a05b 3747 return( NULL );
HannesTschofenig 0:796d0f61a05b 3748
HannesTschofenig 0:796d0f61a05b 3749 memset( key_cert, 0, sizeof( ssl_key_cert ) );
HannesTschofenig 0:796d0f61a05b 3750
HannesTschofenig 0:796d0f61a05b 3751 /* Append the new key_cert to the (possibly empty) current list */
HannesTschofenig 0:796d0f61a05b 3752 if( ssl->key_cert == NULL )
HannesTschofenig 0:796d0f61a05b 3753 {
HannesTschofenig 0:796d0f61a05b 3754 ssl->key_cert = key_cert;
HannesTschofenig 0:796d0f61a05b 3755 if( ssl->handshake != NULL )
HannesTschofenig 0:796d0f61a05b 3756 ssl->handshake->key_cert = key_cert;
HannesTschofenig 0:796d0f61a05b 3757 }
HannesTschofenig 0:796d0f61a05b 3758 else
HannesTschofenig 0:796d0f61a05b 3759 {
HannesTschofenig 0:796d0f61a05b 3760 last = ssl->key_cert;
HannesTschofenig 0:796d0f61a05b 3761 while( last->next != NULL )
HannesTschofenig 0:796d0f61a05b 3762 last = last->next;
HannesTschofenig 0:796d0f61a05b 3763 last->next = key_cert;
HannesTschofenig 0:796d0f61a05b 3764 }
HannesTschofenig 0:796d0f61a05b 3765
HannesTschofenig 0:796d0f61a05b 3766 return key_cert;
HannesTschofenig 0:796d0f61a05b 3767 }
HannesTschofenig 0:796d0f61a05b 3768
HannesTschofenig 0:796d0f61a05b 3769 void ssl_set_ca_chain( ssl_context *ssl, x509_crt *ca_chain,
HannesTschofenig 0:796d0f61a05b 3770 x509_crl *ca_crl, const char *peer_cn )
HannesTschofenig 0:796d0f61a05b 3771 {
HannesTschofenig 0:796d0f61a05b 3772 ssl->ca_chain = ca_chain;
HannesTschofenig 0:796d0f61a05b 3773 ssl->ca_crl = ca_crl;
HannesTschofenig 0:796d0f61a05b 3774 ssl->peer_cn = peer_cn;
HannesTschofenig 0:796d0f61a05b 3775 }
HannesTschofenig 0:796d0f61a05b 3776
HannesTschofenig 0:796d0f61a05b 3777 int ssl_set_own_cert( ssl_context *ssl, x509_crt *own_cert,
HannesTschofenig 0:796d0f61a05b 3778 pk_context *pk_key )
HannesTschofenig 0:796d0f61a05b 3779 {
HannesTschofenig 0:796d0f61a05b 3780 ssl_key_cert *key_cert = ssl_add_key_cert( ssl );
HannesTschofenig 0:796d0f61a05b 3781
HannesTschofenig 0:796d0f61a05b 3782 if( key_cert == NULL )
HannesTschofenig 0:796d0f61a05b 3783 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3784
HannesTschofenig 0:796d0f61a05b 3785 key_cert->cert = own_cert;
HannesTschofenig 0:796d0f61a05b 3786 key_cert->key = pk_key;
HannesTschofenig 0:796d0f61a05b 3787
HannesTschofenig 0:796d0f61a05b 3788 return( 0 );
HannesTschofenig 0:796d0f61a05b 3789 }
HannesTschofenig 0:796d0f61a05b 3790
HannesTschofenig 0:796d0f61a05b 3791 #if defined(POLARSSL_RSA_C)
HannesTschofenig 0:796d0f61a05b 3792 int ssl_set_own_cert_rsa( ssl_context *ssl, x509_crt *own_cert,
HannesTschofenig 0:796d0f61a05b 3793 rsa_context *rsa_key )
HannesTschofenig 0:796d0f61a05b 3794 {
HannesTschofenig 0:796d0f61a05b 3795 int ret;
HannesTschofenig 0:796d0f61a05b 3796 ssl_key_cert *key_cert = ssl_add_key_cert( ssl );
HannesTschofenig 0:796d0f61a05b 3797
HannesTschofenig 0:796d0f61a05b 3798 if( key_cert == NULL )
HannesTschofenig 0:796d0f61a05b 3799 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3800
HannesTschofenig 0:796d0f61a05b 3801 key_cert->key = (pk_context *) polarssl_malloc( sizeof(pk_context) );
HannesTschofenig 0:796d0f61a05b 3802 if( key_cert->key == NULL )
HannesTschofenig 0:796d0f61a05b 3803 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3804
HannesTschofenig 0:796d0f61a05b 3805 pk_init( key_cert->key );
HannesTschofenig 0:796d0f61a05b 3806
HannesTschofenig 0:796d0f61a05b 3807 ret = pk_init_ctx( key_cert->key, pk_info_from_type( POLARSSL_PK_RSA ) );
HannesTschofenig 0:796d0f61a05b 3808 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 3809 return( ret );
HannesTschofenig 0:796d0f61a05b 3810
HannesTschofenig 0:796d0f61a05b 3811 if( ( ret = rsa_copy( pk_rsa( *key_cert->key ), rsa_key ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3812 return( ret );
HannesTschofenig 0:796d0f61a05b 3813
HannesTschofenig 0:796d0f61a05b 3814 key_cert->cert = own_cert;
HannesTschofenig 0:796d0f61a05b 3815 key_cert->key_own_alloc = 1;
HannesTschofenig 0:796d0f61a05b 3816
HannesTschofenig 0:796d0f61a05b 3817 return( 0 );
HannesTschofenig 0:796d0f61a05b 3818 }
HannesTschofenig 0:796d0f61a05b 3819 #endif /* POLARSSL_RSA_C */
HannesTschofenig 0:796d0f61a05b 3820
HannesTschofenig 0:796d0f61a05b 3821 int ssl_set_own_cert_alt( ssl_context *ssl, x509_crt *own_cert,
HannesTschofenig 0:796d0f61a05b 3822 void *rsa_key,
HannesTschofenig 0:796d0f61a05b 3823 rsa_decrypt_func rsa_decrypt,
HannesTschofenig 0:796d0f61a05b 3824 rsa_sign_func rsa_sign,
HannesTschofenig 0:796d0f61a05b 3825 rsa_key_len_func rsa_key_len )
HannesTschofenig 0:796d0f61a05b 3826 {
HannesTschofenig 0:796d0f61a05b 3827 int ret;
HannesTschofenig 0:796d0f61a05b 3828 ssl_key_cert *key_cert = ssl_add_key_cert( ssl );
HannesTschofenig 0:796d0f61a05b 3829
HannesTschofenig 0:796d0f61a05b 3830 if( key_cert == NULL )
HannesTschofenig 0:796d0f61a05b 3831 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3832
HannesTschofenig 0:796d0f61a05b 3833 key_cert->key = (pk_context *) polarssl_malloc( sizeof(pk_context) );
HannesTschofenig 0:796d0f61a05b 3834 if( key_cert->key == NULL )
HannesTschofenig 0:796d0f61a05b 3835 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3836
HannesTschofenig 0:796d0f61a05b 3837 pk_init( key_cert->key );
HannesTschofenig 0:796d0f61a05b 3838
HannesTschofenig 0:796d0f61a05b 3839 if( ( ret = pk_init_ctx_rsa_alt( key_cert->key, rsa_key,
HannesTschofenig 0:796d0f61a05b 3840 rsa_decrypt, rsa_sign, rsa_key_len ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3841 return( ret );
HannesTschofenig 0:796d0f61a05b 3842
HannesTschofenig 0:796d0f61a05b 3843 key_cert->cert = own_cert;
HannesTschofenig 0:796d0f61a05b 3844 key_cert->key_own_alloc = 1;
HannesTschofenig 0:796d0f61a05b 3845
HannesTschofenig 0:796d0f61a05b 3846 return( 0 );
HannesTschofenig 0:796d0f61a05b 3847 }
HannesTschofenig 0:796d0f61a05b 3848 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 3849
HannesTschofenig 0:796d0f61a05b 3850 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 3851 int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
HannesTschofenig 0:796d0f61a05b 3852 const unsigned char *psk_identity, size_t psk_identity_len )
HannesTschofenig 0:796d0f61a05b 3853 {
HannesTschofenig 0:796d0f61a05b 3854 if( psk == NULL || psk_identity == NULL )
HannesTschofenig 0:796d0f61a05b 3855 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 3856
HannesTschofenig 0:796d0f61a05b 3857 /*
HannesTschofenig 0:796d0f61a05b 3858 * The length will be check later anyway, but in case it is obviously
HannesTschofenig 0:796d0f61a05b 3859 * too large, better abort now. The PMS is as follows:
HannesTschofenig 0:796d0f61a05b 3860 * other_len (2 bytes) + other + psk_len (2 bytes) + psk
HannesTschofenig 0:796d0f61a05b 3861 */
HannesTschofenig 0:796d0f61a05b 3862 if( psk_len + 4 > POLARSSL_PREMASTER_SIZE )
HannesTschofenig 0:796d0f61a05b 3863 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 3864
HannesTschofenig 0:796d0f61a05b 3865 if( ssl->psk != NULL )
HannesTschofenig 0:796d0f61a05b 3866 {
HannesTschofenig 0:796d0f61a05b 3867 polarssl_free( ssl->psk );
HannesTschofenig 0:796d0f61a05b 3868 polarssl_free( ssl->psk_identity );
HannesTschofenig 0:796d0f61a05b 3869 }
HannesTschofenig 0:796d0f61a05b 3870
HannesTschofenig 0:796d0f61a05b 3871 ssl->psk_len = psk_len;
HannesTschofenig 0:796d0f61a05b 3872 ssl->psk_identity_len = psk_identity_len;
HannesTschofenig 0:796d0f61a05b 3873
HannesTschofenig 0:796d0f61a05b 3874 ssl->psk = (unsigned char *) polarssl_malloc( ssl->psk_len );
HannesTschofenig 0:796d0f61a05b 3875 ssl->psk_identity = (unsigned char *)
HannesTschofenig 0:796d0f61a05b 3876 polarssl_malloc( ssl->psk_identity_len );
HannesTschofenig 0:796d0f61a05b 3877
HannesTschofenig 0:796d0f61a05b 3878 if( ssl->psk == NULL || ssl->psk_identity == NULL )
HannesTschofenig 0:796d0f61a05b 3879 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3880
HannesTschofenig 0:796d0f61a05b 3881 memcpy( ssl->psk, psk, ssl->psk_len );
HannesTschofenig 0:796d0f61a05b 3882 memcpy( ssl->psk_identity, psk_identity, ssl->psk_identity_len );
HannesTschofenig 0:796d0f61a05b 3883
HannesTschofenig 0:796d0f61a05b 3884 return( 0 );
HannesTschofenig 0:796d0f61a05b 3885 }
HannesTschofenig 0:796d0f61a05b 3886
HannesTschofenig 0:796d0f61a05b 3887 void ssl_set_psk_cb( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 3888 int (*f_psk)(void *, ssl_context *, const unsigned char *,
HannesTschofenig 0:796d0f61a05b 3889 size_t),
HannesTschofenig 0:796d0f61a05b 3890 void *p_psk )
HannesTschofenig 0:796d0f61a05b 3891 {
HannesTschofenig 0:796d0f61a05b 3892 ssl->f_psk = f_psk;
HannesTschofenig 0:796d0f61a05b 3893 ssl->p_psk = p_psk;
HannesTschofenig 0:796d0f61a05b 3894 }
HannesTschofenig 0:796d0f61a05b 3895 #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 3896
HannesTschofenig 0:796d0f61a05b 3897 #if defined(POLARSSL_DHM_C)
HannesTschofenig 0:796d0f61a05b 3898 int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G )
HannesTschofenig 0:796d0f61a05b 3899 {
HannesTschofenig 0:796d0f61a05b 3900 int ret;
HannesTschofenig 0:796d0f61a05b 3901
HannesTschofenig 0:796d0f61a05b 3902 if( ( ret = mpi_read_string( &ssl->dhm_P, 16, dhm_P ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3903 {
HannesTschofenig 0:796d0f61a05b 3904 SSL_DEBUG_RET( 1, "mpi_read_string", ret );
HannesTschofenig 0:796d0f61a05b 3905 return( ret );
HannesTschofenig 0:796d0f61a05b 3906 }
HannesTschofenig 0:796d0f61a05b 3907
HannesTschofenig 0:796d0f61a05b 3908 if( ( ret = mpi_read_string( &ssl->dhm_G, 16, dhm_G ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3909 {
HannesTschofenig 0:796d0f61a05b 3910 SSL_DEBUG_RET( 1, "mpi_read_string", ret );
HannesTschofenig 0:796d0f61a05b 3911 return( ret );
HannesTschofenig 0:796d0f61a05b 3912 }
HannesTschofenig 0:796d0f61a05b 3913
HannesTschofenig 0:796d0f61a05b 3914 return( 0 );
HannesTschofenig 0:796d0f61a05b 3915 }
HannesTschofenig 0:796d0f61a05b 3916
HannesTschofenig 0:796d0f61a05b 3917 int ssl_set_dh_param_ctx( ssl_context *ssl, dhm_context *dhm_ctx )
HannesTschofenig 0:796d0f61a05b 3918 {
HannesTschofenig 0:796d0f61a05b 3919 int ret;
HannesTschofenig 0:796d0f61a05b 3920
HannesTschofenig 0:796d0f61a05b 3921 if( ( ret = mpi_copy(&ssl->dhm_P, &dhm_ctx->P) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3922 {
HannesTschofenig 0:796d0f61a05b 3923 SSL_DEBUG_RET( 1, "mpi_copy", ret );
HannesTschofenig 0:796d0f61a05b 3924 return( ret );
HannesTschofenig 0:796d0f61a05b 3925 }
HannesTschofenig 0:796d0f61a05b 3926
HannesTschofenig 0:796d0f61a05b 3927 if( ( ret = mpi_copy(&ssl->dhm_G, &dhm_ctx->G) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3928 {
HannesTschofenig 0:796d0f61a05b 3929 SSL_DEBUG_RET( 1, "mpi_copy", ret );
HannesTschofenig 0:796d0f61a05b 3930 return( ret );
HannesTschofenig 0:796d0f61a05b 3931 }
HannesTschofenig 0:796d0f61a05b 3932
HannesTschofenig 0:796d0f61a05b 3933 return( 0 );
HannesTschofenig 0:796d0f61a05b 3934 }
HannesTschofenig 0:796d0f61a05b 3935 #endif /* POLARSSL_DHM_C */
HannesTschofenig 0:796d0f61a05b 3936
HannesTschofenig 0:796d0f61a05b 3937 #if defined(POLARSSL_SSL_SET_CURVES)
HannesTschofenig 0:796d0f61a05b 3938 /*
HannesTschofenig 0:796d0f61a05b 3939 * Set the allowed elliptic curves
HannesTschofenig 0:796d0f61a05b 3940 */
HannesTschofenig 0:796d0f61a05b 3941 void ssl_set_curves( ssl_context *ssl, const ecp_group_id *curve_list )
HannesTschofenig 0:796d0f61a05b 3942 {
HannesTschofenig 0:796d0f61a05b 3943 ssl->curve_list = curve_list;
HannesTschofenig 0:796d0f61a05b 3944 }
HannesTschofenig 0:796d0f61a05b 3945 #endif
HannesTschofenig 0:796d0f61a05b 3946
HannesTschofenig 0:796d0f61a05b 3947 #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
HannesTschofenig 0:796d0f61a05b 3948 int ssl_set_hostname( ssl_context *ssl, const char *hostname )
HannesTschofenig 0:796d0f61a05b 3949 {
HannesTschofenig 0:796d0f61a05b 3950 if( hostname == NULL )
HannesTschofenig 0:796d0f61a05b 3951 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 3952
HannesTschofenig 0:796d0f61a05b 3953 ssl->hostname_len = strlen( hostname );
HannesTschofenig 0:796d0f61a05b 3954
HannesTschofenig 0:796d0f61a05b 3955 if( ssl->hostname_len + 1 == 0 )
HannesTschofenig 0:796d0f61a05b 3956 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 3957
HannesTschofenig 0:796d0f61a05b 3958 ssl->hostname = (unsigned char *) polarssl_malloc( ssl->hostname_len + 1 );
HannesTschofenig 0:796d0f61a05b 3959
HannesTschofenig 0:796d0f61a05b 3960 if( ssl->hostname == NULL )
HannesTschofenig 0:796d0f61a05b 3961 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 3962
HannesTschofenig 0:796d0f61a05b 3963 memcpy( ssl->hostname, (const unsigned char *) hostname,
HannesTschofenig 0:796d0f61a05b 3964 ssl->hostname_len );
HannesTschofenig 0:796d0f61a05b 3965
HannesTschofenig 0:796d0f61a05b 3966 ssl->hostname[ssl->hostname_len] = '\0';
HannesTschofenig 0:796d0f61a05b 3967
HannesTschofenig 0:796d0f61a05b 3968 return( 0 );
HannesTschofenig 0:796d0f61a05b 3969 }
HannesTschofenig 0:796d0f61a05b 3970
HannesTschofenig 0:796d0f61a05b 3971 void ssl_set_sni( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 3972 int (*f_sni)(void *, ssl_context *,
HannesTschofenig 0:796d0f61a05b 3973 const unsigned char *, size_t),
HannesTschofenig 0:796d0f61a05b 3974 void *p_sni )
HannesTschofenig 0:796d0f61a05b 3975 {
HannesTschofenig 0:796d0f61a05b 3976 ssl->f_sni = f_sni;
HannesTschofenig 0:796d0f61a05b 3977 ssl->p_sni = p_sni;
HannesTschofenig 0:796d0f61a05b 3978 }
HannesTschofenig 0:796d0f61a05b 3979 #endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
HannesTschofenig 0:796d0f61a05b 3980
HannesTschofenig 0:796d0f61a05b 3981 #if defined(POLARSSL_SSL_ALPN)
HannesTschofenig 0:796d0f61a05b 3982 int ssl_set_alpn_protocols( ssl_context *ssl, const char **protos )
HannesTschofenig 0:796d0f61a05b 3983 {
HannesTschofenig 0:796d0f61a05b 3984 size_t cur_len, tot_len;
HannesTschofenig 0:796d0f61a05b 3985 const char **p;
HannesTschofenig 0:796d0f61a05b 3986
HannesTschofenig 0:796d0f61a05b 3987 /*
HannesTschofenig 0:796d0f61a05b 3988 * "Empty strings MUST NOT be included and byte strings MUST NOT be
HannesTschofenig 0:796d0f61a05b 3989 * truncated". Check lengths now rather than later.
HannesTschofenig 0:796d0f61a05b 3990 */
HannesTschofenig 0:796d0f61a05b 3991 tot_len = 0;
HannesTschofenig 0:796d0f61a05b 3992 for( p = protos; *p != NULL; p++ )
HannesTschofenig 0:796d0f61a05b 3993 {
HannesTschofenig 0:796d0f61a05b 3994 cur_len = strlen( *p );
HannesTschofenig 0:796d0f61a05b 3995 tot_len += cur_len;
HannesTschofenig 0:796d0f61a05b 3996
HannesTschofenig 0:796d0f61a05b 3997 if( cur_len == 0 || cur_len > 255 || tot_len > 65535 )
HannesTschofenig 0:796d0f61a05b 3998 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 3999 }
HannesTschofenig 0:796d0f61a05b 4000
HannesTschofenig 0:796d0f61a05b 4001 ssl->alpn_list = protos;
HannesTschofenig 0:796d0f61a05b 4002
HannesTschofenig 0:796d0f61a05b 4003 return( 0 );
HannesTschofenig 0:796d0f61a05b 4004 }
HannesTschofenig 0:796d0f61a05b 4005
HannesTschofenig 0:796d0f61a05b 4006 const char *ssl_get_alpn_protocol( const ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4007 {
HannesTschofenig 0:796d0f61a05b 4008 return ssl->alpn_chosen;
HannesTschofenig 0:796d0f61a05b 4009 }
HannesTschofenig 0:796d0f61a05b 4010 #endif /* POLARSSL_SSL_ALPN */
HannesTschofenig 0:796d0f61a05b 4011
HannesTschofenig 0:796d0f61a05b 4012 void ssl_set_max_version( ssl_context *ssl, int major, int minor )
HannesTschofenig 0:796d0f61a05b 4013 {
HannesTschofenig 0:796d0f61a05b 4014 if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION &&
HannesTschofenig 0:796d0f61a05b 4015 minor >= SSL_MIN_MINOR_VERSION && minor <= SSL_MAX_MINOR_VERSION )
HannesTschofenig 0:796d0f61a05b 4016 {
HannesTschofenig 0:796d0f61a05b 4017 ssl->max_major_ver = major;
HannesTschofenig 0:796d0f61a05b 4018 ssl->max_minor_ver = minor;
HannesTschofenig 0:796d0f61a05b 4019 }
HannesTschofenig 0:796d0f61a05b 4020 }
HannesTschofenig 0:796d0f61a05b 4021
HannesTschofenig 0:796d0f61a05b 4022 void ssl_set_min_version( ssl_context *ssl, int major, int minor )
HannesTschofenig 0:796d0f61a05b 4023 {
HannesTschofenig 0:796d0f61a05b 4024 if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION &&
HannesTschofenig 0:796d0f61a05b 4025 minor >= SSL_MIN_MINOR_VERSION && minor <= SSL_MAX_MINOR_VERSION )
HannesTschofenig 0:796d0f61a05b 4026 {
HannesTschofenig 0:796d0f61a05b 4027 ssl->min_major_ver = major;
HannesTschofenig 0:796d0f61a05b 4028 ssl->min_minor_ver = minor;
HannesTschofenig 0:796d0f61a05b 4029 }
HannesTschofenig 0:796d0f61a05b 4030 }
HannesTschofenig 0:796d0f61a05b 4031
HannesTschofenig 0:796d0f61a05b 4032 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
HannesTschofenig 0:796d0f61a05b 4033 int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code )
HannesTschofenig 0:796d0f61a05b 4034 {
HannesTschofenig 0:796d0f61a05b 4035 if( mfl_code >= SSL_MAX_FRAG_LEN_INVALID ||
HannesTschofenig 0:796d0f61a05b 4036 mfl_code_to_length[mfl_code] > SSL_MAX_CONTENT_LEN )
HannesTschofenig 0:796d0f61a05b 4037 {
HannesTschofenig 0:796d0f61a05b 4038 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 4039 }
HannesTschofenig 0:796d0f61a05b 4040
HannesTschofenig 0:796d0f61a05b 4041 ssl->mfl_code = mfl_code;
HannesTschofenig 0:796d0f61a05b 4042
HannesTschofenig 0:796d0f61a05b 4043 return( 0 );
HannesTschofenig 0:796d0f61a05b 4044 }
HannesTschofenig 0:796d0f61a05b 4045 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
HannesTschofenig 0:796d0f61a05b 4046
HannesTschofenig 0:796d0f61a05b 4047 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
HannesTschofenig 0:796d0f61a05b 4048 int ssl_set_truncated_hmac( ssl_context *ssl, int truncate )
HannesTschofenig 0:796d0f61a05b 4049 {
HannesTschofenig 0:796d0f61a05b 4050 if( ssl->endpoint != SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 4051 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 4052
HannesTschofenig 0:796d0f61a05b 4053 ssl->trunc_hmac = truncate;
HannesTschofenig 0:796d0f61a05b 4054
HannesTschofenig 0:796d0f61a05b 4055 return( 0 );
HannesTschofenig 0:796d0f61a05b 4056 }
HannesTschofenig 0:796d0f61a05b 4057 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
HannesTschofenig 0:796d0f61a05b 4058
HannesTschofenig 0:796d0f61a05b 4059 void ssl_set_renegotiation( ssl_context *ssl, int renegotiation )
HannesTschofenig 0:796d0f61a05b 4060 {
HannesTschofenig 0:796d0f61a05b 4061 ssl->disable_renegotiation = renegotiation;
HannesTschofenig 0:796d0f61a05b 4062 }
HannesTschofenig 0:796d0f61a05b 4063
HannesTschofenig 0:796d0f61a05b 4064 void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy )
HannesTschofenig 0:796d0f61a05b 4065 {
HannesTschofenig 0:796d0f61a05b 4066 ssl->allow_legacy_renegotiation = allow_legacy;
HannesTschofenig 0:796d0f61a05b 4067 }
HannesTschofenig 0:796d0f61a05b 4068
HannesTschofenig 0:796d0f61a05b 4069 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 4070 int ssl_set_session_tickets( ssl_context *ssl, int use_tickets )
HannesTschofenig 0:796d0f61a05b 4071 {
HannesTschofenig 0:796d0f61a05b 4072 ssl->session_tickets = use_tickets;
HannesTschofenig 0:796d0f61a05b 4073
HannesTschofenig 0:796d0f61a05b 4074 if( ssl->endpoint == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 4075 return( 0 );
HannesTschofenig 0:796d0f61a05b 4076
HannesTschofenig 0:796d0f61a05b 4077 if( ssl->f_rng == NULL )
HannesTschofenig 0:796d0f61a05b 4078 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 4079
HannesTschofenig 0:796d0f61a05b 4080 return( ssl_ticket_keys_init( ssl ) );
HannesTschofenig 0:796d0f61a05b 4081 }
HannesTschofenig 0:796d0f61a05b 4082
HannesTschofenig 0:796d0f61a05b 4083 void ssl_set_session_ticket_lifetime( ssl_context *ssl, int lifetime )
HannesTschofenig 0:796d0f61a05b 4084 {
HannesTschofenig 0:796d0f61a05b 4085 ssl->ticket_lifetime = lifetime;
HannesTschofenig 0:796d0f61a05b 4086 }
HannesTschofenig 0:796d0f61a05b 4087 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 4088
HannesTschofenig 0:796d0f61a05b 4089 /*
HannesTschofenig 0:796d0f61a05b 4090 * SSL get accessors
HannesTschofenig 0:796d0f61a05b 4091 */
HannesTschofenig 0:796d0f61a05b 4092 size_t ssl_get_bytes_avail( const ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4093 {
HannesTschofenig 0:796d0f61a05b 4094 return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
HannesTschofenig 0:796d0f61a05b 4095 }
HannesTschofenig 0:796d0f61a05b 4096
HannesTschofenig 0:796d0f61a05b 4097 int ssl_get_verify_result( const ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4098 {
HannesTschofenig 0:796d0f61a05b 4099 return( ssl->session->verify_result );
HannesTschofenig 0:796d0f61a05b 4100 }
HannesTschofenig 0:796d0f61a05b 4101
HannesTschofenig 0:796d0f61a05b 4102 const char *ssl_get_ciphersuite( const ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4103 {
HannesTschofenig 0:796d0f61a05b 4104 if( ssl == NULL || ssl->session == NULL )
HannesTschofenig 0:796d0f61a05b 4105 return NULL;
HannesTschofenig 0:796d0f61a05b 4106
HannesTschofenig 0:796d0f61a05b 4107 return ssl_get_ciphersuite_name( ssl->session->ciphersuite );
HannesTschofenig 0:796d0f61a05b 4108 }
HannesTschofenig 0:796d0f61a05b 4109
HannesTschofenig 0:796d0f61a05b 4110 const char *ssl_get_version( const ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4111 {
HannesTschofenig 0:796d0f61a05b 4112 switch( ssl->minor_ver )
HannesTschofenig 0:796d0f61a05b 4113 {
HannesTschofenig 0:796d0f61a05b 4114 case SSL_MINOR_VERSION_0:
HannesTschofenig 0:796d0f61a05b 4115 return( "SSLv3.0" );
HannesTschofenig 0:796d0f61a05b 4116
HannesTschofenig 0:796d0f61a05b 4117 case SSL_MINOR_VERSION_1:
HannesTschofenig 0:796d0f61a05b 4118 return( "TLSv1.0" );
HannesTschofenig 0:796d0f61a05b 4119
HannesTschofenig 0:796d0f61a05b 4120 case SSL_MINOR_VERSION_2:
HannesTschofenig 0:796d0f61a05b 4121 return( "TLSv1.1" );
HannesTschofenig 0:796d0f61a05b 4122
HannesTschofenig 0:796d0f61a05b 4123 case SSL_MINOR_VERSION_3:
HannesTschofenig 0:796d0f61a05b 4124 return( "TLSv1.2" );
HannesTschofenig 0:796d0f61a05b 4125
HannesTschofenig 0:796d0f61a05b 4126 default:
HannesTschofenig 0:796d0f61a05b 4127 break;
HannesTschofenig 0:796d0f61a05b 4128 }
HannesTschofenig 0:796d0f61a05b 4129 return( "unknown" );
HannesTschofenig 0:796d0f61a05b 4130 }
HannesTschofenig 0:796d0f61a05b 4131
HannesTschofenig 0:796d0f61a05b 4132 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 4133 const x509_crt *ssl_get_peer_cert( const ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4134 {
HannesTschofenig 0:796d0f61a05b 4135 if( ssl == NULL || ssl->session == NULL )
HannesTschofenig 0:796d0f61a05b 4136 return NULL;
HannesTschofenig 0:796d0f61a05b 4137
HannesTschofenig 0:796d0f61a05b 4138 return ssl->session->peer_cert;
HannesTschofenig 0:796d0f61a05b 4139 }
HannesTschofenig 0:796d0f61a05b 4140 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 4141
HannesTschofenig 0:796d0f61a05b 4142 int ssl_get_session( const ssl_context *ssl, ssl_session *dst )
HannesTschofenig 0:796d0f61a05b 4143 {
HannesTschofenig 0:796d0f61a05b 4144 if( ssl == NULL ||
HannesTschofenig 0:796d0f61a05b 4145 dst == NULL ||
HannesTschofenig 0:796d0f61a05b 4146 ssl->session == NULL ||
HannesTschofenig 0:796d0f61a05b 4147 ssl->endpoint != SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 4148 {
HannesTschofenig 0:796d0f61a05b 4149 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 4150 }
HannesTschofenig 0:796d0f61a05b 4151
HannesTschofenig 0:796d0f61a05b 4152 return( ssl_session_copy( dst, ssl->session ) );
HannesTschofenig 0:796d0f61a05b 4153 }
HannesTschofenig 0:796d0f61a05b 4154
HannesTschofenig 0:796d0f61a05b 4155 /*
HannesTschofenig 0:796d0f61a05b 4156 * Perform a single step of the SSL handshake
HannesTschofenig 0:796d0f61a05b 4157 */
HannesTschofenig 0:796d0f61a05b 4158 int ssl_handshake_step( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4159 {
HannesTschofenig 0:796d0f61a05b 4160 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 4161
HannesTschofenig 0:796d0f61a05b 4162 #if defined(POLARSSL_SSL_CLI_C)
HannesTschofenig 0:796d0f61a05b 4163 if( ssl->endpoint == SSL_IS_CLIENT )
HannesTschofenig 0:796d0f61a05b 4164 ret = ssl_handshake_client_step( ssl );
HannesTschofenig 0:796d0f61a05b 4165 #endif
HannesTschofenig 0:796d0f61a05b 4166
HannesTschofenig 0:796d0f61a05b 4167 #if defined(POLARSSL_SSL_SRV_C)
HannesTschofenig 0:796d0f61a05b 4168 if( ssl->endpoint == SSL_IS_SERVER )
HannesTschofenig 0:796d0f61a05b 4169 ret = ssl_handshake_server_step( ssl );
HannesTschofenig 0:796d0f61a05b 4170 #endif
HannesTschofenig 0:796d0f61a05b 4171
HannesTschofenig 0:796d0f61a05b 4172 return( ret );
HannesTschofenig 0:796d0f61a05b 4173 }
HannesTschofenig 0:796d0f61a05b 4174
HannesTschofenig 0:796d0f61a05b 4175 /*
HannesTschofenig 0:796d0f61a05b 4176 * Perform the SSL handshake
HannesTschofenig 0:796d0f61a05b 4177 */
HannesTschofenig 0:796d0f61a05b 4178 int ssl_handshake( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4179 {
HannesTschofenig 0:796d0f61a05b 4180 int ret = 0;
HannesTschofenig 0:796d0f61a05b 4181
HannesTschofenig 0:796d0f61a05b 4182 SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
HannesTschofenig 0:796d0f61a05b 4183
HannesTschofenig 0:796d0f61a05b 4184 while( ssl->state != SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 4185 {
HannesTschofenig 0:796d0f61a05b 4186 ret = ssl_handshake_step( ssl );
HannesTschofenig 0:796d0f61a05b 4187
HannesTschofenig 0:796d0f61a05b 4188 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 4189 break;
HannesTschofenig 0:796d0f61a05b 4190 }
HannesTschofenig 0:796d0f61a05b 4191
HannesTschofenig 0:796d0f61a05b 4192 SSL_DEBUG_MSG( 2, ( "<= handshake" ) );
HannesTschofenig 0:796d0f61a05b 4193
HannesTschofenig 0:796d0f61a05b 4194 return( ret );
HannesTschofenig 0:796d0f61a05b 4195 }
HannesTschofenig 0:796d0f61a05b 4196
HannesTschofenig 0:796d0f61a05b 4197 #if defined(POLARSSL_SSL_SRV_C)
HannesTschofenig 0:796d0f61a05b 4198 /*
HannesTschofenig 0:796d0f61a05b 4199 * Write HelloRequest to request renegotiation on server
HannesTschofenig 0:796d0f61a05b 4200 */
HannesTschofenig 0:796d0f61a05b 4201 static int ssl_write_hello_request( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4202 {
HannesTschofenig 0:796d0f61a05b 4203 int ret;
HannesTschofenig 0:796d0f61a05b 4204
HannesTschofenig 0:796d0f61a05b 4205 SSL_DEBUG_MSG( 2, ( "=> write hello request" ) );
HannesTschofenig 0:796d0f61a05b 4206
HannesTschofenig 0:796d0f61a05b 4207 ssl->out_msglen = 4;
HannesTschofenig 0:796d0f61a05b 4208 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 4209 ssl->out_msg[0] = SSL_HS_HELLO_REQUEST;
HannesTschofenig 0:796d0f61a05b 4210
HannesTschofenig 0:796d0f61a05b 4211 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4212 {
HannesTschofenig 0:796d0f61a05b 4213 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 4214 return( ret );
HannesTschofenig 0:796d0f61a05b 4215 }
HannesTschofenig 0:796d0f61a05b 4216
HannesTschofenig 0:796d0f61a05b 4217 ssl->renegotiation = SSL_RENEGOTIATION_PENDING;
HannesTschofenig 0:796d0f61a05b 4218
HannesTschofenig 0:796d0f61a05b 4219 SSL_DEBUG_MSG( 2, ( "<= write hello request" ) );
HannesTschofenig 0:796d0f61a05b 4220
HannesTschofenig 0:796d0f61a05b 4221 return( 0 );
HannesTschofenig 0:796d0f61a05b 4222 }
HannesTschofenig 0:796d0f61a05b 4223 #endif /* POLARSSL_SSL_SRV_C */
HannesTschofenig 0:796d0f61a05b 4224
HannesTschofenig 0:796d0f61a05b 4225 /*
HannesTschofenig 0:796d0f61a05b 4226 * Actually renegotiate current connection, triggered by either:
HannesTschofenig 0:796d0f61a05b 4227 * - calling ssl_renegotiate() on client,
HannesTschofenig 0:796d0f61a05b 4228 * - receiving a HelloRequest on client during ssl_read(),
HannesTschofenig 0:796d0f61a05b 4229 * - receiving any handshake message on server during ssl_read() after the
HannesTschofenig 0:796d0f61a05b 4230 * initial handshake is completed
HannesTschofenig 0:796d0f61a05b 4231 * If the handshake doesn't complete due to waiting for I/O, it will continue
HannesTschofenig 0:796d0f61a05b 4232 * during the next calls to ssl_renegotiate() or ssl_read() respectively.
HannesTschofenig 0:796d0f61a05b 4233 */
HannesTschofenig 0:796d0f61a05b 4234 static int ssl_start_renegotiation( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4235 {
HannesTschofenig 0:796d0f61a05b 4236 int ret;
HannesTschofenig 0:796d0f61a05b 4237
HannesTschofenig 0:796d0f61a05b 4238 SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
HannesTschofenig 0:796d0f61a05b 4239
HannesTschofenig 0:796d0f61a05b 4240 if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4241 return( ret );
HannesTschofenig 0:796d0f61a05b 4242
HannesTschofenig 0:796d0f61a05b 4243 ssl->state = SSL_HELLO_REQUEST;
HannesTschofenig 0:796d0f61a05b 4244 ssl->renegotiation = SSL_RENEGOTIATION;
HannesTschofenig 0:796d0f61a05b 4245
HannesTschofenig 0:796d0f61a05b 4246 if( ( ret = ssl_handshake( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4247 {
HannesTschofenig 0:796d0f61a05b 4248 SSL_DEBUG_RET( 1, "ssl_handshake", ret );
HannesTschofenig 0:796d0f61a05b 4249 return( ret );
HannesTschofenig 0:796d0f61a05b 4250 }
HannesTschofenig 0:796d0f61a05b 4251
HannesTschofenig 0:796d0f61a05b 4252 SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) );
HannesTschofenig 0:796d0f61a05b 4253
HannesTschofenig 0:796d0f61a05b 4254 return( 0 );
HannesTschofenig 0:796d0f61a05b 4255 }
HannesTschofenig 0:796d0f61a05b 4256
HannesTschofenig 0:796d0f61a05b 4257 /*
HannesTschofenig 0:796d0f61a05b 4258 * Renegotiate current connection on client,
HannesTschofenig 0:796d0f61a05b 4259 * or request renegotiation on server
HannesTschofenig 0:796d0f61a05b 4260 */
HannesTschofenig 0:796d0f61a05b 4261 int ssl_renegotiate( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4262 {
HannesTschofenig 0:796d0f61a05b 4263 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 4264
HannesTschofenig 0:796d0f61a05b 4265 #if defined(POLARSSL_SSL_SRV_C)
HannesTschofenig 0:796d0f61a05b 4266 /* On server, just send the request */
HannesTschofenig 0:796d0f61a05b 4267 if( ssl->endpoint == SSL_IS_SERVER )
HannesTschofenig 0:796d0f61a05b 4268 {
HannesTschofenig 0:796d0f61a05b 4269 if( ssl->state != SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 4270 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 4271
HannesTschofenig 0:796d0f61a05b 4272 return( ssl_write_hello_request( ssl ) );
HannesTschofenig 0:796d0f61a05b 4273 }
HannesTschofenig 0:796d0f61a05b 4274 #endif /* POLARSSL_SSL_SRV_C */
HannesTschofenig 0:796d0f61a05b 4275
HannesTschofenig 0:796d0f61a05b 4276 #if defined(POLARSSL_SSL_CLI_C)
HannesTschofenig 0:796d0f61a05b 4277 /*
HannesTschofenig 0:796d0f61a05b 4278 * On client, either start the renegotiation process or,
HannesTschofenig 0:796d0f61a05b 4279 * if already in progress, continue the handshake
HannesTschofenig 0:796d0f61a05b 4280 */
HannesTschofenig 0:796d0f61a05b 4281 if( ssl->renegotiation != SSL_RENEGOTIATION )
HannesTschofenig 0:796d0f61a05b 4282 {
HannesTschofenig 0:796d0f61a05b 4283 if( ssl->state != SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 4284 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 4285
HannesTschofenig 0:796d0f61a05b 4286 if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4287 {
HannesTschofenig 0:796d0f61a05b 4288 SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
HannesTschofenig 0:796d0f61a05b 4289 return( ret );
HannesTschofenig 0:796d0f61a05b 4290 }
HannesTschofenig 0:796d0f61a05b 4291 }
HannesTschofenig 0:796d0f61a05b 4292 else
HannesTschofenig 0:796d0f61a05b 4293 {
HannesTschofenig 0:796d0f61a05b 4294 if( ( ret = ssl_handshake( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4295 {
HannesTschofenig 0:796d0f61a05b 4296 SSL_DEBUG_RET( 1, "ssl_handshake", ret );
HannesTschofenig 0:796d0f61a05b 4297 return( ret );
HannesTschofenig 0:796d0f61a05b 4298 }
HannesTschofenig 0:796d0f61a05b 4299 }
HannesTschofenig 0:796d0f61a05b 4300 #endif /* POLARSSL_SSL_CLI_C */
HannesTschofenig 0:796d0f61a05b 4301
HannesTschofenig 0:796d0f61a05b 4302 return( ret );
HannesTschofenig 0:796d0f61a05b 4303 }
HannesTschofenig 0:796d0f61a05b 4304
HannesTschofenig 0:796d0f61a05b 4305 /*
HannesTschofenig 0:796d0f61a05b 4306 * Receive application data decrypted from the SSL layer
HannesTschofenig 0:796d0f61a05b 4307 */
HannesTschofenig 0:796d0f61a05b 4308 int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
HannesTschofenig 0:796d0f61a05b 4309 {
HannesTschofenig 0:796d0f61a05b 4310 int ret;
HannesTschofenig 0:796d0f61a05b 4311 size_t n;
HannesTschofenig 0:796d0f61a05b 4312
HannesTschofenig 0:796d0f61a05b 4313 SSL_DEBUG_MSG( 2, ( "=> read" ) );
HannesTschofenig 0:796d0f61a05b 4314
HannesTschofenig 0:796d0f61a05b 4315 if( ssl->state != SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 4316 {
HannesTschofenig 0:796d0f61a05b 4317 if( ( ret = ssl_handshake( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4318 {
HannesTschofenig 0:796d0f61a05b 4319 SSL_DEBUG_RET( 1, "ssl_handshake", ret );
HannesTschofenig 0:796d0f61a05b 4320 return( ret );
HannesTschofenig 0:796d0f61a05b 4321 }
HannesTschofenig 0:796d0f61a05b 4322 }
HannesTschofenig 0:796d0f61a05b 4323
HannesTschofenig 0:796d0f61a05b 4324 if( ssl->in_offt == NULL )
HannesTschofenig 0:796d0f61a05b 4325 {
HannesTschofenig 0:796d0f61a05b 4326 if( ( ret = ssl_read_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4327 {
HannesTschofenig 0:796d0f61a05b 4328 if( ret == POLARSSL_ERR_SSL_CONN_EOF )
HannesTschofenig 0:796d0f61a05b 4329 return( 0 );
HannesTschofenig 0:796d0f61a05b 4330
HannesTschofenig 0:796d0f61a05b 4331 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
HannesTschofenig 0:796d0f61a05b 4332 return( ret );
HannesTschofenig 0:796d0f61a05b 4333 }
HannesTschofenig 0:796d0f61a05b 4334
HannesTschofenig 0:796d0f61a05b 4335 if( ssl->in_msglen == 0 &&
HannesTschofenig 0:796d0f61a05b 4336 ssl->in_msgtype == SSL_MSG_APPLICATION_DATA )
HannesTschofenig 0:796d0f61a05b 4337 {
HannesTschofenig 0:796d0f61a05b 4338 /*
HannesTschofenig 0:796d0f61a05b 4339 * OpenSSL sends empty messages to randomize the IV
HannesTschofenig 0:796d0f61a05b 4340 */
HannesTschofenig 0:796d0f61a05b 4341 if( ( ret = ssl_read_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4342 {
HannesTschofenig 0:796d0f61a05b 4343 if( ret == POLARSSL_ERR_SSL_CONN_EOF )
HannesTschofenig 0:796d0f61a05b 4344 return( 0 );
HannesTschofenig 0:796d0f61a05b 4345
HannesTschofenig 0:796d0f61a05b 4346 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
HannesTschofenig 0:796d0f61a05b 4347 return( ret );
HannesTschofenig 0:796d0f61a05b 4348 }
HannesTschofenig 0:796d0f61a05b 4349 }
HannesTschofenig 0:796d0f61a05b 4350
HannesTschofenig 0:796d0f61a05b 4351 if( ssl->in_msgtype == SSL_MSG_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 4352 {
HannesTschofenig 0:796d0f61a05b 4353 SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
HannesTschofenig 0:796d0f61a05b 4354
HannesTschofenig 0:796d0f61a05b 4355 if( ssl->endpoint == SSL_IS_CLIENT &&
HannesTschofenig 0:796d0f61a05b 4356 ( ssl->in_msg[0] != SSL_HS_HELLO_REQUEST ||
HannesTschofenig 0:796d0f61a05b 4357 ssl->in_hslen != 4 ) )
HannesTschofenig 0:796d0f61a05b 4358 {
HannesTschofenig 0:796d0f61a05b 4359 SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
HannesTschofenig 0:796d0f61a05b 4360 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
HannesTschofenig 0:796d0f61a05b 4361 }
HannesTschofenig 0:796d0f61a05b 4362
HannesTschofenig 0:796d0f61a05b 4363 if( ssl->disable_renegotiation == SSL_RENEGOTIATION_DISABLED ||
HannesTschofenig 0:796d0f61a05b 4364 ( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 4365 ssl->allow_legacy_renegotiation ==
HannesTschofenig 0:796d0f61a05b 4366 SSL_LEGACY_NO_RENEGOTIATION ) )
HannesTschofenig 0:796d0f61a05b 4367 {
HannesTschofenig 0:796d0f61a05b 4368 SSL_DEBUG_MSG( 3, ( "ignoring renegotiation, sending alert" ) );
HannesTschofenig 0:796d0f61a05b 4369
HannesTschofenig 0:796d0f61a05b 4370 #if defined(POLARSSL_SSL_PROTO_SSL3)
HannesTschofenig 0:796d0f61a05b 4371 if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 4372 {
HannesTschofenig 0:796d0f61a05b 4373 /*
HannesTschofenig 0:796d0f61a05b 4374 * SSLv3 does not have a "no_renegotiation" alert
HannesTschofenig 0:796d0f61a05b 4375 */
HannesTschofenig 0:796d0f61a05b 4376 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4377 return( ret );
HannesTschofenig 0:796d0f61a05b 4378 }
HannesTschofenig 0:796d0f61a05b 4379 else
HannesTschofenig 0:796d0f61a05b 4380 #endif /* POLARSSL_SSL_PROTO_SSL3 */
HannesTschofenig 0:796d0f61a05b 4381 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 4382 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 4383 if( ssl->minor_ver >= SSL_MINOR_VERSION_1 )
HannesTschofenig 0:796d0f61a05b 4384 {
HannesTschofenig 0:796d0f61a05b 4385 if( ( ret = ssl_send_alert_message( ssl,
HannesTschofenig 0:796d0f61a05b 4386 SSL_ALERT_LEVEL_WARNING,
HannesTschofenig 0:796d0f61a05b 4387 SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4388 {
HannesTschofenig 0:796d0f61a05b 4389 return( ret );
HannesTschofenig 0:796d0f61a05b 4390 }
HannesTschofenig 0:796d0f61a05b 4391 }
HannesTschofenig 0:796d0f61a05b 4392 else
HannesTschofenig 0:796d0f61a05b 4393 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 ||
HannesTschofenig 0:796d0f61a05b 4394 POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 4395 {
HannesTschofenig 0:796d0f61a05b 4396 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 4397 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 4398 }
HannesTschofenig 0:796d0f61a05b 4399 }
HannesTschofenig 0:796d0f61a05b 4400 else
HannesTschofenig 0:796d0f61a05b 4401 {
HannesTschofenig 0:796d0f61a05b 4402 if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4403 {
HannesTschofenig 0:796d0f61a05b 4404 SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
HannesTschofenig 0:796d0f61a05b 4405 return( ret );
HannesTschofenig 0:796d0f61a05b 4406 }
HannesTschofenig 0:796d0f61a05b 4407
HannesTschofenig 0:796d0f61a05b 4408 return( POLARSSL_ERR_NET_WANT_READ );
HannesTschofenig 0:796d0f61a05b 4409 }
HannesTschofenig 0:796d0f61a05b 4410 }
HannesTschofenig 0:796d0f61a05b 4411 else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING )
HannesTschofenig 0:796d0f61a05b 4412 {
HannesTschofenig 0:796d0f61a05b 4413 SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
HannesTschofenig 0:796d0f61a05b 4414 "but not honored by client" ) );
HannesTschofenig 0:796d0f61a05b 4415 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
HannesTschofenig 0:796d0f61a05b 4416 }
HannesTschofenig 0:796d0f61a05b 4417 else if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA )
HannesTschofenig 0:796d0f61a05b 4418 {
HannesTschofenig 0:796d0f61a05b 4419 SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
HannesTschofenig 0:796d0f61a05b 4420 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
HannesTschofenig 0:796d0f61a05b 4421 }
HannesTschofenig 0:796d0f61a05b 4422
HannesTschofenig 0:796d0f61a05b 4423 ssl->in_offt = ssl->in_msg;
HannesTschofenig 0:796d0f61a05b 4424 }
HannesTschofenig 0:796d0f61a05b 4425
HannesTschofenig 0:796d0f61a05b 4426 n = ( len < ssl->in_msglen )
HannesTschofenig 0:796d0f61a05b 4427 ? len : ssl->in_msglen;
HannesTschofenig 0:796d0f61a05b 4428
HannesTschofenig 0:796d0f61a05b 4429 memcpy( buf, ssl->in_offt, n );
HannesTschofenig 0:796d0f61a05b 4430 ssl->in_msglen -= n;
HannesTschofenig 0:796d0f61a05b 4431
HannesTschofenig 0:796d0f61a05b 4432 if( ssl->in_msglen == 0 )
HannesTschofenig 0:796d0f61a05b 4433 /* all bytes consumed */
HannesTschofenig 0:796d0f61a05b 4434 ssl->in_offt = NULL;
HannesTschofenig 0:796d0f61a05b 4435 else
HannesTschofenig 0:796d0f61a05b 4436 /* more data available */
HannesTschofenig 0:796d0f61a05b 4437 ssl->in_offt += n;
HannesTschofenig 0:796d0f61a05b 4438
HannesTschofenig 0:796d0f61a05b 4439 SSL_DEBUG_MSG( 2, ( "<= read" ) );
HannesTschofenig 0:796d0f61a05b 4440
HannesTschofenig 0:796d0f61a05b 4441 return( (int) n );
HannesTschofenig 0:796d0f61a05b 4442 }
HannesTschofenig 0:796d0f61a05b 4443
HannesTschofenig 0:796d0f61a05b 4444 /*
HannesTschofenig 0:796d0f61a05b 4445 * Send application data to be encrypted by the SSL layer
HannesTschofenig 0:796d0f61a05b 4446 */
HannesTschofenig 0:796d0f61a05b 4447 int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
HannesTschofenig 0:796d0f61a05b 4448 {
HannesTschofenig 0:796d0f61a05b 4449 int ret;
HannesTschofenig 0:796d0f61a05b 4450 size_t n;
HannesTschofenig 0:796d0f61a05b 4451 unsigned int max_len = SSL_MAX_CONTENT_LEN;
HannesTschofenig 0:796d0f61a05b 4452
HannesTschofenig 0:796d0f61a05b 4453 SSL_DEBUG_MSG( 2, ( "=> write" ) );
HannesTschofenig 0:796d0f61a05b 4454
HannesTschofenig 0:796d0f61a05b 4455 if( ssl->state != SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 4456 {
HannesTschofenig 0:796d0f61a05b 4457 if( ( ret = ssl_handshake( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4458 {
HannesTschofenig 0:796d0f61a05b 4459 SSL_DEBUG_RET( 1, "ssl_handshake", ret );
HannesTschofenig 0:796d0f61a05b 4460 return( ret );
HannesTschofenig 0:796d0f61a05b 4461 }
HannesTschofenig 0:796d0f61a05b 4462 }
HannesTschofenig 0:796d0f61a05b 4463
HannesTschofenig 0:796d0f61a05b 4464 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
HannesTschofenig 0:796d0f61a05b 4465 /*
HannesTschofenig 0:796d0f61a05b 4466 * Assume mfl_code is correct since it was checked when set
HannesTschofenig 0:796d0f61a05b 4467 */
HannesTschofenig 0:796d0f61a05b 4468 max_len = mfl_code_to_length[ssl->mfl_code];
HannesTschofenig 0:796d0f61a05b 4469
HannesTschofenig 0:796d0f61a05b 4470 /*
HannesTschofenig 0:796d0f61a05b 4471 * Check if a smaller max length was negotiated
HannesTschofenig 0:796d0f61a05b 4472 */
HannesTschofenig 0:796d0f61a05b 4473 if( ssl->session_out != NULL &&
HannesTschofenig 0:796d0f61a05b 4474 mfl_code_to_length[ssl->session_out->mfl_code] < max_len )
HannesTschofenig 0:796d0f61a05b 4475 {
HannesTschofenig 0:796d0f61a05b 4476 max_len = mfl_code_to_length[ssl->session_out->mfl_code];
HannesTschofenig 0:796d0f61a05b 4477 }
HannesTschofenig 0:796d0f61a05b 4478 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
HannesTschofenig 0:796d0f61a05b 4479
HannesTschofenig 0:796d0f61a05b 4480 n = ( len < max_len) ? len : max_len;
HannesTschofenig 0:796d0f61a05b 4481
HannesTschofenig 0:796d0f61a05b 4482 if( ssl->out_left != 0 )
HannesTschofenig 0:796d0f61a05b 4483 {
HannesTschofenig 0:796d0f61a05b 4484 if( ( ret = ssl_flush_output( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4485 {
HannesTschofenig 0:796d0f61a05b 4486 SSL_DEBUG_RET( 1, "ssl_flush_output", ret );
HannesTschofenig 0:796d0f61a05b 4487 return( ret );
HannesTschofenig 0:796d0f61a05b 4488 }
HannesTschofenig 0:796d0f61a05b 4489 }
HannesTschofenig 0:796d0f61a05b 4490 else
HannesTschofenig 0:796d0f61a05b 4491 {
HannesTschofenig 0:796d0f61a05b 4492 ssl->out_msglen = n;
HannesTschofenig 0:796d0f61a05b 4493 ssl->out_msgtype = SSL_MSG_APPLICATION_DATA;
HannesTschofenig 0:796d0f61a05b 4494 memcpy( ssl->out_msg, buf, n );
HannesTschofenig 0:796d0f61a05b 4495
HannesTschofenig 0:796d0f61a05b 4496 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4497 {
HannesTschofenig 0:796d0f61a05b 4498 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 4499 return( ret );
HannesTschofenig 0:796d0f61a05b 4500 }
HannesTschofenig 0:796d0f61a05b 4501 }
HannesTschofenig 0:796d0f61a05b 4502
HannesTschofenig 0:796d0f61a05b 4503 SSL_DEBUG_MSG( 2, ( "<= write" ) );
HannesTschofenig 0:796d0f61a05b 4504
HannesTschofenig 0:796d0f61a05b 4505 return( (int) n );
HannesTschofenig 0:796d0f61a05b 4506 }
HannesTschofenig 0:796d0f61a05b 4507
HannesTschofenig 0:796d0f61a05b 4508 /*
HannesTschofenig 0:796d0f61a05b 4509 * Notify the peer that the connection is being closed
HannesTschofenig 0:796d0f61a05b 4510 */
HannesTschofenig 0:796d0f61a05b 4511 int ssl_close_notify( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4512 {
HannesTschofenig 0:796d0f61a05b 4513 int ret;
HannesTschofenig 0:796d0f61a05b 4514
HannesTschofenig 0:796d0f61a05b 4515 SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
HannesTschofenig 0:796d0f61a05b 4516
HannesTschofenig 0:796d0f61a05b 4517 if( ( ret = ssl_flush_output( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4518 {
HannesTschofenig 0:796d0f61a05b 4519 SSL_DEBUG_RET( 1, "ssl_flush_output", ret );
HannesTschofenig 0:796d0f61a05b 4520 return( ret );
HannesTschofenig 0:796d0f61a05b 4521 }
HannesTschofenig 0:796d0f61a05b 4522
HannesTschofenig 0:796d0f61a05b 4523 if( ssl->state == SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 4524 {
HannesTschofenig 0:796d0f61a05b 4525 if( ( ret = ssl_send_alert_message( ssl,
HannesTschofenig 0:796d0f61a05b 4526 SSL_ALERT_LEVEL_WARNING,
HannesTschofenig 0:796d0f61a05b 4527 SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 4528 {
HannesTschofenig 0:796d0f61a05b 4529 return( ret );
HannesTschofenig 0:796d0f61a05b 4530 }
HannesTschofenig 0:796d0f61a05b 4531 }
HannesTschofenig 0:796d0f61a05b 4532
HannesTschofenig 0:796d0f61a05b 4533 SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
HannesTschofenig 0:796d0f61a05b 4534
HannesTschofenig 0:796d0f61a05b 4535 return( ret );
HannesTschofenig 0:796d0f61a05b 4536 }
HannesTschofenig 0:796d0f61a05b 4537
HannesTschofenig 0:796d0f61a05b 4538 void ssl_transform_free( ssl_transform *transform )
HannesTschofenig 0:796d0f61a05b 4539 {
HannesTschofenig 0:796d0f61a05b 4540 #if defined(POLARSSL_ZLIB_SUPPORT)
HannesTschofenig 0:796d0f61a05b 4541 deflateEnd( &transform->ctx_deflate );
HannesTschofenig 0:796d0f61a05b 4542 inflateEnd( &transform->ctx_inflate );
HannesTschofenig 0:796d0f61a05b 4543 #endif
HannesTschofenig 0:796d0f61a05b 4544
HannesTschofenig 0:796d0f61a05b 4545 cipher_free_ctx( &transform->cipher_ctx_enc );
HannesTschofenig 0:796d0f61a05b 4546 cipher_free_ctx( &transform->cipher_ctx_dec );
HannesTschofenig 0:796d0f61a05b 4547
HannesTschofenig 0:796d0f61a05b 4548 md_free_ctx( &transform->md_ctx_enc );
HannesTschofenig 0:796d0f61a05b 4549 md_free_ctx( &transform->md_ctx_dec );
HannesTschofenig 0:796d0f61a05b 4550
HannesTschofenig 0:796d0f61a05b 4551 memset( transform, 0, sizeof( ssl_transform ) );
HannesTschofenig 0:796d0f61a05b 4552 }
HannesTschofenig 0:796d0f61a05b 4553
HannesTschofenig 0:796d0f61a05b 4554 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 4555 static void ssl_key_cert_free( ssl_key_cert *key_cert )
HannesTschofenig 0:796d0f61a05b 4556 {
HannesTschofenig 0:796d0f61a05b 4557 ssl_key_cert *cur = key_cert, *next;
HannesTschofenig 0:796d0f61a05b 4558
HannesTschofenig 0:796d0f61a05b 4559 while( cur != NULL )
HannesTschofenig 0:796d0f61a05b 4560 {
HannesTschofenig 0:796d0f61a05b 4561 next = cur->next;
HannesTschofenig 0:796d0f61a05b 4562
HannesTschofenig 0:796d0f61a05b 4563 if( cur->key_own_alloc )
HannesTschofenig 0:796d0f61a05b 4564 {
HannesTschofenig 0:796d0f61a05b 4565 pk_free( cur->key );
HannesTschofenig 0:796d0f61a05b 4566 polarssl_free( cur->key );
HannesTschofenig 0:796d0f61a05b 4567 }
HannesTschofenig 0:796d0f61a05b 4568 polarssl_free( cur );
HannesTschofenig 0:796d0f61a05b 4569
HannesTschofenig 0:796d0f61a05b 4570 cur = next;
HannesTschofenig 0:796d0f61a05b 4571 }
HannesTschofenig 0:796d0f61a05b 4572 }
HannesTschofenig 0:796d0f61a05b 4573 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 4574
HannesTschofenig 0:796d0f61a05b 4575 void ssl_handshake_free( ssl_handshake_params *handshake )
HannesTschofenig 0:796d0f61a05b 4576 {
HannesTschofenig 0:796d0f61a05b 4577 #if defined(POLARSSL_DHM_C)
HannesTschofenig 0:796d0f61a05b 4578 dhm_free( &handshake->dhm_ctx );
HannesTschofenig 0:796d0f61a05b 4579 #endif
HannesTschofenig 0:796d0f61a05b 4580 #if defined(POLARSSL_ECDH_C)
HannesTschofenig 0:796d0f61a05b 4581 ecdh_free( &handshake->ecdh_ctx );
HannesTschofenig 0:796d0f61a05b 4582 #endif
HannesTschofenig 0:796d0f61a05b 4583
HannesTschofenig 0:796d0f61a05b 4584 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 4585 /* explicit void pointer cast for buggy MS compiler */
HannesTschofenig 0:796d0f61a05b 4586 polarssl_free( (void *) handshake->curves );
HannesTschofenig 0:796d0f61a05b 4587 #endif
HannesTschofenig 0:796d0f61a05b 4588
HannesTschofenig 0:796d0f61a05b 4589 #if defined(POLARSSL_X509_CRT_PARSE_C) && \
HannesTschofenig 0:796d0f61a05b 4590 defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
HannesTschofenig 0:796d0f61a05b 4591 /*
HannesTschofenig 0:796d0f61a05b 4592 * Free only the linked list wrapper, not the keys themselves
HannesTschofenig 0:796d0f61a05b 4593 * since the belong to the SNI callback
HannesTschofenig 0:796d0f61a05b 4594 */
HannesTschofenig 0:796d0f61a05b 4595 if( handshake->sni_key_cert != NULL )
HannesTschofenig 0:796d0f61a05b 4596 {
HannesTschofenig 0:796d0f61a05b 4597 ssl_key_cert *cur = handshake->sni_key_cert, *next;
HannesTschofenig 0:796d0f61a05b 4598
HannesTschofenig 0:796d0f61a05b 4599 while( cur != NULL )
HannesTschofenig 0:796d0f61a05b 4600 {
HannesTschofenig 0:796d0f61a05b 4601 next = cur->next;
HannesTschofenig 0:796d0f61a05b 4602 polarssl_free( cur );
HannesTschofenig 0:796d0f61a05b 4603 cur = next;
HannesTschofenig 0:796d0f61a05b 4604 }
HannesTschofenig 0:796d0f61a05b 4605 }
HannesTschofenig 0:796d0f61a05b 4606 #endif /* POLARSSL_X509_CRT_PARSE_C && POLARSSL_SSL_SERVER_NAME_INDICATION */
HannesTschofenig 0:796d0f61a05b 4607
HannesTschofenig 0:796d0f61a05b 4608 memset( handshake, 0, sizeof( ssl_handshake_params ) );
HannesTschofenig 0:796d0f61a05b 4609 }
HannesTschofenig 0:796d0f61a05b 4610
HannesTschofenig 0:796d0f61a05b 4611 void ssl_session_free( ssl_session *session )
HannesTschofenig 0:796d0f61a05b 4612 {
HannesTschofenig 0:796d0f61a05b 4613 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 4614 if( session->peer_cert != NULL )
HannesTschofenig 0:796d0f61a05b 4615 {
HannesTschofenig 0:796d0f61a05b 4616 x509_crt_free( session->peer_cert );
HannesTschofenig 0:796d0f61a05b 4617 polarssl_free( session->peer_cert );
HannesTschofenig 0:796d0f61a05b 4618 }
HannesTschofenig 0:796d0f61a05b 4619 #endif
HannesTschofenig 0:796d0f61a05b 4620
HannesTschofenig 0:796d0f61a05b 4621 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 4622 polarssl_free( session->ticket );
HannesTschofenig 0:796d0f61a05b 4623 #endif
HannesTschofenig 0:796d0f61a05b 4624
HannesTschofenig 0:796d0f61a05b 4625 memset( session, 0, sizeof( ssl_session ) );
HannesTschofenig 0:796d0f61a05b 4626 }
HannesTschofenig 0:796d0f61a05b 4627
HannesTschofenig 0:796d0f61a05b 4628 /*
HannesTschofenig 0:796d0f61a05b 4629 * Free an SSL context
HannesTschofenig 0:796d0f61a05b 4630 */
HannesTschofenig 0:796d0f61a05b 4631 void ssl_free( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 4632 {
HannesTschofenig 0:796d0f61a05b 4633 SSL_DEBUG_MSG( 2, ( "=> free" ) );
HannesTschofenig 0:796d0f61a05b 4634
HannesTschofenig 0:796d0f61a05b 4635 if( ssl->out_ctr != NULL )
HannesTschofenig 0:796d0f61a05b 4636 {
HannesTschofenig 0:796d0f61a05b 4637 memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
HannesTschofenig 0:796d0f61a05b 4638 polarssl_free( ssl->out_ctr );
HannesTschofenig 0:796d0f61a05b 4639 }
HannesTschofenig 0:796d0f61a05b 4640
HannesTschofenig 0:796d0f61a05b 4641 if( ssl->in_ctr != NULL )
HannesTschofenig 0:796d0f61a05b 4642 {
HannesTschofenig 0:796d0f61a05b 4643 memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
HannesTschofenig 0:796d0f61a05b 4644 polarssl_free( ssl->in_ctr );
HannesTschofenig 0:796d0f61a05b 4645 }
HannesTschofenig 0:796d0f61a05b 4646
HannesTschofenig 0:796d0f61a05b 4647 #if defined(POLARSSL_ZLIB_SUPPORT)
HannesTschofenig 0:796d0f61a05b 4648 if( ssl->compress_buf != NULL )
HannesTschofenig 0:796d0f61a05b 4649 {
HannesTschofenig 0:796d0f61a05b 4650 memset( ssl->compress_buf, 0, SSL_BUFFER_LEN );
HannesTschofenig 0:796d0f61a05b 4651 polarssl_free( ssl->compress_buf );
HannesTschofenig 0:796d0f61a05b 4652 }
HannesTschofenig 0:796d0f61a05b 4653 #endif
HannesTschofenig 0:796d0f61a05b 4654
HannesTschofenig 0:796d0f61a05b 4655 #if defined(POLARSSL_DHM_C)
HannesTschofenig 0:796d0f61a05b 4656 mpi_free( &ssl->dhm_P );
HannesTschofenig 0:796d0f61a05b 4657 mpi_free( &ssl->dhm_G );
HannesTschofenig 0:796d0f61a05b 4658 #endif
HannesTschofenig 0:796d0f61a05b 4659
HannesTschofenig 0:796d0f61a05b 4660 if( ssl->transform )
HannesTschofenig 0:796d0f61a05b 4661 {
HannesTschofenig 0:796d0f61a05b 4662 ssl_transform_free( ssl->transform );
HannesTschofenig 0:796d0f61a05b 4663 polarssl_free( ssl->transform );
HannesTschofenig 0:796d0f61a05b 4664 }
HannesTschofenig 0:796d0f61a05b 4665
HannesTschofenig 0:796d0f61a05b 4666 if( ssl->handshake )
HannesTschofenig 0:796d0f61a05b 4667 {
HannesTschofenig 0:796d0f61a05b 4668 ssl_handshake_free( ssl->handshake );
HannesTschofenig 0:796d0f61a05b 4669 ssl_transform_free( ssl->transform_negotiate );
HannesTschofenig 0:796d0f61a05b 4670 ssl_session_free( ssl->session_negotiate );
HannesTschofenig 0:796d0f61a05b 4671
HannesTschofenig 0:796d0f61a05b 4672 polarssl_free( ssl->handshake );
HannesTschofenig 0:796d0f61a05b 4673 polarssl_free( ssl->transform_negotiate );
HannesTschofenig 0:796d0f61a05b 4674 polarssl_free( ssl->session_negotiate );
HannesTschofenig 0:796d0f61a05b 4675 }
HannesTschofenig 0:796d0f61a05b 4676
HannesTschofenig 0:796d0f61a05b 4677 if( ssl->session )
HannesTschofenig 0:796d0f61a05b 4678 {
HannesTschofenig 0:796d0f61a05b 4679 ssl_session_free( ssl->session );
HannesTschofenig 0:796d0f61a05b 4680 polarssl_free( ssl->session );
HannesTschofenig 0:796d0f61a05b 4681 }
HannesTschofenig 0:796d0f61a05b 4682
HannesTschofenig 0:796d0f61a05b 4683 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 4684 polarssl_free( ssl->ticket_keys );
HannesTschofenig 0:796d0f61a05b 4685 #endif
HannesTschofenig 0:796d0f61a05b 4686
HannesTschofenig 0:796d0f61a05b 4687 #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
HannesTschofenig 0:796d0f61a05b 4688 if ( ssl->hostname != NULL )
HannesTschofenig 0:796d0f61a05b 4689 {
HannesTschofenig 0:796d0f61a05b 4690 memset( ssl->hostname, 0, ssl->hostname_len );
HannesTschofenig 0:796d0f61a05b 4691 polarssl_free( ssl->hostname );
HannesTschofenig 0:796d0f61a05b 4692 ssl->hostname_len = 0;
HannesTschofenig 0:796d0f61a05b 4693 }
HannesTschofenig 0:796d0f61a05b 4694 #endif
HannesTschofenig 0:796d0f61a05b 4695
HannesTschofenig 0:796d0f61a05b 4696 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 4697 if( ssl->psk != NULL )
HannesTschofenig 0:796d0f61a05b 4698 {
HannesTschofenig 0:796d0f61a05b 4699 memset( ssl->psk, 0, ssl->psk_len );
HannesTschofenig 0:796d0f61a05b 4700 memset( ssl->psk_identity, 0, ssl->psk_identity_len );
HannesTschofenig 0:796d0f61a05b 4701 polarssl_free( ssl->psk );
HannesTschofenig 0:796d0f61a05b 4702 polarssl_free( ssl->psk_identity );
HannesTschofenig 0:796d0f61a05b 4703 ssl->psk_len = 0;
HannesTschofenig 0:796d0f61a05b 4704 ssl->psk_identity_len = 0;
HannesTschofenig 0:796d0f61a05b 4705 }
HannesTschofenig 0:796d0f61a05b 4706 #endif
HannesTschofenig 0:796d0f61a05b 4707
HannesTschofenig 0:796d0f61a05b 4708 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 4709 ssl_key_cert_free( ssl->key_cert );
HannesTschofenig 0:796d0f61a05b 4710 #endif
HannesTschofenig 0:796d0f61a05b 4711
HannesTschofenig 0:796d0f61a05b 4712 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
HannesTschofenig 0:796d0f61a05b 4713 if( ssl_hw_record_finish != NULL )
HannesTschofenig 0:796d0f61a05b 4714 {
HannesTschofenig 0:796d0f61a05b 4715 SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_finish()" ) );
HannesTschofenig 0:796d0f61a05b 4716 ssl_hw_record_finish( ssl );
HannesTschofenig 0:796d0f61a05b 4717 }
HannesTschofenig 0:796d0f61a05b 4718 #endif
HannesTschofenig 0:796d0f61a05b 4719
HannesTschofenig 0:796d0f61a05b 4720 SSL_DEBUG_MSG( 2, ( "<= free" ) );
HannesTschofenig 0:796d0f61a05b 4721
HannesTschofenig 0:796d0f61a05b 4722 /* Actually clear after last debug message */
HannesTschofenig 0:796d0f61a05b 4723 memset( ssl, 0, sizeof( ssl_context ) );
HannesTschofenig 0:796d0f61a05b 4724 }
HannesTschofenig 0:796d0f61a05b 4725
HannesTschofenig 0:796d0f61a05b 4726 #if defined(POLARSSL_PK_C)
HannesTschofenig 0:796d0f61a05b 4727 /*
HannesTschofenig 0:796d0f61a05b 4728 * Convert between POLARSSL_PK_XXX and SSL_SIG_XXX
HannesTschofenig 0:796d0f61a05b 4729 */
HannesTschofenig 0:796d0f61a05b 4730 unsigned char ssl_sig_from_pk( pk_context *pk )
HannesTschofenig 0:796d0f61a05b 4731 {
HannesTschofenig 0:796d0f61a05b 4732 #if defined(POLARSSL_RSA_C)
HannesTschofenig 0:796d0f61a05b 4733 if( pk_can_do( pk, POLARSSL_PK_RSA ) )
HannesTschofenig 0:796d0f61a05b 4734 return( SSL_SIG_RSA );
HannesTschofenig 0:796d0f61a05b 4735 #endif
HannesTschofenig 0:796d0f61a05b 4736 #if defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 4737 if( pk_can_do( pk, POLARSSL_PK_ECDSA ) )
HannesTschofenig 0:796d0f61a05b 4738 return( SSL_SIG_ECDSA );
HannesTschofenig 0:796d0f61a05b 4739 #endif
HannesTschofenig 0:796d0f61a05b 4740 return( SSL_SIG_ANON );
HannesTschofenig 0:796d0f61a05b 4741 }
HannesTschofenig 0:796d0f61a05b 4742
HannesTschofenig 0:796d0f61a05b 4743 pk_type_t ssl_pk_alg_from_sig( unsigned char sig )
HannesTschofenig 0:796d0f61a05b 4744 {
HannesTschofenig 0:796d0f61a05b 4745 switch( sig )
HannesTschofenig 0:796d0f61a05b 4746 {
HannesTschofenig 0:796d0f61a05b 4747 #if defined(POLARSSL_RSA_C)
HannesTschofenig 0:796d0f61a05b 4748 case SSL_SIG_RSA:
HannesTschofenig 0:796d0f61a05b 4749 return( POLARSSL_PK_RSA );
HannesTschofenig 0:796d0f61a05b 4750 #endif
HannesTschofenig 0:796d0f61a05b 4751 #if defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 4752 case SSL_SIG_ECDSA:
HannesTschofenig 0:796d0f61a05b 4753 return( POLARSSL_PK_ECDSA );
HannesTschofenig 0:796d0f61a05b 4754 #endif
HannesTschofenig 0:796d0f61a05b 4755 default:
HannesTschofenig 0:796d0f61a05b 4756 return( POLARSSL_PK_NONE );
HannesTschofenig 0:796d0f61a05b 4757 }
HannesTschofenig 0:796d0f61a05b 4758 }
HannesTschofenig 0:796d0f61a05b 4759 #endif /* POLARSSL_PK_C */
HannesTschofenig 0:796d0f61a05b 4760
HannesTschofenig 0:796d0f61a05b 4761 /*
HannesTschofenig 0:796d0f61a05b 4762 * Convert between SSL_HASH_XXX and POLARSSL_MD_XXX
HannesTschofenig 0:796d0f61a05b 4763 */
HannesTschofenig 0:796d0f61a05b 4764 md_type_t ssl_md_alg_from_hash( unsigned char hash )
HannesTschofenig 0:796d0f61a05b 4765 {
HannesTschofenig 0:796d0f61a05b 4766 switch( hash )
HannesTschofenig 0:796d0f61a05b 4767 {
HannesTschofenig 0:796d0f61a05b 4768 #if defined(POLARSSL_MD5_C)
HannesTschofenig 0:796d0f61a05b 4769 case SSL_HASH_MD5:
HannesTschofenig 0:796d0f61a05b 4770 return( POLARSSL_MD_MD5 );
HannesTschofenig 0:796d0f61a05b 4771 #endif
HannesTschofenig 0:796d0f61a05b 4772 #if defined(POLARSSL_SHA1_C)
HannesTschofenig 0:796d0f61a05b 4773 case SSL_HASH_SHA1:
HannesTschofenig 0:796d0f61a05b 4774 return( POLARSSL_MD_SHA1 );
HannesTschofenig 0:796d0f61a05b 4775 #endif
HannesTschofenig 0:796d0f61a05b 4776 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 4777 case SSL_HASH_SHA224:
HannesTschofenig 0:796d0f61a05b 4778 return( POLARSSL_MD_SHA224 );
HannesTschofenig 0:796d0f61a05b 4779 case SSL_HASH_SHA256:
HannesTschofenig 0:796d0f61a05b 4780 return( POLARSSL_MD_SHA256 );
HannesTschofenig 0:796d0f61a05b 4781 #endif
HannesTschofenig 0:796d0f61a05b 4782 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 4783 case SSL_HASH_SHA384:
HannesTschofenig 0:796d0f61a05b 4784 return( POLARSSL_MD_SHA384 );
HannesTschofenig 0:796d0f61a05b 4785 case SSL_HASH_SHA512:
HannesTschofenig 0:796d0f61a05b 4786 return( POLARSSL_MD_SHA512 );
HannesTschofenig 0:796d0f61a05b 4787 #endif
HannesTschofenig 0:796d0f61a05b 4788 default:
HannesTschofenig 0:796d0f61a05b 4789 return( POLARSSL_MD_NONE );
HannesTschofenig 0:796d0f61a05b 4790 }
HannesTschofenig 0:796d0f61a05b 4791 }
HannesTschofenig 0:796d0f61a05b 4792
HannesTschofenig 0:796d0f61a05b 4793 #if defined(POLARSSL_SSL_SET_CURVES)
HannesTschofenig 0:796d0f61a05b 4794 /*
HannesTschofenig 0:796d0f61a05b 4795 * Check is a curve proposed by the peer is in our list.
HannesTschofenig 0:796d0f61a05b 4796 * Return 1 if we're willing to use it, 0 otherwise.
HannesTschofenig 0:796d0f61a05b 4797 */
HannesTschofenig 0:796d0f61a05b 4798 int ssl_curve_is_acceptable( const ssl_context *ssl, ecp_group_id grp_id )
HannesTschofenig 0:796d0f61a05b 4799 {
HannesTschofenig 0:796d0f61a05b 4800 const ecp_group_id *gid;
HannesTschofenig 0:796d0f61a05b 4801
HannesTschofenig 0:796d0f61a05b 4802 for( gid = ssl->curve_list; *gid != POLARSSL_ECP_DP_NONE; gid++ )
HannesTschofenig 0:796d0f61a05b 4803 if( *gid == grp_id )
HannesTschofenig 0:796d0f61a05b 4804 return( 1 );
HannesTschofenig 0:796d0f61a05b 4805
HannesTschofenig 0:796d0f61a05b 4806 return( 0 );
HannesTschofenig 0:796d0f61a05b 4807 }
HannesTschofenig 0:796d0f61a05b 4808 #endif /* POLARSSL_SSL_SET_CURVES */
HannesTschofenig 0:796d0f61a05b 4809
HannesTschofenig 0:796d0f61a05b 4810 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 4811 int ssl_check_cert_usage( const x509_crt *cert,
HannesTschofenig 0:796d0f61a05b 4812 const ssl_ciphersuite_t *ciphersuite,
HannesTschofenig 0:796d0f61a05b 4813 int cert_endpoint )
HannesTschofenig 0:796d0f61a05b 4814 {
HannesTschofenig 0:796d0f61a05b 4815 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
HannesTschofenig 0:796d0f61a05b 4816 int usage = 0;
HannesTschofenig 0:796d0f61a05b 4817 #endif
HannesTschofenig 0:796d0f61a05b 4818 #if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
HannesTschofenig 0:796d0f61a05b 4819 const char *ext_oid;
HannesTschofenig 0:796d0f61a05b 4820 size_t ext_len;
HannesTschofenig 0:796d0f61a05b 4821 #endif
HannesTschofenig 0:796d0f61a05b 4822
HannesTschofenig 0:796d0f61a05b 4823 #if !defined(POLARSSL_X509_CHECK_KEY_USAGE) && \
HannesTschofenig 0:796d0f61a05b 4824 !defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
HannesTschofenig 0:796d0f61a05b 4825 ((void) cert);
HannesTschofenig 0:796d0f61a05b 4826 ((void) cert_endpoint);
HannesTschofenig 0:796d0f61a05b 4827 #endif
HannesTschofenig 0:796d0f61a05b 4828
HannesTschofenig 0:796d0f61a05b 4829 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
HannesTschofenig 0:796d0f61a05b 4830 if( cert_endpoint == SSL_IS_SERVER )
HannesTschofenig 0:796d0f61a05b 4831 {
HannesTschofenig 0:796d0f61a05b 4832 /* Server part of the key exchange */
HannesTschofenig 0:796d0f61a05b 4833 switch( ciphersuite->key_exchange )
HannesTschofenig 0:796d0f61a05b 4834 {
HannesTschofenig 0:796d0f61a05b 4835 case POLARSSL_KEY_EXCHANGE_RSA:
HannesTschofenig 0:796d0f61a05b 4836 case POLARSSL_KEY_EXCHANGE_RSA_PSK:
HannesTschofenig 0:796d0f61a05b 4837 usage = KU_KEY_ENCIPHERMENT;
HannesTschofenig 0:796d0f61a05b 4838 break;
HannesTschofenig 0:796d0f61a05b 4839
HannesTschofenig 0:796d0f61a05b 4840 case POLARSSL_KEY_EXCHANGE_DHE_RSA:
HannesTschofenig 0:796d0f61a05b 4841 case POLARSSL_KEY_EXCHANGE_ECDHE_RSA:
HannesTschofenig 0:796d0f61a05b 4842 case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA:
HannesTschofenig 0:796d0f61a05b 4843 usage = KU_DIGITAL_SIGNATURE;
HannesTschofenig 0:796d0f61a05b 4844 break;
HannesTschofenig 0:796d0f61a05b 4845
HannesTschofenig 0:796d0f61a05b 4846 case POLARSSL_KEY_EXCHANGE_ECDH_RSA:
HannesTschofenig 0:796d0f61a05b 4847 case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA:
HannesTschofenig 0:796d0f61a05b 4848 usage = KU_KEY_AGREEMENT;
HannesTschofenig 0:796d0f61a05b 4849 break;
HannesTschofenig 0:796d0f61a05b 4850
HannesTschofenig 0:796d0f61a05b 4851 /* Don't use default: we want warnings when adding new values */
HannesTschofenig 0:796d0f61a05b 4852 case POLARSSL_KEY_EXCHANGE_NONE:
HannesTschofenig 0:796d0f61a05b 4853 case POLARSSL_KEY_EXCHANGE_PSK:
HannesTschofenig 0:796d0f61a05b 4854 case POLARSSL_KEY_EXCHANGE_DHE_PSK:
HannesTschofenig 0:796d0f61a05b 4855 case POLARSSL_KEY_EXCHANGE_ECDHE_PSK:
HannesTschofenig 0:796d0f61a05b 4856 usage = 0;
HannesTschofenig 0:796d0f61a05b 4857 }
HannesTschofenig 0:796d0f61a05b 4858 }
HannesTschofenig 0:796d0f61a05b 4859 else
HannesTschofenig 0:796d0f61a05b 4860 {
HannesTschofenig 0:796d0f61a05b 4861 /* Client auth: we only implement rsa_sign and ecdsa_sign for now */
HannesTschofenig 0:796d0f61a05b 4862 usage = KU_DIGITAL_SIGNATURE;
HannesTschofenig 0:796d0f61a05b 4863 }
HannesTschofenig 0:796d0f61a05b 4864
HannesTschofenig 0:796d0f61a05b 4865 if( x509_crt_check_key_usage( cert, usage ) != 0 )
HannesTschofenig 0:796d0f61a05b 4866 return( -1 );
HannesTschofenig 0:796d0f61a05b 4867 #else
HannesTschofenig 0:796d0f61a05b 4868 ((void) ciphersuite);
HannesTschofenig 0:796d0f61a05b 4869 #endif /* POLARSSL_X509_CHECK_KEY_USAGE */
HannesTschofenig 0:796d0f61a05b 4870
HannesTschofenig 0:796d0f61a05b 4871 #if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
HannesTschofenig 0:796d0f61a05b 4872 if( cert_endpoint == SSL_IS_SERVER )
HannesTschofenig 0:796d0f61a05b 4873 {
HannesTschofenig 0:796d0f61a05b 4874 ext_oid = OID_SERVER_AUTH;
HannesTschofenig 0:796d0f61a05b 4875 ext_len = OID_SIZE( OID_SERVER_AUTH );
HannesTschofenig 0:796d0f61a05b 4876 }
HannesTschofenig 0:796d0f61a05b 4877 else
HannesTschofenig 0:796d0f61a05b 4878 {
HannesTschofenig 0:796d0f61a05b 4879 ext_oid = OID_CLIENT_AUTH;
HannesTschofenig 0:796d0f61a05b 4880 ext_len = OID_SIZE( OID_CLIENT_AUTH );
HannesTschofenig 0:796d0f61a05b 4881 }
HannesTschofenig 0:796d0f61a05b 4882
HannesTschofenig 0:796d0f61a05b 4883 if( x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 )
HannesTschofenig 0:796d0f61a05b 4884 return( -1 );
HannesTschofenig 0:796d0f61a05b 4885 #endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */
HannesTschofenig 0:796d0f61a05b 4886
HannesTschofenig 0:796d0f61a05b 4887 return( 0 );
HannesTschofenig 0:796d0f61a05b 4888 }
HannesTschofenig 0:796d0f61a05b 4889 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 4890
HannesTschofenig 0:796d0f61a05b 4891 #endif /* POLARSSL_SSL_TLS_C */
HannesTschofenig 0:796d0f61a05b 4892
HannesTschofenig 0:796d0f61a05b 4893