Thu Jun 9 14:47:42 2011 UTC ()
use 64-bit integers for GF128 multiplication on LP64 CPUs


(drochner)
diff -r1.2 -r1.3 src/sys/opencrypto/gmac.c
diff -r1.1 -r1.2 src/sys/opencrypto/gmac.h

cvs diff -r1.2 -r1.3 src/sys/opencrypto/gmac.c (expand / switch to unified diff)

--- src/sys/opencrypto/gmac.c 2011/06/08 10:14:16 1.2
+++ src/sys/opencrypto/gmac.c 2011/06/09 14:47:42 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: gmac.c,v 1.2 2011/06/08 10:14:16 drochner Exp $ */ 1/* $NetBSD: gmac.c,v 1.3 2011/06/09 14:47:42 drochner Exp $ */
2/* OpenBSD: gmac.c,v 1.3 2011/01/11 15:44:23 deraadt Exp */ 2/* OpenBSD: gmac.c,v 1.3 2011/01/11 15:44:23 deraadt Exp */
3 3
4/* 4/*
5 * Copyright (c) 2010 Mike Belopuhov <mike@vantronix.net> 5 * Copyright (c) 2010 Mike Belopuhov <mike@vantronix.net>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -19,71 +19,87 @@ @@ -19,71 +19,87 @@
19 19
20/* 20/*
21 * This code implements the Message Authentication part of the 21 * This code implements the Message Authentication part of the
22 * Galois/Counter Mode (as being described in the RFC 4543) using 22 * Galois/Counter Mode (as being described in the RFC 4543) using
23 * the AES cipher. FIPS SP 800-38D describes the algorithm details. 23 * the AES cipher. FIPS SP 800-38D describes the algorithm details.
24 */ 24 */
25 25
26#include <sys/param.h> 26#include <sys/param.h>
27#include <sys/systm.h> 27#include <sys/systm.h>
28 28
29#include <crypto/rijndael/rijndael.h> 29#include <crypto/rijndael/rijndael.h>
30#include <opencrypto/gmac.h> 30#include <opencrypto/gmac.h>
31 31
32void ghash_gfmul(const uint32_t *, const uint32_t *, uint32_t *); 32void ghash_gfmul(const GMAC_INT *, const GMAC_INT *, GMAC_INT *);
33void ghash_update(GHASH_CTX *, const uint8_t *, size_t); 33void ghash_update(GHASH_CTX *, const uint8_t *, size_t);
34 34
35/* Computes a block multiplication in the GF(2^128) */ 35/* Computes a block multiplication in the GF(2^128) */
36void 36void
37ghash_gfmul(const uint32_t *X, const uint32_t *Y, uint32_t *product) 37ghash_gfmul(const GMAC_INT *X, const GMAC_INT *Y, GMAC_INT *product)
38{ 38{
39 uint32_t v[4]; 39 GMAC_INT v[GMAC_BLOCK_LEN/GMAC_INTLEN];
40 uint32_t mul; 40 uint32_t mul;
41 int i; 41 int i;
42 42
43 memcpy(v, Y, GMAC_BLOCK_LEN); 43 memcpy(v, Y, GMAC_BLOCK_LEN);
44 memset(product, 0, GMAC_BLOCK_LEN); 44 memset(product, 0, GMAC_BLOCK_LEN);
45 45
46 for (i = 0; i < GMAC_BLOCK_LEN * 8; i++) { 46 for (i = 0; i < GMAC_BLOCK_LEN * 8; i++) {
47 /* update Z */ 47 /* update Z */
 48#if GMAC_INTLEN == 8
 49 if (X[i >> 6] & (1ULL << (~i & 63))) {
 50 product[0] ^= v[0];
 51 product[1] ^= v[1];
 52 } /* else: we preserve old values */
 53#else
48 if (X[i >> 5] & (1 << (~i & 31))) { 54 if (X[i >> 5] & (1 << (~i & 31))) {
49 product[0] ^= v[0]; 55 product[0] ^= v[0];
50 product[1] ^= v[1]; 56 product[1] ^= v[1];
51 product[2] ^= v[2]; 57 product[2] ^= v[2];
52 product[3] ^= v[3]; 58 product[3] ^= v[3];
53 } /* else: we preserve old values */ 59 } /* else: we preserve old values */
54 60#endif
55 /* update V */ 61 /* update V */
 62#if GMAC_INTLEN == 8
 63 mul = v[1] & 1;
 64 v[1] = (v[0] << 63) | (v[1] >> 1);
 65 v[0] = (v[0] >> 1) ^ (0xe100000000000000ULL * mul);
 66#else
56 mul = v[3] & 1; 67 mul = v[3] & 1;
57 v[3] = (v[2] << 31) | (v[3] >> 1); 68 v[3] = (v[2] << 31) | (v[3] >> 1);
58 v[2] = (v[1] << 31) | (v[2] >> 1); 69 v[2] = (v[1] << 31) | (v[2] >> 1);
59 v[1] = (v[0] << 31) | (v[1] >> 1); 70 v[1] = (v[0] << 31) | (v[1] >> 1);
60 v[0] = (v[0] >> 1) ^ (0xe1000000 * mul); 71 v[0] = (v[0] >> 1) ^ (0xe1000000 * mul);
 72#endif
61 } 73 }
62} 74}
63 75
64void 76void
65ghash_update(GHASH_CTX *ctx, const uint8_t *X, size_t len) 77ghash_update(GHASH_CTX *ctx, const uint8_t *X, size_t len)
66{ 78{
67 uint32_t x; 79 GMAC_INT x;
68 uint32_t *s = ctx->S; 80 GMAC_INT *s = ctx->S;
69 uint32_t *y = ctx->Z; 81 GMAC_INT *y = ctx->Z;
70 int i, j; 82 int i, j, k;
71 83
72 for (i = 0; i < len / GMAC_BLOCK_LEN; i++) { 84 for (i = 0; i < len / GMAC_BLOCK_LEN; i++) {
73 for (j = 0; j < GMAC_BLOCK_LEN/4; j++) { 85 for (j = 0; j < GMAC_BLOCK_LEN/GMAC_INTLEN; j++) {
74 x = (X[0] << 24) | (X[1] << 16) | (X[2] << 8) | X[3]; 86 x = 0;
 87 for (k = 0; k < GMAC_INTLEN; k++) {
 88 x <<= 8;
 89 x |= X[k];
 90 }
75 s[j] = y[j] ^ x; 91 s[j] = y[j] ^ x;
76 X += 4; 92 X += GMAC_INTLEN;
77 } 93 }
78 94
79 ghash_gfmul(ctx->H, ctx->S, ctx->S); 95 ghash_gfmul(ctx->H, ctx->S, ctx->S);
80 96
81 y = s; 97 y = s;
82 } 98 }
83 99
84 memcpy(ctx->Z, ctx->S, GMAC_BLOCK_LEN); 100 memcpy(ctx->Z, ctx->S, GMAC_BLOCK_LEN);
85} 101}
86 102
87#define AESCTR_NONCESIZE 4 103#define AESCTR_NONCESIZE 4
88 104
89void 105void
@@ -95,28 +111,33 @@ AES_GMAC_Init(AES_GMAC_CTX *ctx) @@ -95,28 +111,33 @@ AES_GMAC_Init(AES_GMAC_CTX *ctx)
95 111
96void 112void
97AES_GMAC_Setkey(AES_GMAC_CTX *ctx, const uint8_t *key, uint16_t klen) 113AES_GMAC_Setkey(AES_GMAC_CTX *ctx, const uint8_t *key, uint16_t klen)
98{ 114{
99 int i; 115 int i;
100 116
101 ctx->rounds = rijndaelKeySetupEnc(ctx->K, (const u_char *)key, 117 ctx->rounds = rijndaelKeySetupEnc(ctx->K, (const u_char *)key,
102 (klen - AESCTR_NONCESIZE) * 8); 118 (klen - AESCTR_NONCESIZE) * 8);
103 /* copy out salt to the counter block */ 119 /* copy out salt to the counter block */
104 memcpy(ctx->J, key + klen - AESCTR_NONCESIZE, AESCTR_NONCESIZE); 120 memcpy(ctx->J, key + klen - AESCTR_NONCESIZE, AESCTR_NONCESIZE);
105 /* prepare a hash subkey */ 121 /* prepare a hash subkey */
106 rijndaelEncrypt(ctx->K, ctx->rounds, (void *)ctx->ghash.H, 122 rijndaelEncrypt(ctx->K, ctx->rounds, (void *)ctx->ghash.H,
107 (void *)ctx->ghash.H); 123 (void *)ctx->ghash.H);
 124#if GMAC_INTLEN == 8
 125 for (i = 0; i < 2; i++)
 126 ctx->ghash.H[i] = be64toh(ctx->ghash.H[i]);
 127#else
108 for (i = 0; i < 4; i++) 128 for (i = 0; i < 4; i++)
109 ctx->ghash.H[i] = be32toh(ctx->ghash.H[i]); 129 ctx->ghash.H[i] = be32toh(ctx->ghash.H[i]);
 130#endif
110} 131}
111 132
112void 133void
113AES_GMAC_Reinit(AES_GMAC_CTX *ctx, const uint8_t *iv, uint16_t ivlen) 134AES_GMAC_Reinit(AES_GMAC_CTX *ctx, const uint8_t *iv, uint16_t ivlen)
114{ 135{
115 /* copy out IV to the counter block */ 136 /* copy out IV to the counter block */
116 memcpy(ctx->J + AESCTR_NONCESIZE, iv, ivlen); 137 memcpy(ctx->J + AESCTR_NONCESIZE, iv, ivlen);
117} 138}
118 139
119int 140int
120AES_GMAC_Update(AES_GMAC_CTX *ctx, const uint8_t *data, uint16_t len) 141AES_GMAC_Update(AES_GMAC_CTX *ctx, const uint8_t *data, uint16_t len)
121{ 142{
122 uint8_t blk[16] = { 0 }; 143 uint8_t blk[16] = { 0 };
@@ -135,23 +156,38 @@ AES_GMAC_Update(AES_GMAC_CTX *ctx, const @@ -135,23 +156,38 @@ AES_GMAC_Update(AES_GMAC_CTX *ctx, const
135} 156}
136 157
137void 158void
138AES_GMAC_Final(uint8_t digest[GMAC_DIGEST_LEN], AES_GMAC_CTX *ctx) 159AES_GMAC_Final(uint8_t digest[GMAC_DIGEST_LEN], AES_GMAC_CTX *ctx)
139{ 160{
140 uint8_t keystream[GMAC_BLOCK_LEN], *k, *d; 161 uint8_t keystream[GMAC_BLOCK_LEN], *k, *d;
141 int i; 162 int i;
142 163
143 /* do one round of GCTR */ 164 /* do one round of GCTR */
144 ctx->J[GMAC_BLOCK_LEN - 1] = 1; 165 ctx->J[GMAC_BLOCK_LEN - 1] = 1;
145 rijndaelEncrypt(ctx->K, ctx->rounds, ctx->J, keystream); 166 rijndaelEncrypt(ctx->K, ctx->rounds, ctx->J, keystream);
146 k = keystream; 167 k = keystream;
147 d = digest; 168 d = digest;
 169#if GMAC_INTLEN == 8
 170 for (i = 0; i < GMAC_DIGEST_LEN/8; i++) {
 171 d[0] = (uint8_t)(ctx->ghash.S[i] >> 56) ^ k[0];
 172 d[1] = (uint8_t)(ctx->ghash.S[i] >> 48) ^ k[1];
 173 d[2] = (uint8_t)(ctx->ghash.S[i] >> 40) ^ k[2];
 174 d[3] = (uint8_t)(ctx->ghash.S[i] >> 32) ^ k[3];
 175 d[4] = (uint8_t)(ctx->ghash.S[i] >> 24) ^ k[4];
 176 d[5] = (uint8_t)(ctx->ghash.S[i] >> 16) ^ k[5];
 177 d[6] = (uint8_t)(ctx->ghash.S[i] >> 8) ^ k[6];
 178 d[7] = (uint8_t)ctx->ghash.S[i] ^ k[7];
 179 d += 8;
 180 k += 8;
 181 }
 182#else
148 for (i = 0; i < GMAC_DIGEST_LEN/4; i++) { 183 for (i = 0; i < GMAC_DIGEST_LEN/4; i++) {
149 d[0] = (uint8_t)(ctx->ghash.S[i] >> 24) ^ k[0]; 184 d[0] = (uint8_t)(ctx->ghash.S[i] >> 24) ^ k[0];
150 d[1] = (uint8_t)(ctx->ghash.S[i] >> 16) ^ k[1]; 185 d[1] = (uint8_t)(ctx->ghash.S[i] >> 16) ^ k[1];
151 d[2] = (uint8_t)(ctx->ghash.S[i] >> 8) ^ k[2]; 186 d[2] = (uint8_t)(ctx->ghash.S[i] >> 8) ^ k[2];
152 d[3] = (uint8_t)ctx->ghash.S[i] ^ k[3]; 187 d[3] = (uint8_t)ctx->ghash.S[i] ^ k[3];
153 d += 4; 188 d += 4;
154 k += 4; 189 k += 4;
155 } 190 }
 191#endif
156 memset(keystream, 0, sizeof(keystream)); 192 memset(keystream, 0, sizeof(keystream));
157} 193}

cvs diff -r1.1 -r1.2 src/sys/opencrypto/gmac.h (expand / switch to unified diff)

--- src/sys/opencrypto/gmac.h 2011/05/26 21:50:03 1.1
+++ src/sys/opencrypto/gmac.h 2011/06/09 14:47:42 1.2
@@ -1,44 +1,52 @@ @@ -1,44 +1,52 @@
1/* $NetBSD: gmac.h,v 1.1 2011/05/26 21:50:03 drochner Exp $ */ 1/* $NetBSD: gmac.h,v 1.2 2011/06/09 14:47:42 drochner Exp $ */
2/* OpenBSD: gmac.h,v 1.1 2010/09/22 11:54:23 mikeb Exp */ 2/* OpenBSD: gmac.h,v 1.1 2010/09/22 11:54:23 mikeb Exp */
3 3
4/* 4/*
5 * Copyright (c) 2010 Mike Belopuhov <mike@vantronix.net> 5 * Copyright (c) 2010 Mike Belopuhov <mike@vantronix.net>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20#ifndef _GMAC_H_ 20#ifndef _GMAC_H_
21#define _GMAC_H_ 21#define _GMAC_H_
22 22
23#include <crypto/rijndael/rijndael.h> 23#include <crypto/rijndael/rijndael.h>
24 24
25#define GMAC_BLOCK_LEN 16 25#define GMAC_BLOCK_LEN 16
26#define GMAC_DIGEST_LEN 16 26#define GMAC_DIGEST_LEN 16
27 27
 28#ifdef _LP64
 29#define GMAC_INT uint64_t
 30#define GMAC_INTLEN 8
 31#else
 32#define GMAC_INT uint32_t
 33#define GMAC_INTLEN 4
 34#endif
 35
28typedef struct _GHASH_CTX { 36typedef struct _GHASH_CTX {
29 uint32_t H[GMAC_BLOCK_LEN/4]; /* hash subkey */ 37 GMAC_INT H[GMAC_BLOCK_LEN/GMAC_INTLEN]; /* hash subkey */
30 uint32_t S[GMAC_BLOCK_LEN/4]; /* state */ 38 GMAC_INT S[GMAC_BLOCK_LEN/GMAC_INTLEN]; /* state */
31 uint32_t Z[GMAC_BLOCK_LEN/4]; /* initial state */ 39 GMAC_INT Z[GMAC_BLOCK_LEN/GMAC_INTLEN]; /* initial state */
32} GHASH_CTX; 40} GHASH_CTX;
33 41
34typedef struct _AES_GMAC_CTX { 42typedef struct _AES_GMAC_CTX {
35 GHASH_CTX ghash; 43 GHASH_CTX ghash;
36 uint32_t K[4*(RIJNDAEL_MAXNR + 1)]; 44 uint32_t K[4*(RIJNDAEL_MAXNR + 1)];
37 uint8_t J[GMAC_BLOCK_LEN]; /* counter block */ 45 uint8_t J[GMAC_BLOCK_LEN]; /* counter block */
38 int rounds; 46 int rounds;
39} AES_GMAC_CTX; 47} AES_GMAC_CTX;
40 48
41#include <sys/cdefs.h> 49#include <sys/cdefs.h>
42 50
43__BEGIN_DECLS 51__BEGIN_DECLS
44void AES_GMAC_Init(AES_GMAC_CTX *); 52void AES_GMAC_Init(AES_GMAC_CTX *);