1238384Sjkim/* ====================================================================
2238384Sjkim * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
3238384Sjkim *
4238384Sjkim * Redistribution and use in source and binary forms, with or without
5238384Sjkim * modification, are permitted provided that the following conditions
6238384Sjkim * are met:
7238384Sjkim *
8238384Sjkim * 1. Redistributions of source code must retain the above copyright
9280304Sjkim *    notice, this list of conditions and the following disclaimer.
10238384Sjkim *
11238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright
12238384Sjkim *    notice, this list of conditions and the following disclaimer in
13238384Sjkim *    the documentation and/or other materials provided with the
14238384Sjkim *    distribution.
15238384Sjkim *
16238384Sjkim * 3. All advertising materials mentioning features or use of this
17238384Sjkim *    software must display the following acknowledgment:
18238384Sjkim *    "This product includes software developed by the OpenSSL Project
19238384Sjkim *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20238384Sjkim *
21238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22238384Sjkim *    endorse or promote products derived from this software without
23238384Sjkim *    prior written permission. For written permission, please contact
24238384Sjkim *    openssl-core@openssl.org.
25238384Sjkim *
26238384Sjkim * 5. Products derived from this software may not be called "OpenSSL"
27238384Sjkim *    nor may "OpenSSL" appear in their names without prior written
28238384Sjkim *    permission of the OpenSSL Project.
29238384Sjkim *
30238384Sjkim * 6. Redistributions of any form whatsoever must retain the following
31238384Sjkim *    acknowledgment:
32238384Sjkim *    "This product includes software developed by the OpenSSL Project
33238384Sjkim *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34238384Sjkim *
35238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38238384Sjkim * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE.
47238384Sjkim * ====================================================================
48238384Sjkim */
49238384Sjkim
50238384Sjkim#define OPENSSL_FIPSAPI
51238384Sjkim
52238384Sjkim#include <openssl/crypto.h>
53238384Sjkim#include "modes_lcl.h"
54238384Sjkim#include <string.h>
55238384Sjkim
56238384Sjkim#ifndef MODES_DEBUG
57238384Sjkim# ifndef NDEBUG
58238384Sjkim#  define NDEBUG
59238384Sjkim# endif
60238384Sjkim#endif
61238384Sjkim#include <assert.h>
62238384Sjkim
63238384Sjkim#if defined(BSWAP4) && defined(STRICT_ALIGNMENT)
64238384Sjkim/* redefine, because alignment is ensured */
65280304Sjkim# undef  GETU32
66280304Sjkim# define GETU32(p)       BSWAP4(*(const u32 *)(p))
67280304Sjkim# undef  PUTU32
68280304Sjkim# define PUTU32(p,v)     *(u32 *)(p) = BSWAP4(v)
69238384Sjkim#endif
70238384Sjkim
71280304Sjkim#define PACK(s)         ((size_t)(s)<<(sizeof(size_t)*8-16))
72280304Sjkim#define REDUCE1BIT(V)   do { \
73280304Sjkim        if (sizeof(size_t)==8) { \
74280304Sjkim                u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \
75280304Sjkim                V.lo  = (V.hi<<63)|(V.lo>>1); \
76280304Sjkim                V.hi  = (V.hi>>1 )^T; \
77280304Sjkim        } \
78280304Sjkim        else { \
79280304Sjkim                u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \
80280304Sjkim                V.lo  = (V.hi<<63)|(V.lo>>1); \
81280304Sjkim                V.hi  = (V.hi>>1 )^((u64)T<<32); \
82280304Sjkim        } \
83238384Sjkim} while(0)
84238384Sjkim
85280304Sjkim/*-
86238384Sjkim * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
87238384Sjkim * never be set to 8. 8 is effectively reserved for testing purposes.
88238384Sjkim * TABLE_BITS>1 are lookup-table-driven implementations referred to as
89238384Sjkim * "Shoup's" in GCM specification. In other words OpenSSL does not cover
90238384Sjkim * whole spectrum of possible table driven implementations. Why? In
91238384Sjkim * non-"Shoup's" case memory access pattern is segmented in such manner,
92238384Sjkim * that it's trivial to see that cache timing information can reveal
93238384Sjkim * fair portion of intermediate hash value. Given that ciphertext is
94238384Sjkim * always available to attacker, it's possible for him to attempt to
95238384Sjkim * deduce secret parameter H and if successful, tamper with messages
96238384Sjkim * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's
97238384Sjkim * not as trivial, but there is no reason to believe that it's resistant
98238384Sjkim * to cache-timing attack. And the thing about "8-bit" implementation is
99238384Sjkim * that it consumes 16 (sixteen) times more memory, 4KB per individual
100238384Sjkim * key + 1KB shared. Well, on pros side it should be twice as fast as
101238384Sjkim * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version
102238384Sjkim * was observed to run ~75% faster, closer to 100% for commercial
103238384Sjkim * compilers... Yet "4-bit" procedure is preferred, because it's
104238384Sjkim * believed to provide better security-performance balance and adequate
105238384Sjkim * all-round performance. "All-round" refers to things like:
106238384Sjkim *
107238384Sjkim * - shorter setup time effectively improves overall timing for
108238384Sjkim *   handling short messages;
109238384Sjkim * - larger table allocation can become unbearable because of VM
110238384Sjkim *   subsystem penalties (for example on Windows large enough free
111238384Sjkim *   results in VM working set trimming, meaning that consequent
112238384Sjkim *   malloc would immediately incur working set expansion);
113238384Sjkim * - larger table has larger cache footprint, which can affect
114238384Sjkim *   performance of other code paths (not necessarily even from same
115238384Sjkim *   thread in Hyper-Threading world);
116238384Sjkim *
117238384Sjkim * Value of 1 is not appropriate for performance reasons.
118238384Sjkim */
119280304Sjkim#if     TABLE_BITS==8
120238384Sjkim
121238384Sjkimstatic void gcm_init_8bit(u128 Htable[256], u64 H[2])
122238384Sjkim{
123280304Sjkim    int i, j;
124280304Sjkim    u128 V;
125238384Sjkim
126280304Sjkim    Htable[0].hi = 0;
127280304Sjkim    Htable[0].lo = 0;
128280304Sjkim    V.hi = H[0];
129280304Sjkim    V.lo = H[1];
130238384Sjkim
131280304Sjkim    for (Htable[128] = V, i = 64; i > 0; i >>= 1) {
132280304Sjkim        REDUCE1BIT(V);
133280304Sjkim        Htable[i] = V;
134280304Sjkim    }
135238384Sjkim
136280304Sjkim    for (i = 2; i < 256; i <<= 1) {
137280304Sjkim        u128 *Hi = Htable + i, H0 = *Hi;
138280304Sjkim        for (j = 1; j < i; ++j) {
139280304Sjkim            Hi[j].hi = H0.hi ^ Htable[j].hi;
140280304Sjkim            Hi[j].lo = H0.lo ^ Htable[j].lo;
141280304Sjkim        }
142280304Sjkim    }
143238384Sjkim}
144238384Sjkim
145238384Sjkimstatic void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256])
146238384Sjkim{
147280304Sjkim    u128 Z = { 0, 0 };
148280304Sjkim    const u8 *xi = (const u8 *)Xi + 15;
149280304Sjkim    size_t rem, n = *xi;
150280304Sjkim    const union {
151280304Sjkim        long one;
152280304Sjkim        char little;
153280304Sjkim    } is_endian = {
154280304Sjkim        1
155280304Sjkim    };
156280304Sjkim    static const size_t rem_8bit[256] = {
157280304Sjkim        PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246),
158280304Sjkim        PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E),
159280304Sjkim        PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56),
160280304Sjkim        PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E),
161280304Sjkim        PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66),
162280304Sjkim        PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E),
163280304Sjkim        PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076),
164280304Sjkim        PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E),
165280304Sjkim        PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06),
166280304Sjkim        PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E),
167280304Sjkim        PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416),
168280304Sjkim        PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E),
169280304Sjkim        PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626),
170280304Sjkim        PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E),
171280304Sjkim        PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836),
172280304Sjkim        PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E),
173280304Sjkim        PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6),
174280304Sjkim        PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE),
175280304Sjkim        PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6),
176280304Sjkim        PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE),
177280304Sjkim        PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6),
178280304Sjkim        PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE),
179280304Sjkim        PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6),
180280304Sjkim        PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE),
181280304Sjkim        PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86),
182280304Sjkim        PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E),
183280304Sjkim        PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496),
184280304Sjkim        PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E),
185280304Sjkim        PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6),
186280304Sjkim        PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE),
187280304Sjkim        PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6),
188280304Sjkim        PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE),
189280304Sjkim        PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346),
190280304Sjkim        PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E),
191280304Sjkim        PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56),
192280304Sjkim        PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E),
193280304Sjkim        PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66),
194280304Sjkim        PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E),
195280304Sjkim        PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176),
196280304Sjkim        PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E),
197280304Sjkim        PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06),
198280304Sjkim        PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E),
199280304Sjkim        PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516),
200280304Sjkim        PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E),
201280304Sjkim        PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726),
202280304Sjkim        PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E),
203280304Sjkim        PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936),
204280304Sjkim        PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E),
205280304Sjkim        PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6),
206280304Sjkim        PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE),
207280304Sjkim        PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6),
208280304Sjkim        PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE),
209280304Sjkim        PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6),
210280304Sjkim        PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE),
211280304Sjkim        PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6),
212280304Sjkim        PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE),
213280304Sjkim        PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86),
214280304Sjkim        PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E),
215280304Sjkim        PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596),
216280304Sjkim        PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E),
217280304Sjkim        PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6),
218280304Sjkim        PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE),
219280304Sjkim        PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6),
220280304Sjkim        PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE)
221280304Sjkim    };
222238384Sjkim
223280304Sjkim    while (1) {
224280304Sjkim        Z.hi ^= Htable[n].hi;
225280304Sjkim        Z.lo ^= Htable[n].lo;
226238384Sjkim
227280304Sjkim        if ((u8 *)Xi == xi)
228280304Sjkim            break;
229238384Sjkim
230280304Sjkim        n = *(--xi);
231238384Sjkim
232280304Sjkim        rem = (size_t)Z.lo & 0xff;
233280304Sjkim        Z.lo = (Z.hi << 56) | (Z.lo >> 8);
234280304Sjkim        Z.hi = (Z.hi >> 8);
235280304Sjkim        if (sizeof(size_t) == 8)
236280304Sjkim            Z.hi ^= rem_8bit[rem];
237280304Sjkim        else
238280304Sjkim            Z.hi ^= (u64)rem_8bit[rem] << 32;
239280304Sjkim    }
240238384Sjkim
241280304Sjkim    if (is_endian.little) {
242280304Sjkim# ifdef BSWAP8
243280304Sjkim        Xi[0] = BSWAP8(Z.hi);
244280304Sjkim        Xi[1] = BSWAP8(Z.lo);
245280304Sjkim# else
246280304Sjkim        u8 *p = (u8 *)Xi;
247280304Sjkim        u32 v;
248280304Sjkim        v = (u32)(Z.hi >> 32);
249280304Sjkim        PUTU32(p, v);
250280304Sjkim        v = (u32)(Z.hi);
251280304Sjkim        PUTU32(p + 4, v);
252280304Sjkim        v = (u32)(Z.lo >> 32);
253280304Sjkim        PUTU32(p + 8, v);
254280304Sjkim        v = (u32)(Z.lo);
255280304Sjkim        PUTU32(p + 12, v);
256280304Sjkim# endif
257280304Sjkim    } else {
258280304Sjkim        Xi[0] = Z.hi;
259280304Sjkim        Xi[1] = Z.lo;
260280304Sjkim    }
261238384Sjkim}
262238384Sjkim
263280304Sjkim# define GCM_MUL(ctx,Xi)   gcm_gmult_8bit(ctx->Xi.u,ctx->Htable)
264238384Sjkim
265280304Sjkim#elif   TABLE_BITS==4
266280304Sjkim
267238384Sjkimstatic void gcm_init_4bit(u128 Htable[16], u64 H[2])
268238384Sjkim{
269280304Sjkim    u128 V;
270280304Sjkim# if defined(OPENSSL_SMALL_FOOTPRINT)
271280304Sjkim    int i;
272280304Sjkim# endif
273238384Sjkim
274280304Sjkim    Htable[0].hi = 0;
275280304Sjkim    Htable[0].lo = 0;
276280304Sjkim    V.hi = H[0];
277280304Sjkim    V.lo = H[1];
278238384Sjkim
279280304Sjkim# if defined(OPENSSL_SMALL_FOOTPRINT)
280280304Sjkim    for (Htable[8] = V, i = 4; i > 0; i >>= 1) {
281280304Sjkim        REDUCE1BIT(V);
282280304Sjkim        Htable[i] = V;
283280304Sjkim    }
284238384Sjkim
285280304Sjkim    for (i = 2; i < 16; i <<= 1) {
286280304Sjkim        u128 *Hi = Htable + i;
287280304Sjkim        int j;
288280304Sjkim        for (V = *Hi, j = 1; j < i; ++j) {
289280304Sjkim            Hi[j].hi = V.hi ^ Htable[j].hi;
290280304Sjkim            Hi[j].lo = V.lo ^ Htable[j].lo;
291280304Sjkim        }
292280304Sjkim    }
293280304Sjkim# else
294280304Sjkim    Htable[8] = V;
295280304Sjkim    REDUCE1BIT(V);
296280304Sjkim    Htable[4] = V;
297280304Sjkim    REDUCE1BIT(V);
298280304Sjkim    Htable[2] = V;
299280304Sjkim    REDUCE1BIT(V);
300280304Sjkim    Htable[1] = V;
301280304Sjkim    Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo;
302280304Sjkim    V = Htable[4];
303280304Sjkim    Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo;
304280304Sjkim    Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo;
305280304Sjkim    Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo;
306280304Sjkim    V = Htable[8];
307280304Sjkim    Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo;
308280304Sjkim    Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo;
309280304Sjkim    Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo;
310280304Sjkim    Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo;
311280304Sjkim    Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo;
312280304Sjkim    Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo;
313280304Sjkim    Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo;
314280304Sjkim# endif
315280304Sjkim# if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm))
316280304Sjkim    /*
317280304Sjkim     * ARM assembler expects specific dword order in Htable.
318280304Sjkim     */
319280304Sjkim    {
320280304Sjkim        int j;
321280304Sjkim        const union {
322280304Sjkim            long one;
323280304Sjkim            char little;
324280304Sjkim        } is_endian = {
325280304Sjkim            1
326280304Sjkim        };
327238384Sjkim
328280304Sjkim        if (is_endian.little)
329280304Sjkim            for (j = 0; j < 16; ++j) {
330280304Sjkim                V = Htable[j];
331280304Sjkim                Htable[j].hi = V.lo;
332280304Sjkim                Htable[j].lo = V.hi;
333280304Sjkim        } else
334280304Sjkim            for (j = 0; j < 16; ++j) {
335280304Sjkim                V = Htable[j];
336280304Sjkim                Htable[j].hi = V.lo << 32 | V.lo >> 32;
337280304Sjkim                Htable[j].lo = V.hi << 32 | V.hi >> 32;
338280304Sjkim            }
339280304Sjkim    }
340280304Sjkim# endif
341238384Sjkim}
342238384Sjkim
343280304Sjkim# ifndef GHASH_ASM
344238384Sjkimstatic const size_t rem_4bit[16] = {
345280304Sjkim    PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460),
346280304Sjkim    PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0),
347280304Sjkim    PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560),
348280304Sjkim    PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0)
349280304Sjkim};
350238384Sjkim
351238384Sjkimstatic void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16])
352238384Sjkim{
353280304Sjkim    u128 Z;
354280304Sjkim    int cnt = 15;
355280304Sjkim    size_t rem, nlo, nhi;
356280304Sjkim    const union {
357280304Sjkim        long one;
358280304Sjkim        char little;
359280304Sjkim    } is_endian = {
360280304Sjkim        1
361280304Sjkim    };
362238384Sjkim
363280304Sjkim    nlo = ((const u8 *)Xi)[15];
364280304Sjkim    nhi = nlo >> 4;
365280304Sjkim    nlo &= 0xf;
366238384Sjkim
367280304Sjkim    Z.hi = Htable[nlo].hi;
368280304Sjkim    Z.lo = Htable[nlo].lo;
369238384Sjkim
370280304Sjkim    while (1) {
371280304Sjkim        rem = (size_t)Z.lo & 0xf;
372280304Sjkim        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
373280304Sjkim        Z.hi = (Z.hi >> 4);
374280304Sjkim        if (sizeof(size_t) == 8)
375280304Sjkim            Z.hi ^= rem_4bit[rem];
376280304Sjkim        else
377280304Sjkim            Z.hi ^= (u64)rem_4bit[rem] << 32;
378238384Sjkim
379280304Sjkim        Z.hi ^= Htable[nhi].hi;
380280304Sjkim        Z.lo ^= Htable[nhi].lo;
381238384Sjkim
382280304Sjkim        if (--cnt < 0)
383280304Sjkim            break;
384238384Sjkim
385280304Sjkim        nlo = ((const u8 *)Xi)[cnt];
386280304Sjkim        nhi = nlo >> 4;
387280304Sjkim        nlo &= 0xf;
388238384Sjkim
389280304Sjkim        rem = (size_t)Z.lo & 0xf;
390280304Sjkim        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
391280304Sjkim        Z.hi = (Z.hi >> 4);
392280304Sjkim        if (sizeof(size_t) == 8)
393280304Sjkim            Z.hi ^= rem_4bit[rem];
394280304Sjkim        else
395280304Sjkim            Z.hi ^= (u64)rem_4bit[rem] << 32;
396238384Sjkim
397280304Sjkim        Z.hi ^= Htable[nlo].hi;
398280304Sjkim        Z.lo ^= Htable[nlo].lo;
399280304Sjkim    }
400238384Sjkim
401280304Sjkim    if (is_endian.little) {
402280304Sjkim#  ifdef BSWAP8
403280304Sjkim        Xi[0] = BSWAP8(Z.hi);
404280304Sjkim        Xi[1] = BSWAP8(Z.lo);
405280304Sjkim#  else
406280304Sjkim        u8 *p = (u8 *)Xi;
407280304Sjkim        u32 v;
408280304Sjkim        v = (u32)(Z.hi >> 32);
409280304Sjkim        PUTU32(p, v);
410280304Sjkim        v = (u32)(Z.hi);
411280304Sjkim        PUTU32(p + 4, v);
412280304Sjkim        v = (u32)(Z.lo >> 32);
413280304Sjkim        PUTU32(p + 8, v);
414280304Sjkim        v = (u32)(Z.lo);
415280304Sjkim        PUTU32(p + 12, v);
416280304Sjkim#  endif
417280304Sjkim    } else {
418280304Sjkim        Xi[0] = Z.hi;
419280304Sjkim        Xi[1] = Z.lo;
420280304Sjkim    }
421238384Sjkim}
422238384Sjkim
423280304Sjkim#  if !defined(OPENSSL_SMALL_FOOTPRINT)
424238384Sjkim/*
425238384Sjkim * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for
426238384Sjkim * details... Compiler-generated code doesn't seem to give any
427238384Sjkim * performance improvement, at least not on x86[_64]. It's here
428238384Sjkim * mostly as reference and a placeholder for possible future
429238384Sjkim * non-trivial optimization[s]...
430238384Sjkim */
431280304Sjkimstatic void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16],
432280304Sjkim                           const u8 *inp, size_t len)
433238384Sjkim{
434238384Sjkim    u128 Z;
435238384Sjkim    int cnt;
436238384Sjkim    size_t rem, nlo, nhi;
437280304Sjkim    const union {
438280304Sjkim        long one;
439280304Sjkim        char little;
440280304Sjkim    } is_endian = {
441280304Sjkim        1
442280304Sjkim    };
443238384Sjkim
444280304Sjkim#   if 1
445238384Sjkim    do {
446280304Sjkim        cnt = 15;
447280304Sjkim        nlo = ((const u8 *)Xi)[15];
448280304Sjkim        nlo ^= inp[15];
449280304Sjkim        nhi = nlo >> 4;
450280304Sjkim        nlo &= 0xf;
451238384Sjkim
452280304Sjkim        Z.hi = Htable[nlo].hi;
453280304Sjkim        Z.lo = Htable[nlo].lo;
454238384Sjkim
455280304Sjkim        while (1) {
456280304Sjkim            rem = (size_t)Z.lo & 0xf;
457280304Sjkim            Z.lo = (Z.hi << 60) | (Z.lo >> 4);
458280304Sjkim            Z.hi = (Z.hi >> 4);
459280304Sjkim            if (sizeof(size_t) == 8)
460280304Sjkim                Z.hi ^= rem_4bit[rem];
461280304Sjkim            else
462280304Sjkim                Z.hi ^= (u64)rem_4bit[rem] << 32;
463238384Sjkim
464280304Sjkim            Z.hi ^= Htable[nhi].hi;
465280304Sjkim            Z.lo ^= Htable[nhi].lo;
466238384Sjkim
467280304Sjkim            if (--cnt < 0)
468280304Sjkim                break;
469238384Sjkim
470280304Sjkim            nlo = ((const u8 *)Xi)[cnt];
471280304Sjkim            nlo ^= inp[cnt];
472280304Sjkim            nhi = nlo >> 4;
473280304Sjkim            nlo &= 0xf;
474238384Sjkim
475280304Sjkim            rem = (size_t)Z.lo & 0xf;
476280304Sjkim            Z.lo = (Z.hi << 60) | (Z.lo >> 4);
477280304Sjkim            Z.hi = (Z.hi >> 4);
478280304Sjkim            if (sizeof(size_t) == 8)
479280304Sjkim                Z.hi ^= rem_4bit[rem];
480280304Sjkim            else
481280304Sjkim                Z.hi ^= (u64)rem_4bit[rem] << 32;
482238384Sjkim
483280304Sjkim            Z.hi ^= Htable[nlo].hi;
484280304Sjkim            Z.lo ^= Htable[nlo].lo;
485280304Sjkim        }
486280304Sjkim#   else
487238384Sjkim    /*
488238384Sjkim     * Extra 256+16 bytes per-key plus 512 bytes shared tables
489238384Sjkim     * [should] give ~50% improvement... One could have PACK()-ed
490238384Sjkim     * the rem_8bit even here, but the priority is to minimize
491238384Sjkim     * cache footprint...
492280304Sjkim     */
493280304Sjkim    u128 Hshr4[16];             /* Htable shifted right by 4 bits */
494280304Sjkim    u8 Hshl4[16];               /* Htable shifted left by 4 bits */
495238384Sjkim    static const unsigned short rem_8bit[256] = {
496280304Sjkim        0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E,
497280304Sjkim        0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E,
498280304Sjkim        0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E,
499280304Sjkim        0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E,
500280304Sjkim        0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E,
501280304Sjkim        0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E,
502280304Sjkim        0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E,
503280304Sjkim        0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E,
504280304Sjkim        0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE,
505280304Sjkim        0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE,
506280304Sjkim        0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE,
507280304Sjkim        0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE,
508280304Sjkim        0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E,
509280304Sjkim        0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E,
510280304Sjkim        0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE,
511280304Sjkim        0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE,
512280304Sjkim        0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E,
513280304Sjkim        0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E,
514280304Sjkim        0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E,
515280304Sjkim        0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E,
516280304Sjkim        0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E,
517280304Sjkim        0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E,
518280304Sjkim        0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E,
519280304Sjkim        0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E,
520280304Sjkim        0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE,
521280304Sjkim        0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE,
522280304Sjkim        0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE,
523280304Sjkim        0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE,
524280304Sjkim        0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E,
525280304Sjkim        0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E,
526280304Sjkim        0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE,
527280304Sjkim        0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE
528280304Sjkim    };
529238384Sjkim    /*
530238384Sjkim     * This pre-processing phase slows down procedure by approximately
531238384Sjkim     * same time as it makes each loop spin faster. In other words
532238384Sjkim     * single block performance is approximately same as straightforward
533238384Sjkim     * "4-bit" implementation, and then it goes only faster...
534238384Sjkim     */
535280304Sjkim    for (cnt = 0; cnt < 16; ++cnt) {
536280304Sjkim        Z.hi = Htable[cnt].hi;
537280304Sjkim        Z.lo = Htable[cnt].lo;
538280304Sjkim        Hshr4[cnt].lo = (Z.hi << 60) | (Z.lo >> 4);
539280304Sjkim        Hshr4[cnt].hi = (Z.hi >> 4);
540280304Sjkim        Hshl4[cnt] = (u8)(Z.lo << 4);
541238384Sjkim    }
542238384Sjkim
543238384Sjkim    do {
544280304Sjkim        for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) {
545280304Sjkim            nlo = ((const u8 *)Xi)[cnt];
546280304Sjkim            nlo ^= inp[cnt];
547280304Sjkim            nhi = nlo >> 4;
548280304Sjkim            nlo &= 0xf;
549238384Sjkim
550280304Sjkim            Z.hi ^= Htable[nlo].hi;
551280304Sjkim            Z.lo ^= Htable[nlo].lo;
552238384Sjkim
553280304Sjkim            rem = (size_t)Z.lo & 0xff;
554238384Sjkim
555280304Sjkim            Z.lo = (Z.hi << 56) | (Z.lo >> 8);
556280304Sjkim            Z.hi = (Z.hi >> 8);
557238384Sjkim
558280304Sjkim            Z.hi ^= Hshr4[nhi].hi;
559280304Sjkim            Z.lo ^= Hshr4[nhi].lo;
560280304Sjkim            Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48;
561280304Sjkim        }
562238384Sjkim
563280304Sjkim        nlo = ((const u8 *)Xi)[0];
564280304Sjkim        nlo ^= inp[0];
565280304Sjkim        nhi = nlo >> 4;
566280304Sjkim        nlo &= 0xf;
567238384Sjkim
568280304Sjkim        Z.hi ^= Htable[nlo].hi;
569280304Sjkim        Z.lo ^= Htable[nlo].lo;
570238384Sjkim
571280304Sjkim        rem = (size_t)Z.lo & 0xf;
572238384Sjkim
573280304Sjkim        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
574280304Sjkim        Z.hi = (Z.hi >> 4);
575238384Sjkim
576280304Sjkim        Z.hi ^= Htable[nhi].hi;
577280304Sjkim        Z.lo ^= Htable[nhi].lo;
578280304Sjkim        Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48;
579280304Sjkim#   endif
580238384Sjkim
581280304Sjkim        if (is_endian.little) {
582280304Sjkim#   ifdef BSWAP8
583280304Sjkim            Xi[0] = BSWAP8(Z.hi);
584280304Sjkim            Xi[1] = BSWAP8(Z.lo);
585280304Sjkim#   else
586280304Sjkim            u8 *p = (u8 *)Xi;
587280304Sjkim            u32 v;
588280304Sjkim            v = (u32)(Z.hi >> 32);
589280304Sjkim            PUTU32(p, v);
590280304Sjkim            v = (u32)(Z.hi);
591280304Sjkim            PUTU32(p + 4, v);
592280304Sjkim            v = (u32)(Z.lo >> 32);
593280304Sjkim            PUTU32(p + 8, v);
594280304Sjkim            v = (u32)(Z.lo);
595280304Sjkim            PUTU32(p + 12, v);
596280304Sjkim#   endif
597280304Sjkim        } else {
598280304Sjkim            Xi[0] = Z.hi;
599280304Sjkim            Xi[1] = Z.lo;
600280304Sjkim        }
601280304Sjkim    } while (inp += 16, len -= 16);
602238384Sjkim}
603280304Sjkim#  endif
604280304Sjkim# else
605280304Sjkimvoid gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]);
606280304Sjkimvoid gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp,
607280304Sjkim                    size_t len);
608280304Sjkim# endif
609238384Sjkim
610280304Sjkim# define GCM_MUL(ctx,Xi)   gcm_gmult_4bit(ctx->Xi.u,ctx->Htable)
611280304Sjkim# if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT)
612280304Sjkim#  define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len)
613280304Sjkim/*
614280304Sjkim * GHASH_CHUNK is "stride parameter" missioned to mitigate cache trashing
615280304Sjkim * effect. In other words idea is to hash data while it's still in L1 cache
616280304Sjkim * after encryption pass...
617280304Sjkim */
618280304Sjkim#  define GHASH_CHUNK       (3*1024)
619280304Sjkim# endif
620238384Sjkim
621280304Sjkim#else                           /* TABLE_BITS */
622238384Sjkim
623280304Sjkimstatic void gcm_gmult_1bit(u64 Xi[2], const u64 H[2])
624238384Sjkim{
625280304Sjkim    u128 V, Z = { 0, 0 };
626280304Sjkim    long X;
627280304Sjkim    int i, j;
628280304Sjkim    const long *xi = (const long *)Xi;
629280304Sjkim    const union {
630280304Sjkim        long one;
631280304Sjkim        char little;
632280304Sjkim    } is_endian = {
633280304Sjkim        1
634280304Sjkim    };
635238384Sjkim
636280304Sjkim    V.hi = H[0];                /* H is in host byte order, no byte swapping */
637280304Sjkim    V.lo = H[1];
638238384Sjkim
639280304Sjkim    for (j = 0; j < 16 / sizeof(long); ++j) {
640280304Sjkim        if (is_endian.little) {
641280304Sjkim            if (sizeof(long) == 8) {
642280304Sjkim# ifdef BSWAP8
643280304Sjkim                X = (long)(BSWAP8(xi[j]));
644280304Sjkim# else
645280304Sjkim                const u8 *p = (const u8 *)(xi + j);
646280304Sjkim                X = (long)((u64)GETU32(p) << 32 | GETU32(p + 4));
647280304Sjkim# endif
648280304Sjkim            } else {
649280304Sjkim                const u8 *p = (const u8 *)(xi + j);
650280304Sjkim                X = (long)GETU32(p);
651280304Sjkim            }
652280304Sjkim        } else
653280304Sjkim            X = xi[j];
654238384Sjkim
655280304Sjkim        for (i = 0; i < 8 * sizeof(long); ++i, X <<= 1) {
656280304Sjkim            u64 M = (u64)(X >> (8 * sizeof(long) - 1));
657280304Sjkim            Z.hi ^= V.hi & M;
658280304Sjkim            Z.lo ^= V.lo & M;
659238384Sjkim
660280304Sjkim            REDUCE1BIT(V);
661280304Sjkim        }
662280304Sjkim    }
663238384Sjkim
664280304Sjkim    if (is_endian.little) {
665280304Sjkim# ifdef BSWAP8
666280304Sjkim        Xi[0] = BSWAP8(Z.hi);
667280304Sjkim        Xi[1] = BSWAP8(Z.lo);
668280304Sjkim# else
669280304Sjkim        u8 *p = (u8 *)Xi;
670280304Sjkim        u32 v;
671280304Sjkim        v = (u32)(Z.hi >> 32);
672280304Sjkim        PUTU32(p, v);
673280304Sjkim        v = (u32)(Z.hi);
674280304Sjkim        PUTU32(p + 4, v);
675280304Sjkim        v = (u32)(Z.lo >> 32);
676280304Sjkim        PUTU32(p + 8, v);
677280304Sjkim        v = (u32)(Z.lo);
678280304Sjkim        PUTU32(p + 12, v);
679280304Sjkim# endif
680280304Sjkim    } else {
681280304Sjkim        Xi[0] = Z.hi;
682280304Sjkim        Xi[1] = Z.lo;
683280304Sjkim    }
684238384Sjkim}
685238384Sjkim
686280304Sjkim# define GCM_MUL(ctx,Xi)   gcm_gmult_1bit(ctx->Xi.u,ctx->H.u)
687280304Sjkim
688238384Sjkim#endif
689238384Sjkim
690280304Sjkim#if     TABLE_BITS==4 && defined(GHASH_ASM)
691280304Sjkim# if    !defined(I386_ONLY) && \
692280304Sjkim        (defined(__i386)        || defined(__i386__)    || \
693280304Sjkim         defined(__x86_64)      || defined(__x86_64__)  || \
694280304Sjkim         defined(_M_IX86)       || defined(_M_AMD64)    || defined(_M_X64))
695238384Sjkim#  define GHASH_ASM_X86_OR_64
696238384Sjkim#  define GCM_FUNCREF_4BIT
697238384Sjkimextern unsigned int OPENSSL_ia32cap_P[2];
698238384Sjkim
699280304Sjkimvoid gcm_init_clmul(u128 Htable[16], const u64 Xi[2]);
700280304Sjkimvoid gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]);
701280304Sjkimvoid gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp,
702280304Sjkim                     size_t len);
703238384Sjkim
704280304Sjkim#  if   defined(__i386) || defined(__i386__) || defined(_M_IX86)
705238384Sjkim#   define GHASH_ASM_X86
706280304Sjkimvoid gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]);
707280304Sjkimvoid gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp,
708280304Sjkim                        size_t len);
709238384Sjkim
710280304Sjkimvoid gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]);
711280304Sjkimvoid gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp,
712280304Sjkim                        size_t len);
713238384Sjkim#  endif
714238384Sjkim# elif defined(__arm__) || defined(__arm)
715238384Sjkim#  include "arm_arch.h"
716238384Sjkim#  if __ARM_ARCH__>=7
717238384Sjkim#   define GHASH_ASM_ARM
718238384Sjkim#   define GCM_FUNCREF_4BIT
719280304Sjkimvoid gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]);
720280304Sjkimvoid gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp,
721280304Sjkim                    size_t len);
722238384Sjkim#  endif
723238384Sjkim# endif
724238384Sjkim#endif
725238384Sjkim
726238384Sjkim#ifdef GCM_FUNCREF_4BIT
727238384Sjkim# undef  GCM_MUL
728280304Sjkim# define GCM_MUL(ctx,Xi)        (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable)
729238384Sjkim# ifdef GHASH
730238384Sjkim#  undef  GHASH
731280304Sjkim#  define GHASH(ctx,in,len)     (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len)
732238384Sjkim# endif
733238384Sjkim#endif
734238384Sjkim
735280304Sjkimvoid CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block)
736238384Sjkim{
737280304Sjkim    const union {
738280304Sjkim        long one;
739280304Sjkim        char little;
740280304Sjkim    } is_endian = {
741280304Sjkim        1
742280304Sjkim    };
743238384Sjkim
744280304Sjkim    memset(ctx, 0, sizeof(*ctx));
745280304Sjkim    ctx->block = block;
746280304Sjkim    ctx->key = key;
747238384Sjkim
748280304Sjkim    (*block) (ctx->H.c, ctx->H.c, key);
749238384Sjkim
750280304Sjkim    if (is_endian.little) {
751280304Sjkim        /* H is stored in host byte order */
752238384Sjkim#ifdef BSWAP8
753280304Sjkim        ctx->H.u[0] = BSWAP8(ctx->H.u[0]);
754280304Sjkim        ctx->H.u[1] = BSWAP8(ctx->H.u[1]);
755238384Sjkim#else
756280304Sjkim        u8 *p = ctx->H.c;
757280304Sjkim        u64 hi, lo;
758280304Sjkim        hi = (u64)GETU32(p) << 32 | GETU32(p + 4);
759280304Sjkim        lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
760280304Sjkim        ctx->H.u[0] = hi;
761280304Sjkim        ctx->H.u[1] = lo;
762238384Sjkim#endif
763280304Sjkim    }
764280304Sjkim#if     TABLE_BITS==8
765280304Sjkim    gcm_init_8bit(ctx->Htable, ctx->H.u);
766280304Sjkim#elif   TABLE_BITS==4
767280304Sjkim# if    defined(GHASH_ASM_X86_OR_64)
768280304Sjkim#  if   !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2)
769280304Sjkim    if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */
770280304Sjkim        OPENSSL_ia32cap_P[1] & (1 << 1)) { /* check PCLMULQDQ bit */
771280304Sjkim        gcm_init_clmul(ctx->Htable, ctx->H.u);
772280304Sjkim        ctx->gmult = gcm_gmult_clmul;
773280304Sjkim        ctx->ghash = gcm_ghash_clmul;
774280304Sjkim        return;
775280304Sjkim    }
776238384Sjkim#  endif
777280304Sjkim    gcm_init_4bit(ctx->Htable, ctx->H.u);
778280304Sjkim#  if   defined(GHASH_ASM_X86)  /* x86 only */
779280304Sjkim#   if  defined(OPENSSL_IA32_SSE2)
780280304Sjkim    if (OPENSSL_ia32cap_P[0] & (1 << 25)) { /* check SSE bit */
781238384Sjkim#   else
782280304Sjkim    if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */
783238384Sjkim#   endif
784280304Sjkim        ctx->gmult = gcm_gmult_4bit_mmx;
785280304Sjkim        ctx->ghash = gcm_ghash_4bit_mmx;
786280304Sjkim    } else {
787280304Sjkim        ctx->gmult = gcm_gmult_4bit_x86;
788280304Sjkim        ctx->ghash = gcm_ghash_4bit_x86;
789280304Sjkim    }
790238384Sjkim#  else
791280304Sjkim    ctx->gmult = gcm_gmult_4bit;
792280304Sjkim    ctx->ghash = gcm_ghash_4bit;
793238384Sjkim#  endif
794280304Sjkim# elif  defined(GHASH_ASM_ARM)
795280304Sjkim    if (OPENSSL_armcap_P & ARMV7_NEON) {
796280304Sjkim        ctx->gmult = gcm_gmult_neon;
797280304Sjkim        ctx->ghash = gcm_ghash_neon;
798280304Sjkim    } else {
799280304Sjkim        gcm_init_4bit(ctx->Htable, ctx->H.u);
800280304Sjkim        ctx->gmult = gcm_gmult_4bit;
801280304Sjkim        ctx->ghash = gcm_ghash_4bit;
802280304Sjkim    }
803238384Sjkim# else
804280304Sjkim    gcm_init_4bit(ctx->Htable, ctx->H.u);
805238384Sjkim# endif
806238384Sjkim#endif
807238384Sjkim}
808238384Sjkim
809280304Sjkimvoid CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
810280304Sjkim                         size_t len)
811238384Sjkim{
812280304Sjkim    const union {
813280304Sjkim        long one;
814280304Sjkim        char little;
815280304Sjkim    } is_endian = {
816280304Sjkim        1
817280304Sjkim    };
818280304Sjkim    unsigned int ctr;
819238384Sjkim#ifdef GCM_FUNCREF_4BIT
820280304Sjkim    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
821238384Sjkim#endif
822238384Sjkim
823280304Sjkim    ctx->Yi.u[0] = 0;
824280304Sjkim    ctx->Yi.u[1] = 0;
825280304Sjkim    ctx->Xi.u[0] = 0;
826280304Sjkim    ctx->Xi.u[1] = 0;
827280304Sjkim    ctx->len.u[0] = 0;          /* AAD length */
828280304Sjkim    ctx->len.u[1] = 0;          /* message length */
829280304Sjkim    ctx->ares = 0;
830280304Sjkim    ctx->mres = 0;
831238384Sjkim
832280304Sjkim    if (len == 12) {
833280304Sjkim        memcpy(ctx->Yi.c, iv, 12);
834280304Sjkim        ctx->Yi.c[15] = 1;
835280304Sjkim        ctr = 1;
836280304Sjkim    } else {
837280304Sjkim        size_t i;
838280304Sjkim        u64 len0 = len;
839238384Sjkim
840280304Sjkim        while (len >= 16) {
841280304Sjkim            for (i = 0; i < 16; ++i)
842280304Sjkim                ctx->Yi.c[i] ^= iv[i];
843280304Sjkim            GCM_MUL(ctx, Yi);
844280304Sjkim            iv += 16;
845280304Sjkim            len -= 16;
846280304Sjkim        }
847280304Sjkim        if (len) {
848280304Sjkim            for (i = 0; i < len; ++i)
849280304Sjkim                ctx->Yi.c[i] ^= iv[i];
850280304Sjkim            GCM_MUL(ctx, Yi);
851280304Sjkim        }
852280304Sjkim        len0 <<= 3;
853280304Sjkim        if (is_endian.little) {
854238384Sjkim#ifdef BSWAP8
855280304Sjkim            ctx->Yi.u[1] ^= BSWAP8(len0);
856238384Sjkim#else
857280304Sjkim            ctx->Yi.c[8] ^= (u8)(len0 >> 56);
858280304Sjkim            ctx->Yi.c[9] ^= (u8)(len0 >> 48);
859280304Sjkim            ctx->Yi.c[10] ^= (u8)(len0 >> 40);
860280304Sjkim            ctx->Yi.c[11] ^= (u8)(len0 >> 32);
861280304Sjkim            ctx->Yi.c[12] ^= (u8)(len0 >> 24);
862280304Sjkim            ctx->Yi.c[13] ^= (u8)(len0 >> 16);
863280304Sjkim            ctx->Yi.c[14] ^= (u8)(len0 >> 8);
864280304Sjkim            ctx->Yi.c[15] ^= (u8)(len0);
865238384Sjkim#endif
866280304Sjkim        } else
867280304Sjkim            ctx->Yi.u[1] ^= len0;
868238384Sjkim
869280304Sjkim        GCM_MUL(ctx, Yi);
870238384Sjkim
871280304Sjkim        if (is_endian.little)
872264331Sjkim#ifdef BSWAP4
873280304Sjkim            ctr = BSWAP4(ctx->Yi.d[3]);
874264331Sjkim#else
875280304Sjkim            ctr = GETU32(ctx->Yi.c + 12);
876264331Sjkim#endif
877280304Sjkim        else
878280304Sjkim            ctr = ctx->Yi.d[3];
879280304Sjkim    }
880238384Sjkim
881280304Sjkim    (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key);
882280304Sjkim    ++ctr;
883280304Sjkim    if (is_endian.little)
884264331Sjkim#ifdef BSWAP4
885280304Sjkim        ctx->Yi.d[3] = BSWAP4(ctr);
886264331Sjkim#else
887280304Sjkim        PUTU32(ctx->Yi.c + 12, ctr);
888264331Sjkim#endif
889280304Sjkim    else
890280304Sjkim        ctx->Yi.d[3] = ctr;
891238384Sjkim}
892238384Sjkim
893280304Sjkimint CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
894280304Sjkim                      size_t len)
895238384Sjkim{
896280304Sjkim    size_t i;
897280304Sjkim    unsigned int n;
898280304Sjkim    u64 alen = ctx->len.u[0];
899238384Sjkim#ifdef GCM_FUNCREF_4BIT
900280304Sjkim    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
901238384Sjkim# ifdef GHASH
902280304Sjkim    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
903280304Sjkim                         const u8 *inp, size_t len) = ctx->ghash;
904238384Sjkim# endif
905238384Sjkim#endif
906238384Sjkim
907280304Sjkim    if (ctx->len.u[1])
908280304Sjkim        return -2;
909238384Sjkim
910280304Sjkim    alen += len;
911280304Sjkim    if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len))
912280304Sjkim        return -1;
913280304Sjkim    ctx->len.u[0] = alen;
914238384Sjkim
915280304Sjkim    n = ctx->ares;
916280304Sjkim    if (n) {
917280304Sjkim        while (n && len) {
918280304Sjkim            ctx->Xi.c[n] ^= *(aad++);
919280304Sjkim            --len;
920280304Sjkim            n = (n + 1) % 16;
921280304Sjkim        }
922280304Sjkim        if (n == 0)
923280304Sjkim            GCM_MUL(ctx, Xi);
924280304Sjkim        else {
925280304Sjkim            ctx->ares = n;
926280304Sjkim            return 0;
927280304Sjkim        }
928280304Sjkim    }
929238384Sjkim#ifdef GHASH
930280304Sjkim    if ((i = (len & (size_t)-16))) {
931280304Sjkim        GHASH(ctx, aad, i);
932280304Sjkim        aad += i;
933280304Sjkim        len -= i;
934280304Sjkim    }
935238384Sjkim#else
936280304Sjkim    while (len >= 16) {
937280304Sjkim        for (i = 0; i < 16; ++i)
938280304Sjkim            ctx->Xi.c[i] ^= aad[i];
939280304Sjkim        GCM_MUL(ctx, Xi);
940280304Sjkim        aad += 16;
941280304Sjkim        len -= 16;
942280304Sjkim    }
943238384Sjkim#endif
944280304Sjkim    if (len) {
945280304Sjkim        n = (unsigned int)len;
946280304Sjkim        for (i = 0; i < len; ++i)
947280304Sjkim            ctx->Xi.c[i] ^= aad[i];
948280304Sjkim    }
949238384Sjkim
950280304Sjkim    ctx->ares = n;
951280304Sjkim    return 0;
952238384Sjkim}
953238384Sjkim
954238384Sjkimint CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
955280304Sjkim                          const unsigned char *in, unsigned char *out,
956280304Sjkim                          size_t len)
957238384Sjkim{
958280304Sjkim    const union {
959280304Sjkim        long one;
960280304Sjkim        char little;
961280304Sjkim    } is_endian = {
962280304Sjkim        1
963280304Sjkim    };
964280304Sjkim    unsigned int n, ctr;
965280304Sjkim    size_t i;
966280304Sjkim    u64 mlen = ctx->len.u[1];
967280304Sjkim    block128_f block = ctx->block;
968280304Sjkim    void *key = ctx->key;
969238384Sjkim#ifdef GCM_FUNCREF_4BIT
970280304Sjkim    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
971238384Sjkim# ifdef GHASH
972280304Sjkim    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
973280304Sjkim                         const u8 *inp, size_t len) = ctx->ghash;
974238384Sjkim# endif
975238384Sjkim#endif
976238384Sjkim
977238384Sjkim#if 0
978280304Sjkim    n = (unsigned int)mlen % 16; /* alternative to ctx->mres */
979238384Sjkim#endif
980280304Sjkim    mlen += len;
981280304Sjkim    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
982280304Sjkim        return -1;
983280304Sjkim    ctx->len.u[1] = mlen;
984238384Sjkim
985280304Sjkim    if (ctx->ares) {
986280304Sjkim        /* First call to encrypt finalizes GHASH(AAD) */
987280304Sjkim        GCM_MUL(ctx, Xi);
988280304Sjkim        ctx->ares = 0;
989280304Sjkim    }
990238384Sjkim
991280304Sjkim    if (is_endian.little)
992264331Sjkim#ifdef BSWAP4
993280304Sjkim        ctr = BSWAP4(ctx->Yi.d[3]);
994264331Sjkim#else
995280304Sjkim        ctr = GETU32(ctx->Yi.c + 12);
996264331Sjkim#endif
997280304Sjkim    else
998280304Sjkim        ctr = ctx->Yi.d[3];
999238384Sjkim
1000280304Sjkim    n = ctx->mres;
1001238384Sjkim#if !defined(OPENSSL_SMALL_FOOTPRINT)
1002280304Sjkim    if (16 % sizeof(size_t) == 0) { /* always true actually */
1003280304Sjkim        do {
1004280304Sjkim            if (n) {
1005280304Sjkim                while (n && len) {
1006280304Sjkim                    ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
1007280304Sjkim                    --len;
1008280304Sjkim                    n = (n + 1) % 16;
1009280304Sjkim                }
1010280304Sjkim                if (n == 0)
1011280304Sjkim                    GCM_MUL(ctx, Xi);
1012280304Sjkim                else {
1013280304Sjkim                    ctx->mres = n;
1014280304Sjkim                    return 0;
1015280304Sjkim                }
1016280304Sjkim            }
1017280304Sjkim# if defined(STRICT_ALIGNMENT)
1018280304Sjkim            if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
1019280304Sjkim                break;
1020280304Sjkim# endif
1021280304Sjkim# if defined(GHASH) && defined(GHASH_CHUNK)
1022280304Sjkim            while (len >= GHASH_CHUNK) {
1023280304Sjkim                size_t j = GHASH_CHUNK;
1024238384Sjkim
1025280304Sjkim                while (j) {
1026280304Sjkim                    size_t *out_t = (size_t *)out;
1027280304Sjkim                    const size_t *in_t = (const size_t *)in;
1028264331Sjkim
1029280304Sjkim                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
1030280304Sjkim                    ++ctr;
1031280304Sjkim                    if (is_endian.little)
1032280304Sjkim#  ifdef BSWAP4
1033280304Sjkim                        ctx->Yi.d[3] = BSWAP4(ctr);
1034280304Sjkim#  else
1035280304Sjkim                        PUTU32(ctx->Yi.c + 12, ctr);
1036280304Sjkim#  endif
1037280304Sjkim                    else
1038280304Sjkim                        ctx->Yi.d[3] = ctr;
1039280304Sjkim                    for (i = 0; i < 16 / sizeof(size_t); ++i)
1040280304Sjkim                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
1041280304Sjkim                    out += 16;
1042280304Sjkim                    in += 16;
1043280304Sjkim                    j -= 16;
1044280304Sjkim                }
1045280304Sjkim                GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK);
1046280304Sjkim                len -= GHASH_CHUNK;
1047280304Sjkim            }
1048280304Sjkim            if ((i = (len & (size_t)-16))) {
1049280304Sjkim                size_t j = i;
1050238384Sjkim
1051280304Sjkim                while (len >= 16) {
1052280304Sjkim                    size_t *out_t = (size_t *)out;
1053280304Sjkim                    const size_t *in_t = (const size_t *)in;
1054264331Sjkim
1055280304Sjkim                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
1056280304Sjkim                    ++ctr;
1057280304Sjkim                    if (is_endian.little)
1058280304Sjkim#  ifdef BSWAP4
1059280304Sjkim                        ctx->Yi.d[3] = BSWAP4(ctr);
1060280304Sjkim#  else
1061280304Sjkim                        PUTU32(ctx->Yi.c + 12, ctr);
1062280304Sjkim#  endif
1063280304Sjkim                    else
1064280304Sjkim                        ctx->Yi.d[3] = ctr;
1065280304Sjkim                    for (i = 0; i < 16 / sizeof(size_t); ++i)
1066280304Sjkim                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
1067280304Sjkim                    out += 16;
1068280304Sjkim                    in += 16;
1069280304Sjkim                    len -= 16;
1070280304Sjkim                }
1071280304Sjkim                GHASH(ctx, out - j, j);
1072280304Sjkim            }
1073280304Sjkim# else
1074280304Sjkim            while (len >= 16) {
1075280304Sjkim                size_t *out_t = (size_t *)out;
1076280304Sjkim                const size_t *in_t = (const size_t *)in;
1077264331Sjkim
1078280304Sjkim                (*block) (ctx->Yi.c, ctx->EKi.c, key);
1079280304Sjkim                ++ctr;
1080280304Sjkim                if (is_endian.little)
1081280304Sjkim#  ifdef BSWAP4
1082280304Sjkim                    ctx->Yi.d[3] = BSWAP4(ctr);
1083280304Sjkim#  else
1084280304Sjkim                    PUTU32(ctx->Yi.c + 12, ctr);
1085280304Sjkim#  endif
1086280304Sjkim                else
1087280304Sjkim                    ctx->Yi.d[3] = ctr;
1088280304Sjkim                for (i = 0; i < 16 / sizeof(size_t); ++i)
1089280304Sjkim                    ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i];
1090280304Sjkim                GCM_MUL(ctx, Xi);
1091280304Sjkim                out += 16;
1092280304Sjkim                in += 16;
1093280304Sjkim                len -= 16;
1094280304Sjkim            }
1095280304Sjkim# endif
1096280304Sjkim            if (len) {
1097280304Sjkim                (*block) (ctx->Yi.c, ctx->EKi.c, key);
1098280304Sjkim                ++ctr;
1099280304Sjkim                if (is_endian.little)
1100280304Sjkim# ifdef BSWAP4
1101280304Sjkim                    ctx->Yi.d[3] = BSWAP4(ctr);
1102280304Sjkim# else
1103280304Sjkim                    PUTU32(ctx->Yi.c + 12, ctr);
1104280304Sjkim# endif
1105280304Sjkim                else
1106280304Sjkim                    ctx->Yi.d[3] = ctr;
1107280304Sjkim                while (len--) {
1108280304Sjkim                    ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
1109280304Sjkim                    ++n;
1110280304Sjkim                }
1111280304Sjkim            }
1112238384Sjkim
1113280304Sjkim            ctx->mres = n;
1114280304Sjkim            return 0;
1115280304Sjkim        } while (0);
1116280304Sjkim    }
1117238384Sjkim#endif
1118280304Sjkim    for (i = 0; i < len; ++i) {
1119280304Sjkim        if (n == 0) {
1120280304Sjkim            (*block) (ctx->Yi.c, ctx->EKi.c, key);
1121280304Sjkim            ++ctr;
1122280304Sjkim            if (is_endian.little)
1123264331Sjkim#ifdef BSWAP4
1124280304Sjkim                ctx->Yi.d[3] = BSWAP4(ctr);
1125264331Sjkim#else
1126280304Sjkim                PUTU32(ctx->Yi.c + 12, ctr);
1127264331Sjkim#endif
1128280304Sjkim            else
1129280304Sjkim                ctx->Yi.d[3] = ctr;
1130280304Sjkim        }
1131280304Sjkim        ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n];
1132280304Sjkim        n = (n + 1) % 16;
1133280304Sjkim        if (n == 0)
1134280304Sjkim            GCM_MUL(ctx, Xi);
1135280304Sjkim    }
1136238384Sjkim
1137280304Sjkim    ctx->mres = n;
1138280304Sjkim    return 0;
1139238384Sjkim}
1140238384Sjkim
1141238384Sjkimint CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
1142280304Sjkim                          const unsigned char *in, unsigned char *out,
1143280304Sjkim                          size_t len)
1144238384Sjkim{
1145280304Sjkim    const union {
1146280304Sjkim        long one;
1147280304Sjkim        char little;
1148280304Sjkim    } is_endian = {
1149280304Sjkim        1
1150280304Sjkim    };
1151280304Sjkim    unsigned int n, ctr;
1152280304Sjkim    size_t i;
1153280304Sjkim    u64 mlen = ctx->len.u[1];
1154280304Sjkim    block128_f block = ctx->block;
1155280304Sjkim    void *key = ctx->key;
1156238384Sjkim#ifdef GCM_FUNCREF_4BIT
1157280304Sjkim    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
1158238384Sjkim# ifdef GHASH
1159280304Sjkim    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
1160280304Sjkim                         const u8 *inp, size_t len) = ctx->ghash;
1161238384Sjkim# endif
1162238384Sjkim#endif
1163238384Sjkim
1164280304Sjkim    mlen += len;
1165280304Sjkim    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
1166280304Sjkim        return -1;
1167280304Sjkim    ctx->len.u[1] = mlen;
1168238384Sjkim
1169280304Sjkim    if (ctx->ares) {
1170280304Sjkim        /* First call to decrypt finalizes GHASH(AAD) */
1171280304Sjkim        GCM_MUL(ctx, Xi);
1172280304Sjkim        ctx->ares = 0;
1173280304Sjkim    }
1174238384Sjkim
1175280304Sjkim    if (is_endian.little)
1176264331Sjkim#ifdef BSWAP4
1177280304Sjkim        ctr = BSWAP4(ctx->Yi.d[3]);
1178264331Sjkim#else
1179280304Sjkim        ctr = GETU32(ctx->Yi.c + 12);
1180264331Sjkim#endif
1181280304Sjkim    else
1182280304Sjkim        ctr = ctx->Yi.d[3];
1183238384Sjkim
1184280304Sjkim    n = ctx->mres;
1185238384Sjkim#if !defined(OPENSSL_SMALL_FOOTPRINT)
1186280304Sjkim    if (16 % sizeof(size_t) == 0) { /* always true actually */
1187280304Sjkim        do {
1188280304Sjkim            if (n) {
1189280304Sjkim                while (n && len) {
1190280304Sjkim                    u8 c = *(in++);
1191280304Sjkim                    *(out++) = c ^ ctx->EKi.c[n];
1192280304Sjkim                    ctx->Xi.c[n] ^= c;
1193280304Sjkim                    --len;
1194280304Sjkim                    n = (n + 1) % 16;
1195280304Sjkim                }
1196280304Sjkim                if (n == 0)
1197280304Sjkim                    GCM_MUL(ctx, Xi);
1198280304Sjkim                else {
1199280304Sjkim                    ctx->mres = n;
1200280304Sjkim                    return 0;
1201280304Sjkim                }
1202280304Sjkim            }
1203280304Sjkim# if defined(STRICT_ALIGNMENT)
1204280304Sjkim            if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
1205280304Sjkim                break;
1206280304Sjkim# endif
1207280304Sjkim# if defined(GHASH) && defined(GHASH_CHUNK)
1208280304Sjkim            while (len >= GHASH_CHUNK) {
1209280304Sjkim                size_t j = GHASH_CHUNK;
1210238384Sjkim
1211280304Sjkim                GHASH(ctx, in, GHASH_CHUNK);
1212280304Sjkim                while (j) {
1213280304Sjkim                    size_t *out_t = (size_t *)out;
1214280304Sjkim                    const size_t *in_t = (const size_t *)in;
1215264331Sjkim
1216280304Sjkim                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
1217280304Sjkim                    ++ctr;
1218280304Sjkim                    if (is_endian.little)
1219280304Sjkim#  ifdef BSWAP4
1220280304Sjkim                        ctx->Yi.d[3] = BSWAP4(ctr);
1221280304Sjkim#  else
1222280304Sjkim                        PUTU32(ctx->Yi.c + 12, ctr);
1223280304Sjkim#  endif
1224280304Sjkim                    else
1225280304Sjkim                        ctx->Yi.d[3] = ctr;
1226280304Sjkim                    for (i = 0; i < 16 / sizeof(size_t); ++i)
1227280304Sjkim                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
1228280304Sjkim                    out += 16;
1229280304Sjkim                    in += 16;
1230280304Sjkim                    j -= 16;
1231280304Sjkim                }
1232280304Sjkim                len -= GHASH_CHUNK;
1233280304Sjkim            }
1234280304Sjkim            if ((i = (len & (size_t)-16))) {
1235280304Sjkim                GHASH(ctx, in, i);
1236280304Sjkim                while (len >= 16) {
1237280304Sjkim                    size_t *out_t = (size_t *)out;
1238280304Sjkim                    const size_t *in_t = (const size_t *)in;
1239264331Sjkim
1240280304Sjkim                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
1241280304Sjkim                    ++ctr;
1242280304Sjkim                    if (is_endian.little)
1243280304Sjkim#  ifdef BSWAP4
1244280304Sjkim                        ctx->Yi.d[3] = BSWAP4(ctr);
1245280304Sjkim#  else
1246280304Sjkim                        PUTU32(ctx->Yi.c + 12, ctr);
1247280304Sjkim#  endif
1248280304Sjkim                    else
1249280304Sjkim                        ctx->Yi.d[3] = ctr;
1250280304Sjkim                    for (i = 0; i < 16 / sizeof(size_t); ++i)
1251280304Sjkim                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
1252280304Sjkim                    out += 16;
1253280304Sjkim                    in += 16;
1254280304Sjkim                    len -= 16;
1255280304Sjkim                }
1256280304Sjkim            }
1257280304Sjkim# else
1258280304Sjkim            while (len >= 16) {
1259280304Sjkim                size_t *out_t = (size_t *)out;
1260280304Sjkim                const size_t *in_t = (const size_t *)in;
1261264331Sjkim
1262280304Sjkim                (*block) (ctx->Yi.c, ctx->EKi.c, key);
1263280304Sjkim                ++ctr;
1264280304Sjkim                if (is_endian.little)
1265280304Sjkim#  ifdef BSWAP4
1266280304Sjkim                    ctx->Yi.d[3] = BSWAP4(ctr);
1267280304Sjkim#  else
1268280304Sjkim                    PUTU32(ctx->Yi.c + 12, ctr);
1269280304Sjkim#  endif
1270280304Sjkim                else
1271280304Sjkim                    ctx->Yi.d[3] = ctr;
1272280304Sjkim                for (i = 0; i < 16 / sizeof(size_t); ++i) {
1273280304Sjkim                    size_t c = in[i];
1274280304Sjkim                    out[i] = c ^ ctx->EKi.t[i];
1275280304Sjkim                    ctx->Xi.t[i] ^= c;
1276280304Sjkim                }
1277280304Sjkim                GCM_MUL(ctx, Xi);
1278280304Sjkim                out += 16;
1279280304Sjkim                in += 16;
1280280304Sjkim                len -= 16;
1281280304Sjkim            }
1282280304Sjkim# endif
1283280304Sjkim            if (len) {
1284280304Sjkim                (*block) (ctx->Yi.c, ctx->EKi.c, key);
1285280304Sjkim                ++ctr;
1286280304Sjkim                if (is_endian.little)
1287280304Sjkim# ifdef BSWAP4
1288280304Sjkim                    ctx->Yi.d[3] = BSWAP4(ctr);
1289280304Sjkim# else
1290280304Sjkim                    PUTU32(ctx->Yi.c + 12, ctr);
1291280304Sjkim# endif
1292280304Sjkim                else
1293280304Sjkim                    ctx->Yi.d[3] = ctr;
1294280304Sjkim                while (len--) {
1295280304Sjkim                    u8 c = in[n];
1296280304Sjkim                    ctx->Xi.c[n] ^= c;
1297280304Sjkim                    out[n] = c ^ ctx->EKi.c[n];
1298280304Sjkim                    ++n;
1299280304Sjkim                }
1300280304Sjkim            }
1301238384Sjkim
1302280304Sjkim            ctx->mres = n;
1303280304Sjkim            return 0;
1304280304Sjkim        } while (0);
1305280304Sjkim    }
1306238384Sjkim#endif
1307280304Sjkim    for (i = 0; i < len; ++i) {
1308280304Sjkim        u8 c;
1309280304Sjkim        if (n == 0) {
1310280304Sjkim            (*block) (ctx->Yi.c, ctx->EKi.c, key);
1311280304Sjkim            ++ctr;
1312280304Sjkim            if (is_endian.little)
1313264331Sjkim#ifdef BSWAP4
1314280304Sjkim                ctx->Yi.d[3] = BSWAP4(ctr);
1315264331Sjkim#else
1316280304Sjkim                PUTU32(ctx->Yi.c + 12, ctr);
1317264331Sjkim#endif
1318280304Sjkim            else
1319280304Sjkim                ctx->Yi.d[3] = ctr;
1320280304Sjkim        }
1321280304Sjkim        c = in[i];
1322280304Sjkim        out[i] = c ^ ctx->EKi.c[n];
1323280304Sjkim        ctx->Xi.c[n] ^= c;
1324280304Sjkim        n = (n + 1) % 16;
1325280304Sjkim        if (n == 0)
1326280304Sjkim            GCM_MUL(ctx, Xi);
1327280304Sjkim    }
1328238384Sjkim
1329280304Sjkim    ctx->mres = n;
1330280304Sjkim    return 0;
1331238384Sjkim}
1332238384Sjkim
1333238384Sjkimint CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
1334280304Sjkim                                const unsigned char *in, unsigned char *out,
1335280304Sjkim                                size_t len, ctr128_f stream)
1336238384Sjkim{
1337280304Sjkim    const union {
1338280304Sjkim        long one;
1339280304Sjkim        char little;
1340280304Sjkim    } is_endian = {
1341280304Sjkim        1
1342280304Sjkim    };
1343280304Sjkim    unsigned int n, ctr;
1344280304Sjkim    size_t i;
1345280304Sjkim    u64 mlen = ctx->len.u[1];
1346280304Sjkim    void *key = ctx->key;
1347238384Sjkim#ifdef GCM_FUNCREF_4BIT
1348280304Sjkim    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
1349238384Sjkim# ifdef GHASH
1350280304Sjkim    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
1351280304Sjkim                         const u8 *inp, size_t len) = ctx->ghash;
1352238384Sjkim# endif
1353238384Sjkim#endif
1354238384Sjkim
1355280304Sjkim    mlen += len;
1356280304Sjkim    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
1357280304Sjkim        return -1;
1358280304Sjkim    ctx->len.u[1] = mlen;
1359238384Sjkim
1360280304Sjkim    if (ctx->ares) {
1361280304Sjkim        /* First call to encrypt finalizes GHASH(AAD) */
1362280304Sjkim        GCM_MUL(ctx, Xi);
1363280304Sjkim        ctx->ares = 0;
1364280304Sjkim    }
1365238384Sjkim
1366280304Sjkim    if (is_endian.little)
1367264331Sjkim#ifdef BSWAP4
1368280304Sjkim        ctr = BSWAP4(ctx->Yi.d[3]);
1369264331Sjkim#else
1370280304Sjkim        ctr = GETU32(ctx->Yi.c + 12);
1371264331Sjkim#endif
1372280304Sjkim    else
1373280304Sjkim        ctr = ctx->Yi.d[3];
1374238384Sjkim
1375280304Sjkim    n = ctx->mres;
1376280304Sjkim    if (n) {
1377280304Sjkim        while (n && len) {
1378280304Sjkim            ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
1379280304Sjkim            --len;
1380280304Sjkim            n = (n + 1) % 16;
1381280304Sjkim        }
1382280304Sjkim        if (n == 0)
1383280304Sjkim            GCM_MUL(ctx, Xi);
1384280304Sjkim        else {
1385280304Sjkim            ctx->mres = n;
1386280304Sjkim            return 0;
1387280304Sjkim        }
1388280304Sjkim    }
1389238384Sjkim#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
1390280304Sjkim    while (len >= GHASH_CHUNK) {
1391280304Sjkim        (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
1392280304Sjkim        ctr += GHASH_CHUNK / 16;
1393280304Sjkim        if (is_endian.little)
1394280304Sjkim# ifdef BSWAP4
1395280304Sjkim            ctx->Yi.d[3] = BSWAP4(ctr);
1396280304Sjkim# else
1397280304Sjkim            PUTU32(ctx->Yi.c + 12, ctr);
1398280304Sjkim# endif
1399280304Sjkim        else
1400280304Sjkim            ctx->Yi.d[3] = ctr;
1401280304Sjkim        GHASH(ctx, out, GHASH_CHUNK);
1402280304Sjkim        out += GHASH_CHUNK;
1403280304Sjkim        in += GHASH_CHUNK;
1404280304Sjkim        len -= GHASH_CHUNK;
1405280304Sjkim    }
1406264331Sjkim#endif
1407280304Sjkim    if ((i = (len & (size_t)-16))) {
1408280304Sjkim        size_t j = i / 16;
1409238384Sjkim
1410280304Sjkim        (*stream) (in, out, j, key, ctx->Yi.c);
1411280304Sjkim        ctr += (unsigned int)j;
1412280304Sjkim        if (is_endian.little)
1413264331Sjkim#ifdef BSWAP4
1414280304Sjkim            ctx->Yi.d[3] = BSWAP4(ctr);
1415264331Sjkim#else
1416280304Sjkim            PUTU32(ctx->Yi.c + 12, ctr);
1417264331Sjkim#endif
1418280304Sjkim        else
1419280304Sjkim            ctx->Yi.d[3] = ctr;
1420280304Sjkim        in += i;
1421280304Sjkim        len -= i;
1422238384Sjkim#if defined(GHASH)
1423280304Sjkim        GHASH(ctx, out, i);
1424280304Sjkim        out += i;
1425238384Sjkim#else
1426280304Sjkim        while (j--) {
1427280304Sjkim            for (i = 0; i < 16; ++i)
1428280304Sjkim                ctx->Xi.c[i] ^= out[i];
1429280304Sjkim            GCM_MUL(ctx, Xi);
1430280304Sjkim            out += 16;
1431280304Sjkim        }
1432238384Sjkim#endif
1433280304Sjkim    }
1434280304Sjkim    if (len) {
1435280304Sjkim        (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key);
1436280304Sjkim        ++ctr;
1437280304Sjkim        if (is_endian.little)
1438264331Sjkim#ifdef BSWAP4
1439280304Sjkim            ctx->Yi.d[3] = BSWAP4(ctr);
1440264331Sjkim#else
1441280304Sjkim            PUTU32(ctx->Yi.c + 12, ctr);
1442264331Sjkim#endif
1443280304Sjkim        else
1444280304Sjkim            ctx->Yi.d[3] = ctr;
1445280304Sjkim        while (len--) {
1446280304Sjkim            ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
1447280304Sjkim            ++n;
1448280304Sjkim        }
1449280304Sjkim    }
1450238384Sjkim
1451280304Sjkim    ctx->mres = n;
1452280304Sjkim    return 0;
1453238384Sjkim}
1454238384Sjkim
1455238384Sjkimint CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
1456280304Sjkim                                const unsigned char *in, unsigned char *out,
1457280304Sjkim                                size_t len, ctr128_f stream)
1458238384Sjkim{
1459280304Sjkim    const union {
1460280304Sjkim        long one;
1461280304Sjkim        char little;
1462280304Sjkim    } is_endian = {
1463280304Sjkim        1
1464280304Sjkim    };
1465280304Sjkim    unsigned int n, ctr;
1466280304Sjkim    size_t i;
1467280304Sjkim    u64 mlen = ctx->len.u[1];
1468280304Sjkim    void *key = ctx->key;
1469238384Sjkim#ifdef GCM_FUNCREF_4BIT
1470280304Sjkim    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
1471238384Sjkim# ifdef GHASH
1472280304Sjkim    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
1473280304Sjkim                         const u8 *inp, size_t len) = ctx->ghash;
1474238384Sjkim# endif
1475238384Sjkim#endif
1476238384Sjkim
1477280304Sjkim    mlen += len;
1478280304Sjkim    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
1479280304Sjkim        return -1;
1480280304Sjkim    ctx->len.u[1] = mlen;
1481238384Sjkim
1482280304Sjkim    if (ctx->ares) {
1483280304Sjkim        /* First call to decrypt finalizes GHASH(AAD) */
1484280304Sjkim        GCM_MUL(ctx, Xi);
1485280304Sjkim        ctx->ares = 0;
1486280304Sjkim    }
1487238384Sjkim
1488280304Sjkim    if (is_endian.little)
1489264331Sjkim#ifdef BSWAP4
1490280304Sjkim        ctr = BSWAP4(ctx->Yi.d[3]);
1491264331Sjkim#else
1492280304Sjkim        ctr = GETU32(ctx->Yi.c + 12);
1493264331Sjkim#endif
1494280304Sjkim    else
1495280304Sjkim        ctr = ctx->Yi.d[3];
1496238384Sjkim
1497280304Sjkim    n = ctx->mres;
1498280304Sjkim    if (n) {
1499280304Sjkim        while (n && len) {
1500280304Sjkim            u8 c = *(in++);
1501280304Sjkim            *(out++) = c ^ ctx->EKi.c[n];
1502280304Sjkim            ctx->Xi.c[n] ^= c;
1503280304Sjkim            --len;
1504280304Sjkim            n = (n + 1) % 16;
1505280304Sjkim        }
1506280304Sjkim        if (n == 0)
1507280304Sjkim            GCM_MUL(ctx, Xi);
1508280304Sjkim        else {
1509280304Sjkim            ctx->mres = n;
1510280304Sjkim            return 0;
1511280304Sjkim        }
1512280304Sjkim    }
1513238384Sjkim#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
1514280304Sjkim    while (len >= GHASH_CHUNK) {
1515280304Sjkim        GHASH(ctx, in, GHASH_CHUNK);
1516280304Sjkim        (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
1517280304Sjkim        ctr += GHASH_CHUNK / 16;
1518280304Sjkim        if (is_endian.little)
1519280304Sjkim# ifdef BSWAP4
1520280304Sjkim            ctx->Yi.d[3] = BSWAP4(ctr);
1521280304Sjkim# else
1522280304Sjkim            PUTU32(ctx->Yi.c + 12, ctr);
1523280304Sjkim# endif
1524280304Sjkim        else
1525280304Sjkim            ctx->Yi.d[3] = ctr;
1526280304Sjkim        out += GHASH_CHUNK;
1527280304Sjkim        in += GHASH_CHUNK;
1528280304Sjkim        len -= GHASH_CHUNK;
1529280304Sjkim    }
1530264331Sjkim#endif
1531280304Sjkim    if ((i = (len & (size_t)-16))) {
1532280304Sjkim        size_t j = i / 16;
1533238384Sjkim
1534238384Sjkim#if defined(GHASH)
1535280304Sjkim        GHASH(ctx, in, i);
1536238384Sjkim#else
1537280304Sjkim        while (j--) {
1538280304Sjkim            size_t k;
1539280304Sjkim            for (k = 0; k < 16; ++k)
1540280304Sjkim                ctx->Xi.c[k] ^= in[k];
1541280304Sjkim            GCM_MUL(ctx, Xi);
1542280304Sjkim            in += 16;
1543280304Sjkim        }
1544280304Sjkim        j = i / 16;
1545280304Sjkim        in -= i;
1546238384Sjkim#endif
1547280304Sjkim        (*stream) (in, out, j, key, ctx->Yi.c);
1548280304Sjkim        ctr += (unsigned int)j;
1549280304Sjkim        if (is_endian.little)
1550264331Sjkim#ifdef BSWAP4
1551280304Sjkim            ctx->Yi.d[3] = BSWAP4(ctr);
1552264331Sjkim#else
1553280304Sjkim            PUTU32(ctx->Yi.c + 12, ctr);
1554264331Sjkim#endif
1555280304Sjkim        else
1556280304Sjkim            ctx->Yi.d[3] = ctr;
1557280304Sjkim        out += i;
1558280304Sjkim        in += i;
1559280304Sjkim        len -= i;
1560280304Sjkim    }
1561280304Sjkim    if (len) {
1562280304Sjkim        (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key);
1563280304Sjkim        ++ctr;
1564280304Sjkim        if (is_endian.little)
1565264331Sjkim#ifdef BSWAP4
1566280304Sjkim            ctx->Yi.d[3] = BSWAP4(ctr);
1567264331Sjkim#else
1568280304Sjkim            PUTU32(ctx->Yi.c + 12, ctr);
1569264331Sjkim#endif
1570280304Sjkim        else
1571280304Sjkim            ctx->Yi.d[3] = ctr;
1572280304Sjkim        while (len--) {
1573280304Sjkim            u8 c = in[n];
1574280304Sjkim            ctx->Xi.c[n] ^= c;
1575280304Sjkim            out[n] = c ^ ctx->EKi.c[n];
1576280304Sjkim            ++n;
1577280304Sjkim        }
1578280304Sjkim    }
1579238384Sjkim
1580280304Sjkim    ctx->mres = n;
1581280304Sjkim    return 0;
1582238384Sjkim}
1583238384Sjkim
1584280304Sjkimint CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
1585280304Sjkim                         size_t len)
1586238384Sjkim{
1587280304Sjkim    const union {
1588280304Sjkim        long one;
1589280304Sjkim        char little;
1590280304Sjkim    } is_endian = {
1591280304Sjkim        1
1592280304Sjkim    };
1593280304Sjkim    u64 alen = ctx->len.u[0] << 3;
1594280304Sjkim    u64 clen = ctx->len.u[1] << 3;
1595238384Sjkim#ifdef GCM_FUNCREF_4BIT
1596280304Sjkim    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
1597238384Sjkim#endif
1598238384Sjkim
1599280304Sjkim    if (ctx->mres || ctx->ares)
1600280304Sjkim        GCM_MUL(ctx, Xi);
1601238384Sjkim
1602280304Sjkim    if (is_endian.little) {
1603238384Sjkim#ifdef BSWAP8
1604280304Sjkim        alen = BSWAP8(alen);
1605280304Sjkim        clen = BSWAP8(clen);
1606238384Sjkim#else
1607280304Sjkim        u8 *p = ctx->len.c;
1608238384Sjkim
1609280304Sjkim        ctx->len.u[0] = alen;
1610280304Sjkim        ctx->len.u[1] = clen;
1611238384Sjkim
1612280304Sjkim        alen = (u64)GETU32(p) << 32 | GETU32(p + 4);
1613280304Sjkim        clen = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
1614238384Sjkim#endif
1615280304Sjkim    }
1616238384Sjkim
1617280304Sjkim    ctx->Xi.u[0] ^= alen;
1618280304Sjkim    ctx->Xi.u[1] ^= clen;
1619280304Sjkim    GCM_MUL(ctx, Xi);
1620238384Sjkim
1621280304Sjkim    ctx->Xi.u[0] ^= ctx->EK0.u[0];
1622280304Sjkim    ctx->Xi.u[1] ^= ctx->EK0.u[1];
1623238384Sjkim
1624280304Sjkim    if (tag && len <= sizeof(ctx->Xi))
1625284285Sjkim        return CRYPTO_memcmp(ctx->Xi.c, tag, len);
1626280304Sjkim    else
1627280304Sjkim        return -1;
1628238384Sjkim}
1629238384Sjkim
1630238384Sjkimvoid CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
1631238384Sjkim{
1632280304Sjkim    CRYPTO_gcm128_finish(ctx, NULL, 0);
1633280304Sjkim    memcpy(tag, ctx->Xi.c,
1634280304Sjkim           len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c));
1635238384Sjkim}
1636238384Sjkim
1637238384SjkimGCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block)
1638238384Sjkim{
1639280304Sjkim    GCM128_CONTEXT *ret;
1640238384Sjkim
1641280304Sjkim    if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT))))
1642280304Sjkim        CRYPTO_gcm128_init(ret, key, block);
1643238384Sjkim
1644280304Sjkim    return ret;
1645238384Sjkim}
1646238384Sjkim
1647238384Sjkimvoid CRYPTO_gcm128_release(GCM128_CONTEXT *ctx)
1648238384Sjkim{
1649280304Sjkim    if (ctx) {
1650280304Sjkim        OPENSSL_cleanse(ctx, sizeof(*ctx));
1651280304Sjkim        OPENSSL_free(ctx);
1652280304Sjkim    }
1653238384Sjkim}
1654238384Sjkim
1655238384Sjkim#if defined(SELFTEST)
1656280304Sjkim# include <stdio.h>
1657280304Sjkim# include <openssl/aes.h>
1658238384Sjkim
1659238384Sjkim/* Test Case 1 */
1660280304Sjkimstatic const u8 K1[16], *P1 = NULL, *A1 = NULL, IV1[12], *C1 = NULL;
1661280304Sjkimstatic const u8 T1[] = {
1662280304Sjkim    0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
1663280304Sjkim    0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a
1664280304Sjkim};
1665238384Sjkim
1666238384Sjkim/* Test Case 2 */
1667280304Sjkim# define K2 K1
1668280304Sjkim# define A2 A1
1669280304Sjkim# define IV2 IV1
1670280304Sjkimstatic const u8 P2[16];
1671280304Sjkimstatic const u8 C2[] = {
1672280304Sjkim    0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
1673280304Sjkim    0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78
1674280304Sjkim};
1675238384Sjkim
1676280304Sjkimstatic const u8 T2[] = {
1677280304Sjkim    0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
1678280304Sjkim    0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf
1679280304Sjkim};
1680280304Sjkim
1681238384Sjkim/* Test Case 3 */
1682280304Sjkim# define A3 A2
1683280304Sjkimstatic const u8 K3[] = {
1684280304Sjkim    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
1685280304Sjkim    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
1686280304Sjkim};
1687238384Sjkim
1688280304Sjkimstatic const u8 P3[] = {
1689280304Sjkim    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
1690280304Sjkim    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
1691280304Sjkim    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
1692280304Sjkim    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
1693280304Sjkim    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
1694280304Sjkim    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
1695280304Sjkim    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
1696280304Sjkim    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
1697280304Sjkim};
1698280304Sjkim
1699280304Sjkimstatic const u8 IV3[] = {
1700280304Sjkim    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
1701280304Sjkim    0xde, 0xca, 0xf8, 0x88
1702280304Sjkim};
1703280304Sjkim
1704280304Sjkimstatic const u8 C3[] = {
1705280304Sjkim    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
1706280304Sjkim    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
1707280304Sjkim    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
1708280304Sjkim    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
1709280304Sjkim    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
1710280304Sjkim    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
1711280304Sjkim    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
1712280304Sjkim    0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85
1713280304Sjkim};
1714280304Sjkim
1715280304Sjkimstatic const u8 T3[] = {
1716280304Sjkim    0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
1717280304Sjkim    0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4
1718280304Sjkim};
1719280304Sjkim
1720238384Sjkim/* Test Case 4 */
1721280304Sjkim# define K4 K3
1722280304Sjkim# define IV4 IV3
1723280304Sjkimstatic const u8 P4[] = {
1724280304Sjkim    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
1725280304Sjkim    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
1726280304Sjkim    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
1727280304Sjkim    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
1728280304Sjkim    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
1729280304Sjkim    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
1730280304Sjkim    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
1731280304Sjkim    0xba, 0x63, 0x7b, 0x39
1732280304Sjkim};
1733238384Sjkim
1734280304Sjkimstatic const u8 A4[] = {
1735280304Sjkim    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
1736280304Sjkim    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
1737280304Sjkim    0xab, 0xad, 0xda, 0xd2
1738280304Sjkim};
1739280304Sjkim
1740280304Sjkimstatic const u8 C4[] = {
1741280304Sjkim    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
1742280304Sjkim    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
1743280304Sjkim    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
1744280304Sjkim    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
1745280304Sjkim    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
1746280304Sjkim    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
1747280304Sjkim    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
1748280304Sjkim    0x3d, 0x58, 0xe0, 0x91
1749280304Sjkim};
1750280304Sjkim
1751280304Sjkimstatic const u8 T4[] = {
1752280304Sjkim    0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
1753280304Sjkim    0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47
1754280304Sjkim};
1755280304Sjkim
1756238384Sjkim/* Test Case 5 */
1757280304Sjkim# define K5 K4
1758280304Sjkim# define P5 P4
1759280304Sjkim# define A5 A4
1760280304Sjkimstatic const u8 IV5[] = {
1761280304Sjkim    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad
1762280304Sjkim};
1763238384Sjkim
1764280304Sjkimstatic const u8 C5[] = {
1765280304Sjkim    0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
1766280304Sjkim    0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
1767280304Sjkim    0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
1768280304Sjkim    0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
1769280304Sjkim    0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
1770280304Sjkim    0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
1771280304Sjkim    0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
1772280304Sjkim    0xc2, 0x3f, 0x45, 0x98
1773280304Sjkim};
1774280304Sjkim
1775280304Sjkimstatic const u8 T5[] = {
1776280304Sjkim    0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
1777280304Sjkim    0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb
1778280304Sjkim};
1779280304Sjkim
1780238384Sjkim/* Test Case 6 */
1781280304Sjkim# define K6 K5
1782280304Sjkim# define P6 P5
1783280304Sjkim# define A6 A5
1784280304Sjkimstatic const u8 IV6[] = {
1785280304Sjkim    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
1786280304Sjkim    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
1787280304Sjkim    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
1788280304Sjkim    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
1789280304Sjkim    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
1790280304Sjkim    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
1791280304Sjkim    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
1792280304Sjkim    0xa6, 0x37, 0xb3, 0x9b
1793280304Sjkim};
1794238384Sjkim
1795280304Sjkimstatic const u8 C6[] = {
1796280304Sjkim    0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
1797280304Sjkim    0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
1798280304Sjkim    0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
1799280304Sjkim    0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
1800280304Sjkim    0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
1801280304Sjkim    0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
1802280304Sjkim    0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
1803280304Sjkim    0x4c, 0x34, 0xae, 0xe5
1804280304Sjkim};
1805280304Sjkim
1806280304Sjkimstatic const u8 T6[] = {
1807280304Sjkim    0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
1808280304Sjkim    0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50
1809280304Sjkim};
1810280304Sjkim
1811238384Sjkim/* Test Case 7 */
1812280304Sjkimstatic const u8 K7[24], *P7 = NULL, *A7 = NULL, IV7[12], *C7 = NULL;
1813280304Sjkimstatic const u8 T7[] = {
1814280304Sjkim    0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
1815280304Sjkim    0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35
1816280304Sjkim};
1817238384Sjkim
1818238384Sjkim/* Test Case 8 */
1819280304Sjkim# define K8 K7
1820280304Sjkim# define IV8 IV7
1821280304Sjkim# define A8 A7
1822280304Sjkimstatic const u8 P8[16];
1823280304Sjkimstatic const u8 C8[] = {
1824280304Sjkim    0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
1825280304Sjkim    0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00
1826280304Sjkim};
1827238384Sjkim
1828280304Sjkimstatic const u8 T8[] = {
1829280304Sjkim    0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
1830280304Sjkim    0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb
1831280304Sjkim};
1832280304Sjkim
1833238384Sjkim/* Test Case 9 */
1834280304Sjkim# define A9 A8
1835280304Sjkimstatic const u8 K9[] = {
1836280304Sjkim    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
1837280304Sjkim    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
1838280304Sjkim    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c
1839280304Sjkim};
1840238384Sjkim
1841280304Sjkimstatic const u8 P9[] = {
1842280304Sjkim    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
1843280304Sjkim    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
1844280304Sjkim    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
1845280304Sjkim    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
1846280304Sjkim    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
1847280304Sjkim    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
1848280304Sjkim    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
1849280304Sjkim    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
1850280304Sjkim};
1851280304Sjkim
1852280304Sjkimstatic const u8 IV9[] = {
1853280304Sjkim    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
1854280304Sjkim    0xde, 0xca, 0xf8, 0x88
1855280304Sjkim};
1856280304Sjkim
1857280304Sjkimstatic const u8 C9[] = {
1858280304Sjkim    0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
1859280304Sjkim    0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
1860280304Sjkim    0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
1861280304Sjkim    0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
1862280304Sjkim    0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
1863280304Sjkim    0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
1864280304Sjkim    0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
1865280304Sjkim    0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56
1866280304Sjkim};
1867280304Sjkim
1868280304Sjkimstatic const u8 T9[] = {
1869280304Sjkim    0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
1870280304Sjkim    0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14
1871280304Sjkim};
1872280304Sjkim
1873238384Sjkim/* Test Case 10 */
1874280304Sjkim# define K10 K9
1875280304Sjkim# define IV10 IV9
1876280304Sjkimstatic const u8 P10[] = {
1877280304Sjkim    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
1878280304Sjkim    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
1879280304Sjkim    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
1880280304Sjkim    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
1881280304Sjkim    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
1882280304Sjkim    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
1883280304Sjkim    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
1884280304Sjkim    0xba, 0x63, 0x7b, 0x39
1885280304Sjkim};
1886238384Sjkim
1887280304Sjkimstatic const u8 A10[] = {
1888280304Sjkim    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
1889280304Sjkim    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
1890280304Sjkim    0xab, 0xad, 0xda, 0xd2
1891280304Sjkim};
1892280304Sjkim
1893280304Sjkimstatic const u8 C10[] = {
1894280304Sjkim    0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
1895280304Sjkim    0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
1896280304Sjkim    0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
1897280304Sjkim    0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
1898280304Sjkim    0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
1899280304Sjkim    0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
1900280304Sjkim    0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
1901280304Sjkim    0xcc, 0xda, 0x27, 0x10
1902280304Sjkim};
1903280304Sjkim
1904280304Sjkimstatic const u8 T10[] = {
1905280304Sjkim    0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
1906280304Sjkim    0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c
1907280304Sjkim};
1908280304Sjkim
1909238384Sjkim/* Test Case 11 */
1910280304Sjkim# define K11 K10
1911280304Sjkim# define P11 P10
1912280304Sjkim# define A11 A10
1913280304Sjkimstatic const u8 IV11[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
1914238384Sjkim
1915280304Sjkimstatic const u8 C11[] = {
1916280304Sjkim    0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
1917280304Sjkim    0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
1918280304Sjkim    0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
1919280304Sjkim    0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
1920280304Sjkim    0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
1921280304Sjkim    0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
1922280304Sjkim    0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
1923280304Sjkim    0xa0, 0xf0, 0x62, 0xf7
1924280304Sjkim};
1925280304Sjkim
1926280304Sjkimstatic const u8 T11[] = {
1927280304Sjkim    0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
1928280304Sjkim    0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8
1929280304Sjkim};
1930280304Sjkim
1931238384Sjkim/* Test Case 12 */
1932280304Sjkim# define K12 K11
1933280304Sjkim# define P12 P11
1934280304Sjkim# define A12 A11
1935280304Sjkimstatic const u8 IV12[] = {
1936280304Sjkim    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
1937280304Sjkim    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
1938280304Sjkim    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
1939280304Sjkim    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
1940280304Sjkim    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
1941280304Sjkim    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
1942280304Sjkim    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
1943280304Sjkim    0xa6, 0x37, 0xb3, 0x9b
1944280304Sjkim};
1945238384Sjkim
1946280304Sjkimstatic const u8 C12[] = {
1947280304Sjkim    0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
1948280304Sjkim    0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
1949280304Sjkim    0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
1950280304Sjkim    0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
1951280304Sjkim    0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
1952280304Sjkim    0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
1953280304Sjkim    0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
1954280304Sjkim    0xe9, 0xb7, 0x37, 0x3b
1955280304Sjkim};
1956280304Sjkim
1957280304Sjkimstatic const u8 T12[] = {
1958280304Sjkim    0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
1959280304Sjkim    0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9
1960280304Sjkim};
1961280304Sjkim
1962238384Sjkim/* Test Case 13 */
1963280304Sjkimstatic const u8 K13[32], *P13 = NULL, *A13 = NULL, IV13[12], *C13 = NULL;
1964280304Sjkimstatic const u8 T13[] = {
1965280304Sjkim    0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
1966280304Sjkim    0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b
1967280304Sjkim};
1968238384Sjkim
1969238384Sjkim/* Test Case 14 */
1970280304Sjkim# define K14 K13
1971280304Sjkim# define A14 A13
1972280304Sjkimstatic const u8 P14[16], IV14[12];
1973280304Sjkimstatic const u8 C14[] = {
1974280304Sjkim    0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
1975280304Sjkim    0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18
1976280304Sjkim};
1977238384Sjkim
1978280304Sjkimstatic const u8 T14[] = {
1979280304Sjkim    0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
1980280304Sjkim    0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19
1981280304Sjkim};
1982280304Sjkim
1983238384Sjkim/* Test Case 15 */
1984280304Sjkim# define A15 A14
1985280304Sjkimstatic const u8 K15[] = {
1986280304Sjkim    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
1987280304Sjkim    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
1988280304Sjkim    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
1989280304Sjkim    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
1990280304Sjkim};
1991238384Sjkim
1992280304Sjkimstatic const u8 P15[] = {
1993280304Sjkim    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
1994280304Sjkim    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
1995280304Sjkim    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
1996280304Sjkim    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
1997280304Sjkim    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
1998280304Sjkim    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
1999280304Sjkim    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
2000280304Sjkim    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
2001280304Sjkim};
2002280304Sjkim
2003280304Sjkimstatic const u8 IV15[] = {
2004280304Sjkim    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
2005280304Sjkim    0xde, 0xca, 0xf8, 0x88
2006280304Sjkim};
2007280304Sjkim
2008280304Sjkimstatic const u8 C15[] = {
2009280304Sjkim    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
2010280304Sjkim    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
2011280304Sjkim    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
2012280304Sjkim    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
2013280304Sjkim    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
2014280304Sjkim    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
2015280304Sjkim    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
2016280304Sjkim    0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
2017280304Sjkim};
2018280304Sjkim
2019280304Sjkimstatic const u8 T15[] = {
2020280304Sjkim    0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
2021280304Sjkim    0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c
2022280304Sjkim};
2023280304Sjkim
2024238384Sjkim/* Test Case 16 */
2025280304Sjkim# define K16 K15
2026280304Sjkim# define IV16 IV15
2027280304Sjkimstatic const u8 P16[] = {
2028280304Sjkim    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
2029280304Sjkim    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
2030280304Sjkim    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
2031280304Sjkim    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
2032280304Sjkim    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
2033280304Sjkim    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
2034280304Sjkim    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
2035280304Sjkim    0xba, 0x63, 0x7b, 0x39
2036280304Sjkim};
2037238384Sjkim
2038280304Sjkimstatic const u8 A16[] = {
2039280304Sjkim    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
2040280304Sjkim    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
2041280304Sjkim    0xab, 0xad, 0xda, 0xd2
2042280304Sjkim};
2043280304Sjkim
2044280304Sjkimstatic const u8 C16[] = {
2045280304Sjkim    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
2046280304Sjkim    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
2047280304Sjkim    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
2048280304Sjkim    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
2049280304Sjkim    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
2050280304Sjkim    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
2051280304Sjkim    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
2052280304Sjkim    0xbc, 0xc9, 0xf6, 0x62
2053280304Sjkim};
2054280304Sjkim
2055280304Sjkimstatic const u8 T16[] = {
2056280304Sjkim    0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
2057280304Sjkim    0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
2058280304Sjkim};
2059280304Sjkim
2060238384Sjkim/* Test Case 17 */
2061280304Sjkim# define K17 K16
2062280304Sjkim# define P17 P16
2063280304Sjkim# define A17 A16
2064280304Sjkimstatic const u8 IV17[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
2065238384Sjkim
2066280304Sjkimstatic const u8 C17[] = {
2067280304Sjkim    0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
2068280304Sjkim    0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
2069280304Sjkim    0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
2070280304Sjkim    0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
2071280304Sjkim    0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
2072280304Sjkim    0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
2073280304Sjkim    0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
2074280304Sjkim    0xf4, 0x7c, 0x9b, 0x1f
2075280304Sjkim};
2076280304Sjkim
2077280304Sjkimstatic const u8 T17[] = {
2078280304Sjkim    0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
2079280304Sjkim    0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2
2080280304Sjkim};
2081280304Sjkim
2082238384Sjkim/* Test Case 18 */
2083280304Sjkim# define K18 K17
2084280304Sjkim# define P18 P17
2085280304Sjkim# define A18 A17
2086280304Sjkimstatic const u8 IV18[] = {
2087280304Sjkim    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
2088280304Sjkim    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
2089280304Sjkim    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
2090280304Sjkim    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
2091280304Sjkim    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
2092280304Sjkim    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
2093280304Sjkim    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
2094280304Sjkim    0xa6, 0x37, 0xb3, 0x9b
2095280304Sjkim};
2096238384Sjkim
2097280304Sjkimstatic const u8 C18[] = {
2098280304Sjkim    0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
2099280304Sjkim    0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
2100280304Sjkim    0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
2101280304Sjkim    0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
2102280304Sjkim    0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
2103280304Sjkim    0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
2104280304Sjkim    0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
2105280304Sjkim    0x44, 0xae, 0x7e, 0x3f
2106280304Sjkim};
2107280304Sjkim
2108280304Sjkimstatic const u8 T18[] = {
2109280304Sjkim    0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
2110280304Sjkim    0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a
2111280304Sjkim};
2112280304Sjkim
2113264331Sjkim/* Test Case 19 */
2114280304Sjkim# define K19 K1
2115280304Sjkim# define P19 P1
2116280304Sjkim# define IV19 IV1
2117280304Sjkim# define C19 C1
2118280304Sjkimstatic const u8 A19[] = {
2119280304Sjkim    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
2120280304Sjkim    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
2121280304Sjkim    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
2122280304Sjkim    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
2123280304Sjkim    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
2124280304Sjkim    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
2125280304Sjkim    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
2126280304Sjkim    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
2127280304Sjkim    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
2128280304Sjkim    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
2129280304Sjkim    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
2130280304Sjkim    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
2131280304Sjkim    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
2132280304Sjkim    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
2133280304Sjkim    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
2134280304Sjkim    0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
2135280304Sjkim};
2136264331Sjkim
2137280304Sjkimstatic const u8 T19[] = {
2138280304Sjkim    0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d,
2139280304Sjkim    0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92
2140280304Sjkim};
2141280304Sjkim
2142264331Sjkim/* Test Case 20 */
2143280304Sjkim# define K20 K1
2144280304Sjkim# define A20 A1
2145280304Sjkim/* this results in 0xff in counter LSB */
2146280304Sjkimstatic const u8 IV20[64] = { 0xff, 0xff, 0xff, 0xff };
2147264331Sjkim
2148280304Sjkimstatic const u8 P20[288];
2149280304Sjkimstatic const u8 C20[] = {
2150280304Sjkim    0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a,
2151280304Sjkim    0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14,
2152280304Sjkim    0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce,
2153280304Sjkim    0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f,
2154280304Sjkim    0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70,
2155280304Sjkim    0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18,
2156280304Sjkim    0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf,
2157280304Sjkim    0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49,
2158280304Sjkim    0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab,
2159280304Sjkim    0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c,
2160280304Sjkim    0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c,
2161280304Sjkim    0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29,
2162280304Sjkim    0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1,
2163280304Sjkim    0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76,
2164280304Sjkim    0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2,
2165280304Sjkim    0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce,
2166280304Sjkim    0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f,
2167280304Sjkim    0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86,
2168280304Sjkim    0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb,
2169280304Sjkim    0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18,
2170280304Sjkim    0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65,
2171280304Sjkim    0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42,
2172280304Sjkim    0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b,
2173280304Sjkim    0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06,
2174280304Sjkim    0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24,
2175280304Sjkim    0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c,
2176280304Sjkim    0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4,
2177280304Sjkim    0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64,
2178280304Sjkim    0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03,
2179280304Sjkim    0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6,
2180280304Sjkim    0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90,
2181280304Sjkim    0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74,
2182280304Sjkim    0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67,
2183280304Sjkim    0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46,
2184280304Sjkim    0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78,
2185280304Sjkim    0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c
2186280304Sjkim};
2187238384Sjkim
2188280304Sjkimstatic const u8 T20[] = {
2189280304Sjkim    0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a,
2190280304Sjkim    0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f
2191280304Sjkim};
2192280304Sjkim
2193280304Sjkim# define TEST_CASE(n)    do {                                    \
2194280304Sjkim        u8 out[sizeof(P##n)];                                   \
2195280304Sjkim        AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key);          \
2196280304Sjkim        CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt);  \
2197280304Sjkim        CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));          \
2198280304Sjkim        memset(out,0,sizeof(out));                              \
2199280304Sjkim        if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));    \
2200280304Sjkim        if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out));     \
2201280304Sjkim        if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||               \
2202280304Sjkim            (C##n && memcmp(out,C##n,sizeof(out))))             \
2203280304Sjkim                ret++, printf ("encrypt test#%d failed.\n",n);  \
2204280304Sjkim        CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));          \
2205280304Sjkim        memset(out,0,sizeof(out));                              \
2206280304Sjkim        if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));    \
2207280304Sjkim        if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out));     \
2208280304Sjkim        if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||               \
2209280304Sjkim            (P##n && memcmp(out,P##n,sizeof(out))))             \
2210280304Sjkim                ret++, printf ("decrypt test#%d failed.\n",n);  \
2211280304Sjkim        } while(0)
2212280304Sjkim
2213238384Sjkimint main()
2214238384Sjkim{
2215280304Sjkim    GCM128_CONTEXT ctx;
2216280304Sjkim    AES_KEY key;
2217280304Sjkim    int ret = 0;
2218238384Sjkim
2219280304Sjkim    TEST_CASE(1);
2220280304Sjkim    TEST_CASE(2);
2221280304Sjkim    TEST_CASE(3);
2222280304Sjkim    TEST_CASE(4);
2223280304Sjkim    TEST_CASE(5);
2224280304Sjkim    TEST_CASE(6);
2225280304Sjkim    TEST_CASE(7);
2226280304Sjkim    TEST_CASE(8);
2227280304Sjkim    TEST_CASE(9);
2228280304Sjkim    TEST_CASE(10);
2229280304Sjkim    TEST_CASE(11);
2230280304Sjkim    TEST_CASE(12);
2231280304Sjkim    TEST_CASE(13);
2232280304Sjkim    TEST_CASE(14);
2233280304Sjkim    TEST_CASE(15);
2234280304Sjkim    TEST_CASE(16);
2235280304Sjkim    TEST_CASE(17);
2236280304Sjkim    TEST_CASE(18);
2237280304Sjkim    TEST_CASE(19);
2238280304Sjkim    TEST_CASE(20);
2239238384Sjkim
2240280304Sjkim# ifdef OPENSSL_CPUID_OBJ
2241280304Sjkim    {
2242280304Sjkim        size_t start, stop, gcm_t, ctr_t, OPENSSL_rdtsc();
2243280304Sjkim        union {
2244280304Sjkim            u64 u;
2245280304Sjkim            u8 c[1024];
2246280304Sjkim        } buf;
2247280304Sjkim        int i;
2248238384Sjkim
2249280304Sjkim        AES_set_encrypt_key(K1, sizeof(K1) * 8, &key);
2250280304Sjkim        CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt);
2251280304Sjkim        CRYPTO_gcm128_setiv(&ctx, IV1, sizeof(IV1));
2252238384Sjkim
2253280304Sjkim        CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
2254280304Sjkim        start = OPENSSL_rdtsc();
2255280304Sjkim        CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
2256280304Sjkim        gcm_t = OPENSSL_rdtsc() - start;
2257238384Sjkim
2258280304Sjkim        CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
2259280304Sjkim                              &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
2260280304Sjkim                              (block128_f) AES_encrypt);
2261280304Sjkim        start = OPENSSL_rdtsc();
2262280304Sjkim        CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
2263280304Sjkim                              &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
2264280304Sjkim                              (block128_f) AES_encrypt);
2265280304Sjkim        ctr_t = OPENSSL_rdtsc() - start;
2266238384Sjkim
2267280304Sjkim        printf("%.2f-%.2f=%.2f\n",
2268280304Sjkim               gcm_t / (double)sizeof(buf),
2269280304Sjkim               ctr_t / (double)sizeof(buf),
2270280304Sjkim               (gcm_t - ctr_t) / (double)sizeof(buf));
2271280304Sjkim#  ifdef GHASH
2272280304Sjkim        {
2273280304Sjkim            void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
2274280304Sjkim                                 const u8 *inp, size_t len) = ctx.ghash;
2275264331Sjkim
2276280304Sjkim            GHASH((&ctx), buf.c, sizeof(buf));
2277280304Sjkim            start = OPENSSL_rdtsc();
2278280304Sjkim            for (i = 0; i < 100; ++i)
2279280304Sjkim                GHASH((&ctx), buf.c, sizeof(buf));
2280280304Sjkim            gcm_t = OPENSSL_rdtsc() - start;
2281280304Sjkim            printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i);
2282280304Sjkim        }
2283280304Sjkim#  endif
2284280304Sjkim    }
2285280304Sjkim# endif
2286238384Sjkim
2287280304Sjkim    return ret;
2288238384Sjkim}
2289238384Sjkim#endif
2290