Align data with future location based on IV size

This commit is contained in:
Paul Bakker 2013-01-02 17:30:03 +01:00
parent 07eb38ba31
commit 92be97b8e6
2 changed files with 72 additions and 53 deletions

View file

@ -448,7 +448,8 @@ struct _ssl_context
*/ */
unsigned char *in_ctr; /*!< 64-bit incoming message counter */ unsigned char *in_ctr; /*!< 64-bit incoming message counter */
unsigned char *in_hdr; /*!< 5-byte record header (in_ctr+8) */ unsigned char *in_hdr; /*!< 5-byte record header (in_ctr+8) */
unsigned char *in_msg; /*!< the message contents (in_hdr+5) */ unsigned char *in_iv; /*!< ivlen-byte IV (in_hdr+5) */
unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */
unsigned char *in_offt; /*!< read offset in application data */ unsigned char *in_offt; /*!< read offset in application data */
int in_msgtype; /*!< record header: message type */ int in_msgtype; /*!< record header: message type */
@ -463,7 +464,8 @@ struct _ssl_context
*/ */
unsigned char *out_ctr; /*!< 64-bit outgoing message counter */ unsigned char *out_ctr; /*!< 64-bit outgoing message counter */
unsigned char *out_hdr; /*!< 5-byte record header (out_ctr+8) */ unsigned char *out_hdr; /*!< 5-byte record header (out_ctr+8) */
unsigned char *out_msg; /*!< the message contents (out_hdr+5) */ unsigned char *out_iv; /*!< ivlen-byte IV (out_hdr+5) */
unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */
int out_msgtype; /*!< record header: message type */ int out_msgtype; /*!< record header: message type */
size_t out_msglen; /*!< record header: message length */ size_t out_msglen; /*!< record header: message length */

View file

