From f5791af386b90d5e629687e23ba0681dd4070395 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Sat, 14 Oct 2017 10:14:29 +0200 Subject: [PATCH] modes/gcm128.c: harmonize GCM_MUL macro with GHASH. Reviewed-by: Rich Salz --- crypto/modes/gcm128.c | 101 +++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/crypto/modes/gcm128.c b/crypto/modes/gcm128.c index c3a9259451..4c8ae910ed 100644 --- a/crypto/modes/gcm128.c +++ b/crypto/modes/gcm128.c @@ -209,7 +209,7 @@ static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) } } -# define GCM_MUL(ctx,Xi) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable) +# define GCM_MUL(ctx) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable) #elif TABLE_BITS==4 @@ -550,7 +550,7 @@ void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len); # endif -# define GCM_MUL(ctx,Xi) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable) +# define GCM_MUL(ctx) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable) # if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT) # define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len) /* @@ -624,7 +624,7 @@ static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) } } -# define GCM_MUL(ctx,Xi) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u) +# define GCM_MUL(ctx) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u) #endif @@ -703,7 +703,7 @@ void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp, #ifdef GCM_FUNCREF_4BIT # undef GCM_MUL -# define GCM_MUL(ctx,Xi) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable) +# define GCM_MUL(ctx) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable) # ifdef GHASH # undef GHASH # define GHASH(ctx,in,len) (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len) @@ -836,10 +836,6 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; #endif - ctx->Yi.u[0] = 0; - ctx->Yi.u[1] = 0; - ctx->Xi.u[0] = 0; - ctx->Xi.u[1] = 0; ctx->len.u[0] = 0; /* AAD length */ ctx->len.u[1] = 0; /* message length */ ctx->ares = 0; @@ -847,53 +843,68 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, if (len == 12) { memcpy(ctx->Yi.c, iv, 12); + ctx->Yi.c[12] = 0; + ctx->Yi.c[13] = 0; + ctx->Yi.c[14] = 0; ctx->Yi.c[15] = 1; ctr = 1; } else { size_t i; u64 len0 = len; + /* Borrow ctx->Xi to calculate initial Yi */ + ctx->Xi.u[0] = 0; + ctx->Xi.u[1] = 0; + while (len >= 16) { for (i = 0; i < 16; ++i) - ctx->Yi.c[i] ^= iv[i]; - GCM_MUL(ctx, Yi); + ctx->Xi.c[i] ^= iv[i]; + GCM_MUL(ctx); iv += 16; len -= 16; } if (len) { for (i = 0; i < len; ++i) - ctx->Yi.c[i] ^= iv[i]; - GCM_MUL(ctx, Yi); + ctx->Xi.c[i] ^= iv[i]; + GCM_MUL(ctx); } len0 <<= 3; if (is_endian.little) { #ifdef BSWAP8 - ctx->Yi.u[1] ^= BSWAP8(len0); + ctx->Xi.u[1] ^= BSWAP8(len0); #else - ctx->Yi.c[8] ^= (u8)(len0 >> 56); - ctx->Yi.c[9] ^= (u8)(len0 >> 48); - ctx->Yi.c[10] ^= (u8)(len0 >> 40); - ctx->Yi.c[11] ^= (u8)(len0 >> 32); - ctx->Yi.c[12] ^= (u8)(len0 >> 24); - ctx->Yi.c[13] ^= (u8)(len0 >> 16); - ctx->Yi.c[14] ^= (u8)(len0 >> 8); - ctx->Yi.c[15] ^= (u8)(len0); + ctx->Xi.c[8] ^= (u8)(len0 >> 56); + ctx->Xi.c[9] ^= (u8)(len0 >> 48); + ctx->Xi.c[10] ^= (u8)(len0 >> 40); + ctx->Xi.c[11] ^= (u8)(len0 >> 32); + ctx->Xi.c[12] ^= (u8)(len0 >> 24); + ctx->Xi.c[13] ^= (u8)(len0 >> 16); + ctx->Xi.c[14] ^= (u8)(len0 >> 8); + ctx->Xi.c[15] ^= (u8)(len0); #endif - } else - ctx->Yi.u[1] ^= len0; + } else { + ctx->Xi.u[1] ^= len0; + } - GCM_MUL(ctx, Yi); + GCM_MUL(ctx); if (is_endian.little) #ifdef BSWAP4 - ctr = BSWAP4(ctx->Yi.d[3]); + ctr = BSWAP4(ctx->Xi.d[3]); #else - ctr = GETU32(ctx->Yi.c + 12); + ctr = GETU32(ctx->Xi.c + 12); #endif else - ctr = ctx->Yi.d[3]; + ctr = ctx->Xi.d[3]; + + /* Copy borrowed Xi to Yi */ + ctx->Yi.u[0] = ctx->Xi.u[0]; + ctx->Yi.u[1] = ctx->Xi.u[1]; } + ctx->Xi.u[0] = 0; + ctx->Xi.u[1] = 0; + (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key); ++ctr; if (is_endian.little) @@ -936,7 +947,7 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, n = (n + 1) % 16; } if (n == 0) - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); else { ctx->ares = n; return 0; @@ -952,7 +963,7 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, while (len >= 16) { for (i = 0; i < 16; ++i) ctx->Xi.c[i] ^= aad[i]; - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); aad += 16; len -= 16; } @@ -995,7 +1006,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, if (ctx->ares) { /* First call to encrypt finalizes GHASH(AAD) */ - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); ctx->ares = 0; } @@ -1019,7 +1030,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, n = (n + 1) % 16; } if (n == 0) - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); else { ctx->mres = n; return 0; @@ -1100,7 +1111,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, ctx->Yi.d[3] = ctr; for (i = 0; i < 16 / sizeof(size_t); ++i) ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i]; - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); out += 16; in += 16; len -= 16; @@ -1144,7 +1155,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n]; n = (n + 1) % 16; if (n == 0) - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); } ctx->mres = n; @@ -1179,7 +1190,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, if (ctx->ares) { /* First call to decrypt finalizes GHASH(AAD) */ - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); ctx->ares = 0; } @@ -1205,7 +1216,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, n = (n + 1) % 16; } if (n == 0) - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); else { ctx->mres = n; return 0; @@ -1287,7 +1298,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, out[i] = c ^ ctx->EKi.t[i]; ctx->Xi.t[i] ^= c; } - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); out += 16; in += 16; len -= 16; @@ -1336,7 +1347,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, ctx->Xi.c[n] ^= c; n = (n + 1) % 16; if (n == 0) - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); } ctx->mres = n; @@ -1373,7 +1384,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, if (ctx->ares) { /* First call to encrypt finalizes GHASH(AAD) */ - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); ctx->ares = 0; } @@ -1394,7 +1405,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, n = (n + 1) % 16; } if (n == 0) - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); else { ctx->mres = n; return 0; @@ -1440,7 +1451,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, while (j--) { for (i = 0; i < 16; ++i) ctx->Xi.c[i] ^= out[i]; - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); out += 16; } # endif @@ -1497,7 +1508,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, if (ctx->ares) { /* First call to decrypt finalizes GHASH(AAD) */ - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); ctx->ares = 0; } @@ -1520,7 +1531,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, n = (n + 1) % 16; } if (n == 0) - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); else { ctx->mres = n; return 0; @@ -1554,7 +1565,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, size_t k; for (k = 0; k < 16; ++k) ctx->Xi.c[k] ^= in[k]; - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); in += 16; } j = i / 16; @@ -1612,7 +1623,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, #endif if (ctx->mres || ctx->ares) - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); if (is_endian.little) { #ifdef BSWAP8 @@ -1631,7 +1642,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, ctx->Xi.u[0] ^= alen; ctx->Xi.u[1] ^= clen; - GCM_MUL(ctx, Xi); + GCM_MUL(ctx); ctx->Xi.u[0] ^= ctx->EK0.u[0]; ctx->Xi.u[1] ^= ctx->EK0.u[1];