dont you need endian.h to get bemtoh64 and htobem64?

On 13 Oct 2014, at 7:57, Christian Weisgerber <na...@mips.inka.de> wrote:

> Here's a cleaned-up diff.  Briefly tested on amd64 & sparc64.  I'll
> do some more testing tomorrow.  This already has mikeb@'s blessing.
> 
> Index: regress/sys/crypto/gmac/Makefile
> ===================================================================
> RCS file: /cvs/src/regress/sys/crypto/gmac/Makefile,v
> retrieving revision 1.2
> diff -u -p -r1.2 Makefile
> --- regress/sys/crypto/gmac/Makefile  18 Jan 2014 05:54:52 -0000      1.2
> +++ regress/sys/crypto/gmac/Makefile  12 Oct 2014 19:05:35 -0000
> @@ -3,7 +3,7 @@
> DIR=${.CURDIR}/../../../../sys
> 
> PROG= gmac_test
> -SRCS+=       rijndael.c gmac.c gmac_test.c
> +SRCS+=       rijndael.c gfmult.c gmac.c gmac_test.c
> CDIAGFLAGS=   -Wall
> CDIAGFLAGS+=  -Werror
> CDIAGFLAGS+=  -Wpointer-arith
> Index: sys/crypto/gfmult.c
> ===================================================================
> RCS file: sys/crypto/gfmult.c
> diff -N sys/crypto/gfmult.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ sys/crypto/gfmult.c       12 Oct 2014 17:28:42 -0000
> @@ -0,0 +1,275 @@
> +/*-
> + * Copyright (c) 2014 The FreeBSD Foundation
> + * All rights reserved.
> + *
> + * This software was developed by John-Mark Gurney under
> + * the sponsorship of the FreeBSD Foundation and
> + * Rubicon Communications, LLC (Netgate).
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1.  Redistributions of source code must retain the above copyright
> + *     notice, this list of conditions and the following disclaimer.
> + * 2.  Redistributions in binary form must reproduce the above copyright
> + *     notice, this list of conditions and the following disclaimer in the
> + *     documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + *
> + *   $FreeBSD$
> + *
> + */
> +
> +#include <crypto/gfmult.h>
> +
> +#define REV_POLY_REDUCT      0xe1    /* 0x87 bit reversed */
> +
> +/* reverse the bits of a nibble */
> +static const uint8_t nib_rev[] = {
> +     0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
> +     0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf,
> +};
> +
> +/* calulate v * 2 */
> +static inline struct gf128
> +gf128_mulalpha(struct gf128 v)
> +{
> +     uint64_t mask;
> +
> +     mask = !!(v.v[1] & 1);
> +     mask = ~(mask - 1);
> +     v.v[1] = (v.v[1] >> 1) | ((v.v[0] & 1) << 63);
> +     v.v[0] = (v.v[0] >> 1) ^ ((mask & REV_POLY_REDUCT) << 56);
> +
> +     return v;
> +}
> +
> +/*
> + * Generate a table for 0-16 * h.  Store the results in the table w/ indexes
> + * bit reversed, and the words striped across the values.
> + */
> +void
> +gf128_genmultable(struct gf128 h, struct gf128table *t)
> +{
> +     struct gf128 tbl[16];
> +     int i;
> +
> +     tbl[0] = MAKE_GF128(0, 0);
> +     tbl[1] = h;
> +
> +     for (i = 2; i < 16; i += 2) {
> +             tbl[i] = gf128_mulalpha(tbl[i / 2]);
> +             tbl[i + 1] = gf128_add(tbl[i], h);
> +     }
> +
> +     for (i = 0; i < 16; i++) {
> +             t->a[nib_rev[i]] = tbl[i].v[0] >> 32;
> +             t->b[nib_rev[i]] = tbl[i].v[0];
> +             t->c[nib_rev[i]] = tbl[i].v[1] >> 32;
> +             t->d[nib_rev[i]] = tbl[i].v[1];
> +     }
> +}
> +
> +/*
> + * Generate tables containing h, h^2, h^3 and h^4, starting at 0.
> + */
> +void
> +gf128_genmultable4(struct gf128 h, struct gf128table4 *t)
> +{
> +     struct gf128 h2, h3, h4;
> +
> +     gf128_genmultable(h, &t->tbls[0]);
> +
> +     h2 = gf128_mul(h, &t->tbls[0]);
> +
> +     gf128_genmultable(h2, &t->tbls[1]);
> +
> +     h3 = gf128_mul(h, &t->tbls[1]);
> +     gf128_genmultable(h3, &t->tbls[2]);
> +
> +     h4 = gf128_mul(h2, &t->tbls[1]);
> +     gf128_genmultable(h4, &t->tbls[3]);
> +}
> +
> +/*
> + * Read a row from the table.
> + */
> +static inline struct gf128
> +readrow(struct gf128table *tbl, unsigned bits)
> +{
> +     struct gf128 r;
> +
> +     bits = bits % 16;
> +
> +     r.v[0] = ((uint64_t)tbl->a[bits] << 32) | tbl->b[bits];
> +     r.v[1] = ((uint64_t)tbl->c[bits] << 32) | tbl->d[bits];
> +
> +     return r;
> +}
> +
> +/*
> + * These are the reduction values.  Since we are dealing with bit reversed
> + * version, the values need to be bit reversed, AND the indexes are also
> + * bit reversed to make lookups quicker.
> + */
> +static uint16_t reduction[] = {
> +     0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0,
> +     0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0,
> +};
> +
> +/*
> + * Calculate:
> + * (x*2^4 + word[3,0]*h) *
> + * 2^4 + word[7,4]*h) *
> + * ...
> + * 2^4 + word[63,60]*h
> + */
> +static struct gf128
> +gfmultword(uint64_t word, struct gf128 x, struct gf128table *tbl)
> +{
> +     struct gf128 row;
> +     unsigned bits;
> +     unsigned redbits;
> +     int i;
> +
> +     for (i = 0; i < 64; i += 4) {
> +             bits = word % 16;
> +
> +             /* fetch row */
> +             row = readrow(tbl, bits);
> +
> +             /* x * 2^4 */
> +             redbits = x.v[1] % 16;
> +             x.v[1] = (x.v[1] >> 4) | (x.v[0] % 16) << 60;
> +             x.v[0] >>= 4;
> +             x.v[0] ^= (uint64_t)reduction[redbits] << (64 - 16);
> +
> +             word >>= 4;
> +
> +             x = gf128_add(x, row);
> +     }
> +
> +     return x;
> +}
> +
> +/*
> + * Calculate
> + * (x*2^4 + worda[3,0]*h^4+wordb[3,0]*h^3+...+wordd[3,0]*h) *
> + * ...
> + * 2^4 + worda[63,60]*h^4+ ... + wordd[63,60]*h
> + *
> + * Passing/returning struct is .5% faster than passing in via pointer on
> + * amd64.
> + */
> +static struct gf128
> +gfmultword4(uint64_t worda, uint64_t wordb, uint64_t wordc, uint64_t wordd,
> +    struct gf128 x, struct gf128table4 *tbl)
> +{
> +     struct gf128 rowa, rowb, rowc, rowd;
> +     unsigned bitsa, bitsb, bitsc, bitsd;
> +     unsigned redbits;
> +     int i;
> +
> +     /*
> +      * XXX - nibble reverse words to save a shift? probably not as
> +      * nibble reverse would take 20 ops (5 * 4) verse 16
> +      */
> +
> +     for (i = 0; i < 64; i += 4) {
> +             bitsa = worda % 16;
> +             bitsb = wordb % 16;
> +             bitsc = wordc % 16;
> +             bitsd = wordd % 16;
> +
> +             /* fetch row */
> +             rowa = readrow(&tbl->tbls[3], bitsa);
> +             rowb = readrow(&tbl->tbls[2], bitsb);
> +             rowc = readrow(&tbl->tbls[1], bitsc);
> +             rowd = readrow(&tbl->tbls[0], bitsd);
> +
> +             /* x * 2^4 */
> +             redbits = x.v[1] % 16;
> +             x.v[1] = (x.v[1] >> 4) | (x.v[0] % 16) << 60;
> +             x.v[0] >>= 4;
> +             x.v[0] ^= (uint64_t)reduction[redbits] << (64 - 16);
> +
> +             worda >>= 4;
> +             wordb >>= 4;
> +             wordc >>= 4;
> +             wordd >>= 4;
> +
> +             x = gf128_add(x, gf128_add(rowa, gf128_add(rowb,
> +                 gf128_add(rowc, rowd))));
> +     }
> +
> +     return x;
> +}
> +
> +struct gf128
> +gf128_mul(struct gf128 v, struct gf128table *tbl)
> +{
> +     struct gf128 ret;
> +
> +     ret = MAKE_GF128(0, 0);
> +
> +     ret = gfmultword(v.v[1], ret, tbl);
> +     ret = gfmultword(v.v[0], ret, tbl);
> +
> +     return ret;
> +}
> +
> +/*
> + * Calculate a*h^4 + b*h^3 + c*h^2 + d*h, or:
> + * (((a*h+b)*h+c)*h+d)*h
> + */
> +struct gf128
> +gf128_mul4(struct gf128 a, struct gf128 b, struct gf128 c, struct gf128 d,
> +    struct gf128table4 *tbl)
> +{
> +     struct gf128 tmp;
> +
> +     tmp = MAKE_GF128(0, 0);
> +
> +     tmp = gfmultword4(a.v[1], b.v[1], c.v[1], d.v[1], tmp, tbl);
> +     tmp = gfmultword4(a.v[0], b.v[0], c.v[0], d.v[0], tmp, tbl);
> +
> +     return tmp;
> +}
> +
> +/*
> + * a = data[0..15] + r
> + * b = data[16..31]
> + * c = data[32..47]
> + * d = data[48..63]
> + *
> + * Calculate a*h^4 + b*h^3 + c*h^2 + d*h, or:
> + * (((a*h+b)*h+c)*h+d)*h
> + */
> +struct gf128
> +gf128_mul4b(struct gf128 r, const uint8_t *v, struct gf128table4 *tbl)
> +{
> +     struct gf128 a, b, c, d;
> +     struct gf128 tmp;
> +
> +     tmp = MAKE_GF128(0, 0);
> +
> +     a = gf128_add(r, gf128_read(&v[0*16]));
> +     b = gf128_read(&v[1*16]);
> +     c = gf128_read(&v[2*16]);
> +     d = gf128_read(&v[3*16]);
> +
> +     tmp = gfmultword4(a.v[1], b.v[1], c.v[1], d.v[1], tmp, tbl);
> +     tmp = gfmultword4(a.v[0], b.v[0], c.v[0], d.v[0], tmp, tbl);
> +
> +     return tmp;
> +}
> Index: sys/crypto/gfmult.h
> ===================================================================
> RCS file: sys/crypto/gfmult.h
> diff -N sys/crypto/gfmult.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ sys/crypto/gfmult.h       12 Oct 2014 19:54:03 -0000
> @@ -0,0 +1,125 @@
> +/*-
> + * Copyright (c) 2014 The FreeBSD Foundation
> + * All rights reserved.
> + *
> + * This software was developed by John-Mark Gurney under
> + * the sponsorship of the FreeBSD Foundation and
> + * Rubicon Communications, LLC (Netgate).
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1.  Redistributions of source code must retain the above copyright
> + *     notice, this list of conditions and the following disclaimer.
> + * 2.  Redistributions in binary form must reproduce the above copyright
> + *     notice, this list of conditions and the following disclaimer in the
> + *     documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + *
> + *   $FreeBSD$
> + *
> + */
> +
> +#ifndef _GFMULT_H_
> +#define _GFMULT_H_
> +
> +#include <sys/types.h>
> +
> +#ifdef _KERNEL
> +#define be64dec(buf) bemtoh64(buf)
> +#define be64enc(buf, x)      htobem64(buf, x)
> +#else
> +#include <endian.h>
> +#define be64dec(buf) be64toh(*(uint64_t *)buf)
> +#define be64enc(buf, x)      (*(uint64_t *)buf = htobe64(x))
> +#endif
> +
> +/* XXX GCC 4.2 cannot align stack variables to 64 */
> +#define REQ_ALIGN    (16/* * 4*/)
> +/*
> + * The rows are striped across cache lines.  Note that the indexes
> + * are bit reversed to make accesses quicker.
> + */
> +struct gf128table {
> +     uint32_t a[16] __aligned(REQ_ALIGN);    /* bits   0 - 31 */
> +     uint32_t b[16] __aligned(REQ_ALIGN);    /* bits  63 - 32 */
> +     uint32_t c[16] __aligned(REQ_ALIGN);    /* bits  95 - 64 */
> +     uint32_t d[16] __aligned(REQ_ALIGN);    /* bits 127 - 96 */
> +} __aligned(REQ_ALIGN);
> +
> +/*
> + * A set of tables that contain h, h^2, h^3, h^4.  To be used w/ gf128_mul4.
> + */
> +struct gf128table4 {
> +     struct gf128table       tbls[4];
> +};
> +
> +/*
> + * GCM per spec is bit reversed in memory.  So byte 0 is really bit reversed
> + * and contains bits 0-7.  We can deal w/ this by using right shifts and
> + * related math instead of having to bit reverse everything.  This means that
> + * the low bits are in v[0] (bits 0-63) and reverse order, while the high
> + * bits are in v[1] (bits 64-127) and reverse order.  The high bit of v[0] is
> + * bit 0, and the low bit of v[1] is bit 127.
> + */
> +struct gf128 {
> +     uint64_t v[2];
> +};
> +
> +/* Note that we don't bit reverse in MAKE_GF128. */
> +#define MAKE_GF128(a, b)     ((struct gf128){.v = { (a), (b) } })
> +#define GF128_EQ(a, b)               ((((a).v[0] ^ (b).v[0]) | \
> +                                 ((a).v[1] ^ (b).v[1])) == 0)
> +
> +static inline struct gf128
> +gf128_read(const uint8_t *buf)
> +{
> +     struct gf128 r;
> +
> +     r.v[0] = be64dec(buf);
> +     buf += sizeof(uint64_t);
> +
> +     r.v[1] = be64dec(buf);
> +
> +     return r;
> +}
> +
> +static inline void
> +gf128_write(struct gf128 v, uint8_t *buf)
> +{
> +     uint64_t tmp;
> +
> +     be64enc(buf, v.v[0]);
> +     buf += sizeof tmp;
> +
> +     be64enc(buf, v.v[1]);
> +}
> +
> +static inline struct gf128 __pure /* XXX - __pure2 instead */
> +gf128_add(struct gf128 a, struct gf128 b)
> +{
> +     a.v[0] ^= b.v[0];
> +     a.v[1] ^= b.v[1];
> +
> +     return a;
> +}
> +
> +void gf128_genmultable(struct gf128 h, struct gf128table *t);
> +void gf128_genmultable4(struct gf128 h, struct gf128table4 *t);
> +struct gf128 gf128_mul(struct gf128 v, struct gf128table *tbl);
> +struct gf128 gf128_mul4(struct gf128 a, struct gf128 b, struct gf128 c,
> +    struct gf128 d, struct gf128table4 *tbl);
> +struct gf128 gf128_mul4b(struct gf128 r, const uint8_t *v,
> +    struct gf128table4 *tbl);
> +
> +#endif /* _GFMULT_H_ */
> Index: sys/crypto/gmac.c
> ===================================================================
> RCS file: /cvs/src/sys/crypto/gmac.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 gmac.c
> --- sys/crypto/gmac.c 11 Jan 2011 15:44:23 -0000      1.3
> +++ sys/crypto/gmac.c 12 Oct 2014 20:09:20 -0000
> @@ -16,6 +16,35 @@
>  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>  */
> 
> +/*-
> + * Copyright (c) 2014 The FreeBSD Foundation
> + * All rights reserved.
> + *
> + * This software was developed by John-Mark Gurney under
> + * the sponsorship of the FreeBSD Foundation and
> + * Rubicon Communications, LLC (Netgate).
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1.  Redistributions of source code must retain the above copyright
> + *     notice, this list of conditions and the following disclaimer.
> + * 2.  Redistributions in binary form must reproduce the above copyright
> + *     notice, this list of conditions and the following disclaimer in the
> + *     documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> /*
>  * This code implements the Message Authentication part of the
>  * Galois/Counter Mode (as being described in the RFC 4543) using
> @@ -28,91 +57,33 @@
> #include <crypto/rijndael.h>
> #include <crypto/gmac.h>
> 
> -void ghash_gfmul(uint32_t *, uint32_t *, uint32_t *);
> -void ghash_update(GHASH_CTX *, uint8_t *, size_t);
> -
> -/* Computes a block multiplication in the GF(2^128) */
> -void
> -ghash_gfmul(uint32_t *X, uint32_t *Y, uint32_t *product)
> -{
> -     uint32_t        v[4];
> -     uint32_t        z[4] = { 0, 0, 0, 0};
> -     uint8_t         *x = (uint8_t *)X;
> -     uint32_t        mul;
> -     int             i;
> -
> -     v[0] = betoh32(Y[0]);
> -     v[1] = betoh32(Y[1]);
> -     v[2] = betoh32(Y[2]);
> -     v[3] = betoh32(Y[3]);
> -
> -     for (i = 0; i < GMAC_BLOCK_LEN * 8; i++) {
> -             /* update Z */
> -             if (x[i >> 3] & (1 << (~i & 7))) {
> -                     z[0] ^= v[0];
> -                     z[1] ^= v[1];
> -                     z[2] ^= v[2];
> -                     z[3] ^= v[3];
> -             } /* else: we preserve old values */
> -
> -             /* update V */
> -             mul = v[3] & 1;
> -             v[3] = (v[2] << 31) | (v[3] >> 1);
> -             v[2] = (v[1] << 31) | (v[2] >> 1);
> -             v[1] = (v[0] << 31) | (v[1] >> 1);
> -             v[0] = (v[0] >> 1) ^ (0xe1000000 * mul);
> -     }
> -
> -     product[0] = htobe32(z[0]);
> -     product[1] = htobe32(z[1]);
> -     product[2] = htobe32(z[2]);
> -     product[3] = htobe32(z[3]);
> -}
> -
> -void
> -ghash_update(GHASH_CTX *ctx, uint8_t *X, size_t len)
> -{
> -     uint32_t        *x = (uint32_t *)X;
> -     uint32_t        *s = (uint32_t *)ctx->S;
> -     uint32_t        *y = (uint32_t *)ctx->Z;
> -     int             i;
> -
> -     for (i = 0; i < len / GMAC_BLOCK_LEN; i++) {
> -             s[0] = y[0] ^ x[0];
> -             s[1] = y[1] ^ x[1];
> -             s[2] = y[2] ^ x[2];
> -             s[3] = y[3] ^ x[3];
> -
> -             ghash_gfmul((uint32_t *)ctx->S, (uint32_t *)ctx->H,
> -                 (uint32_t *)ctx->S);
> -
> -             y = s;
> -             x += 4;
> -     }
> -
> -     bcopy(ctx->S, ctx->Z, GMAC_BLOCK_LEN);
> -}
> -
> #define AESCTR_NONCESIZE      4
> 
> void
> AES_GMAC_Init(AES_GMAC_CTX *ctx)
> {
> -     bzero(ctx->ghash.H, GMAC_BLOCK_LEN);
> -     bzero(ctx->ghash.S, GMAC_BLOCK_LEN);
> -     bzero(ctx->ghash.Z, GMAC_BLOCK_LEN);
> -     bzero(ctx->J, GMAC_BLOCK_LEN);
> +     bzero(ctx, sizeof(*ctx));
> }
> 
> void
> AES_GMAC_Setkey(AES_GMAC_CTX *ctx, const uint8_t *key, uint16_t klen)
> {
> +     const uint8_t   zeros[GMAC_BLOCK_LEN] = {};
> +     struct gf128    h;
> +     uint8_t         hbuf[GMAC_BLOCK_LEN];
> +
>       ctx->rounds = rijndaelKeySetupEnc(ctx->K, (u_char *)key,
>           (klen - AESCTR_NONCESIZE) * 8);
>       /* copy out salt to the counter block */
>       bcopy(key + klen - AESCTR_NONCESIZE, ctx->J, AESCTR_NONCESIZE);
>       /* prepare a hash subkey */
> -     rijndaelEncrypt(ctx->K, ctx->rounds, ctx->ghash.H, ctx->ghash.H);
> +     rijndaelEncrypt(ctx->K, ctx->rounds, zeros, hbuf);
> +
> +     h = gf128_read(hbuf);
> +     gf128_genmultable4(h, &ctx->ghashtbl);
> +
> +     explicit_bzero(&h, sizeof(h));
> +     explicit_bzero(hbuf, sizeof(hbuf));
> }
> 
> void
> @@ -125,20 +96,34 @@ AES_GMAC_Reinit(AES_GMAC_CTX *ctx, const
> int
> AES_GMAC_Update(AES_GMAC_CTX *ctx, const uint8_t *data, uint16_t len)
> {
> -     uint32_t        blk[4] = { 0, 0, 0, 0 };
> -     int             plen;
> +     struct gf128    v;
> +     uint8_t         buf[GMAC_BLOCK_LEN] = {};
> +     int             i;
> +
> +     v = ctx->hash;
> 
> -     if (len > 0) {
> -             plen = len % GMAC_BLOCK_LEN;
> -             if (len >= GMAC_BLOCK_LEN)
> -                     ghash_update(&ctx->ghash, (uint8_t *)data, len - plen);
> -             if (plen) {
> -                     bcopy((uint8_t *)data + (len - plen), (uint8_t *)blk,
> -                         plen);
> -                     ghash_update(&ctx->ghash, (uint8_t *)blk,
> -                         GMAC_BLOCK_LEN);
> +     while (len > 0) {
> +             if (len >= 4*GMAC_BLOCK_LEN) {
> +                     i = 4*GMAC_BLOCK_LEN;
> +                     v = gf128_mul4b(v, data, &ctx->ghashtbl);
> +             } else if (len >= GMAC_BLOCK_LEN) {
> +                     i = GMAC_BLOCK_LEN;
> +                     v = gf128_add(v, gf128_read(data));
> +                     v = gf128_mul(v, &ctx->ghashtbl.tbls[0]);
> +             } else {
> +                     i = len;
> +                     bcopy(data, buf, i);
> +                     v = gf128_add(v, gf128_read(&buf[0]));
> +                     v = gf128_mul(v, &ctx->ghashtbl.tbls[0]);
> +                     explicit_bzero(buf, sizeof buf);
>               }
> +             len -= i;
> +             data += i;
>       }
> +
> +     ctx->hash = v;
> +     explicit_bzero(&v, sizeof v);
> +
>       return (0);
> }
> 
> @@ -146,12 +131,12 @@ void
> AES_GMAC_Final(uint8_t digest[GMAC_DIGEST_LEN], AES_GMAC_CTX *ctx)
> {
>       uint8_t         keystream[GMAC_BLOCK_LEN];
> -     int             i;
> +     struct gf128    a;
> 
>       /* do one round of GCTR */
>       ctx->J[GMAC_BLOCK_LEN - 1] = 1;
>       rijndaelEncrypt(ctx->K, ctx->rounds, ctx->J, keystream);
> -     for (i = 0; i < GMAC_DIGEST_LEN; i++)
> -             digest[i] = ctx->ghash.S[i] ^ keystream[i];
> +     a = gf128_add(ctx->hash, gf128_read(keystream));
> +     gf128_write(a, digest);
>       explicit_bzero(keystream, sizeof(keystream));
> }
> Index: sys/crypto/gmac.h
> ===================================================================
> RCS file: /cvs/src/sys/crypto/gmac.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 gmac.h
> --- sys/crypto/gmac.h 5 Dec 2012 23:20:15 -0000       1.2
> +++ sys/crypto/gmac.h 12 Oct 2014 17:40:58 -0000
> @@ -19,6 +19,7 @@
> #ifndef _GMAC_H_
> #define _GMAC_H_
> 
> +#include <crypto/gfmult.h>
> #include <crypto/rijndael.h>
> 
> #define GMAC_BLOCK_LEN                16
> @@ -31,7 +32,8 @@ typedef struct _GHASH_CTX {
> } GHASH_CTX;
> 
> typedef struct _AES_GMAC_CTX {
> -     GHASH_CTX       ghash;
> +     struct gf128table4 ghashtbl;
> +     struct gf128    hash;
>       uint32_t        K[4*(AES_MAXROUNDS + 1)];
>       uint8_t         J[GMAC_BLOCK_LEN];              /* counter block */
>       int             rounds;
> -- 
> Christian "naddy" Weisgerber                          na...@mips.inka.de
> 


Reply via email to