@ -923,21 +923,27 @@ static int ssl_encrypt_buf( ssl_context *ssl )
{ {
if( ssl->transform_out->maclen == 16 ) if( ssl->transform_out->maclen == 16 )
{ {
md5_hmac( ssl->transform_out->mac_enc, 16, md5_context md5;
ssl->out_ctr, ssl->out_msglen + 13, md5_hmac_starts( &md5, ssl->transform_out->mac_enc, 16 );
ssl->out_msg + ssl->out_msglen ); md5_hmac_update( &md5, ssl->out_ctr, 13 );
md5_hmac_update( &md5, ssl->out_msg, ssl->out_msglen );
md5_hmac_finish( &md5, ssl->out_msg + ssl->out_msglen );
} }
else if( ssl->transform_out->maclen == 20 ) else if( ssl->transform_out->maclen == 20 )
{ {
sha1_hmac( ssl->transform_out->mac_enc, 20, sha1_context sha1;
ssl->out_ctr, ssl->out_msglen + 13, sha1_hmac_starts( &sha1, ssl->transform_out->mac_enc, 20 );
ssl->out_msg + ssl->out_msglen ); sha1_hmac_update( &sha1, ssl->out_ctr, 13 );
sha1_hmac_update( &sha1, ssl->out_msg, ssl->out_msglen );
sha1_hmac_finish( &sha1, ssl->out_msg + ssl->out_msglen );
} }
else if( ssl->transform_out->maclen == 32 ) else if( ssl->transform_out->maclen == 32 )
{ {
sha2_hmac( ssl->transform_out->mac_enc, 32, sha2_context sha2;
ssl->out_ctr, ssl->out_msglen + 13, sha2_hmac_starts( &sha2, ssl->transform_out->mac_enc, 32, 0 );
ssl->out_msg + ssl->out_msglen, 0 ); sha2_hmac_update( &sha2, ssl->out_ctr, 13 );
sha2_hmac_update( &sha2, ssl->out_msg, ssl->out_msglen );
sha2_hmac_finish( &sha2, ssl->out_msg + ssl->out_msglen );
} }
else if( ssl->transform_out->maclen != 0 ) else if( ssl->transform_out->maclen != 0 )
{ {
@ -1017,21 +1023,14 @@ static int ssl_encrypt_buf( ssl_context *ssl )
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
/* memcpy( ssl->out_iv,
* 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->iv_enc + ssl->transform_out->fixed_ivlen,
ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
/* /*
* Fix pointer positions and message length with added IV * Fix pointer positions and message length with added IV
*/ */
enc_msg = ssl->out_msg + ssl->transform_out->ivlen - enc_msg = ssl->out_msg;
ssl->transform_out->fixed_ivlen;
enc_msglen = ssl->out_msglen; enc_msglen = ssl->out_msglen;
ssl->out_msglen += ssl->transform_out->ivlen - ssl->out_msglen += ssl->transform_out->ivlen -
ssl->transform_out->fixed_ivlen; ssl->transform_out->fixed_ivlen;
@ -1041,7 +1040,7 @@ static int ssl_encrypt_buf( ssl_context *ssl )
ssl->out_msglen, 0 ) ); ssl->out_msglen, 0 ) );
SSL_DEBUG_BUF( 4, "before encrypt: output payload", SSL_DEBUG_BUF( 4, "before encrypt: output payload",
ssl->out_msg, ssl->out_msglen ); ssl->out_iv, ssl->out_msglen );
/* /*
* Adjust for tag * Adjust for tag
@ -1094,18 +1093,13 @@ static int ssl_encrypt_buf( ssl_context *ssl )
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
/* memcpy( ssl->out_iv, ssl->transform_out->iv_enc,
* 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 ); ssl->transform_out->ivlen );
/* /*
* Fix pointer positions and message length with added IV * Fix pointer positions and message length with added IV
*/ */
enc_msg = ssl->out_msg + ssl->transform_out->ivlen; enc_msg = ssl->out_msg;
enc_msglen = ssl->out_msglen; enc_msglen = ssl->out_msglen;
ssl->out_msglen += ssl->transform_out->ivlen; ssl->out_msglen += ssl->transform_out->ivlen;
} }
@ -1115,7 +1109,7 @@ static int ssl_encrypt_buf( ssl_context *ssl )
ssl->out_msglen, ssl->transform_out->ivlen, padlen + 1 ) ); ssl->out_msglen, ssl->transform_out->ivlen, padlen + 1 ) );
SSL_DEBUG_BUF( 4, "before encrypt: output payload", SSL_DEBUG_BUF( 4, "before encrypt: output payload",
ssl->out_msg, ssl->out_msglen ); ssl->out_iv, ssl->out_msglen );
switch( ssl->transform_out->ivlen ) switch( ssl->transform_out->ivlen )
{ {
@ -1242,8 +1236,7 @@ static int ssl_decrypt_buf( ssl_context *ssl )
dec_msglen = ssl->in_msglen - ( ssl->transform_in->ivlen - dec_msglen = ssl->in_msglen - ( ssl->transform_in->ivlen -
ssl->transform_in->fixed_ivlen ); ssl->transform_in->fixed_ivlen );
dec_msglen -= 16; dec_msglen -= 16;
dec_msg = ssl->in_msg + ( ssl->transform_in->ivlen - dec_msg = ssl->in_msg;
ssl->transform_in->fixed_ivlen );
dec_msg_result = ssl->in_msg; dec_msg_result = ssl->in_msg;
ssl->in_msglen = dec_msglen; ssl->in_msglen = dec_msglen;
@ -1258,17 +1251,13 @@ static int ssl_decrypt_buf( ssl_context *ssl )
add_data, 13 ); add_data, 13 );
memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen, memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
ssl->in_msg, ssl->in_iv,
ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen ); ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec, SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec,
ssl->transform_in->ivlen ); ssl->transform_in->ivlen );
SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, 16 ); 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, ret = gcm_auth_decrypt( (gcm_context *) ssl->transform_in->ctx_dec,
dec_msglen, dec_msglen,
ssl->transform_in->iv_dec, ssl->transform_in->iv_dec,
@ -1328,12 +1317,11 @@ static int ssl_decrypt_buf( ssl_context *ssl )
*/ */
if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
{ {
dec_msg += ssl->transform_in->ivlen;
dec_msglen -= ssl->transform_in->ivlen; dec_msglen -= ssl->transform_in->ivlen;
ssl->in_msglen -= ssl->transform_in->ivlen; ssl->in_msglen -= ssl->transform_in->ivlen;
for( i = 0; i < ssl->transform_in->ivlen; i++ ) for( i = 0; i < ssl->transform_in->ivlen; i++ )
ssl->transform_in->iv_dec[i] = ssl->in_msg[i]; ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
} }
switch( ssl->transform_in->ivlen ) switch( ssl->transform_in->ivlen )
@ -1502,33 +1490,36 @@ static int ssl_decrypt_buf( ssl_context *ssl )
if( ssl->transform_in->maclen == 16 ) if( ssl->transform_in->maclen == 16 )
{ {
md5_context ctx; md5_context md5;
md5_hmac_starts( &ctx, ssl->transform_in->mac_dec, 16 ); md5_hmac_starts( &md5, ssl->transform_in->mac_dec, 16 );
md5_hmac_update( &ctx, ssl->in_ctr, ssl->in_msglen + 13 ); md5_hmac_update( &md5, ssl->in_ctr, 13 );
md5_hmac_finish( &ctx, ssl->in_msg + ssl->in_msglen ); md5_hmac_update( &md5, ssl->in_msg, ssl->in_msglen );
md5_hmac_finish( &md5, ssl->in_msg + ssl->in_msglen );
for( j = 0; j < extra_run; j++ ) for( j = 0; j < extra_run; j++ )
md5_process( &ctx, ssl->in_msg ); md5_process( &md5, ssl->in_msg );
} }
else if( ssl->transform_in->maclen == 20 ) else if( ssl->transform_in->maclen == 20 )
{ {
sha1_context ctx; sha1_context sha1;
sha1_hmac_starts( &ctx, ssl->transform_in->mac_dec, 20 ); sha1_hmac_starts( &sha1, ssl->transform_in->mac_dec, 20 );
sha1_hmac_update( &ctx, ssl->in_ctr, ssl->in_msglen + 13 ); sha1_hmac_update( &sha1, ssl->in_ctr, 13 );
sha1_hmac_finish( &ctx, ssl->in_msg + ssl->in_msglen ); sha1_hmac_update( &sha1, ssl->in_msg, ssl->in_msglen );
sha1_hmac_finish( &sha1, ssl->in_msg + ssl->in_msglen );
for( j = 0; j < extra_run; j++ ) for( j = 0; j < extra_run; j++ )
sha1_process( &ctx, ssl->in_msg ); sha1_process( &sha1, ssl->in_msg );
} }
else if( ssl->transform_in->maclen == 32 ) else if( ssl->transform_in->maclen == 32 )
{ {
sha2_context ctx; sha2_context sha2;
sha2_hmac_starts( &ctx, ssl->transform_in->mac_dec, 32, 0 ); sha2_hmac_starts( &sha2, ssl->transform_in->mac_dec, 32, 0 );
sha2_hmac_update( &ctx, ssl->in_ctr, ssl->in_msglen + 13 ); sha2_hmac_update( &sha2, ssl->in_ctr, 13 );
sha2_hmac_finish( &ctx, ssl->in_msg + ssl->in_msglen ); sha2_hmac_update( &sha2, ssl->in_msg, ssl->in_msglen );
sha2_hmac_finish( &sha2, ssl->in_msg + ssl->in_msglen );
for( j = 0; j < extra_run; j++ ) for( j = 0; j < extra_run; j++ )
sha2_process( &ctx, ssl->in_msg ); sha2_process( &sha2, ssl->in_msg );
} }
else if( ssl->transform_in->maclen != 0 ) else if( ssl->transform_in->maclen != 0 )
{ {
@ -2764,6 +2755,17 @@ int ssl_write_finished( ssl_context *ssl )
SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
/*
* Set the out_msg pointer to the correct location based on IV length
*/
if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
{
ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen -
ssl->transform_negotiate->fixed_ivlen;
}
else
ssl->out_msg = ssl->out_iv;
ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->endpoint ); ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->endpoint );
// TODO TLS/1.2 Hash length is determined by cipher suite (Page 63) // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
@ -2838,6 +2840,17 @@ int ssl_parse_finished( ssl_context *ssl )
ssl->session_in = ssl->session_negotiate; ssl->session_in = ssl->session_negotiate;
memset( ssl->in_ctr, 0, 8 ); memset( ssl->in_ctr, 0, 8 );
/*
* Set the in_msg pointer to the correct location based on IV length
*/
if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
{
ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen -
ssl->transform_negotiate->fixed_ivlen;
}
else
ssl->in_msg = ssl->in_iv;
#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
if( ssl_hw_record_activate != NULL) if( ssl_hw_record_activate != NULL)
{ {
@ -2976,6 +2989,7 @@ int ssl_init( ssl_context *ssl )
*/ */
ssl->in_ctr = (unsigned char *) malloc( len ); ssl->in_ctr = (unsigned char *) malloc( len );
ssl->in_hdr = ssl->in_ctr + 8; ssl->in_hdr = ssl->in_ctr + 8;
ssl->in_iv = ssl->in_ctr + 13;
ssl->in_msg = ssl->in_ctr + 13; ssl->in_msg = ssl->in_ctr + 13;
if( ssl->in_ctr == NULL ) if( ssl->in_ctr == NULL )
@ -2986,6 +3000,7 @@ int ssl_init( ssl_context *ssl )
ssl->out_ctr = (unsigned char *) malloc( len ); ssl->out_ctr = (unsigned char *) malloc( len );
ssl->out_hdr = ssl->out_ctr + 8; ssl->out_hdr = ssl->out_ctr + 8;
ssl->out_iv = ssl->out_ctr + 13;
ssl->out_msg = ssl->out_ctr + 13; ssl->out_msg = ssl->out_ctr + 13;
if( ssl->out_ctr == NULL ) if( ssl->out_ctr == NULL )
@ -3025,6 +3040,7 @@ int ssl_session_reset( ssl_context *ssl )
ssl->in_offt = NULL; ssl->in_offt = NULL;
ssl->in_msg = ssl->in_ctr + 13;
ssl->in_msgtype = 0; ssl->in_msgtype = 0;
ssl->in_msglen = 0; ssl->in_msglen = 0;
ssl->in_left = 0; ssl->in_left = 0;
@ -3032,6 +3048,7 @@ int ssl_session_reset( ssl_context *ssl )
ssl->in_hslen = 0; ssl->in_hslen = 0;
ssl->nb_zero = 0; ssl->nb_zero = 0;
ssl->out_msg = ssl->out_ctr + 13;
ssl->out_msgtype = 0; ssl->out_msgtype = 0;
ssl->out_msglen = 0; ssl->out_msglen = 0;
ssl->out_left = 0; ssl->out_left = 0;