1275732Sjmg/*- 2275732Sjmg * Copyright (c) 2014 The FreeBSD Foundation 3275732Sjmg * All rights reserved. 4275732Sjmg * 5275732Sjmg * This software was developed by John-Mark Gurney under 6275732Sjmg * the sponsorship of the FreeBSD Foundation and 7275732Sjmg * Rubicon Communications, LLC (Netgate). 8275732Sjmg * Redistribution and use in source and binary forms, with or without 9275732Sjmg * modification, are permitted provided that the following conditions 10275732Sjmg * are met: 11275732Sjmg * 1. Redistributions of source code must retain the above copyright 12275732Sjmg * notice, this list of conditions and the following disclaimer. 13275732Sjmg * 2. Redistributions in binary form must reproduce the above copyright 14275732Sjmg * notice, this list of conditions and the following disclaimer in the 15275732Sjmg * documentation and/or other materials provided with the distribution. 16275732Sjmg * 17275732Sjmg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18275732Sjmg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19275732Sjmg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20275732Sjmg * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21275732Sjmg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22275732Sjmg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23275732Sjmg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24275732Sjmg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25275732Sjmg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26275732Sjmg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27275732Sjmg * SUCH DAMAGE. 28275732Sjmg * 29275732Sjmg * $FreeBSD$ 30275732Sjmg * 31275732Sjmg */ 32275732Sjmg 33275732Sjmg#ifndef _GFMULT_H_ 34275732Sjmg#define _GFMULT_H_ 35275732Sjmg 36275732Sjmg#ifdef __APPLE__ 37275732Sjmg#define __aligned(x) __attribute__((__aligned__(x))) 38275732Sjmg#define be64dec(buf) __builtin_bswap64(*(uint64_t *)buf) 39275732Sjmg#define be64enc(buf, x) (*(uint64_t *)buf = __builtin_bswap64(x)) 40275732Sjmg#else 41275732Sjmg#include <sys/endian.h> 42275732Sjmg#endif 43275732Sjmg 44275732Sjmg#ifdef _KERNEL 45275732Sjmg#include <sys/types.h> 46275732Sjmg#else 47275732Sjmg#include <stdint.h> 48275732Sjmg#include <strings.h> 49275732Sjmg#endif 50275732Sjmg 51275732Sjmg#define REQ_ALIGN (16 * 4) 52275732Sjmg/* 53275732Sjmg * The rows are striped across cache lines. Note that the indexes 54275732Sjmg * are bit reversed to make accesses quicker. 55275732Sjmg */ 56275732Sjmgstruct gf128table { 57275732Sjmg uint32_t a[16] __aligned(REQ_ALIGN); /* bits 0 - 31 */ 58275732Sjmg uint32_t b[16] __aligned(REQ_ALIGN); /* bits 63 - 32 */ 59275732Sjmg uint32_t c[16] __aligned(REQ_ALIGN); /* bits 95 - 64 */ 60275732Sjmg uint32_t d[16] __aligned(REQ_ALIGN); /* bits 127 - 96 */ 61275732Sjmg} __aligned(REQ_ALIGN); 62275732Sjmg 63275732Sjmg/* 64275732Sjmg * A set of tables that contain h, h^2, h^3, h^4. To be used w/ gf128_mul4. 65275732Sjmg */ 66275732Sjmgstruct gf128table4 { 67275732Sjmg struct gf128table tbls[4]; 68275732Sjmg}; 69275732Sjmg 70275732Sjmg/* 71275732Sjmg * GCM per spec is bit reversed in memory. So byte 0 is really bit reversed 72275732Sjmg * and contains bits 0-7. We can deal w/ this by using right shifts and 73275732Sjmg * related math instead of having to bit reverse everything. This means that 74275732Sjmg * the low bits are in v[0] (bits 0-63) and reverse order, while the high 75275732Sjmg * bits are in v[1] (bits 64-127) and reverse order. The high bit of v[0] is 76275732Sjmg * bit 0, and the low bit of v[1] is bit 127. 77275732Sjmg */ 78275732Sjmgstruct gf128 { 79275732Sjmg uint64_t v[2]; 80275732Sjmg}; 81275732Sjmg 82275732Sjmg/* Note that we don't bit reverse in MAKE_GF128. */ 83275732Sjmg#define MAKE_GF128(a, b) ((struct gf128){.v = { (a), (b) } }) 84275732Sjmg#define GF128_EQ(a, b) ((((a).v[0] ^ (b).v[0]) | \ 85275732Sjmg ((a).v[1] ^ (b).v[1])) == 0) 86275732Sjmg 87275732Sjmgstatic inline struct gf128 88275732Sjmggf128_read(const uint8_t *buf) 89275732Sjmg{ 90275732Sjmg struct gf128 r; 91275732Sjmg 92275732Sjmg r.v[0] = be64dec(buf); 93275732Sjmg buf += sizeof(uint64_t); 94275732Sjmg 95275732Sjmg r.v[1] = be64dec(buf); 96275732Sjmg 97275732Sjmg return r; 98275732Sjmg} 99275732Sjmg 100275732Sjmgstatic inline void 101275732Sjmggf128_write(struct gf128 v, uint8_t *buf) 102275732Sjmg{ 103275732Sjmg uint64_t tmp; 104275732Sjmg 105275732Sjmg be64enc(buf, v.v[0]); 106275732Sjmg buf += sizeof tmp; 107275732Sjmg 108275732Sjmg be64enc(buf, v.v[1]); 109275732Sjmg} 110275732Sjmg 111275732Sjmgstatic inline struct gf128 __pure /* XXX - __pure2 instead */ 112275732Sjmggf128_add(struct gf128 a, struct gf128 b) 113275732Sjmg{ 114275732Sjmg a.v[0] ^= b.v[0]; 115275732Sjmg a.v[1] ^= b.v[1]; 116275732Sjmg 117275732Sjmg return a; 118275732Sjmg} 119275732Sjmg 120275732Sjmgvoid gf128_genmultable(struct gf128 h, struct gf128table *t); 121275732Sjmgvoid gf128_genmultable4(struct gf128 h, struct gf128table4 *t); 122275732Sjmgstruct gf128 gf128_mul(struct gf128 v, struct gf128table *tbl); 123275732Sjmgstruct gf128 gf128_mul4(struct gf128 a, struct gf128 b, struct gf128 c, 124275732Sjmg struct gf128 d, struct gf128table4 *tbl); 125275732Sjmgstruct gf128 gf128_mul4b(struct gf128 r, const uint8_t *v, 126275732Sjmg struct gf128table4 *tbl); 127275732Sjmg 128275732Sjmg#endif /* _GFMULT_H_ */ 129