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)