/library/ssl_tls.c
C | 3928 lines | 2932 code | 683 blank | 313 comment | 607 complexity | 504bfd6a3b35637d9b6b914116e0df85 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- * SSLv3/TLSv1 shared functions
- *
- * Copyright (C) 2006-2012, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- /*
- * The SSL 3.0 specification was drafted by Netscape in 1996,
- * and became an IETF standard in 1999.
- *
- * http://wp.netscape.com/eng/ssl3/
- * http://www.ietf.org/rfc/rfc2246.txt
- * http://www.ietf.org/rfc/rfc4346.txt
- */
- #include "polarssl/config.h"
- #if defined(POLARSSL_SSL_TLS_C)
- #include "polarssl/aes.h"
- #include "polarssl/arc4.h"
- #include "polarssl/camellia.h"
- #include "polarssl/des.h"
- #include "polarssl/debug.h"
- #include "polarssl/ssl.h"
- #include "polarssl/sha2.h"
- #if defined(POLARSSL_GCM_C)
- #include "polarssl/gcm.h"
- #endif
- #include <stdlib.h>
- #include <time.h>
- #if defined _MSC_VER && !defined strcasecmp
- #define strcasecmp _stricmp
- #endif
- #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
- int (*ssl_hw_record_init)(ssl_context *ssl,
- const unsigned char *key_enc, const unsigned char *key_dec,
- const unsigned char *iv_enc, const unsigned char *iv_dec,
- const unsigned char *mac_enc, const unsigned char *mac_dec) = NULL;
- int (*ssl_hw_record_reset)(ssl_context *ssl) = NULL;
- int (*ssl_hw_record_write)(ssl_context *ssl) = NULL;
- int (*ssl_hw_record_read)(ssl_context *ssl) = NULL;
- int (*ssl_hw_record_finish)(ssl_context *ssl) = NULL;
- #endif
- static int ssl_rsa_decrypt( void *ctx, int mode, size_t *olen,
- const unsigned char *input, unsigned char *output,
- size_t output_max_len )
- {
- return rsa_pkcs1_decrypt( (rsa_context *) ctx, mode, olen, input, output,
- output_max_len );
- }
- static int ssl_rsa_sign( void *ctx,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
- int mode, int hash_id, unsigned int hashlen,
- const unsigned char *hash, unsigned char *sig )
- {
- return rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, mode, hash_id,
- hashlen, hash, sig );
- }
- static size_t ssl_rsa_key_len( void *ctx )
- {
- return ( (rsa_context *) ctx )->len;
- }
- /*
- * Key material generation
- */
- static int ssl3_prf( unsigned char *secret, size_t slen, char *label,
- unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- size_t i;
- md5_context md5;
- sha1_context sha1;
- unsigned char padding[16];
- unsigned char sha1sum[20];
- ((void)label);
- /*
- * SSLv3:
- * block =
- * MD5( secret + SHA1( 'A' + secret + random ) ) +
- * MD5( secret + SHA1( 'BB' + secret + random ) ) +
- * MD5( secret + SHA1( 'CCC' + secret + random ) ) +
- * ...
- */
- for( i = 0; i < dlen / 16; i++ )
- {
- memset( padding, 'A' + i, 1 + i );
- sha1_starts( &sha1 );
- sha1_update( &sha1, padding, 1 + i );
- sha1_update( &sha1, secret, slen );
- sha1_update( &sha1, random, rlen );
- sha1_finish( &sha1, sha1sum );
- md5_starts( &md5 );
- md5_update( &md5, secret, slen );
- md5_update( &md5, sha1sum, 20 );
- md5_finish( &md5, dstbuf + i * 16 );
- }
- memset( &md5, 0, sizeof( md5 ) );
- memset( &sha1, 0, sizeof( sha1 ) );
- memset( padding, 0, sizeof( padding ) );
- memset( sha1sum, 0, sizeof( sha1sum ) );
- return( 0 );
- }
- static int tls1_prf( unsigned char *secret, size_t slen, char *label,
- unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- size_t nb, hs;
- size_t i, j, k;
- unsigned char *S1, *S2;
- unsigned char tmp[128];
- unsigned char h_i[20];
- if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
- return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
- hs = ( slen + 1 ) / 2;
- S1 = secret;
- S2 = secret + slen - hs;
- nb = strlen( label );
- memcpy( tmp + 20, label, nb );
- memcpy( tmp + 20 + nb, random, rlen );
- nb += rlen;
- /*
- * First compute P_md5(secret,label+random)[0..dlen]
- */
- md5_hmac( S1, hs, tmp + 20, nb, 4 + tmp );
- for( i = 0; i < dlen; i += 16 )
- {
- md5_hmac( S1, hs, 4 + tmp, 16 + nb, h_i );
- md5_hmac( S1, hs, 4 + tmp, 16, 4 + tmp );
- k = ( i + 16 > dlen ) ? dlen % 16 : 16;
- for( j = 0; j < k; j++ )
- dstbuf[i + j] = h_i[j];
- }
- /*
- * XOR out with P_sha1(secret,label+random)[0..dlen]
- */
- sha1_hmac( S2, hs, tmp + 20, nb, tmp );
- for( i = 0; i < dlen; i += 20 )
- {
- sha1_hmac( S2, hs, tmp, 20 + nb, h_i );
- sha1_hmac( S2, hs, tmp, 20, tmp );
- k = ( i + 20 > dlen ) ? dlen % 20 : 20;
- for( j = 0; j < k; j++ )
- dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
- }
- memset( tmp, 0, sizeof( tmp ) );
- memset( h_i, 0, sizeof( h_i ) );
- return( 0 );
- }
- static int tls_prf_sha256( unsigned char *secret, size_t slen, char *label,
- unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- size_t nb;
- size_t i, j, k;
- unsigned char tmp[128];
- unsigned char h_i[32];
- if( sizeof( tmp ) < 32 + strlen( label ) + rlen )
- return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
- nb = strlen( label );
- memcpy( tmp + 32, label, nb );
- memcpy( tmp + 32 + nb, random, rlen );
- nb += rlen;
- /*
- * Compute P_<hash>(secret, label + random)[0..dlen]
- */
- sha2_hmac( secret, slen, tmp + 32, nb, tmp, 0 );
- for( i = 0; i < dlen; i += 32 )
- {
- sha2_hmac( secret, slen, tmp, 32 + nb, h_i, 0 );
- sha2_hmac( secret, slen, tmp, 32, tmp, 0 );
- k = ( i + 32 > dlen ) ? dlen % 32 : 32;
- for( j = 0; j < k; j++ )
- dstbuf[i + j] = h_i[j];
- }
- memset( tmp, 0, sizeof( tmp ) );
- memset( h_i, 0, sizeof( h_i ) );
- return( 0 );
- }
- #if defined(POLARSSL_SHA4_C)
- static int tls_prf_sha384( unsigned char *secret, size_t slen, char *label,
- unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- size_t nb;
- size_t i, j, k;
- unsigned char tmp[128];
- unsigned char h_i[48];
- if( sizeof( tmp ) < 48 + strlen( label ) + rlen )
- return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
- nb = strlen( label );
- memcpy( tmp + 48, label, nb );
- memcpy( tmp + 48 + nb, random, rlen );
- nb += rlen;
- /*
- * Compute P_<hash>(secret, label + random)[0..dlen]
- */
- sha4_hmac( secret, slen, tmp + 48, nb, tmp, 1 );
- for( i = 0; i < dlen; i += 48 )
- {
- sha4_hmac( secret, slen, tmp, 48 + nb, h_i, 1 );
- sha4_hmac( secret, slen, tmp, 48, tmp, 1 );
- k = ( i + 48 > dlen ) ? dlen % 48 : 48;
- for( j = 0; j < k; j++ )
- dstbuf[i + j] = h_i[j];
- }
- memset( tmp, 0, sizeof( tmp ) );
- memset( h_i, 0, sizeof( h_i ) );
- return( 0 );
- }
- #endif
- static void ssl_update_checksum_start(ssl_context *, unsigned char *, size_t);
- static void ssl_update_checksum_md5sha1(ssl_context *, unsigned char *, size_t);
- static void ssl_update_checksum_sha256(ssl_context *, unsigned char *, size_t);
- static void ssl_calc_verify_ssl(ssl_context *,unsigned char *);
- static void ssl_calc_verify_tls(ssl_context *,unsigned char *);
- static void ssl_calc_verify_tls_sha256(ssl_context *,unsigned char *);
- static void ssl_calc_finished_ssl(ssl_context *,unsigned char *,int);
- static void ssl_calc_finished_tls(ssl_context *,unsigned char *,int);
- static void ssl_calc_finished_tls_sha256(ssl_context *,unsigned char *,int);
- #if defined(POLARSSL_SHA4_C)
- static void ssl_update_checksum_sha384(ssl_context *, unsigned char *, size_t);
- static void ssl_calc_verify_tls_sha384(ssl_context *,unsigned char *);
- static void ssl_calc_finished_tls_sha384(ssl_context *,unsigned char *,int);
- #endif
- int ssl_derive_keys( ssl_context *ssl )
- {
- unsigned char tmp[64];
- unsigned char keyblk[256];
- unsigned char *key1;
- unsigned char *key2;
- unsigned int iv_copy_len;
- ssl_session *session = ssl->session_negotiate;
- ssl_transform *transform = ssl->transform_negotiate;
- ssl_handshake_params *handshake = ssl->handshake;
- SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
- /*
- * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
- */
- if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
- {
- handshake->tls_prf = ssl3_prf;
- handshake->calc_verify = ssl_calc_verify_ssl;
- handshake->calc_finished = ssl_calc_finished_ssl;
- }
- else if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
- {
- handshake->tls_prf = tls1_prf;
- handshake->calc_verify = ssl_calc_verify_tls;
- handshake->calc_finished = ssl_calc_finished_tls;
- }
- #if defined(POLARSSL_SHA4_C)
- else if( session->ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
- session->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
- {
- handshake->tls_prf = tls_prf_sha384;
- handshake->calc_verify = ssl_calc_verify_tls_sha384;
- handshake->calc_finished = ssl_calc_finished_tls_sha384;
- }
- #endif
- else
- {
- handshake->tls_prf = tls_prf_sha256;
- handshake->calc_verify = ssl_calc_verify_tls_sha256;
- handshake->calc_finished = ssl_calc_finished_tls_sha256;
- }
- /*
- * SSLv3:
- * master =
- * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) +
- * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) +
- * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
- *
- * TLSv1:
- * master = PRF( premaster, "master secret", randbytes )[0..47]
- */
- if( handshake->resume == 0 )
- {
- SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
- handshake->pmslen );
- handshake->tls_prf( handshake->premaster, handshake->pmslen,
- "master secret",
- handshake->randbytes, 64, session->master, 48 );
- memset( handshake->premaster, 0, sizeof( handshake->premaster ) );
- }
- else
- SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
- /*
- * Swap the client and server random values.
- */
- memcpy( tmp, handshake->randbytes, 64 );
- memcpy( handshake->randbytes, tmp + 32, 32 );
- memcpy( handshake->randbytes + 32, tmp, 32 );
- memset( tmp, 0, sizeof( tmp ) );
- /*
- * SSLv3:
- * key block =
- * MD5( master + SHA1( 'A' + master + randbytes ) ) +
- * MD5( master + SHA1( 'BB' + master + randbytes ) ) +
- * MD5( master + SHA1( 'CCC' + master + randbytes ) ) +
- * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
- * ...
- *
- * TLSv1:
- * key block = PRF( master, "key expansion", randbytes )
- */
- handshake->tls_prf( session->master, 48, "key expansion",
- handshake->randbytes, 64, keyblk, 256 );
- SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
- ssl_get_ciphersuite_name( session->ciphersuite ) ) );
- SSL_DEBUG_BUF( 3, "master secret", session->master, 48 );
- SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
- SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
- memset( handshake->randbytes, 0, sizeof( handshake->randbytes ) );
- /*
- * Determine the appropriate key, IV and MAC length.
- */
- switch( session->ciphersuite )
- {
- #if defined(POLARSSL_ARC4_C)
- case TLS_RSA_WITH_RC4_128_MD5:
- transform->keylen = 16; transform->minlen = 16;
- transform->ivlen = 0; transform->maclen = 16;
- break;
- case TLS_RSA_WITH_RC4_128_SHA:
- transform->keylen = 16; transform->minlen = 20;
- transform->ivlen = 0; transform->maclen = 20;
- break;
- #endif
- #if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- transform->keylen = 24; transform->minlen = 24;
- transform->ivlen = 8; transform->maclen = 20;
- break;
- #endif
- #if defined(POLARSSL_AES_C)
- case TLS_RSA_WITH_AES_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- transform->keylen = 16; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 20;
- break;
- case TLS_RSA_WITH_AES_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- transform->keylen = 32; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 20;
- break;
- #if defined(POLARSSL_SHA2_C)
- case TLS_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- transform->keylen = 16; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 32;
- break;
- case TLS_RSA_WITH_AES_256_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- transform->keylen = 32; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 32;
- break;
- #endif
- #if defined(POLARSSL_GCM_C)
- case TLS_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- transform->keylen = 16; transform->minlen = 1;
- transform->ivlen = 12; transform->maclen = 0;
- transform->fixed_ivlen = 4;
- break;
- case TLS_RSA_WITH_AES_256_GCM_SHA384:
- case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- transform->keylen = 32; transform->minlen = 1;
- transform->ivlen = 12; transform->maclen = 0;
- transform->fixed_ivlen = 4;
- break;
- #endif
- #endif
- #if defined(POLARSSL_CAMELLIA_C)
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- transform->keylen = 16; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 20;
- break;
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- transform->keylen = 32; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 20;
- break;
- #if defined(POLARSSL_SHA2_C)
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- transform->keylen = 16; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 32;
- break;
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- transform->keylen = 32; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 32;
- break;
- #endif
- #endif
- #if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
- #if defined(POLARSSL_CIPHER_NULL_CIPHER)
- case TLS_RSA_WITH_NULL_MD5:
- transform->keylen = 0; transform->minlen = 0;
- transform->ivlen = 0; transform->maclen = 16;
- break;
- case TLS_RSA_WITH_NULL_SHA:
- transform->keylen = 0; transform->minlen = 0;
- transform->ivlen = 0; transform->maclen = 20;
- break;
- case TLS_RSA_WITH_NULL_SHA256:
- transform->keylen = 0; transform->minlen = 0;
- transform->ivlen = 0; transform->maclen = 32;
- break;
- #endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
- #if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_DES_CBC_SHA:
- case TLS_DHE_RSA_WITH_DES_CBC_SHA:
- transform->keylen = 8; transform->minlen = 8;
- transform->ivlen = 8; transform->maclen = 20;
- break;
- #endif
- #endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
- default:
- SSL_DEBUG_MSG( 1, ( "ciphersuite %s is not available",
- ssl_get_ciphersuite_name( session->ciphersuite ) ) );
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
- transform->keylen, transform->minlen, transform->ivlen,
- transform->maclen ) );
- /*
- * Finally setup the cipher contexts, IVs and MAC secrets.
- */
- if( ssl->endpoint == SSL_IS_CLIENT )
- {
- key1 = keyblk + transform->maclen * 2;
- key2 = keyblk + transform->maclen * 2 + transform->keylen;
- memcpy( transform->mac_enc, keyblk, transform->maclen );
- memcpy( transform->mac_dec, keyblk + transform->maclen,
- transform->maclen );
- /*
- * This is not used in TLS v1.1.
- */
- iv_copy_len = ( transform->fixed_ivlen ) ?
- transform->fixed_ivlen : transform->ivlen;
- memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len );
- memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len,
- iv_copy_len );
- }
- else
- {
- key1 = keyblk + transform->maclen * 2 + transform->keylen;
- key2 = keyblk + transform->maclen * 2;
- memcpy( transform->mac_dec, keyblk, transform->maclen );
- memcpy( transform->mac_enc, keyblk + transform->maclen,
- transform->maclen );
- /*
- * This is not used in TLS v1.1.
- */
- iv_copy_len = ( transform->fixed_ivlen ) ?
- transform->fixed_ivlen : transform->ivlen;
- memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len );
- memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len,
- iv_copy_len );
- }
- #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
- if( ssl_hw_record_init != NULL)
- {
- int ret = 0;
- SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_init()" ) );
- if( ( ret = ssl_hw_record_init( ssl, key1, key2, transform->iv_enc,
- transform->iv_dec, transform->mac_enc,
- transform->mac_dec ) ) != 0 )
- {
- SSL_DEBUG_RET( 1, "ssl_hw_record_init", ret );
- return POLARSSL_ERR_SSL_HW_ACCEL_FAILED;
- }
- }
- #endif
- switch( session->ciphersuite )
- {
- #if defined(POLARSSL_ARC4_C)
- case TLS_RSA_WITH_RC4_128_MD5:
- case TLS_RSA_WITH_RC4_128_SHA:
- arc4_setup( (arc4_context *) transform->ctx_enc, key1,
- transform->keylen );
- arc4_setup( (arc4_context *) transform->ctx_dec, key2,
- transform->keylen );
- break;
- #endif
- #if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- des3_set3key_enc( (des3_context *) transform->ctx_enc, key1 );
- des3_set3key_dec( (des3_context *) transform->ctx_dec, key2 );
- break;
- #endif
- #if defined(POLARSSL_AES_C)
- case TLS_RSA_WITH_AES_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- case TLS_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- aes_setkey_enc( (aes_context *) transform->ctx_enc, key1, 128 );
- aes_setkey_dec( (aes_context *) transform->ctx_dec, key2, 128 );
- break;
- case TLS_RSA_WITH_AES_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- case TLS_RSA_WITH_AES_256_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- aes_setkey_enc( (aes_context *) transform->ctx_enc, key1, 256 );
- aes_setkey_dec( (aes_context *) transform->ctx_dec, key2, 256 );
- break;
- #if defined(POLARSSL_GCM_C)
- case TLS_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- gcm_init( (gcm_context *) transform->ctx_enc, key1, 128 );
- gcm_init( (gcm_context *) transform->ctx_dec, key2, 128 );
- break;
- case TLS_RSA_WITH_AES_256_GCM_SHA384:
- case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- gcm_init( (gcm_context *) transform->ctx_enc, key1, 256 );
- gcm_init( (gcm_context *) transform->ctx_dec, key2, 256 );
- break;
- #endif
- #endif
- #if defined(POLARSSL_CAMELLIA_C)
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- camellia_setkey_enc( (camellia_context *) transform->ctx_enc, key1, 128 );
- camellia_setkey_dec( (camellia_context *) transform->ctx_dec, key2, 128 );
- break;
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- camellia_setkey_enc( (camellia_context *) transform->ctx_enc, key1, 256 );
- camellia_setkey_dec( (camellia_context *) transform->ctx_dec, key2, 256 );
- break;
- #endif
- #if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
- #if defined(POLARSSL_CIPHER_NULL_CIPHER)
- case TLS_RSA_WITH_NULL_MD5:
- case TLS_RSA_WITH_NULL_SHA:
- case TLS_RSA_WITH_NULL_SHA256:
- break;
- #endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
- #if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_DES_CBC_SHA:
- case TLS_DHE_RSA_WITH_DES_CBC_SHA:
- des_setkey_enc( (des_context *) transform->ctx_enc, key1 );
- des_setkey_dec( (des_context *) transform->ctx_dec, key2 );
- break;
- #endif
- #endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
- default:
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- memset( keyblk, 0, sizeof( keyblk ) );
- #if defined(POLARSSL_ZLIB_SUPPORT)
- // Initialize compression
- //
- if( session->compression == SSL_COMPRESS_DEFLATE )
- {
- SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) );
- memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) );
- memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) );
- if( deflateInit( &transform->ctx_deflate, Z_DEFAULT_COMPRESSION ) != Z_OK ||
- inflateInit( &transform->ctx_inflate ) != Z_OK )
- {
- SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
- return( POLARSSL_ERR_SSL_COMPRESSION_FAILED );
- }
- }
- #endif /* POLARSSL_ZLIB_SUPPORT */
- SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
- return( 0 );
- }
- void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] )
- {
- md5_context md5;
- sha1_context sha1;
- unsigned char pad_1[48];
- unsigned char pad_2[48];
- SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) );
- memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) );
- memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) );
- memset( pad_1, 0x36, 48 );
- memset( pad_2, 0x5C, 48 );
- md5_update( &md5, ssl->session_negotiate->master, 48 );
- md5_update( &md5, pad_1, 48 );
- md5_finish( &md5, hash );
- md5_starts( &md5 );
- md5_update( &md5, ssl->session_negotiate->master, 48 );
- md5_update( &md5, pad_2, 48 );
- md5_update( &md5, hash, 16 );
- md5_finish( &md5, hash );
- sha1_update( &sha1, ssl->session_negotiate->master, 48 );
- sha1_update( &sha1, pad_1, 40 );
- sha1_finish( &sha1, hash + 16 );
- sha1_starts( &sha1 );
- sha1_update( &sha1, ssl->session_negotiate->master, 48 );
- sha1_update( &sha1, pad_2, 40 );
- sha1_update( &sha1, hash + 16, 20 );
- sha1_finish( &sha1, hash + 16 );
- SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
- SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
- return;
- }
- void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] )
- {
- md5_context md5;
- sha1_context sha1;
- SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) );
- memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) );
- memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) );
- md5_finish( &md5, hash );
- sha1_finish( &sha1, hash + 16 );
- SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
- SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
- return;
- }
- void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] )
- {
- sha2_context sha2;
- SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
- memcpy( &sha2, &ssl->handshake->fin_sha2, sizeof(sha2_context) );
- sha2_finish( &sha2, hash );
- SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
- SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
- return;
- }
- #if defined(POLARSSL_SHA4_C)
- void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] )
- {
- sha4_context sha4;
- SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
- memcpy( &sha4, &ssl->handshake->fin_sha4, sizeof(sha4_context) );
- sha4_finish( &sha4, hash );
- SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
- SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
- return;
- }
- #endif
- /*
- * SSLv3.0 MAC functions
- */
- static void ssl_mac_md5( unsigned char *secret,
- unsigned char *buf, size_t len,
- unsigned char *ctr, int type )
- {
- unsigned char header[11];
- unsigned char padding[48];
- md5_context md5;
- memcpy( header, ctr, 8 );
- header[ 8] = (unsigned char) type;
- header[ 9] = (unsigned char)( len >> 8 );
- header[10] = (unsigned char)( len );
- memset( padding, 0x36, 48 );
- md5_starts( &md5 );
- md5_update( &md5, secret, 16 );
- md5_update( &md5, padding, 48 );
- md5_update( &md5, header, 11 );
- md5_update( &md5, buf, len );
- md5_finish( &md5, buf + len );
- memset( padding, 0x5C, 48 );
- md5_starts( &md5 );
- md5_update( &md5, secret, 16 );
- md5_update( &md5, padding, 48 );
- md5_update( &md5, buf + len, 16 );
- md5_finish( &md5, buf + len );
- }
- static void ssl_mac_sha1( unsigned char *secret,
- unsigned char *buf, size_t len,
- unsigned char *ctr, int type )
- {
- unsigned char header[11];
- unsigned char padding[40];
- sha1_context sha1;
- memcpy( header, ctr, 8 );
- header[ 8] = (unsigned char) type;
- header[ 9] = (unsigned char)( len >> 8 );
- header[10] = (unsigned char)( len );
- memset( padding, 0x36, 40 );
- sha1_starts( &sha1 );
- sha1_update( &sha1, secret, 20 );
- sha1_update( &sha1, padding, 40 );
- sha1_update( &sha1, header, 11 );
- sha1_update( &sha1, buf, len );
- sha1_finish( &sha1, buf + len );
- memset( padding, 0x5C, 40 );
- sha1_starts( &sha1 );
- sha1_update( &sha1, secret, 20 );
- sha1_update( &sha1, padding, 40 );
- sha1_update( &sha1, buf + len, 20 );
- sha1_finish( &sha1, buf + len );
- }
- static void ssl_mac_sha2( unsigned char *secret,
- unsigned char *buf, size_t len,
- unsigned char *ctr, int type )
- {
- unsigned char header[11];
- unsigned char padding[32];
- sha2_context sha2;
- memcpy( header, ctr, 8 );
- header[ 8] = (unsigned char) type;
- header[ 9] = (unsigned char)( len >> 8 );
- header[10] = (unsigned char)( len );
- memset( padding, 0x36, 32 );
- sha2_starts( &sha2, 0 );
- sha2_update( &sha2, secret, 32 );
- sha2_update( &sha2, padding, 32 );
- sha2_update( &sha2, header, 11 );
- sha2_update( &sha2, buf, len );
- sha2_finish( &sha2, buf + len );
- memset( padding, 0x5C, 32 );
- sha2_starts( &sha2, 0 );
- sha2_update( &sha2, secret, 32 );
- sha2_update( &sha2, padding, 32 );
- sha2_update( &sha2, buf + len, 32 );
- sha2_finish( &sha2, buf + len );
- }
- /*
- * Encryption/decryption functions
- */
- static int ssl_encrypt_buf( ssl_context *ssl )
- {
- size_t i, padlen;
- SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
- /*
- * Add MAC then encrypt
- */
- if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
- {
- if( ssl->transform_out->maclen == 16 )
- ssl_mac_md5( ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype );
- else if( ssl->transform_out->maclen == 20 )
- ssl_mac_sha1( ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype );
- else if( ssl->transform_out->maclen == 32 )
- ssl_mac_sha2( ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype );
- else if( ssl->transform_out->maclen != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "invalid MAC len: %d",
- ssl->transform_out->maclen ) );
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- }
- else
- {
- if( ssl->transform_out->maclen == 16 )
- {
- md5_context ctx;
- md5_hmac_starts( &ctx, ssl->transform_out->mac_enc, 16 );
- md5_hmac_update( &ctx, ssl->out_ctr, 13 );
- md5_hmac_update( &ctx, ssl->out_msg, ssl->out_msglen );
- md5_hmac_finish( &ctx, ssl->out_msg + ssl->out_msglen );
- memset( &ctx, 0, sizeof(md5_context));
- }
- else if( ssl->transform_out->maclen == 20 )
- {
- sha1_context ctx;
- sha1_hmac_starts( &ctx, ssl->transform_out->mac_enc, 20 );
- sha1_hmac_update( &ctx, ssl->out_ctr, 13 );
- sha1_hmac_update( &ctx, ssl->out_msg, ssl->out_msglen );
- sha1_hmac_finish( &ctx, ssl->out_msg + ssl->out_msglen );
- memset( &ctx, 0, sizeof(sha1_context));
- }
- else if( ssl->transform_out->maclen == 32 )
- {
- sha2_context ctx;
- sha2_hmac_starts( &ctx, ssl->transform_out->mac_enc, 32, 0 );
- sha2_hmac_update( &ctx, ssl->out_ctr, 13 );
- sha2_hmac_update( &ctx, ssl->out_msg, ssl->out_msglen );
- sha2_hmac_finish( &ctx, ssl->out_msg + ssl->out_msglen );
- memset( &ctx, 0, sizeof(sha2_context));
- }
- else if( ssl->transform_out->maclen != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "invalid MAC len: %d",
- ssl->transform_out->maclen ) );
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- }
- SSL_DEBUG_BUF( 4, "computed mac",
- ssl->out_msg + ssl->out_msglen, ssl->transform_out->maclen );
- ssl->out_msglen += ssl->transform_out->maclen;
- if( ssl->transform_out->ivlen == 0 )
- {
- padlen = 0;
- SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of padding",
- ssl->out_msglen, 0 ) );
- SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
- #if defined(POLARSSL_ARC4_C)
- if( ssl->session_out->ciphersuite == TLS_RSA_WITH_RC4_128_MD5 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_RC4_128_SHA )
- {
- arc4_crypt( (arc4_context *) ssl->transform_out->ctx_enc,
- ssl->out_msglen, ssl->out_msg,
- ssl->out_msg );
- } else
- #endif
- #if defined(POLARSSL_CIPHER_NULL_CIPHER)
- if( ssl->session_out->ciphersuite == TLS_RSA_WITH_NULL_MD5 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_NULL_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_NULL_SHA256 )
- {
- } else
- #endif
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- else if( ssl->transform_out->ivlen == 12 )
- {
- size_t enc_msglen;
- unsigned char *enc_msg;
- unsigned char add_data[13];
- int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
- padlen = 0;
- enc_msglen = ssl->out_msglen;
- memcpy( add_data, ssl->out_ctr, 8 );
- add_data[8] = ssl->out_msgtype;
- add_data[9] = ssl->major_ver;
- add_data[10] = ssl->minor_ver;
- add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->out_msglen & 0xFF;
- SSL_DEBUG_BUF( 4, "additional data used for AEAD",
- add_data, 13 );
- #if defined(POLARSSL_AES_C) && defined(POLARSSL_GCM_C)
- if( ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
- {
- /*
- * Generate IV
- */
- ret = ssl->f_rng( ssl->p_rng,
- ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
- if( ret != 0 )
- return( ret );
- /*
- * Shift message for ivlen bytes and prepend IV
- */
- memmove( ssl->out_msg + ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen,
- ssl->out_msg, ssl->out_msglen );
- memcpy( ssl->out_msg,
- ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
- /*
- * Fix pointer positions and message length with added IV
- */
- enc_msg = ssl->out_msg + ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen;
- SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of padding",
- ssl->out_msglen, 0 ) );
- SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
- /*
- * Adjust for tag
- */
- ssl->out_msglen += 16;
-
- gcm_crypt_and_tag( (gcm_context *) ssl->transform_out->ctx_enc,
- GCM_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, ssl->transform_out->ivlen,
- add_data, 13,
- enc_msg, enc_msg,
- 16, enc_msg + enc_msglen );
- SSL_DEBUG_BUF( 4, "after encrypt: tag",
- enc_msg + enc_msglen, 16 );
- } else
- #endif
- return( ret );
- }
- else
- {
- unsigned char *enc_msg;
- size_t enc_msglen;
- padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) %
- ssl->transform_out->ivlen;
- if( padlen == ssl->transform_out->ivlen )
- padlen = 0;
- for( i = 0; i <= padlen; i++ )
- ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen;
- ssl->out_msglen += padlen + 1;
- enc_msglen = ssl->out_msglen;
- enc_msg = ssl->out_msg;
- /*
- * Prepend per-record IV for block cipher in TLS v1.1 and up as per
- * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
- */
- if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
- {
- /*
- * Generate IV
- */
- int ret = ssl->f_rng( ssl->p_rng, ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen );
- if( ret != 0 )
- return( ret );
- /*
- * Shift message for ivlen bytes and prepend IV
- */
- memmove( ssl->out_msg + ssl->transform_out->ivlen, ssl->out_msg,
- ssl->out_msglen );
- memcpy( ssl->out_msg, ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen );
- /*
- * Fix pointer positions and message length with added IV
- */
- enc_msg = ssl->out_msg + ssl->transform_out->ivlen;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += ssl->transform_out->ivlen;
- }
- SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of IV and %d bytes of padding",
- ssl->out_msglen, ssl->transform_out->ivlen, padlen + 1 ) );
- SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
- switch( ssl->transform_out->ivlen )
- {
- #if defined(POLARSSL_DES_C)
- case 8:
- #if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
- if( ssl->session_out->ciphersuite == TLS_RSA_WITH_DES_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_DES_CBC_SHA )
- {
- des_crypt_cbc( (des_context *) ssl->transform_out->ctx_enc,
- DES_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, enc_msg, enc_msg );
- }
- else
- #endif
- des3_crypt_cbc( (des3_context *) ssl->transform_out->ctx_enc,
- DES_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, enc_msg, enc_msg );
- break;
- #endif
- case 16:
- #if defined(POLARSSL_AES_C)
- if ( ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_256_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 )
- {
- aes_crypt_cbc( (aes_context *) ssl->transform_out->ctx_enc,
- AES_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, enc_msg, enc_msg);
- break;
- }
- #endif
- #if defined(POLARSSL_CAMELLIA_C)
- if ( ssl->session_out->ciphersuite == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 )
- {
- camellia_crypt_cbc( (camellia_context *) ssl->transform_out->ctx_enc,
- CAMELLIA_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, enc_msg, enc_msg );
- break;
- }
- #endif
- default:
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- }
- for( i = 8; i > 0; i-- )
- if( ++ssl->out_ctr[i - 1] != 0 )
- break;
- SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
- return( 0 );
- }
- /*
- * TODO: Use digest version when integrated!
- */
- #define POLARSSL_SSL_MAX_MAC_SIZE 32
- static int ssl_decrypt_buf( ssl_context *ssl )
- {
- size_t i, padlen = 0, correct = 1;
- unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE];
- SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
- if( ssl->in_msglen < ssl->transform_in->minlen )
- {
- SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)",
- ssl->in_msglen, ssl->transform_in->minlen ) );
- return( POLARSSL_ERR_SSL_INVALID_MAC );
- }
- if( ssl->transform_in->ivlen == 0 )
- {
- #if defined(POLARSSL_ARC4_C)
- if( ssl->session_in->ciphersuite == TLS_RSA_WITH_RC4_128_MD5 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_RC4_128_SHA )
- {
- arc4_crypt( (arc4_context *) ssl->transform_in->ctx_dec,
- ssl->in_msglen, ssl->in_msg,
- ssl->in_msg );
- } else
- #endif
- #if defined(POLARSSL_CIPHER_NULL_CIPHER)
- if( ssl->session_in->ciphersuite == TLS_RSA_WITH_NULL_MD5 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_NULL_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_NULL_SHA256 )
- {
- } else
- #endif
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- else if( ssl->transform_in->ivlen == 12 )
- {
- unsigned char *dec_msg;
- unsigned char *dec_msg_result;
- size_t dec_msglen;
- unsigned char add_data[13];
- int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
- #if defined(POLARSSL_AES_C) && defined(POLARSSL_GCM_C)
- if( ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
- {
- dec_msglen = ssl->in_msglen - ( ssl->transform_in->ivlen -
- ssl->transform_in->fixed_ivlen );
- dec_msglen -= 16;
- dec_msg = ssl->in_msg + ( ssl->transform_in->ivlen -
- ssl->transform_in->fixed_ivlen );
- dec_msg_result = ssl->in_msg;
- ssl->in_msglen = dec_msglen;
- memcpy( add_data, ssl->in_ctr, 8 );
- add_data[8] = ssl->in_msgtype;
- add_data[9] = ssl->major_ver;
- add_data[10] = ssl->minor_ver;
- add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->in_msglen & 0xFF;
- SSL_DEBUG_BUF( 4, "additional data used for AEAD",
- add_data, 13 );
- memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
- ssl->in_msg,
- ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
- SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen );
- SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, 16 );
- memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
- ssl->in_msg,
- ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
- ret = gcm_auth_decrypt( (gcm_context *) ssl->transform_in->ctx_dec,
- dec_msglen,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- add_data, 13,
- dec_msg + dec_msglen, 16,
- dec_msg, dec_msg_result );
-
- if( ret != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "AEAD decrypt failed on validation (ret = -0x%02x)",
- -ret ) );
- return( POLARSSL_ERR_SSL_INVALID_MAC );
- }
- } else
- #endif
- return( ret );
- }
- else
- {
- /*
- * Decrypt and check the padding
- */
- unsigned char *dec_msg;
- unsigned char *dec_msg_result;
- size_t dec_msglen;
- size_t minlen = 0, fake_padlen;
- /*
- * Check immediate ciphertext sanity
- */
- if( ssl->in_msglen % ssl->transform_in->ivlen != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
- ssl->in_msglen, ssl->transform_in->ivlen ) );
- return( POLARSSL_ERR_SSL_INVALID_MAC );
- }
- if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
- minlen += ssl->transform_in->ivlen;
- if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
- ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
- {
- SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) + 1 ) ( + expl IV )",
- ssl->in_msglen, ssl->transform_in->ivlen, ssl->transform_in->maclen ) );
- return( POLARSSL_ERR_SSL_INVALID_MAC );
- }
- dec_msglen = ssl->in_msglen;
- dec_msg = ssl->in_msg;
- dec_msg_result = ssl->in_msg;
- /*
- * Initialize for prepended IV for block cipher in TLS v1.1 and up
- */
- if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
- {
- dec_msg += ssl->transform_in->ivlen;
- dec_msglen -= ssl->transform_in->ivlen;
- ssl->in_msglen -= ssl->transform_in->ivlen;
- for( i = 0; i < ssl->transform_in->ivlen; i++ )
- ssl->transform_in->iv_dec[i] = ssl->in_msg[i];
- }
- switch( ssl->transform_in->ivlen )
- {
- #if defined(POLARSSL_DES_C)
- case 8:
- #if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
- if( ssl->session_in->ciphersuite == TLS_RSA_WITH_DES_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_DES_CBC_SHA )
- {
- des_crypt_cbc( (des_context *) ssl->transform_in->ctx_dec,
- DES_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
- }
- else
- #endif
- des3_crypt_cbc( (des3_context *) ssl->transform_in->ctx_dec,
- DES_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
- break;
- #endif
- case 16:
- #if defined(POLARSSL_AES_C)
- if ( ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_256_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 )
- {
- aes_crypt_cbc( (aes_context *) ssl->transform_in->ctx_dec,
- AES_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
- break;
- }
- #endif
- #if defined(POLARSSL_CAMELLIA_C)
- if ( ssl->session_in->ciphersuite == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 )
- {
- camellia_crypt_cbc( (camellia_context *) ssl->transform_in->ctx_dec,
- CAMELLIA_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
- break;
- }
- #endif
- default:
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
- fake_padlen = 256 - padlen;
- if( ssl->in_msglen < ssl->transform_in->maclen + padlen )
- {
- #if defined(POLARSSL_SSL_DEBUG_ALL)
- SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
- ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
- #endif
- padlen = 0;
- fake_padlen = 256;
- correct = 0;
- }
- if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
- {
- if( padlen > ssl->transform_in->ivlen )
- {
- #if defined(POLARSSL_SSL_DEBUG_ALL)
- SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
- "should be no more than %d",
- padlen, ssl->transform_in->ivlen ) );
- #endif
- correct = 0;
- }
- …
Large files files are truncated, but you can click here to view the full file