]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/modes/gcm128.c
RSA PSS verification support including certificates and certificate
[thirdparty/openssl.git] / crypto / modes / gcm128.c
CommitLineData
e7f5b1cd
AP
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__)
61typedef __int64 i64;
62typedef unsigned __int64 u64;
63#define U64(C) C##UI64
64#elif defined(__arch64__)
65typedef long i64;
66typedef unsigned long u64;
67#define U64(C) C##UL
68#else
69typedef long long i64;
70typedef unsigned long long u64;
71#define U64(C) C##ULL
72#endif
73
74typedef unsigned int u32;
75typedef unsigned char u8;
76typedef 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
123static 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
156static 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
265static 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
298static 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
360static 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
433typedef 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
445void 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
473void 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
533void 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
552void 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
637void 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
730void 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 */
767static 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
777static 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
783static 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
798static 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
813static 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
825static 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 */
836static 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
847static 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
853static 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
869static 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
885static 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
896static 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 */
907static 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
917static 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
924static 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
940static 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
956static 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
967static 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
995int 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