Change cipher prototypes for GCM
diff --git a/library/cipher.c b/library/cipher.c
index 733f6e5..d7cac05 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -396,7 +396,9 @@
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
}
-int cipher_reset( cipher_context_t *ctx, const unsigned char *iv )
+int cipher_reset( cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len )
{
if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
@@ -406,11 +408,13 @@
#if defined(POLARSSL_GCM_C)
if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
{
- // TODO: allow other IV length
- // TODO: allow additional data
return gcm_starts( ctx->cipher_ctx, ctx->operation,
- iv, 12, (unsigned char *) "", 0 );
+ iv, iv_len, ad, ad_len );
}
+#else
+ ((void) ad);
+ ((void) ad_len);
+ ((void) iv_len);
#endif
memcpy( ctx->iv, iv, cipher_get_iv_size( ctx ) );
@@ -742,7 +746,9 @@
return 0;
}
-int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen)
+int cipher_finish( cipher_context_t *ctx,
+ unsigned char *output, size_t *olen,
+ unsigned char *tag, size_t tag_len )
{
int ret = 0;
@@ -761,8 +767,9 @@
#if defined(POLARSSL_GCM_C)
if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
{
- size_t tag_len = 0; // TODO
- unsigned char tag[16];
+ unsigned char check_tag[16];
+ size_t i;
+ int diff;
if( 0 != ( ret = gcm_update( ctx->cipher_ctx,
ctx->unprocessed_len, ctx->unprocessed_data,
@@ -773,11 +780,29 @@
*olen += ctx->unprocessed_len;
- if( 0 != ( ret = gcm_finish( ctx->cipher_ctx, tag, tag_len ) ) )
+ if( 0 != ( ret = gcm_finish( ctx->cipher_ctx, check_tag, tag_len ) ) )
return( ret );
+ /* On encryption, write the tag */
+ if( POLARSSL_ENCRYPT == ctx->operation )
+ {
+ if( tag_len != 0 )
+ memcpy( tag, check_tag, tag_len );
+ return( 0 );
+ }
+
+ /* On decryption, check the tag (in "constant-time") */
+ for( diff = 0, i = 0; i < tag_len; i++ )
+ diff |= tag[i] ^ check_tag[i];
+
+ if( diff != 0 )
+ return( POLARSSL_ERR_GCM_AUTH_FAILED );
+
return( 0 );
}
+#else
+ ((void) tag);
+ ((void) tag_len);
#endif
if( POLARSSL_MODE_CBC == ctx->cipher_info->mode )