Skip to content
Snippets Groups Projects
Commit c79c71f2 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Niels Möller
Browse files

gcm: move block shifting function to block-internal.h


Move GCM's block shift function to block-internal.h. This concludes
moving of all Galois mul-by-2 to single header.

Signed-off-by: default avatarDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
parent 685cc919
Branches
Tags
No related merge requests found
...@@ -95,11 +95,15 @@ block8_xor_bytes (union nettle_block8 *r, ...@@ -95,11 +95,15 @@ block8_xor_bytes (union nettle_block8 *r,
#define LSHIFT_ALIEN_UINT64(x) \ #define LSHIFT_ALIEN_UINT64(x) \
((((x) & UINT64_C(0x7f7f7f7f7f7f7f7f)) << 1) | \ ((((x) & UINT64_C(0x7f7f7f7f7f7f7f7f)) << 1) | \
(((x) & UINT64_C(0x8080808080808080)) >> 15)) (((x) & UINT64_C(0x8080808080808080)) >> 15))
#define RSHIFT_ALIEN_UINT64(x) \
((((x) & UINT64_C(0xfefefefefefefefe)) >> 1) | \
(((x) & UINT64_C(0x0001010101010101)) << 15))
/* Two typical defining polynoms */ /* Two typical defining polynoms */
#define BLOCK16_POLY (UINT64_C(0x87)) #define BLOCK16_POLY (UINT64_C(0x87))
#define BLOCK8_POLY (UINT64_C(0x1b)) #define BLOCK8_POLY (UINT64_C(0x1b))
#define GHASH_POLY (UINT64_C(0xE1))
/* Galois multiplications by 2: /* Galois multiplications by 2:
* functions differ in shifting right or left, big- or little- endianness * functions differ in shifting right or left, big- or little- endianness
...@@ -133,6 +137,18 @@ block8_mulx_be (union nettle_block8 *dst, ...@@ -133,6 +137,18 @@ block8_mulx_be (union nettle_block8 *dst,
dst->u64 = (src->u64 << 1) ^ (BLOCK8_POLY & -carry); dst->u64 = (src->u64 << 1) ^ (BLOCK8_POLY & -carry);
} }
static inline void
block16_mulx_ghash (union nettle_block16 *r,
const union nettle_block16 *x)
{
uint64_t mask;
/* Shift uses big-endian representation. */
mask = - (x->u64[1] & 1);
r->u64[1] = (x->u64[1] >> 1) | ((x->u64[0] & 1) << 63);
r->u64[0] = (x->u64[0] >> 1) ^ (mask & (GHASH_POLY << 56));
}
#else /* !WORDS_BIGENDIAN */ #else /* !WORDS_BIGENDIAN */
static inline void static inline void
block16_mulx_be (union nettle_block16 *dst, block16_mulx_be (union nettle_block16 *dst,
...@@ -160,6 +176,18 @@ block8_mulx_be (union nettle_block8 *dst, ...@@ -160,6 +176,18 @@ block8_mulx_be (union nettle_block8 *dst,
dst->u64 = LSHIFT_ALIEN_UINT64(src->u64) ^ ((BLOCK8_POLY << 56) & -carry); dst->u64 = LSHIFT_ALIEN_UINT64(src->u64) ^ ((BLOCK8_POLY << 56) & -carry);
} }
static inline void
block16_mulx_ghash (union nettle_block16 *r,
const union nettle_block16 *x)
{
uint64_t mask;
/* Shift uses big-endian representation. */
mask = - ((x->u64[1] >> 56) & 1);
r->u64[1] = RSHIFT_ALIEN_UINT64(x->u64[1]) | ((x->u64[0] >> 49) & 0x80);
r->u64[0] = RSHIFT_ALIEN_UINT64(x->u64[0]) ^ (mask & GHASH_POLY);
}
#endif /* ! WORDS_BIGENDIAN */ #endif /* ! WORDS_BIGENDIAN */
#endif /* NETTLE_BLOCK_INTERNAL_H_INCLUDED */ #endif /* NETTLE_BLOCK_INTERNAL_H_INCLUDED */
...@@ -55,32 +55,6 @@ ...@@ -55,32 +55,6 @@
#include "ctr-internal.h" #include "ctr-internal.h"
#include "block-internal.h" #include "block-internal.h"
#define GHASH_POLYNOMIAL 0xE1UL
/* Multiplication by 010...0; a big-endian shift right. If the bit
shifted out is one, the defining polynomial is added to cancel it
out. r == x is allowed. */
static void
gcm_gf_shift (union nettle_block16 *r, const union nettle_block16 *x)
{
uint64_t mask;
/* Shift uses big-endian representation. */
#if WORDS_BIGENDIAN
mask = - (x->u64[1] & 1);
r->u64[1] = (x->u64[1] >> 1) | ((x->u64[0] & 1) << 63);
r->u64[0] = (x->u64[0] >> 1) ^ (mask & ((uint64_t) GHASH_POLYNOMIAL << 56));
#else /* ! WORDS_BIGENDIAN */
#define RSHIFT_WORD(x) \
((((x) & 0xfefefefefefefefeUL) >> 1) \
| (((x) & 0x0001010101010101UL) << 15))
mask = - ((x->u64[1] >> 56) & 1);
r->u64[1] = RSHIFT_WORD(x->u64[1]) | ((x->u64[0] >> 49) & 0x80);
r->u64[0] = RSHIFT_WORD(x->u64[0]) ^ (mask & GHASH_POLYNOMIAL);
# undef RSHIFT_WORD
#endif /* ! WORDS_BIGENDIAN */
}
#if GCM_TABLE_BITS == 0 #if GCM_TABLE_BITS == 0
/* Sets x <- x * y mod r, using the plain bitwise algorithm from the /* Sets x <- x * y mod r, using the plain bitwise algorithm from the
specification. y may be shorter than a full block, missing bytes specification. y may be shorter than a full block, missing bytes
...@@ -104,7 +78,7 @@ gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *y) ...@@ -104,7 +78,7 @@ gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *y)
if (b & 0x80) if (b & 0x80)
block16_xor(&Z, &V); block16_xor(&Z, &V);
gcm_gf_shift(&V, &V); block16_mulx_ghash(&V, &V);
} }
} }
memcpy (x->b, Z.b, sizeof(Z)); memcpy (x->b, Z.b, sizeof(Z));
...@@ -275,7 +249,7 @@ gcm_set_key(struct gcm_key *key, ...@@ -275,7 +249,7 @@ gcm_set_key(struct gcm_key *key,
/* Algorithm 3 from the gcm paper. First do powers of two, then do /* Algorithm 3 from the gcm paper. First do powers of two, then do
the rest by adding. */ the rest by adding. */
while (i /= 2) while (i /= 2)
gcm_gf_shift(&key->h[i], &key->h[2*i]); block16_mulx_ghash(&key->h[i], &key->h[2*i]);
for (i = 2; i < 1<<GCM_TABLE_BITS; i *= 2) for (i = 2; i < 1<<GCM_TABLE_BITS; i *= 2)
{ {
unsigned j; unsigned j;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment