This problem occurs in the FIPS 2.0 and 2.0.1 Object Modules.   The 
conditions for the test are:

Platform:  Linux 32-bit
AAD length:  greater than 16 bytes and not evenly divisible by 16 (e.g. 
20 bytes of AAD)
Cipher text length: 0

Under these conditions, the remaining AAD bytes beyond the last 16 byte 
block are never hashed.  This results in a TAG mismatch when finalizing 
the decrypt operation.  The problem can be easily reproduced by running 
the following command using the attached test vector file:

test/fips_gcmtest -decrypt gcm_decrypt_vect.req vector.rsp

The test case in this vector should result in a matching tag.

The attached patch is a potential fix.  The solution is to process the 
remainder AAD when CRYPTO_gcm128_finish() is invoked.  Please confirm 
that this is a bug and comment on the patch.  Specifically, will this 
patch work on all platforms?  Thank you.

Also, the OpenSSL test vectors for AES GCM mode only used AAD lengths 
that were divisible by 16, which explains why this problem was not 
identified during FIPS validation.

Index: crypto/modes/gcm128.c
===================================================================
--- crypto/modes/gcm128.c	(revision 713)
+++ crypto/modes/gcm128.c	(working copy)
@@ -1396,6 +1396,15 @@
 #ifdef GCM_FUNCREF_4BIT
 	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
 #endif
+	/*
+	 * Check if there is any residual AAD that needs to
+	 * be hashed.  This may occur if the amount of AAD
+	 * is not evenly divisible by 16 bytes 
+	 */
+	if (ctx->ares) {
+		GCM_MUL(ctx,Xi);
+		ctx->ares = 0;
+	}
 
 	if (ctx->mres)
 		GCM_MUL(ctx,Xi);
# CAVS 12.2
# GCM Decrypt with keysize 192 test information
# Generated on Mon Jul 30 13:55:03 2012

[Keylen = 192]
[IVlen = 96]
[PTlen = 0]
[AADlen = 160]
[Taglen = 128]

Count = 1
Key = cb9c9ba95ba34917db831e2f8438b5c9e702a1dfe2aa5451
IV = 1e19de9f8ec80fd940d07e4f
CT = 
AAD = 01d783d290c62d6c46d6adda205057e327029586
Tag = cade2680b5bb72d7a9ef8dc2388353f1

<<inline: foleyj.vcf>>

Reply via email to