Commit 685cc919 authored by Dmitry Eremin-Solenikov's avatar Dmitry Eremin-Solenikov Committed by Niels Möller

block modes: move Galois shifts to block-internal.h

Move Galois polynomial shifts to block-internal.h, simplifying common
code. GCM is left unconverted for now, this will be fixed later.
Signed-off-by: default avatarDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
parent 508908b1
......@@ -231,7 +231,7 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \
nettle.pc.in hogweed.pc.in \
$(des_headers) descore.README desdata.stamp \
aes-internal.h block-internal.h \
camellia-internal.h cmac-internal.h serpent-internal.h \
camellia-internal.h serpent-internal.h \
cast128_sboxes.h desinfo.h desCode.h \
ripemd160-internal.h sha2-internal.h \
memxor-internal.h nettle-internal.h nettle-write.h \
......
......@@ -90,4 +90,76 @@ block8_xor_bytes (union nettle_block8 *r,
memxor3 (r->b, x->b, bytes, 8);
}
/* Do a foreign-endianness shift of data */
#define LSHIFT_ALIEN_UINT64(x) \
((((x) & UINT64_C(0x7f7f7f7f7f7f7f7f)) << 1) | \
(((x) & UINT64_C(0x8080808080808080)) >> 15))
/* Two typical defining polynoms */
#define BLOCK16_POLY (UINT64_C(0x87))
#define BLOCK8_POLY (UINT64_C(0x1b))
/* Galois multiplications by 2:
* functions differ in shifting right or left, big- or little- endianness
* and by defining polynom.
* r == x is allowed. */
#if WORDS_BIGENDIAN
static inline void
block16_mulx_be (union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = src->u64[0] >> 63;
dst->u64[0] = (src->u64[0] << 1) | (src->u64[1] >> 63);
dst->u64[1] = (src->u64[1] << 1) ^ (BLOCK16_POLY & -carry);
}
static inline void
block16_mulx_le (union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = (src->u64[1] & 0x80) >> 7;
dst->u64[1] = LSHIFT_ALIEN_UINT64(src->u64[1]) | ((src->u64[0] & 0x80) << 49);
dst->u64[0] = LSHIFT_ALIEN_UINT64(src->u64[0]) ^ ((BLOCK16_POLY << 56) & -carry);
}
static inline void
block8_mulx_be (union nettle_block8 *dst,
const union nettle_block8 *src)
{
uint64_t carry = src->u64 >> 63;
dst->u64 = (src->u64 << 1) ^ (BLOCK8_POLY & -carry);
}
#else /* !WORDS_BIGENDIAN */
static inline void
block16_mulx_be (union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = (src->u64[0] & 0x80) >> 7;
dst->u64[0] = LSHIFT_ALIEN_UINT64(src->u64[0]) | ((src->u64[1] & 0x80) << 49);
dst->u64[1] = LSHIFT_ALIEN_UINT64(src->u64[1]) ^ ((BLOCK16_POLY << 56) & -carry);
}
static inline void
block16_mulx_le (union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = src->u64[1] >> 63;
dst->u64[1] = (src->u64[1] << 1) | (src->u64[0] >> 63);
dst->u64[0] = (src->u64[0] << 1) ^ (BLOCK16_POLY & -carry);
}
static inline void
block8_mulx_be (union nettle_block8 *dst,
const union nettle_block8 *src)
{
uint64_t carry = (src->u64 & 0x80) >> 7;
dst->u64 = LSHIFT_ALIEN_UINT64(src->u64) ^ ((BLOCK8_POLY << 56) & -carry);
}
#endif /* !WORDS_BIGENDIAN */
#endif /* NETTLE_BLOCK_INTERNAL_H_INCLUDED */
/* cmac-internal.h
CMAC mode internal functions
Copyright (C) 2017 Red Hat, Inc.
Contributed by Nikos Mavrogiannopoulos
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_CMAC_INTERNAL_H_INCLUDED
#define NETTLE_CMAC_INTERNAL_H_INCLUDED
#include "cmac.h"
#ifdef __cplusplus
extern "C" {
#endif
#define _cmac128_block_mulx _nettle_cmac128_block_mulx
void _cmac128_block_mulx(union nettle_block16 *out,
const union nettle_block16 *in);
#ifdef __cplusplus
}
#endif
#endif /* CMAC_INTERNAL_H_INCLUDED */
......@@ -44,33 +44,9 @@
#include "memxor.h"
#include "nettle-internal.h"
#include "cmac-internal.h"
#include "block-internal.h"
#include "macros.h"
/* shift one and XOR with 0x87. */
#if WORDS_BIGENDIAN
void
_cmac128_block_mulx(union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = src->u64[0] >> 63;
dst->u64[0] = (src->u64[0] << 1) | (src->u64[1] >> 63);
dst->u64[1] = (src->u64[1] << 1) ^ (0x87 & -carry);
}
#else /* !WORDS_BIGENDIAN */
#define LE_SHIFT(x) ((((x) & 0x7f7f7f7f7f7f7f7f) << 1) | \
(((x) & 0x8080808080808080) >> 15))
void
_cmac128_block_mulx(union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = (src->u64[0] & 0x80) >> 7;
dst->u64[0] = LE_SHIFT(src->u64[0]) | ((src->u64[1] & 0x80) << 49);
dst->u64[1] = LE_SHIFT(src->u64[1]) ^ (0x8700000000000000 & -carry);
}
#endif /* !WORDS_BIGENDIAN */
void
cmac128_set_key(struct cmac128_key *key, const void *cipher,
nettle_cipher_func *encrypt)
......@@ -81,8 +57,8 @@ cmac128_set_key(struct cmac128_key *key, const void *cipher,
/* step 1 - generate subkeys k1 and k2 */
encrypt(cipher, 16, L.b, zero_block.b);
_cmac128_block_mulx(&key->K1, &L);
_cmac128_block_mulx(&key->K2, &key->K1);
block16_mulx_be(&key->K1, &L);
block16_mulx_be(&key->K2, &key->K1);
}
void
......
......@@ -47,29 +47,6 @@
#include "block-internal.h"
#include "macros.h"
/* shift one and XOR with 0x87. */
#if WORDS_BIGENDIAN
static void
_cmac64_block_mulx(union nettle_block8 *dst,
const union nettle_block8 *src)
{
uint64_t carry = src->u64 >> 63;
dst->u64 = (src->u64 << 1) ^ (0x1b & -carry);
}
#else /* !WORDS_BIGENDIAN */
#define LE_SHIFT(x) ((((x) & 0x7f7f7f7f7f7f7f7f) << 1) | \
(((x) & 0x8080808080808080) >> 15))
static void
_cmac64_block_mulx(union nettle_block8 *dst,
const union nettle_block8 *src)
{
uint64_t carry = (src->u64 & 0x80) >> 7;
dst->u64 = LE_SHIFT(src->u64) ^ (0x1b00000000000000 & -carry);
}
#endif /* !WORDS_BIGENDIAN */
void
cmac64_set_key(struct cmac64_key *key, const void *cipher,
nettle_cipher_func *encrypt)
......@@ -80,8 +57,8 @@ cmac64_set_key(struct cmac64_key *key, const void *cipher,
/* step 1 - generate subkeys k1 and k2 */
encrypt(cipher, 8, L.b, zero_block.b);
_cmac64_block_mulx(&key->K1, &L);
_cmac64_block_mulx(&key->K2, &key->K1);
block8_mulx_be(&key->K1, &L);
block8_mulx_be(&key->K2, &key->K1);
}
void
......
......@@ -82,27 +82,13 @@ omac_final (union nettle_block16 *state, const struct eax_key *key,
f (cipher, EAX_BLOCK_SIZE, state->b, state->b);
}
/* Allows r == a */
static void
gf2_double (uint8_t *r, const uint8_t *a)
{
unsigned high = - (a[0] >> 7);
unsigned i;
/* Shift left */
for (i = 0; i < EAX_BLOCK_SIZE - 1; i++)
r[i] = (a[i] << 1) + (a[i+1] >> 7);
/* Wrap around for x^{128} = x^7 + x^2 + x + 1 */
r[EAX_BLOCK_SIZE - 1] = (a[EAX_BLOCK_SIZE - 1] << 1) ^ (high & 0x87);
}
void
eax_set_key (struct eax_key *key, const void *cipher, nettle_cipher_func *f)
{
static const union nettle_block16 zero_block;
f (cipher, EAX_BLOCK_SIZE, key->pad_block.b, zero_block.b);
gf2_double (key->pad_block.b, key->pad_block.b);
gf2_double (key->pad_partial.b, key->pad_block.b);
block16_mulx_be (&key->pad_block, &key->pad_block);
block16_mulx_be (&key->pad_partial, &key->pad_block);
block16_xor (&key->pad_partial, &key->pad_block);
}
......
......@@ -44,7 +44,6 @@
#include "ctr.h"
#include "memxor.h"
#include "memops.h"
#include "cmac-internal.h"
void
siv_cmac_aes128_set_key(struct siv_cmac_aes128_ctx *ctx, const uint8_t *key)
......
......@@ -44,7 +44,6 @@
#include "ctr.h"
#include "memxor.h"
#include "memops.h"
#include "cmac-internal.h"
void
siv_cmac_aes256_set_key(struct siv_cmac_aes256_ctx *ctx, const uint8_t *key)
......
......@@ -44,7 +44,6 @@
#include "ctr.h"
#include "memxor.h"
#include "memops.h"
#include "cmac-internal.h"
#include "nettle-internal.h"
#include "block-internal.h"
......@@ -67,12 +66,12 @@ _siv_s2v (const struct nettle_cipher *nc,
cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, const_zero.b);
cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, D.b);
_cmac128_block_mulx (&D, &D);
block16_mulx_be (&D, &D);
cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, alength, adata);
cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
block16_xor (&D, &S);
_cmac128_block_mulx (&D, &D);
block16_mulx_be (&D, &D);
cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, nlength, nonce);
cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
block16_xor (&D, &S);
......@@ -90,7 +89,7 @@ _siv_s2v (const struct nettle_cipher *nc,
{
union nettle_block16 pad;
_cmac128_block_mulx (&T, &D);
block16_mulx_be (&T, &D);
memcpy (pad.b, pdata, plength);
pad.b[plength] = 0x80;
if (plength + 1 < 16)
......
......@@ -44,31 +44,7 @@
#include "macros.h"
#include "memxor.h"
#include "nettle-internal.h"
/* shift left one and XOR with 0x87 if there is carry. */
/* the algorithm reads this as a 128bit Little Endian number */
/* src and dest can point to the same buffer for in-place operations */
#if WORDS_BIGENDIAN
#define BE_SHIFT(x) ((((x) & 0x7f7f7f7f7f7f7f7f) << 1) | \
(((x) & 0x8080808080808080) >> 15))
static void
xts_shift(union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = (src->u64[1] & 0x80) >> 7;
dst->u64[1] = BE_SHIFT(src->u64[1]) | ((src->u64[0] & 0x80) << 49);
dst->u64[0] = BE_SHIFT(src->u64[0]) ^ (0x8700000000000000 & -carry);
}
#else /* !WORDS_BIGENDIAN */
static void
xts_shift(union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = src->u64[1] >> 63;
dst->u64[1] = (src->u64[1] << 1) | (src->u64[0] >> 63);
dst->u64[0] = (src->u64[0] << 1) ^ (0x87 & -carry);
}
#endif /* !WORDS_BIGNDIAN */
#include "block-internal.h"
static void
check_length(size_t length, uint8_t *dst)
......@@ -107,7 +83,7 @@ xts_encrypt_message(const void *enc_ctx, const void *twk_ctx,
/* shift T for next block if any */
if (length > XTS_BLOCK_SIZE)
xts_shift(&T, &T);
block16_mulx_le(&T, &T);
}
/* if the last block is partial, handle via stealing */
......@@ -121,7 +97,7 @@ xts_encrypt_message(const void *enc_ctx, const void *twk_ctx,
memxor(S.b, T.b, XTS_BLOCK_SIZE); /* CC -> S */
/* shift T for next block */
xts_shift(&T, &T);
block16_mulx_le(&T, &T);
length -= XTS_BLOCK_SIZE;
src += XTS_BLOCK_SIZE;
......@@ -162,7 +138,7 @@ xts_decrypt_message(const void *dec_ctx, const void *twk_ctx,
/* shift T for next block if any */
if (length > XTS_BLOCK_SIZE)
xts_shift(&T, &T);
block16_mulx_le(&T, &T);
}
/* if the last block is partial, handle via stealing */
......@@ -173,7 +149,7 @@ xts_decrypt_message(const void *dec_ctx, const void *twk_ctx,
union nettle_block16 S;
/* we need the last T(n) and save the T(n-1) for later */
xts_shift(&T1, &T);
block16_mulx_le(&T1, &T);
memxor3(C.b, src, T1.b, XTS_BLOCK_SIZE); /* C -> CC */
decf(dec_ctx, XTS_BLOCK_SIZE, S.b, C.b); /* PP */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment