Initial version of Galois Counter Mode implementation. Interface is still
[openssl.git] / crypto / modes / gcm128.c
1 /* ====================================================================
2  * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer. 
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the OpenSSL Project
19  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20  *
21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    openssl-core@openssl.org.
25  *
26  * 5. Products derived from this software may not be called "OpenSSL"
27  *    nor may "OpenSSL" appear in their names without prior written
28  *    permission of the OpenSSL Project.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the OpenSSL Project
33  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  */
49
50 #include "modes.h"
51 #include <string.h>
52
53 #ifndef MODES_DEBUG
54 # ifndef NDEBUG
55 #  define NDEBUG
56 # endif
57 #endif
58 #include <assert.h>
59
60 #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
61 typedef __int64 i64;
62 typedef unsigned __int64 u64;
63 #define U64(C) C##UI64
64 #elif defined(__arch64__)
65 typedef long i64;
66 typedef unsigned long u64;
67 #define U64(C) C##UL
68 #else
69 typedef long long i64;
70 typedef unsigned long long u64;
71 #define U64(C) C##ULL
72 #endif
73
74 typedef unsigned int u32;
75 typedef unsigned char u8;
76 typedef struct { u64 hi,lo; } u128;
77
78 #define STRICT_ALIGNMENT
79 #if defined(__i386)     || defined(__i386__)    || \
80     defined(__x86_64)   || defined(__x86_64__)  || \
81     defined(_M_IX86)    || defined(_M_AMD64)    || defined(_M_X64) || \
82     defined(__s390__)   || defined(__s390x__)
83 # undef STRICT_ALIGNMENT
84 #endif
85
86 #if defined(__GNUC__) && __GNUC__>=2
87 # if defined(__x86_64) || defined(__x86_64__)
88 #  define BSWAP8(x) ({  u64 ret=(x);                    \
89                         asm volatile ("bswapq %0"       \
90                         : "+r"(ret));   ret;            })
91 #  define BSWAP4(x) ({  u32 ret=(x);                    \
92                         asm volatile ("bswapl %0"       \
93                         : "+r"(ret));   ret;            })
94 # elif defined(__i386) || defined(__i386__)
95 #  define BSWAP8(x) ({  u32 lo=(u64)(x)>>32,hi=(x);     \
96                         asm volatile ("bswapl %0; bswapl %1"    \
97                         : "+r"(hi),"+r"(lo));           \
98                         (u64)hi<<32|lo;                 })
99 #  define BSWAP4(x) ({  u32 ret=(x);                    \
100                         asm volatile ("bswapl %0"       \
101                         : "+r"(ret));   ret;            })
102 # endif
103 #elif defined(_MSC_VER)
104 # if _MSC_VER>=1300
105 #  pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
106 #  define BSWAP8(x)     _byteswap_uint64((u64)(x))
107 #  define BSWAP4(x)     _byteswap_ulong((u32)(x))
108 # elif defined(_M_IX86)
109 # endif
110 #endif
111
112 #ifdef BSWAP4
113 #define GETU32(p)       BSWAP4(*(const u32 *)(p))
114 #define PUTU32(p,v)     *(u32 *)(p) = BSWAP4(v)
115 #else
116 #define GETU32(p)       ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
117 #define PUTU32(p,v)     ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
118 #endif
119
120 #define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16))
121
122 #if 0
123 static void gcm_init_8bit(u128 Htable[256], u64 H[2])
124 {
125         int  i, j;
126         u128 V;
127
128         Htable[0].hi = 0;
129         Htable[0].lo = 0;
130         V.hi = H[0];
131         V.lo = H[1];
132
133         for (Htable[128]=V, i=64; i>0; i>>=1) {
134                 if (sizeof(size_t)==8) {
135                         u64 T = U64(0xe100000000000000) & (0-(V.lo&1));
136                         V.lo  = (V.hi<<63)|(V.lo>>1);
137                         V.hi  = (V.hi>>1 )^T;
138                 }
139                 else {
140                         u32 T = 0xe1000000U & (0-(u32)(V.lo&1));
141                         V.lo  = (V.hi<<63)|(V.lo>>1);
142                         V.hi  = (V.hi>>1) ^((u64)T<<32);
143                 }
144                 Htable[i] = V;
145         }
146
147         for (i=2; i<256; i<<=1) {
148                 u128 *Hi = Htable+i, H0 = *Hi;
149                 for (j=1; j<i; ++j) {
150                         Hi[j].hi = H0.hi^Htable[j].hi;
151                         Hi[j].lo = H0.lo^Htable[j].lo;
152                 }
153         }
154 }
155
156 static void gcm_mul_8bit(u64 Xi[2], u128 Htable[256])
157 {
158         u128 Z = { 0, 0};
159         const u8 *xi = (const u8 *)Xi+15;
160         size_t rem, n = *xi;
161         const union { long one; char little; } is_endian = {1};
162         static const size_t rem_8bit[256] = {
163                 PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246),
164                 PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E),
165                 PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56),
166                 PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E),
167                 PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66),
168                 PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E),
169                 PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076),
170                 PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E),
171                 PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06),
172                 PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E),
173                 PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416),
174                 PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E),
175                 PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626),
176                 PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E),
177                 PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836),
178                 PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E),
179                 PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6),
180                 PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE),
181                 PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6),
182                 PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE),
183                 PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6),
184                 PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE),
185                 PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6),
186                 PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE),
187                 PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86),
188                 PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E),
189                 PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496),
190                 PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E),
191                 PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6),
192                 PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE),
193                 PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6),
194                 PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE),
195                 PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346),
196                 PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E),
197                 PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56),
198                 PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E),
199                 PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66),
200                 PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E),
201                 PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176),
202                 PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E),
203                 PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06),
204                 PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E),
205                 PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516),
206                 PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E),
207                 PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726),
208                 PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E),
209                 PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936),
210                 PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E),
211                 PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6),
212                 PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE),
213                 PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6),
214                 PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE),
215                 PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6),
216                 PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE),
217                 PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6),
218                 PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE),
219                 PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86),
220                 PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E),
221                 PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596),
222                 PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E),
223                 PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6),
224                 PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE),
225                 PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6),
226                 PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE) };
227
228         while (1) {
229                 Z.hi ^= Htable[n].hi;
230                 Z.lo ^= Htable[n].lo;
231
232                 if ((u8 *)Xi==xi)       break;
233
234                 n = *(--xi);
235
236                 rem  = (size_t)Z.lo&0xff;
237                 Z.lo = (Z.hi<<56)|(Z.lo>>8);
238                 Z.hi = (Z.hi>>8);
239                 if (sizeof(size_t)==8)
240                         Z.hi ^= rem_8bit[rem];
241                 else
242                         Z.hi ^= (u64)rem_8bit[rem]<<32;
243         }
244
245         if (is_endian.little) {
246 #ifdef BSWAP8
247                 Xi[0] = BSWAP8(Z.hi);
248                 Xi[1] = BSWAP8(Z.lo);
249 #else
250                 u8 *p = (u8 *)Xi;
251                 u32 v;
252                 v = (u32)(Z.hi>>32);    PUTU32(p,v);
253                 v = (u32)(Z.hi);        PUTU32(p+4,v);
254                 v = (u32)(Z.lo>>32);    PUTU32(p+8,v);
255                 v = (u32)(Z.lo);        PUTU32(p+12,v);
256 #endif
257         }
258         else {
259                 Xi[0] = Z.hi;
260                 Xi[1] = Z.lo;
261         }
262 }
263 #endif
264
265 static void gcm_init_4bit(u128 Htable[16], u64 H[2])
266 {
267         int  i, j;
268         u128 V;
269
270         Htable[0].hi = 0;
271         Htable[0].lo = 0;
272         V.hi = H[0];
273         V.lo = H[1];
274
275         for (Htable[8]=V, i=4; i>0; i>>=1) {
276                 if (sizeof(size_t)==8) {
277                         u64 T = U64(0xe100000000000000) & (0-(V.lo&1));
278                         V.lo  = (V.hi<<63)|(V.lo>>1);
279                         V.hi  = (V.hi>>1 )^T;
280                 }
281                 else {
282                         u32 T = 0xe1000000U & (0-(u32)(V.lo&1));
283                         V.lo  = (V.hi<<63)|(V.lo>>1);
284                         V.hi  = (V.hi>>1 )^((u64)T<<32);
285                 }
286                 Htable[i] = V;
287         }
288
289         for (i=2; i<16; i<<=1) {
290                 u128 *Hi = Htable+i, H0 = *Hi;
291                 for (j=1; j<i; ++j) {
292                         Hi[j].hi = H0.hi^Htable[j].hi;
293                         Hi[j].lo = H0.lo^Htable[j].lo;
294                 }
295         }
296 }
297
298 static void gcm_mul_4bit(u64 Xi[2], u128 Htable[16])
299 {
300         u128 Z = { 0, 0};
301         const u8 *xi = (const u8 *)Xi+15;
302         size_t rem, nlo = *xi, nhi;
303         const union { long one; char little; } is_endian = {1};
304         static const size_t rem_4bit[16] = {
305                 PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460),
306                 PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0),
307                 PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560),
308                 PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) };
309
310         while (1) {
311                 nhi  = nlo>>4;
312                 nlo &= 0xf;
313
314                 Z.hi ^= Htable[nlo].hi;
315                 Z.lo ^= Htable[nlo].lo;
316
317                 rem  = (size_t)Z.lo&0xf;
318                 Z.lo = (Z.hi<<60)|(Z.lo>>4);
319                 Z.hi = (Z.hi>>4);
320                 if (sizeof(size_t)==8)
321                         Z.hi ^= rem_4bit[rem];
322                 else
323                         Z.hi ^= (u64)rem_4bit[rem]<<32;
324
325                 Z.hi ^= Htable[nhi].hi;
326                 Z.lo ^= Htable[nhi].lo;
327
328                 if ((u8 *)Xi==xi)       break;
329
330                 nlo = *(--xi);
331
332                 rem  = (size_t)Z.lo&0xf;
333                 Z.lo = (Z.hi<<60)|(Z.lo>>4);
334                 Z.hi = (Z.hi>>4);
335                 if (sizeof(size_t)==8)
336                         Z.hi ^= rem_4bit[rem];
337                 else
338                         Z.hi ^= (u64)rem_4bit[rem]<<32;
339         }
340
341         if (is_endian.little) {
342 #ifdef BSWAP8
343                 Xi[0] = BSWAP8(Z.hi);
344                 Xi[1] = BSWAP8(Z.lo);
345 #else
346                 u8 *p = (u8 *)Xi;
347                 u32 v;
348                 v = (u32)(Z.hi>>32);    PUTU32(p,v);
349                 v = (u32)(Z.hi);        PUTU32(p+4,v);
350                 v = (u32)(Z.lo>>32);    PUTU32(p+8,v);
351                 v = (u32)(Z.lo);        PUTU32(p+12,v);
352 #endif
353         }
354         else {
355                 Xi[0] = Z.hi;
356                 Xi[1] = Z.lo;
357         }
358 }
359
360 static void gcm_mul_1bit(u64 Xi[2],const u64 H[2])
361 {
362         u128 V,Z = { 0,0 };
363         long X;
364         int  i,j;
365         const long *xi = (const long *)Xi;
366         const union { long one; char little; } is_endian = {1};
367
368         V.hi = H[0];    /* h is in host byte order, no byte swaping */
369         V.lo = H[1];
370
371         for (j=0; j<16/sizeof(long); ++j) {
372                 if (is_endian.little) {
373                         if (sizeof(long)==8) {
374 #ifdef BSWAP8
375                                 X = (long)(BSWAP8(xi[j]));
376 #else
377                                 const u8 *p = (const u8 *)(xi+j);
378                                 X = (long)((u64)GETU32(p)<<32|GETU32(p+4));
379 #endif
380                         }
381                         else {
382                                 const u8 *p = (const u8 *)(xi+j);
383                                 X = (long)GETU32(p);
384                         }
385                 }
386                 else
387                         X = xi[j];
388
389                 for (i=0; i<8*sizeof(long); ++i, X<<=1) {
390                         u64 M = (u64)(X>>(8*sizeof(long)-1));
391                         Z.hi ^= V.hi&M;
392                         Z.lo ^= V.lo&M;
393
394                         if (sizeof(size_t)==8) {
395                                 u64 T = U64(0xe100000000000000) & (0-(V.lo&1));
396                                 V.lo  = (V.hi<<63)|(V.lo>>1);
397                                 V.hi  = (V.hi>>1 )^T;
398                         }
399                         else {
400                                 u32 T = 0xe1000000U & (0-(u32)(V.lo&1));
401                                 V.lo  = (V.hi<<63)|(V.lo>>1);
402                                 V.hi  = (V.hi>>1 )^((u64)T<<32);
403                         }
404                                 
405                 }
406         }
407
408         if (is_endian.little) {
409 #ifdef BSWAP8
410                 Xi[0] = BSWAP8(Z.hi);
411                 Xi[1] = BSWAP8(Z.lo);
412 #else
413                 u8 *p = (u8 *)Xi;
414                 u32 v;
415                 v = (u32)(Z.hi>>32);    PUTU32(p,v);
416                 v = (u32)(Z.hi);        PUTU32(p+4,v);
417                 v = (u32)(Z.lo>>32);    PUTU32(p+8,v);
418                 v = (u32)(Z.lo);        PUTU32(p+12,v);
419 #endif
420         }
421         else {
422                 Xi[0] = Z.hi;
423                 Xi[1] = Z.lo;
424         }
425 }
426
427 #if 0
428 #define GCM_MUL(ctx,Xi) gcm_mul_1bit(ctx->Xi.u,ctx->H.u)
429 #else
430 #define GCM_MUL(ctx,Xi) gcm_mul_4bit(ctx->Xi.u,ctx->Htable)
431 #endif
432
433 typedef struct {
434         /* Following 6 names follow names in GCM specification */
435         union { u64 u[2]; u32 d[4]; u8 c[16]; } Yi,EKi,EK0,
436                                                 Xi,H,
437                                                 len;
438         /* Pre-computed table used by gcm_mul_4bit */
439         u128 Htable[16];
440         unsigned int res, ctr;
441         block128_f block;
442         void *key;
443 } GCM128_CONTEXT;
444
445 void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)
446 {
447         const union { long one; char little; } is_endian = {1};
448
449         memset(ctx,0,sizeof(*ctx));
450         ctx->block = block;
451         ctx->key   = key;
452
453         (*block)(ctx->H.c,ctx->H.c,key);
454
455         if (is_endian.little) {
456                 /* H is stored in host byte order */
457 #ifdef BSWAP8
458                 ctx->H.u[0] = BSWAP8(ctx->H.u[0]);
459                 ctx->H.u[1] = BSWAP8(ctx->H.u[1]);
460 #else
461                 u8 *p = ctx->H.c;
462                 u64 hi,lo;
463                 hi = (u64)GETU32(p)  <<32|GETU32(p+4);
464                 lo = (u64)GETU32(p+8)<<32|GETU32(p+12);
465                 ctx->H.u[0] = hi;
466                 ctx->H.u[1] = lo;
467 #endif
468         }
469
470         gcm_init_4bit(ctx->Htable,ctx->H.u);
471 }
472
473 void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx,const unsigned char *iv,size_t len)
474 {
475         const union { long one; char little; } is_endian = {1};
476
477         ctx->Yi.u[0]  = 0;
478         ctx->Yi.u[1]  = 0;
479         ctx->Xi.u[0]  = 0;
480         ctx->Xi.u[1]  = 0;
481         ctx->len.u[0] = 0;
482         ctx->len.u[1] = 0;
483         ctx->res = 0;
484
485         if (len==12) {
486                 memcpy(ctx->Yi.c,iv,12);
487                 ctx->Yi.c[15]=1;
488                 ctx->ctr=1;
489         }
490         else {
491                 size_t i;
492                 u64 len0 = len;
493
494                 while (len>=16) {
495                         for (i=0; i<16; ++i) ctx->Yi.c[i] ^= iv[i];
496                         GCM_MUL(ctx,Yi);
497                         iv += 16;
498                         len -= 16;
499                 }
500                 if (len) {
501                         for (i=0; i<len; ++i) ctx->Yi.c[i] ^= iv[i];
502                         GCM_MUL(ctx,Yi);
503                 }
504                 len0 <<= 3;
505                 if (is_endian.little) {
506 #ifdef BSWAP8
507                         ctx->Yi.u[1]  ^= BSWAP8(len0);
508 #else
509                         ctx->Yi.c[8]  ^= (u8)(len0>>56);
510                         ctx->Yi.c[9]  ^= (u8)(len0>>48);
511                         ctx->Yi.c[10] ^= (u8)(len0>>40);
512                         ctx->Yi.c[11] ^= (u8)(len0>>32);
513                         ctx->Yi.c[12] ^= (u8)(len0>>24);
514                         ctx->Yi.c[13] ^= (u8)(len0>>16);
515                         ctx->Yi.c[14] ^= (u8)(len0>>8);
516                         ctx->Yi.c[15] ^= (u8)(len0);
517 #endif
518                 }
519                 else
520                         ctx->Yi.u[1]  ^= len0;
521
522                 GCM_MUL(ctx,Yi);
523
524                 if (is_endian.little)
525                         ctx->ctr = GETU32(ctx->Yi.c+12);
526                 else
527                         ctx->ctr = ctx->Yi.d[3];
528         }
529
530         (*ctx->block)(ctx->Yi.c,ctx->EK0.c,ctx->key);
531 }
532
533 void CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx,const unsigned char *aad,size_t len)
534 {
535         size_t i;
536
537         ctx->len.u[0] += len;
538
539         while (len>=16) {
540                 for (i=0; i<16; ++i) ctx->Xi.c[i] ^= aad[i];
541                 GCM_MUL(ctx,Xi);
542                 aad += 16;
543                 len -= 16;
544         }
545
546         if (len) {
547                 for (i=0; i<len; ++i) ctx->Xi.c[i] ^= aad[i];
548                 GCM_MUL(ctx,Xi);
549         }
550 }
551
552 void CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
553                 const unsigned char *in, unsigned char *out,
554                 size_t len)
555 {
556         const union { long one; char little; } is_endian = {1};
557         unsigned int n, ctr;
558         size_t i;
559
560         ctx->len.u[1] += len;
561         n   = ctx->res;
562         ctr = ctx->ctr;
563
564 #if !defined(OPENSSL_SMALL_FOOTPRINT)
565         if (16%sizeof(size_t) == 0) do {        /* always true actually */
566                 if (n) {
567                         while (n && len) {
568                                 ctx->Xi.c[n] ^= *(out++) = *(in++)^ctx->EKi.c[n];
569                                 --len;
570                                 n = (n+1)%16;
571                         }
572                         if (n==0) GCM_MUL(ctx,Xi);
573                         else {
574                                 ctx->res = n;
575                                 return;
576                         }
577                 }
578
579 #if defined(STRICT_ALIGNMENT)
580                 if (((size_t)in|(size_t)out)%sizeof(size_t) != 0)
581                         break;
582 #endif
583                 while (len>=16) {
584                         ++ctr;
585                         if (is_endian.little)
586                                 PUTU32(ctx->Yi.c+12,ctr);
587                         else
588                                 ctx->Yi.d[3] = ctr;
589                         (*ctx->block)(ctx->Yi.c,ctx->EKi.c,ctx->key);
590                         for (i=0; i<16; i+=sizeof(size_t))
591                                 *(size_t *)(ctx->Xi.c+i) ^=
592                                 *(size_t *)(out+i) =
593                                 *(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
594                         GCM_MUL(ctx,Xi);
595                         out += 16;
596                         in  += 16;
597                         len -= 16;
598                 }
599
600                 if (len) {
601                         ++ctr;
602                         if (is_endian.little)
603                                 PUTU32(ctx->Yi.c+12,ctr);
604                         else
605                                 ctx->Yi.d[3] = ctr;
606                         (*ctx->block)(ctx->Yi.c,ctx->EKi.c,ctx->key);
607                         while (len--) {
608                                 ctx->Xi.c[n] ^= out[n] = in[n]^ctx->EKi.c[n];
609                                 ++n;
610                         }
611                 }
612
613                 ctx->res = n;
614                 ctx->ctr = ctr;
615                 return;
616         } while(0);
617 #endif
618         for (i=0;i<len;++i) {
619                 if (n==0) {
620                         ++ctr;
621                         if (is_endian.little)
622                                 PUTU32(ctx->Yi.c+12,ctr);
623                         else
624                                 ctx->Yi.d[3] = ctr;
625                         (*ctx->block)(ctx->Yi.c,ctx->EKi.c,ctx->key);
626                 }
627                 ctx->Xi.c[n] ^= out[i] = in[i]^ctx->EKi.c[n];
628                 n = (n+1)%16;
629                 if (n==0)
630                         GCM_MUL(ctx,Xi);
631         }
632
633         ctx->res = n;
634         ctx->ctr = ctr;
635 }
636
637 void CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
638                 const unsigned char *in, unsigned char *out,
639                 size_t len)
640 {
641         const union { long one; char little; } is_endian = {1};
642         unsigned int n, ctr;
643         size_t i;
644
645         ctx->len.u[1] += len;
646         n   = ctx->res;
647         ctr = ctx->ctr;
648
649 #if !defined(OPENSSL_SMALL_FOOTPRINT)
650         if (16%sizeof(size_t) == 0) do {        /* always true actually */
651                 if (n) {
652                         while (n && len) {
653                                 u8 c = *(in++);
654                                 *(out++) = c^ctx->EKi.c[n];
655                                 ctx->Xi.c[n] ^= c;
656                                 --len;
657                                 n = (n+1)%16;
658                         }
659                         if (n==0) GCM_MUL (ctx,Xi);
660                         else {
661                                 ctx->res = n;
662                                 return;
663                         }
664                 }
665
666 #if defined(STRICT_ALIGNMENT)
667                 if (((size_t)in|(size_t)out)%sizeof(size_t) != 0)
668                         break;
669 #endif
670                 while (len>=16) {
671                         ++ctr;
672                         if (is_endian.little)
673                                 PUTU32(ctx->Yi.c+12,ctr);
674                         else
675                                 ctx->Yi.d[3] = ctr;
676                         (*ctx->block)(ctx->Yi.c,ctx->EKi.c,ctx->key);
677                         for (i=0; i<16; i+=sizeof(size_t)) {
678                                 size_t c = *(size_t *)(in+i);
679                                 *(size_t *)(out+i) = c^*(size_t *)(ctx->EKi.c+i);
680                                 *(size_t *)(ctx->Xi.c+i) ^= c;
681                         }
682                         GCM_MUL (ctx,Xi);
683                         out += 16;
684                         in  += 16;
685                         len -= 16;
686                 }
687
688                 if (len) {
689                         ++ctr;
690                         if (is_endian.little)
691                                 PUTU32(ctx->Yi.c+12,ctr);
692                         else
693                                 ctx->Yi.d[3] = ctr;
694                         (*ctx->block)(ctx->Yi.c,ctx->EKi.c,ctx->key);
695                         while (len--) {
696                                 u8 c = in[n];
697                                 ctx->Xi.c[n] ^= c;
698                                 out[n] = c^ctx->EKi.c[n];
699                                 ++n;
700                         }
701                 }
702
703                 ctx->res = n;
704                 ctx->ctr = ctr;
705                 return;
706         } while(0);
707 #endif
708         for (i=0;i<len;++i) {
709                 u8 c;
710                 if (n==0) {
711                         ++ctr;
712                         if (is_endian.little)
713                                 PUTU32(ctx->Yi.c+12,ctr);
714                         else
715                                 ctx->Yi.d[3] = ctr;
716                         (*ctx->block)(ctx->Yi.c,ctx->EKi.c,ctx->key);
717                 }
718                 c = in[i];
719                 out[i] ^= ctx->EKi.c[n];
720                 ctx->Xi.c[n] ^= c;
721                 n = (n+1)%16;
722                 if (n==0)
723                         GCM_MUL(ctx,Xi);
724         }
725
726         ctx->res = n;
727         ctx->ctr = ctr;
728 }
729
730 void CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx)
731 {
732         const union { long one; char little; } is_endian = {1};
733         u64 alen = ctx->len.u[0]<<3;
734         u64 clen = ctx->len.u[1]<<3;
735
736         if (ctx->res)
737                 GCM_MUL(ctx,Xi);
738
739         if (is_endian.little) {
740 #ifdef BSWAP8
741                 alen = BSWAP8(alen);
742                 clen = BSWAP8(clen);
743 #else
744                 u8 *p = ctx->len.c;
745
746                 ctx->len.u[0] = alen;
747                 ctx->len.u[1] = clen;
748
749                 alen = (u64)GETU32(p)  <<32|GETU32(p+4);
750                 clen = (u64)GETU32(p+8)<<32|GETU32(p+12);
751 #endif
752         }
753
754         ctx->Xi.u[0] ^= alen;
755         ctx->Xi.u[1] ^= clen;
756         GCM_MUL(ctx,Xi);
757
758         ctx->Xi.u[0] ^= ctx->EK0.u[0];
759         ctx->Xi.u[1] ^= ctx->EK0.u[1];
760 }
761
762 #if defined(SELFTEST)
763 #include <stdio.h>
764 #include <openssl/aes.h>
765
766 /* Test Case 1 */
767 static const u8 K1[16],
768                 *P1=NULL,
769                 *A1=NULL,
770                 IV1[12],
771                 *C1=NULL,
772                 T1[]=  {0x58,0xe2,0xfc,0xce,0xfa,0x7e,0x30,0x61,0x36,0x7f,0x1d,0x57,0xa4,0xe7,0x45,0x5a};
773 /* Test Case 2 */
774 #define K2 K1
775 #define A2 A1
776 #define IV2 IV1
777 static const u8 P2[16],
778                 C2[]=  {0x03,0x88,0xda,0xce,0x60,0xb6,0xa3,0x92,0xf3,0x28,0xc2,0xb9,0x71,0xb2,0xfe,0x78},
779                 T2[]=  {0xab,0x6e,0x47,0xd4,0x2c,0xec,0x13,0xbd,0xf5,0x3a,0x67,0xb2,0x12,0x57,0xbd,0xdf};
780
781 /* Test Case 3 */
782 #define A3 A2
783 static const u8 K3[]=  {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08},
784                 P3[]=  {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
785                         0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
786                         0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
787                         0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
788                 IV3[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
789                 C3[]=  {0x42,0x83,0x1e,0xc2,0x21,0x77,0x74,0x24,0x4b,0x72,0x21,0xb7,0x84,0xd0,0xd4,0x9c,
790                         0xe3,0xaa,0x21,0x2f,0x2c,0x02,0xa4,0xe0,0x35,0xc1,0x7e,0x23,0x29,0xac,0xa1,0x2e,
791                         0x21,0xd5,0x14,0xb2,0x54,0x66,0x93,0x1c,0x7d,0x8f,0x6a,0x5a,0xac,0x84,0xaa,0x05,
792                         0x1b,0xa3,0x0b,0x39,0x6a,0x0a,0xac,0x97,0x3d,0x58,0xe0,0x91,0x47,0x3f,0x59,0x85},
793                 T3[]=  {0x4d,0x5c,0x2a,0xf3,0x27,0xcd,0x64,0xa6,0x2c,0xf3,0x5a,0xbd,0x2b,0xa6,0xfa,0xb4,};
794
795 /* Test Case 4 */
796 #define K4 K3
797 #define IV4 IV3
798 static const u8 P4[]=  {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
799                         0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
800                         0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
801                         0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
802                 A4[]=  {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
803                         0xab,0xad,0xda,0xd2},
804                 C4[]=  {0x42,0x83,0x1e,0xc2,0x21,0x77,0x74,0x24,0x4b,0x72,0x21,0xb7,0x84,0xd0,0xd4,0x9c,
805                         0xe3,0xaa,0x21,0x2f,0x2c,0x02,0xa4,0xe0,0x35,0xc1,0x7e,0x23,0x29,0xac,0xa1,0x2e,
806                         0x21,0xd5,0x14,0xb2,0x54,0x66,0x93,0x1c,0x7d,0x8f,0x6a,0x5a,0xac,0x84,0xaa,0x05,
807                         0x1b,0xa3,0x0b,0x39,0x6a,0x0a,0xac,0x97,0x3d,0x58,0xe0,0x91},
808                 T4[]=  {0x5b,0xc9,0x4f,0xbc,0x32,0x21,0xa5,0xdb,0x94,0xfa,0xe9,0x5a,0xe7,0x12,0x1a,0x47};
809
810 /* Test Case 5 */
811 #define K5 K4
812 #define P5 P4
813 static const u8 A5[]=  {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
814                         0xab,0xad,0xda,0xd2},
815                 IV5[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
816                 C5[]=  {0x61,0x35,0x3b,0x4c,0x28,0x06,0x93,0x4a,0x77,0x7f,0xf5,0x1f,0xa2,0x2a,0x47,0x55,
817                         0x69,0x9b,0x2a,0x71,0x4f,0xcd,0xc6,0xf8,0x37,0x66,0xe5,0xf9,0x7b,0x6c,0x74,0x23,
818                         0x73,0x80,0x69,0x00,0xe4,0x9f,0x24,0xb2,0x2b,0x09,0x75,0x44,0xd4,0x89,0x6b,0x42,
819                         0x49,0x89,0xb5,0xe1,0xeb,0xac,0x0f,0x07,0xc2,0x3f,0x45,0x98},
820                 T5[]=  {0x36,0x12,0xd2,0xe7,0x9e,0x3b,0x07,0x85,0x56,0x1b,0xe1,0x4a,0xac,0xa2,0xfc,0xcb};
821 /* Test Case 6 */
822 #define K6 K5
823 #define P6 P5
824 #define A6 A5
825 static const u8 IV6[]= {0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
826                         0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
827                         0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
828                         0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
829                 C6[]=  {0x8c,0xe2,0x49,0x98,0x62,0x56,0x15,0xb6,0x03,0xa0,0x33,0xac,0xa1,0x3f,0xb8,0x94,
830                         0xbe,0x91,0x12,0xa5,0xc3,0xa2,0x11,0xa8,0xba,0x26,0x2a,0x3c,0xca,0x7e,0x2c,0xa7,
831                         0x01,0xe4,0xa9,0xa4,0xfb,0xa4,0x3c,0x90,0xcc,0xdc,0xb2,0x81,0xd4,0x8c,0x7c,0x6f,
832                         0xd6,0x28,0x75,0xd2,0xac,0xa4,0x17,0x03,0x4c,0x34,0xae,0xe5},
833                 T6[]=  {0x61,0x9c,0xc5,0xae,0xff,0xfe,0x0b,0xfa,0x46,0x2a,0xf4,0x3c,0x16,0x99,0xd0,0x50};
834
835 /* Test Case 7 */
836 static const u8 K7[24],
837                 *P7=NULL,
838                 *A7=NULL,
839                 IV7[12],
840                 *C7=NULL,
841                 T7[]=  {0xcd,0x33,0xb2,0x8a,0xc7,0x73,0xf7,0x4b,0xa0,0x0e,0xd1,0xf3,0x12,0x57,0x24,0x35};
842
843 /* Test Case 8 */
844 #define K8 K7
845 #define IV8 IV7
846 #define A8 A7
847 static const u8 P8[16],
848                 C8[]=  {0x98,0xe7,0x24,0x7c,0x07,0xf0,0xfe,0x41,0x1c,0x26,0x7e,0x43,0x84,0xb0,0xf6,0x00},
849                 T8[]=  {0x2f,0xf5,0x8d,0x80,0x03,0x39,0x27,0xab,0x8e,0xf4,0xd4,0x58,0x75,0x14,0xf0,0xfb};
850
851 /* Test Case 9 */
852 #define A9 A8
853 static const u8 K9[]=  {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,
854                         0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c},
855                 P9[]=  {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
856                         0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
857                         0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
858                         0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
859                 IV9[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
860                 C9[]=  {0x39,0x80,0xca,0x0b,0x3c,0x00,0xe8,0x41,0xeb,0x06,0xfa,0xc4,0x87,0x2a,0x27,0x57,
861                         0x85,0x9e,0x1c,0xea,0xa6,0xef,0xd9,0x84,0x62,0x85,0x93,0xb4,0x0c,0xa1,0xe1,0x9c,
862                         0x7d,0x77,0x3d,0x00,0xc1,0x44,0xc5,0x25,0xac,0x61,0x9d,0x18,0xc8,0x4a,0x3f,0x47,
863                         0x18,0xe2,0x44,0x8b,0x2f,0xe3,0x24,0xd9,0xcc,0xda,0x27,0x10,0xac,0xad,0xe2,0x56},
864                 T9[]=  {0x99,0x24,0xa7,0xc8,0x58,0x73,0x36,0xbf,0xb1,0x18,0x02,0x4d,0xb8,0x67,0x4a,0x14};
865
866 /* Test Case 10 */
867 #define K10 K9
868 #define IV10 IV9
869 static const u8 P10[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
870                         0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
871                         0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
872                         0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
873                 A10[]= {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
874                         0xab,0xad,0xda,0xd2},
875                 C10[]= {0x39,0x80,0xca,0x0b,0x3c,0x00,0xe8,0x41,0xeb,0x06,0xfa,0xc4,0x87,0x2a,0x27,0x57,
876                         0x85,0x9e,0x1c,0xea,0xa6,0xef,0xd9,0x84,0x62,0x85,0x93,0xb4,0x0c,0xa1,0xe1,0x9c,
877                         0x7d,0x77,0x3d,0x00,0xc1,0x44,0xc5,0x25,0xac,0x61,0x9d,0x18,0xc8,0x4a,0x3f,0x47,
878                         0x18,0xe2,0x44,0x8b,0x2f,0xe3,0x24,0xd9,0xcc,0xda,0x27,0x10},
879                 T10[]= {0x25,0x19,0x49,0x8e,0x80,0xf1,0x47,0x8f,0x37,0xba,0x55,0xbd,0x6d,0x27,0x61,0x8c};
880
881 /* Test Case 11 */
882 #define K11 K10
883 #define P11 P10
884 #define A11 A10
885 static const u8 IV11[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
886                 C11[]= {0x0f,0x10,0xf5,0x99,0xae,0x14,0xa1,0x54,0xed,0x24,0xb3,0x6e,0x25,0x32,0x4d,0xb8,
887                         0xc5,0x66,0x63,0x2e,0xf2,0xbb,0xb3,0x4f,0x83,0x47,0x28,0x0f,0xc4,0x50,0x70,0x57,
888                         0xfd,0xdc,0x29,0xdf,0x9a,0x47,0x1f,0x75,0xc6,0x65,0x41,0xd4,0xd4,0xda,0xd1,0xc9,
889                         0xe9,0x3a,0x19,0xa5,0x8e,0x8b,0x47,0x3f,0xa0,0xf0,0x62,0xf7},
890                 T11[]= {0x65,0xdc,0xc5,0x7f,0xcf,0x62,0x3a,0x24,0x09,0x4f,0xcc,0xa4,0x0d,0x35,0x33,0xf8};
891
892 /* Test Case 12 */
893 #define K12 K11
894 #define P12 P11
895 #define A12 A11
896 static const u8 IV12[]={0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
897                         0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
898                         0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
899                         0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
900                 C12[]= {0xd2,0x7e,0x88,0x68,0x1c,0xe3,0x24,0x3c,0x48,0x30,0x16,0x5a,0x8f,0xdc,0xf9,0xff,
901                         0x1d,0xe9,0xa1,0xd8,0xe6,0xb4,0x47,0xef,0x6e,0xf7,0xb7,0x98,0x28,0x66,0x6e,0x45,
902                         0x81,0xe7,0x90,0x12,0xaf,0x34,0xdd,0xd9,0xe2,0xf0,0x37,0x58,0x9b,0x29,0x2d,0xb3,
903                         0xe6,0x7c,0x03,0x67,0x45,0xfa,0x22,0xe7,0xe9,0xb7,0x37,0x3b},
904                 T12[]= {0xdc,0xf5,0x66,0xff,0x29,0x1c,0x25,0xbb,0xb8,0x56,0x8f,0xc3,0xd3,0x76,0xa6,0xd9};
905
906 /* Test Case 13 */
907 static const u8 K13[32],
908                 *P13=NULL,
909                 *A13=NULL,
910                 IV13[12],
911                 *C13=NULL,
912                 T13[]={0x53,0x0f,0x8a,0xfb,0xc7,0x45,0x36,0xb9,0xa9,0x63,0xb4,0xf1,0xc4,0xcb,0x73,0x8b};
913
914 /* Test Case 14 */
915 #define K14 K13
916 #define A14 A13
917 static const u8 P14[16],
918                 IV14[12],
919                 C14[]= {0xce,0xa7,0x40,0x3d,0x4d,0x60,0x6b,0x6e,0x07,0x4e,0xc5,0xd3,0xba,0xf3,0x9d,0x18},
920                 T14[]= {0xd0,0xd1,0xc8,0xa7,0x99,0x99,0x6b,0xf0,0x26,0x5b,0x98,0xb5,0xd4,0x8a,0xb9,0x19};
921
922 /* Test Case 15 */
923 #define A15 A14
924 static const u8 K15[]= {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,
925                         0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08},
926                 P15[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
927                         0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
928                         0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
929                         0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
930                 IV15[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
931                 C15[]= {0x52,0x2d,0xc1,0xf0,0x99,0x56,0x7d,0x07,0xf4,0x7f,0x37,0xa3,0x2a,0x84,0x42,0x7d,
932                         0x64,0x3a,0x8c,0xdc,0xbf,0xe5,0xc0,0xc9,0x75,0x98,0xa2,0xbd,0x25,0x55,0xd1,0xaa,
933                         0x8c,0xb0,0x8e,0x48,0x59,0x0d,0xbb,0x3d,0xa7,0xb0,0x8b,0x10,0x56,0x82,0x88,0x38,
934                         0xc5,0xf6,0x1e,0x63,0x93,0xba,0x7a,0x0a,0xbc,0xc9,0xf6,0x62,0x89,0x80,0x15,0xad},
935                 T15[]= {0xb0,0x94,0xda,0xc5,0xd9,0x34,0x71,0xbd,0xec,0x1a,0x50,0x22,0x70,0xe3,0xcc,0x6c};
936
937 /* Test Case 16 */
938 #define K16 K15
939 #define IV16 IV15
940 static const u8 P16[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
941                         0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
942                         0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
943                         0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
944                 A16[]= {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
945                         0xab,0xad,0xda,0xd2},
946                 C16[]= {0x52,0x2d,0xc1,0xf0,0x99,0x56,0x7d,0x07,0xf4,0x7f,0x37,0xa3,0x2a,0x84,0x42,0x7d,
947                         0x64,0x3a,0x8c,0xdc,0xbf,0xe5,0xc0,0xc9,0x75,0x98,0xa2,0xbd,0x25,0x55,0xd1,0xaa,
948                         0x8c,0xb0,0x8e,0x48,0x59,0x0d,0xbb,0x3d,0xa7,0xb0,0x8b,0x10,0x56,0x82,0x88,0x38,
949                         0xc5,0xf6,0x1e,0x63,0x93,0xba,0x7a,0x0a,0xbc,0xc9,0xf6,0x62},
950                 T16[]= {0x76,0xfc,0x6e,0xce,0x0f,0x4e,0x17,0x68,0xcd,0xdf,0x88,0x53,0xbb,0x2d,0x55,0x1b};
951
952 /* Test Case 17 */
953 #define K17 K16
954 #define P17 P16
955 #define A17 A16
956 static const u8 IV17[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
957                 C17[]= {0xc3,0x76,0x2d,0xf1,0xca,0x78,0x7d,0x32,0xae,0x47,0xc1,0x3b,0xf1,0x98,0x44,0xcb,
958                         0xaf,0x1a,0xe1,0x4d,0x0b,0x97,0x6a,0xfa,0xc5,0x2f,0xf7,0xd7,0x9b,0xba,0x9d,0xe0,
959                         0xfe,0xb5,0x82,0xd3,0x39,0x34,0xa4,0xf0,0x95,0x4c,0xc2,0x36,0x3b,0xc7,0x3f,0x78,
960                         0x62,0xac,0x43,0x0e,0x64,0xab,0xe4,0x99,0xf4,0x7c,0x9b,0x1f},
961                 T17[]= {0x3a,0x33,0x7d,0xbf,0x46,0xa7,0x92,0xc4,0x5e,0x45,0x49,0x13,0xfe,0x2e,0xa8,0xf2};
962
963 /* Test Case 18 */
964 #define K18 K17
965 #define P18 P17
966 #define A18 A17
967 static const u8 IV18[]={0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
968                         0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
969                         0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
970                         0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
971                 C18[]= {0x5a,0x8d,0xef,0x2f,0x0c,0x9e,0x53,0xf1,0xf7,0x5d,0x78,0x53,0x65,0x9e,0x2a,0x20,
972                         0xee,0xb2,0xb2,0x2a,0xaf,0xde,0x64,0x19,0xa0,0x58,0xab,0x4f,0x6f,0x74,0x6b,0xf4,
973                         0x0f,0xc0,0xc3,0xb7,0x80,0xf2,0x44,0x45,0x2d,0xa3,0xeb,0xf1,0xc5,0xd8,0x2c,0xde,
974                         0xa2,0x41,0x89,0x97,0x20,0x0e,0xf8,0x2e,0x44,0xae,0x7e,0x3f},
975                 T18[]= {0xa4,0x4a,0x82,0x66,0xee,0x1c,0x8e,0xb0,0xc8,0xb5,0xd4,0xcf,0x5a,0xe9,0xf1,0x9a};
976
977 #define TEST_CASE(n)    do {                                    \
978         u8 out[sizeof(P##n)];                                   \
979         AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key);          \
980         CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt);  \
981         CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));          \
982         if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));    \
983         if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out));     \
984         CRYPTO_gcm128_finish(&ctx);                             \
985         if (memcmp(ctx.Xi.c,T##n,16) || (C##n && memcmp(out,C##n,sizeof(out)))) \
986                 ret++, printf ("encrypt test#%d failed.\n",##n);\
987         CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));          \
988         if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));    \
989         if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out));     \
990         CRYPTO_gcm128_finish(&ctx);                             \
991         if (memcmp(ctx.Xi.c,T##n,16) || (P##n && memcmp(out,P##n,sizeof(out)))) \
992                 ret++, printf ("decrypt test#%d failed.\n",##n);\
993         } while(0)
994
995 int main()
996 {
997         GCM128_CONTEXT ctx;
998         AES_KEY key;
999         int ret=0;
1000
1001         TEST_CASE(1);
1002         TEST_CASE(2);
1003         TEST_CASE(3);
1004         TEST_CASE(4);
1005         TEST_CASE(5);
1006         TEST_CASE(6);
1007         TEST_CASE(7);
1008         TEST_CASE(8);
1009         TEST_CASE(9);
1010         TEST_CASE(10);
1011         TEST_CASE(11);
1012         TEST_CASE(12);
1013         TEST_CASE(13);
1014         TEST_CASE(14);
1015         TEST_CASE(15);
1016         TEST_CASE(16);
1017         TEST_CASE(17);
1018         TEST_CASE(18);
1019
1020         return ret;
1021 }
1022 #endif