GCM ciphersuites using only cipher layer
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 7e7ddd7..2095424 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -982,7 +982,7 @@
if( ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_AES_128_GCM ||
ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_AES_256_GCM )
{
- size_t enc_msglen;
+ size_t enc_msglen, olen, totlen;
unsigned char *enc_msg;
unsigned char add_data[13];
int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -1032,19 +1032,55 @@
ssl->out_msg, ssl->out_msglen );
/*
- * Adjust for tag
+ * Encrypt
+ */
+ if( ( ret = cipher_set_iv( &ssl->transform_out->cipher_ctx_enc,
+ ssl->transform_out->iv_enc,
+ ssl->transform_out->ivlen ) ) != 0 ||
+ ( ret = cipher_reset( &ssl->transform_out->cipher_ctx_enc ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_update_ad( &ssl->transform_out->cipher_ctx_enc,
+ add_data, 13 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_update( &ssl->transform_out->cipher_ctx_enc,
+ enc_msg, enc_msglen,
+ enc_msg, &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+ totlen = olen;
+
+ if( ( ret = cipher_finish( &ssl->transform_out->cipher_ctx_enc,
+ enc_msg + olen, &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+ totlen += olen;
+
+ if( totlen != enc_msglen )
+ {
+ SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( -1 );
+ }
+
+ /*
+ * Authenticate
*/
ssl->out_msglen += 16;
- gcm_crypt_and_tag( ssl->transform_out->cipher_ctx_enc.cipher_ctx,
- 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 );
+ if( ( ret = cipher_write_tag( &ssl->transform_out->cipher_ctx_enc,
+ enc_msg + enc_msglen, 16 ) ) != 0 )
+ {
+ return( ret );
+ }
- SSL_DEBUG_BUF( 4, "after encrypt: tag",
- enc_msg + enc_msglen, 16 );
+ SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, 16 );
}
else
#endif /* POLARSSL_GCM_C */
@@ -1244,7 +1280,7 @@
{
unsigned char *dec_msg;
unsigned char *dec_msg_result;
- size_t dec_msglen;
+ size_t dec_msglen, olen, totlen;
unsigned char add_data[13];
int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -1275,19 +1311,51 @@
ssl->transform_in->ivlen );
SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, 16 );
- ret = gcm_auth_decrypt( ssl->transform_in->cipher_ctx_dec.cipher_ctx,
- 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 )
+ /*
+ * Decrypt
+ */
+ if( ( ret = cipher_set_iv( &ssl->transform_in->cipher_ctx_dec,
+ ssl->transform_in->iv_dec,
+ ssl->transform_in->ivlen ) ) != 0 ||
+ ( ret = cipher_reset( &ssl->transform_in->cipher_ctx_dec ) ) != 0 )
{
- SSL_DEBUG_MSG( 1, ( "AEAD decrypt failed on validation (ret = -0x%02x)",
- -ret ) );
+ return( ret );
+ }
+ if( ( ret = cipher_update_ad( &ssl->transform_in->cipher_ctx_dec,
+ add_data, 13 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = cipher_update( &ssl->transform_in->cipher_ctx_dec,
+ dec_msg, dec_msglen,
+ dec_msg_result, &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+ totlen = olen;
+
+ if( ( ret = cipher_finish( &ssl->transform_in->cipher_ctx_dec,
+ dec_msg_result + olen, &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+ totlen += olen;
+
+ if( totlen != dec_msglen )
+ {
+ SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( -1 );
+ }
+
+ /*
+ * Authenticate
+ */
+ if( ( ret = cipher_check_tag( &ssl->transform_in->cipher_ctx_dec,
+ dec_msg + dec_msglen, 16 ) ) != 0 )
+ {
+ SSL_DEBUG_RET( 1, "cipher_check_tag", ret );
return( POLARSSL_ERR_SSL_INVALID_MAC );
}