From 23f75f58f9b71e39756858cb6747e542c7c759e3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Niels=20M=C3=B6ller?= Date: Thu, 10 Feb 2022 18:32:12 +0100 Subject: [PATCH] Rearrange gcm configuration defines, and add tests for internal functions. --- ChangeLog | 11 ++++++ gcm-internal.h | 39 +++++++++++++++---- gcm.c | 53 ++++++++++---------------- testsuite/gcm-test.c | 91 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 152 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca2a6718..abb3e6ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2022-02-08 Niels Möller + + * gcm-internal.h (_gcm_hash): Arrange so that this is an alias for + the appropriate implementation. Updated all users. + * gcm.c (_nettle_gcm_set_key): New internal function, intended to + make tests of internal ghash functions easier. + (gcm_set_key): Use it. + * testsuite/gcm-test.c (test_ghash_internal): New function. + (test_main): Add tests of internal ghash functions, with keys + corresponding to various single-bit polynomials. + 2022-01-28 Niels Möller * testsuite/poly1305-test.c (poly1305_internal): Renamed function, diff --git a/gcm-internal.h b/gcm-internal.h index 2e28be2d..e1871562 100644 --- a/gcm-internal.h +++ b/gcm-internal.h @@ -32,23 +32,46 @@ #ifndef NETTLE_GCM_INTERNAL_H_INCLUDED #define NETTLE_GCM_INTERNAL_H_INCLUDED -/* Functions available only in some configurations */ +#if GCM_TABLE_BITS != 8 +/* The native implementations (currently ppc64 only) depend on the + GCM_TABLE_BITS == 8 layout */ +#undef HAVE_NATIVE_gcm_hash +#undef HAVE_NATIVE_gcm_init_key +#undef HAVE_NATIVE_fat_gcm_hash +#undef HAVE_NATIVE_fat_gcm_init_key +#endif + +/* Arrange so that _gcm_hash is an alias for the right implementation. */ +#if HAVE_NATIVE_gcm_hash || HAVE_NATIVE_fat_gcm_hash +# define _gcm_hash _nettle_gcm_hash +#elif GCM_TABLE_BITS == 8 && HAVE_NATIVE_gcm_hash8 +# define _gcm_hash _nettle_gcm_hash8 +#else +# define _gcm_hash _nettle_gcm_hash_c +#endif + +/* Declare all variants, if defined depends on configuration. */ void -_nettle_gcm_init_key (union nettle_block16 *table); +_nettle_gcm_set_key (struct gcm_key *gcm, const uint8_t *key); void _nettle_gcm_hash(const struct gcm_key *key, union nettle_block16 *x, size_t length, const uint8_t *data); -#if HAVE_NATIVE_fat_gcm_init_key void -_nettle_gcm_init_key_c (union nettle_block16 *table); -#endif +_nettle_gcm_hash8(const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data); -#if HAVE_NATIVE_fat_gcm_hash void -_nettle_gcm_hash_c (const struct gcm_key *key, union nettle_block16 *x, - size_t length, const uint8_t *data); +_nettle_gcm_hash_c(const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data); + +void +_nettle_gcm_init_key (union nettle_block16 *table); + +#if HAVE_NATIVE_fat_gcm_init_key +void +_nettle_gcm_init_key_c (union nettle_block16 *table); #endif #endif /* NETTLE_GCM_INTERNAL_H_INCLUDED */ diff --git a/gcm.c b/gcm.c index d1f21d3a..fce1682b 100644 --- a/gcm.c +++ b/gcm.c @@ -56,15 +56,6 @@ #include "ctr-internal.h" #include "block-internal.h" -#if GCM_TABLE_BITS != 8 -/* The native implementations (currently ppc64 only) depend on the - GCM_TABLE_BITS == 8 layout */ -#undef HAVE_NATIVE_gcm_hash -#undef HAVE_NATIVE_gcm_init_key -#undef HAVE_NATIVE_fat_gcm_hash -#undef HAVE_NATIVE_fat_gcm_init_key -#endif - #if !HAVE_NATIVE_gcm_hash # if GCM_TABLE_BITS == 0 /* Sets x <- x * y mod r, using the plain bitwise algorithm from the @@ -151,13 +142,7 @@ gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *table) memcpy (x->b, Z.b, sizeof(Z)); } # elif GCM_TABLE_BITS == 8 -# if HAVE_NATIVE_gcm_hash8 - -#define _nettle_gcm_hash _nettle_gcm_hash8 -void -_nettle_gcm_hash8 (const struct gcm_key *key, union nettle_block16 *x, - size_t length, const uint8_t *data); -# else /* !HAVE_NATIVE_gcm_hash8 */ +# if !HAVE_NATIVE_gcm_hash8 static const uint16_t shift_table[0x100] = { W(00,00),W(01,c2),W(03,84),W(02,46),W(07,08),W(06,ca),W(04,8c),W(05,4e), @@ -267,6 +252,16 @@ _nettle_gcm_init_key_c(union nettle_block16 *table) } #endif /* !HAVE_NATIVE_gcm_init_key */ +void +_nettle_gcm_set_key (struct gcm_key *gcm, const uint8_t *key) +{ + memset (gcm->h[0].b, 0, GCM_BLOCK_SIZE); + /* Middle element if GCM_TABLE_BITS > 0, otherwise the first + element */ + memcpy (gcm->h[(1<h); +} + /* Initialization of GCM. * @ctx: The context of GCM * @cipher: The context of the underlying block cipher @@ -276,22 +271,14 @@ void gcm_set_key(struct gcm_key *key, const void *cipher, nettle_cipher_func *f) { - /* Middle element if GCM_TABLE_BITS > 0, otherwise the first - element */ - unsigned i = (1<h[0].b, 0, GCM_BLOCK_SIZE); - f (cipher, GCM_BLOCK_SIZE, key->h[i].b, key->h[0].b); - - _nettle_gcm_init_key(key->h); + _nettle_gcm_set_key (key, key_block.b); } #if !(HAVE_NATIVE_gcm_hash || HAVE_NATIVE_gcm_hash8) -# if !HAVE_NATIVE_fat_gcm_hash -# define _nettle_gcm_hash _nettle_gcm_hash_c -static -# endif void _nettle_gcm_hash_c(const struct gcm_key *key, union nettle_block16 *x, size_t length, const uint8_t *data) @@ -322,7 +309,7 @@ gcm_hash_sizes(const struct gcm_key *key, union nettle_block16 *x, WRITE_UINT64 (buffer, auth_size); WRITE_UINT64 (buffer + 8, data_size); - _nettle_gcm_hash(key, x, GCM_BLOCK_SIZE, buffer); + _gcm_hash(key, x, GCM_BLOCK_SIZE, buffer); } /* NOTE: The key is needed only if length != GCM_IV_SIZE */ @@ -341,7 +328,7 @@ gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key, else { memset(ctx->iv.b, 0, GCM_BLOCK_SIZE); - _nettle_gcm_hash(key, &ctx->iv, length, iv); + _gcm_hash(key, &ctx->iv, length, iv); gcm_hash_sizes(key, &ctx->iv, 0, length); } @@ -360,7 +347,7 @@ gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key, assert(ctx->auth_size % GCM_BLOCK_SIZE == 0); assert(ctx->data_size == 0); - _nettle_gcm_hash(key, &ctx->x, length, data); + _gcm_hash(key, &ctx->x, length, data); ctx->auth_size += length; } @@ -431,7 +418,7 @@ gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key, assert(ctx->data_size % GCM_BLOCK_SIZE == 0); _nettle_ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src); - _nettle_gcm_hash(key, &ctx->x, length, dst); + _gcm_hash(key, &ctx->x, length, dst); ctx->data_size += length; } @@ -443,7 +430,7 @@ gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key, { assert(ctx->data_size % GCM_BLOCK_SIZE == 0); - _nettle_gcm_hash(key, &ctx->x, length, src); + _gcm_hash(key, &ctx->x, length, src); _nettle_ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src); ctx->data_size += length; diff --git a/testsuite/gcm-test.c b/testsuite/gcm-test.c index df1fc94a..d68af4e0 100644 --- a/testsuite/gcm-test.c +++ b/testsuite/gcm-test.c @@ -4,6 +4,7 @@ #include "testutils.h" #include "nettle-internal.h" #include "gcm.h" +#include "gcm-internal.h" static void test_gcm_hash (const struct tstring *msg, const struct tstring *ref) @@ -28,6 +29,39 @@ test_gcm_hash (const struct tstring *msg, const struct tstring *ref) } } +static void +test_ghash_internal (const struct tstring *key, + const struct tstring *iv, + const struct tstring *message, + const struct tstring *digest) +{ + ASSERT (key->length == GCM_BLOCK_SIZE); + ASSERT (iv->length == GCM_BLOCK_SIZE); + ASSERT (digest->length == GCM_BLOCK_SIZE); + struct gcm_key gcm_key; + union nettle_block16 state; + + _nettle_gcm_set_key (&gcm_key, key->data); + memcpy (state.b, iv->data, GCM_BLOCK_SIZE); + _gcm_hash (&gcm_key, &state, message->length, message->data); + if (!MEMEQ(GCM_BLOCK_SIZE, state.b, digest->data)) + { + fprintf (stderr, "gcm_hash (internal) failed\n"); + fprintf(stderr, "Key: "); + tstring_print_hex(key); + fprintf(stderr, "\nIV: "); + tstring_print_hex(iv); + fprintf(stderr, "\nMessage: "); + tstring_print_hex(message); + fprintf(stderr, "\nOutput: "); + print_hex(GCM_BLOCK_SIZE, state.b); + fprintf(stderr, "\nExpected:"); + tstring_print_hex(digest); + fprintf(stderr, "\n"); + FAIL(); + } +} + static nettle_set_key_func gcm_unified_aes128_set_key; static nettle_set_key_func gcm_unified_aes128_set_iv; static void @@ -578,5 +612,60 @@ test_main(void) SHEX("65f8245330febf15 6fd95e324304c258")); test_gcm_hash (SDATA("abcdefghijklmnopqr"), SHEX("d07259e85d4fc998 5a662eed41c8ed1d")); -} + /* Test internal ghash function. */ + test_ghash_internal(SHEX("0000000000000000 0000000000000000"), + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("0000000000000000 0000000000000000")); + + test_ghash_internal(SHEX("8000000000000000 0000000000000000"), /* 1 polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("0011223344556677 89abcdef01234567")); + + test_ghash_internal(SHEX("8000000000000000 0000000000000000"), + SHEX("0123456789abcdef fedcba9876543210"), /* XOR:ed to the message */ + SHEX("0011223344556677 89abcdef01234567"), + SHEX("01326754cdfeab98 7777777777777777")); + + test_ghash_internal(SHEX("4000000000000000 0000000000000000"), /* x polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("e1089119a22ab33b c4d5e6f78091a2b3")); + + test_ghash_internal(SHEX("0800000000000000 0000000000000000"), /* x^4 polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("54e1122334455667 789abcdef0123456")); + + test_ghash_internal(SHEX("0000000080000000 0000000000000000"), /* x^32 polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("01f870078e112233 4455667789abcdef")); + + test_ghash_internal(SHEX("0000000000000001 0000000000000000"), /* x^63 polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("1e0f1ff13ff0e00f 1c22446688aaccef")); + + test_ghash_internal(SHEX("0000000000000000 8000000000000000"), /* x^64 polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("ee078ff89ff87007 8e11223344556677")); + + test_ghash_internal(SHEX("0000000000000000 0000000100000000"), /* x^95 polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("efc44c3a800f1ff1 3ff0e00f1c224466")); + + test_ghash_internal(SHEX("0000000000000000 0000000080000000"), /* x^96 polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("77e2261d40078ff8 9ff870078e112233")); + + test_ghash_internal(SHEX("0000000000000000 0000000000000001"), /* x^127 polynomial */ + SHEX("0000000000000000 0000000000000000"), + SHEX("0011223344556677 89abcdef01234567"), + SHEX("1503b3c4a3c44c3a 800f1ff13ff0e00f")); +} -- 2.47.2