Merged new cipher layer enhancements
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 354c6c2..aafbfb6 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -504,6 +504,9 @@
md_context_t md_ctx_enc; /*!< MAC (encryption) */
md_context_t md_ctx_dec; /*!< MAC (decryption) */
+ cipher_context_t cipher_ctx_enc; /*!< encryption context */
+ cipher_context_t cipher_ctx_dec; /*!< decryption context */
+
uint32_t ctx_enc[SSL_CTX_MAX / 4]; /*!< encryption context */
uint32_t ctx_dec[SSL_CTX_MAX / 4]; /*!< decryption context */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index ed95d3e..52d4b33 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -355,6 +355,7 @@
int ssl_derive_keys( ssl_context *ssl )
{
+ int ret = 0;
unsigned char tmp[64];
unsigned char keyblk[256];
unsigned char *key1;
@@ -632,48 +633,73 @@
switch( cipher_info->type )
{
-#if defined(POLARSSL_ARC4_C)
case POLARSSL_CIPHER_ARC4_128:
- 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 POLARSSL_CIPHER_DES_EDE3_CBC:
- 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 POLARSSL_CIPHER_AES_128_CBC:
- case POLARSSL_CIPHER_AES_256_CBC:
- aes_setkey_enc( (aes_context*) transform->ctx_enc, key1,
- cipher_info->key_length );
- aes_setkey_dec( (aes_context*) transform->ctx_dec, key2,
- cipher_info->key_length );
- break;
-#endif
-
-#if defined(POLARSSL_CAMELLIA_C)
case POLARSSL_CIPHER_CAMELLIA_128_CBC:
case POLARSSL_CIPHER_CAMELLIA_256_CBC:
- camellia_setkey_enc( (camellia_context*) transform->ctx_enc, key1,
- cipher_info->key_length );
- camellia_setkey_dec( (camellia_context*) transform->ctx_dec, key2,
- cipher_info->key_length );
- break;
-#endif
-
-#if defined(POLARSSL_DES_C)
+ case POLARSSL_CIPHER_AES_128_CBC:
+ case POLARSSL_CIPHER_AES_256_CBC:
case POLARSSL_CIPHER_DES_CBC:
- des_setkey_enc( (des_context *) transform->ctx_enc, key1 );
- des_setkey_dec( (des_context *) transform->ctx_dec, key2 );
+ if( ( ret = cipher_init_ctx( &transform->cipher_ctx_enc,
+ cipher_info ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_init_ctx( &transform->cipher_ctx_dec,
+ cipher_info ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( cipher_info->type == POLARSSL_CIPHER_ARC4_128 )
+ {
+ if( ( ret = cipher_setkey( &transform->cipher_ctx_enc, key1,
+ cipher_info->key_length / 8,
+ POLARSSL_ENCRYPT ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_setkey( &transform->cipher_ctx_dec, key2,
+ cipher_info->key_length / 8,
+ POLARSSL_DECRYPT ) ) != 0 )
+ {
+ return( ret );
+ }
+ }
+ else
+ {
+ if( ( ret = cipher_setkey( &transform->cipher_ctx_enc, key1,
+ cipher_info->key_length,
+ POLARSSL_ENCRYPT ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_setkey( &transform->cipher_ctx_dec, key2,
+ cipher_info->key_length,
+ POLARSSL_DECRYPT ) ) != 0 )
+ {
+ return( ret );
+ }
+ }
+
+ if( cipher_info->mode == POLARSSL_MODE_CBC )
+ {
+ if( ( ret = cipher_set_padding_mode( &transform->cipher_ctx_enc,
+ POLARSSL_PADDING_NONE ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_set_padding_mode( &transform->cipher_ctx_dec,
+ POLARSSL_PADDING_NONE ) ) != 0 )
+ {
+ return( ret );
+ }
+ }
break;
-#endif
#if defined(POLARSSL_GCM_C)
case POLARSSL_CIPHER_AES_128_GCM:
@@ -913,9 +939,11 @@
}
else
#endif /* POLARSSL_CIPHER_NULL_CIPHER */
-#if defined(POLARSSL_ARC4_C)
if( ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_ARC4_128 )
{
+ int ret;
+ size_t olen = 0;
+
padlen = 0;
SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
@@ -925,12 +953,43 @@
SSL_DEBUG_BUF( 4, "before encrypt: output payload",
ssl->out_msg, ssl->out_msglen );
- arc4_crypt( (arc4_context *) ssl->transform_out->ctx_enc,
- ssl->out_msglen, ssl->out_msg,
- ssl->out_msg );
+ if( ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc,
+ ssl->transform_out->iv_enc,
+ ssl->transform_out->ivlen, NULL, 0 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc,
+ ssl->out_msg, ssl->out_msglen, ssl->out_msg,
+ &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ssl->out_msglen != olen )
+ {
+ SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
+ ssl->out_msglen, olen ) );
+ // TODO Real error number
+ return( -1 );
+ }
+
+ if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc,
+ ssl->out_msg + olen, &olen, NULL, 0 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( 0 != olen )
+ {
+ SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
+ 0, olen ) );
+ // TODO Real error number
+ return( -1 );
+ }
}
else
-#endif /* POLARSSL_ARC4_C */
#if defined(POLARSSL_GCM_C)
if( ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_AES_128_GCM ||
ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_AES_256_GCM )
@@ -999,8 +1058,10 @@
else
#endif /* POLARSSL_GCM_C */
{
+ int ret;
unsigned char *enc_msg;
size_t enc_msglen;
+ size_t olen = 0;
padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) %
ssl->transform_out->ivlen;
@@ -1049,43 +1110,47 @@
SSL_DEBUG_BUF( 4, "before encrypt: output payload",
ssl->out_iv, ssl->out_msglen );
- switch( ssl->transform_out->ciphersuite_info->cipher )
+ if( ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc,
+ ssl->transform_out->iv_enc,
+ ssl->transform_out->ivlen, NULL, 0 ) ) != 0 )
{
-#if defined(POLARSSL_DES_C)
- case POLARSSL_CIPHER_DES_CBC:
- des_crypt_cbc( (des_context *) ssl->transform_out->ctx_enc,
- DES_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, enc_msg, enc_msg );
- break;
-
- case POLARSSL_CIPHER_DES_EDE3_CBC:
- 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
-
-#if defined(POLARSSL_AES_C)
- case POLARSSL_CIPHER_AES_128_CBC:
- case POLARSSL_CIPHER_AES_256_CBC:
- 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)
- case POLARSSL_CIPHER_CAMELLIA_128_CBC:
- case POLARSSL_CIPHER_CAMELLIA_256_CBC:
- 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 );
+ return( ret );
}
+
+ if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc,
+ enc_msg, enc_msglen, enc_msg,
+ &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ enc_msglen -= olen;
+
+ if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc,
+ enc_msg + olen, &olen, NULL, 0 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( enc_msglen != olen )
+ {
+ SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect %d %d",
+ enc_msglen, olen ) );
+ // TODO Real error number
+ return( -1 );
+ }
+
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1)
+ if( ssl->minor_ver < SSL_MINOR_VERSION_2 )
+ {
+ /*
+ * Save IV in SSL3 and TLS1
+ */
+ memcpy( ssl->transform_out->iv_enc,
+ ssl->transform_out->cipher_ctx_enc.iv,
+ ssl->transform_out->ivlen );
+ }
+#endif
}
for( i = 8; i > 0; i-- )
@@ -1123,11 +1188,44 @@
#if defined(POLARSSL_ARC4_C)
if( ssl->transform_in->ciphersuite_info->cipher == POLARSSL_CIPHER_ARC4_128 )
{
+ int ret;
+ size_t olen = 0;
+
padlen = 0;
- arc4_crypt( (arc4_context *) ssl->transform_in->ctx_dec,
- ssl->in_msglen, ssl->in_msg,
- ssl->in_msg );
+ if( ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec,
+ ssl->transform_in->iv_dec,
+ ssl->transform_in->ivlen, NULL, 0 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec,
+ ssl->in_msg, ssl->in_msglen, ssl->in_msg,
+ &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ssl->in_msglen != olen )
+ {
+ SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) );
+ // TODO Real error number
+ return( -1 );
+ }
+
+ if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec,
+ ssl->in_msg + olen, &olen, NULL, 0 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( 0 != olen )
+ {
+ SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) );
+ // TODO Real error number
+ return( -1 );
+ }
}
else
#endif /* POLARSSL_ARC4_C */
@@ -1190,10 +1288,12 @@
/*
* Decrypt and check the padding
*/
+ int ret;
unsigned char *dec_msg;
unsigned char *dec_msg_result;
size_t dec_msglen;
size_t minlen = 0;
+ size_t olen = 0;
/*
* Check immediate ciphertext sanity
@@ -1236,44 +1336,46 @@
}
#endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */
- switch( ssl->transform_in->ciphersuite_info->cipher )
+ if( ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec,
+ ssl->transform_in->iv_dec,
+ ssl->transform_in->ivlen, NULL, 0 ) ) != 0 )
{
-#if defined(POLARSSL_DES_C)
- case POLARSSL_CIPHER_DES_CBC:
- des_crypt_cbc( (des_context *) ssl->transform_in->ctx_dec,
- DES_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
- break;
-
- case POLARSSL_CIPHER_DES_EDE3_CBC:
- 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
-
-#if defined(POLARSSL_AES_C)
- case POLARSSL_CIPHER_AES_128_CBC:
- case POLARSSL_CIPHER_AES_256_CBC:
- 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)
- case POLARSSL_CIPHER_CAMELLIA_128_CBC:
- case POLARSSL_CIPHER_CAMELLIA_256_CBC:
- 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 );
+ return( ret );
}
+ if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec,
+ dec_msg, dec_msglen, dec_msg_result,
+ &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ dec_msglen -= olen;
+ if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec,
+ dec_msg_result + olen, &olen, NULL, 0 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( dec_msglen != olen )
+ {
+ SSL_DEBUG_MSG( 1, ( "total encrypted length incorrect" ) );
+ // TODO Real error number
+ return( -1 );
+ }
+
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1)
+ if( ssl->minor_ver < SSL_MINOR_VERSION_2 )
+ {
+ /*
+ * Save IV in SSL3 and TLS1
+ */
+ memcpy( ssl->transform_in->iv_dec,
+ ssl->transform_in->cipher_ctx_dec.iv,
+ ssl->transform_in->ivlen );
+ }
+#endif
+
padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
if( ssl->in_msglen < ssl->transform_in->maclen + padlen )