The CRYPTO_gcm128_decrypt() function has a bug when compiling with the
OPENSSL_SMALL_FOOTPRINT option - the code in question does not get
exercised unless that option is set.

In addition, the test cases when compiling with SELFTEST are designed
such that this bug does not get reported.

The included patch fixes the bug and the test cases.
----
Michael Heyman

--- gcm128.c	2011-01-14 10:59:04.104386199 -0500
+++ gcm128.c	2011-01-14 11:04:34.685296210 -0500
@@ -1080,11 +1080,11 @@
 				PUTU32(ctx->Yi.c+12,ctr);
 			else
 				ctx->Yi.d[3] = ctr;
 		}
 		c = in[i];
-		out[i] ^= ctx->EKi.c[n];
+		out[i] = c^ctx->EKi.c[n];
 		ctx->Xi.c[n] ^= c;
 		n = (n+1)%16;
 		if (n==0)
 			GCM_MUL(ctx,Xi);
 	}
@@ -1540,11 +1540,12 @@
 	if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||		\
 	    (C##n && memcmp(out,C##n,sizeof(out))))		\
 		ret++, printf ("encrypt test#%d failed.\n",n);\
 	CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));		\
 	if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));	\
-	if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out));	\
+	if (C##n) { memset(out,0,sizeof(out));                  \
+            CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out));}	\
 	if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||		\
 	    (P##n && memcmp(out,P##n,sizeof(out))))		\
 		ret++, printf ("decrypt test#%d failed.\n",n);	\
 	} while(0)
 

Reply via email to