From 92be97b8e6b7d2ffd6eda13f283e68ecba9b0495 Mon Sep 17 00:00:00 2001
From: Paul Bakker
Date: Wed, 2 Jan 2013 17:30:03 +0100
Subject: [PATCH] Align data with future location based on IV size
---
include/polarssl/ssl.h | 6 ++-
library/ssl_tls.c | 119 +++++++++++++++++++++++------------------
2 files changed, 72 insertions(+), 53 deletions(-)
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index cc2bb9681..c2ecbaf72 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -448,7 +448,8 @@ struct _ssl_context
*/
unsigned char *in_ctr; /*!< 64-bit incoming message counter */
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 */
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_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 */
size_t out_msglen; /*!< record header: message length */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 94eb649ad..bf22fd0a9 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -923,21 +923,27 @@ static int ssl_encrypt_buf( ssl_context *ssl )
{
if( ssl->transform_out->maclen == 16 )
{
- md5_hmac( ssl->transform_out->mac_enc, 16,
- ssl->out_ctr, ssl->out_msglen + 13,
- ssl->out_msg + ssl->out_msglen );
+ md5_context md5;
+ md5_hmac_starts( &md5, ssl->transform_out->mac_enc, 16 );
+ 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 )
{
- sha1_hmac( ssl->transform_out->mac_enc, 20,
- ssl->out_ctr, ssl->out_msglen + 13,
- ssl->out_msg + ssl->out_msglen );
+ sha1_context sha1;
+ sha1_hmac_starts( &sha1, ssl->transform_out->mac_enc, 20 );
+ 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 )
{
- sha2_hmac( ssl->transform_out->mac_enc, 32,
- ssl->out_ctr, ssl->out_msglen + 13,
- ssl->out_msg + ssl->out_msglen, 0 );
+ sha2_context sha2;
+ sha2_hmac_starts( &sha2, ssl->transform_out->mac_enc, 32, 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 )
{
@@ -1017,21 +1023,14 @@ static int ssl_encrypt_buf( ssl_context *ssl )
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,
+ memcpy( ssl->out_iv,
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_msg = ssl->out_msg;
enc_msglen = ssl->out_msglen;
ssl->out_msglen += ssl->transform_out->ivlen -
ssl->transform_out->fixed_ivlen;
@@ -1041,7 +1040,7 @@ static int ssl_encrypt_buf( ssl_context *ssl )
ssl->out_msglen, 0 ) );
SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
+ ssl->out_iv, ssl->out_msglen );
/*
* Adjust for tag
@@ -1094,18 +1093,13 @@ static int ssl_encrypt_buf( ssl_context *ssl )
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,
+ memcpy( ssl->out_iv, 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_msg = ssl->out_msg;
enc_msglen = ssl->out_msglen;
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_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
+ ssl->out_iv, ssl->out_msglen );
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 -
ssl->transform_in->fixed_ivlen );
dec_msglen -= 16;
- dec_msg = ssl->in_msg + ( ssl->transform_in->ivlen -
- ssl->transform_in->fixed_ivlen );
+ dec_msg = ssl->in_msg;
dec_msg_result = ssl->in_msg;
ssl->in_msglen = dec_msglen;
@@ -1258,17 +1251,13 @@ static int ssl_decrypt_buf( ssl_context *ssl )
add_data, 13 );
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_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,
@@ -1328,12 +1317,11 @@ static int ssl_decrypt_buf( ssl_context *ssl )
*/
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];
+ ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
}
switch( ssl->transform_in->ivlen )
@@ -1502,33 +1490,36 @@ static int ssl_decrypt_buf( ssl_context *ssl )
if( ssl->transform_in->maclen == 16 )
{
- md5_context ctx;
- md5_hmac_starts( &ctx, ssl->transform_in->mac_dec, 16 );
- md5_hmac_update( &ctx, ssl->in_ctr, ssl->in_msglen + 13 );
- md5_hmac_finish( &ctx, ssl->in_msg + ssl->in_msglen );
+ md5_context md5;
+ md5_hmac_starts( &md5, ssl->transform_in->mac_dec, 16 );
+ md5_hmac_update( &md5, ssl->in_ctr, 13 );
+ 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++ )
- md5_process( &ctx, ssl->in_msg );
+ md5_process( &md5, ssl->in_msg );
}
else if( ssl->transform_in->maclen == 20 )
{
- sha1_context ctx;
- sha1_hmac_starts( &ctx, ssl->transform_in->mac_dec, 20 );
- sha1_hmac_update( &ctx, ssl->in_ctr, ssl->in_msglen + 13 );
- sha1_hmac_finish( &ctx, ssl->in_msg + ssl->in_msglen );
+ sha1_context sha1;
+ sha1_hmac_starts( &sha1, ssl->transform_in->mac_dec, 20 );
+ sha1_hmac_update( &sha1, ssl->in_ctr, 13 );
+ 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++ )
- sha1_process( &ctx, ssl->in_msg );
+ sha1_process( &sha1, ssl->in_msg );
}
else if( ssl->transform_in->maclen == 32 )
{
- sha2_context ctx;
- sha2_hmac_starts( &ctx, ssl->transform_in->mac_dec, 32, 0 );
- sha2_hmac_update( &ctx, ssl->in_ctr, ssl->in_msglen + 13 );
- sha2_hmac_finish( &ctx, ssl->in_msg + ssl->in_msglen );
+ sha2_context sha2;
+ sha2_hmac_starts( &sha2, ssl->transform_in->mac_dec, 32, 0 );
+ sha2_hmac_update( &sha2, ssl->in_ctr, 13 );
+ 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++ )
- sha2_process( &ctx, ssl->in_msg );
+ sha2_process( &sha2, ssl->in_msg );
}
else if( ssl->transform_in->maclen != 0 )
{
@@ -2764,6 +2755,17 @@ int ssl_write_finished( ssl_context *ssl )
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 );
// 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;
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( ssl_hw_record_activate != NULL)
{
@@ -2976,6 +2989,7 @@ int ssl_init( ssl_context *ssl )
*/
ssl->in_ctr = (unsigned char *) malloc( len );
ssl->in_hdr = ssl->in_ctr + 8;
+ ssl->in_iv = ssl->in_ctr + 13;
ssl->in_msg = ssl->in_ctr + 13;
if( ssl->in_ctr == NULL )
@@ -2986,6 +3000,7 @@ int ssl_init( ssl_context *ssl )
ssl->out_ctr = (unsigned char *) malloc( len );
ssl->out_hdr = ssl->out_ctr + 8;
+ ssl->out_iv = ssl->out_ctr + 13;
ssl->out_msg = ssl->out_ctr + 13;
if( ssl->out_ctr == NULL )
@@ -3025,6 +3040,7 @@ int ssl_session_reset( ssl_context *ssl )
ssl->in_offt = NULL;
+ ssl->in_msg = ssl->in_ctr + 13;
ssl->in_msgtype = 0;
ssl->in_msglen = 0;
ssl->in_left = 0;
@@ -3032,6 +3048,7 @@ int ssl_session_reset( ssl_context *ssl )
ssl->in_hslen = 0;
ssl->nb_zero = 0;
+ ssl->out_msg = ssl->out_ctr + 13;
ssl->out_msgtype = 0;
ssl->out_msglen = 0;
ssl->out_left = 0;