Commit f5791af3 authored by Andy Polyakov's avatar Andy Polyakov
Browse files

modes/gcm128.c: harmonize GCM_MUL macro with GHASH.



Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent b5895815
Loading
Loading
Loading
Loading
+56 −45
Original line number Diff line number Diff line
@@ -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];