blob: ba42fd0640759f96aef4cf1727f508092e9f2575 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
4 * Copyright (C) 2006-2012, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
27 */
28#include "polarssl/config.h"
29
30#if defined(POLARSSL_GCM_C)
31
32#include "polarssl/gcm.h"
33
34/*
35 * 32-bit integer manipulation macros (big endian)
36 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000037#ifndef GET_UINT32_BE
38#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000039{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000040 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
41 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
42 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
43 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000044}
45#endif
46
Paul Bakker5c2364c2012-10-01 14:41:15 +000047#ifndef PUT_UINT32_BE
48#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000049{ \
50 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
51 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
52 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
53 (b)[(i) + 3] = (unsigned char) ( (n) ); \
54}
55#endif
56
57static void gcm_gen_table( gcm_context *ctx )
58{
59 int i, j;
60 uint64_t hi, lo;
61 uint64_t vl, vh;
62 unsigned char h[16];
63
64 memset( h, 0, 16 );
65 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, h, h );
66
67 ctx->HH[0] = 0;
68 ctx->HL[0] = 0;
69
Paul Bakker5c2364c2012-10-01 14:41:15 +000070 GET_UINT32_BE( hi, h, 0 );
71 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000072 vh = (uint64_t) hi << 32 | lo;
73
Paul Bakker5c2364c2012-10-01 14:41:15 +000074 GET_UINT32_BE( hi, h, 8 );
75 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000076 vl = (uint64_t) hi << 32 | lo;
77
78 ctx->HL[8] = vl;
79 ctx->HH[8] = vh;
80
81 for( i = 4; i > 0; i >>= 1 )
82 {
Paul Bakkerf42e5cc2013-04-12 13:21:29 +020083 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +000084 vl = ( vh << 63 ) | ( vl >> 1 );
85 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
86
87 ctx->HL[i] = vl;
88 ctx->HH[i] = vh;
89 }
90
91 for (i = 2; i < 16; i <<= 1 )
92 {
93 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
94 vh = *HiH;
95 vl = *HiL;
96 for( j = 1; j < i; j++ )
97 {
98 HiH[j] = vh ^ ctx->HH[j];
99 HiL[j] = vl ^ ctx->HL[j];
100 }
101 }
102
103}
104
105int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize )
106{
107 int ret;
108
109 memset( ctx, 0, sizeof(gcm_context) );
110
111 if( ( ret = aes_setkey_enc( &ctx->aes_ctx, key, keysize ) ) != 0 )
112 return( ret );
113
114 gcm_gen_table( ctx );
115
116 return( 0 );
117}
118
119static const uint64_t last4[16] =
120{
121 0x0000, 0x1c20, 0x3840, 0x2460,
122 0x7080, 0x6ca0, 0x48c0, 0x54e0,
123 0xe100, 0xfd20, 0xd940, 0xc560,
124 0x9180, 0x8da0, 0xa9c0, 0xb5e0
125};
126
127void gcm_mult( gcm_context *ctx, const unsigned char x[16], unsigned char output[16] )
128{
129 int i = 0;
130 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000131 unsigned char lo, hi, rem;
132 uint64_t zh, zl;
133
134 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000135
136 lo = x[15] & 0xf;
137 hi = x[15] >> 4;
138
139 zh = ctx->HH[lo];
140 zl = ctx->HL[lo];
141
142 for( i = 15; i >= 0; i-- )
143 {
144 lo = x[i] & 0xf;
145 hi = x[i] >> 4;
146
147 if( i != 15 )
148 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000149 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000150 zl = ( zh << 60 ) | ( zl >> 4 );
151 zh = ( zh >> 4 );
152 zh ^= (uint64_t) last4[rem] << 48;
153 zh ^= ctx->HH[lo];
154 zl ^= ctx->HL[lo];
155
156 }
157
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000158 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000159 zl = ( zh << 60 ) | ( zl >> 4 );
160 zh = ( zh >> 4 );
161 zh ^= (uint64_t) last4[rem] << 48;
162 zh ^= ctx->HH[hi];
163 zl ^= ctx->HL[hi];
164 }
165
Paul Bakker5c2364c2012-10-01 14:41:15 +0000166 PUT_UINT32_BE( zh >> 32, output, 0 );
167 PUT_UINT32_BE( zh, output, 4 );
168 PUT_UINT32_BE( zl >> 32, output, 8 );
169 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000170}
171
172int gcm_crypt_and_tag( gcm_context *ctx,
173 int mode,
174 size_t length,
175 const unsigned char *iv,
176 size_t iv_len,
177 const unsigned char *add,
178 size_t add_len,
179 const unsigned char *input,
180 unsigned char *output,
181 size_t tag_len,
182 unsigned char *tag )
183{
Paul Bakker89e80c92012-03-20 13:50:09 +0000184 unsigned char y[16];
185 unsigned char ectr[16];
186 unsigned char buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000187 unsigned char work_buf[16];
188 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000189 const unsigned char *p;
190 unsigned char *out_p = output;
191 size_t use_len;
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200192 uint64_t orig_len = length * 8;
193 uint64_t orig_add_len = add_len * 8;
Paul Bakker89e80c92012-03-20 13:50:09 +0000194
Paul Bakker89e80c92012-03-20 13:50:09 +0000195 memset( y, 0x00, 16 );
196 memset( work_buf, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000197 memset( tag, 0x00, tag_len );
198 memset( buf, 0x00, 16 );
199
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000200 if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
201 ( output > input && (size_t) ( output - input ) < length ) )
202 {
203 return( POLARSSL_ERR_GCM_BAD_INPUT );
204 }
205
Paul Bakker89e80c92012-03-20 13:50:09 +0000206 if( iv_len == 12 )
207 {
208 memcpy( y, iv, iv_len );
209 y[15] = 1;
210 }
211 else
212 {
213 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000215
216 p = iv;
217 while( iv_len > 0 )
218 {
219 use_len = ( iv_len < 16 ) ? iv_len : 16;
220
Paul Bakker67f9d532012-10-23 11:49:05 +0000221 for( i = 0; i < use_len; i++ )
222 y[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000223
224 gcm_mult( ctx, y, y );
225
226 iv_len -= use_len;
227 p += use_len;
228 }
229
Paul Bakker67f9d532012-10-23 11:49:05 +0000230 for( i = 0; i < 16; i++ )
231 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000232
233 gcm_mult( ctx, y, y );
234 }
235
236 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
237 memcpy( tag, ectr, tag_len );
238
239 p = add;
240 while( add_len > 0 )
241 {
242 use_len = ( add_len < 16 ) ? add_len : 16;
243
Paul Bakker67f9d532012-10-23 11:49:05 +0000244 for( i = 0; i < use_len; i++ )
245 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000246
247 gcm_mult( ctx, buf, buf );
248
249 add_len -= use_len;
250 p += use_len;
251 }
252
253 p = input;
254 while( length > 0 )
255 {
256 use_len = ( length < 16 ) ? length : 16;
257
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100258 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000259 if( ++y[i - 1] != 0 )
260 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000261
262 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
263
Paul Bakker67f9d532012-10-23 11:49:05 +0000264 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000265 {
Paul Bakker67f9d532012-10-23 11:49:05 +0000266 out_p[i] = ectr[i] ^ p[i];
Paul Bakkereae09db2013-06-06 12:35:54 +0200267 if( mode == GCM_ENCRYPT )
268 buf[i] ^= out_p[i];
269 else
270 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000271 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000272
273 gcm_mult( ctx, buf, buf );
274
275 length -= use_len;
276 p += use_len;
277 out_p += use_len;
278 }
279
280 if( orig_len || orig_add_len )
281 {
282 memset( work_buf, 0x00, 16 );
283
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200284 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
285 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
286 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
287 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000288
Paul Bakker67f9d532012-10-23 11:49:05 +0000289 for( i = 0; i < 16; i++ )
290 buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000291
292 gcm_mult( ctx, buf, buf );
293
Paul Bakker67f9d532012-10-23 11:49:05 +0000294 for( i = 0; i < tag_len; i++ )
295 tag[i] ^= buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000296 }
297
298 return( 0 );
299}
300
301int gcm_auth_decrypt( gcm_context *ctx,
302 size_t length,
303 const unsigned char *iv,
304 size_t iv_len,
305 const unsigned char *add,
306 size_t add_len,
307 const unsigned char *tag,
308 size_t tag_len,
309 const unsigned char *input,
310 unsigned char *output )
311{
Manuel Pégourié-Gonnardb55f5782014-01-18 18:49:32 +0100312 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000313 unsigned char check_tag[16];
314
Manuel Pégourié-Gonnardb55f5782014-01-18 18:49:32 +0100315 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
316 iv, iv_len, add, add_len,
317 input, output, tag_len, check_tag ) ) != 0 )
318 {
319 return( ret );
320 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000321
322 if( memcmp( check_tag, tag, tag_len ) == 0 )
323 return( 0 );
324
325 memset( output, 0, length );
326
327 return( POLARSSL_ERR_GCM_AUTH_FAILED );
328}
329
330#if defined(POLARSSL_SELF_TEST)
331
332#include <stdio.h>
333
334/*
335 * GCM test vectors from:
336 *
337 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
338 */
339#define MAX_TESTS 6
340
341int key_index[MAX_TESTS] =
342 { 0, 0, 1, 1, 1, 1 };
343
344unsigned char key[MAX_TESTS][32] =
345{
346 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
350 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
351 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
352 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
353 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
354};
355
356size_t iv_len[MAX_TESTS] =
357 { 12, 12, 12, 12, 8, 60 };
358
359int iv_index[MAX_TESTS] =
360 { 0, 0, 1, 1, 1, 2 };
361
362unsigned char iv[MAX_TESTS][64] =
363{
364 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00 },
366 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
367 0xde, 0xca, 0xf8, 0x88 },
368 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
369 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
370 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
371 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
372 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
373 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
374 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
375 0xa6, 0x37, 0xb3, 0x9b },
376};
377
378size_t add_len[MAX_TESTS] =
379 { 0, 0, 0, 20, 20, 20 };
380
381int add_index[MAX_TESTS] =
382 { 0, 0, 0, 1, 1, 1 };
383
384unsigned char additional[MAX_TESTS][64] =
385{
386 { 0x00 },
387 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
388 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
389 0xab, 0xad, 0xda, 0xd2 },
390};
391
392size_t pt_len[MAX_TESTS] =
393 { 0, 16, 64, 60, 60, 60 };
394
395int pt_index[MAX_TESTS] =
396 { 0, 0, 1, 1, 1, 1 };
397
398unsigned char pt[MAX_TESTS][64] =
399{
400 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
402 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
403 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
404 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
405 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
406 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
407 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
408 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
409 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
410};
411
412unsigned char ct[MAX_TESTS * 3][64] =
413{
414 { 0x00 },
415 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
416 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
417 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
418 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
419 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
420 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
421 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
422 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
423 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
424 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
425 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
426 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
427 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
428 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
429 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
430 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
431 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
432 0x3d, 0x58, 0xe0, 0x91 },
433 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
434 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
435 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
436 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
437 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
438 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
439 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
440 0xc2, 0x3f, 0x45, 0x98 },
441 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
442 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
443 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
444 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
445 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
446 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
447 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
448 0x4c, 0x34, 0xae, 0xe5 },
449 { 0x00 },
450 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
451 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
452 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
453 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
454 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
455 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
456 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
457 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
458 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
459 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
460 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
461 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
462 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
463 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
464 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
465 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
466 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
467 0xcc, 0xda, 0x27, 0x10 },
468 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
469 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
470 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
471 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
472 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
473 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
474 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
475 0xa0, 0xf0, 0x62, 0xf7 },
476 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
477 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
478 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
479 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
480 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
481 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
482 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
483 0xe9, 0xb7, 0x37, 0x3b },
484 { 0x00 },
485 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
486 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
487 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
488 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
489 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
490 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
491 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
492 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
493 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
494 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
495 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
496 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
497 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
498 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
499 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
500 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
501 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
502 0xbc, 0xc9, 0xf6, 0x62 },
503 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
504 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
505 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
506 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
507 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
508 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
509 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
510 0xf4, 0x7c, 0x9b, 0x1f },
511 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
512 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
513 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
514 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
515 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
516 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
517 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
518 0x44, 0xae, 0x7e, 0x3f },
519};
520
521unsigned char tag[MAX_TESTS * 3][16] =
522{
523 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
524 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
525 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
526 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
527 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
528 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
529 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
530 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
531 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
532 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
533 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
534 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
535 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
536 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
537 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
538 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
539 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
540 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
541 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
542 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
543 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
544 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
545 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
546 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
547 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
548 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
549 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
550 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
551 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
552 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
553 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
554 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
555 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
556 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
557 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
558 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
559};
560
561int gcm_self_test( int verbose )
562{
563 gcm_context ctx;
564 unsigned char buf[64];
565 unsigned char tag_buf[16];
566 int i, j, ret;
567
568 for( j = 0; j < 3; j++ )
569 {
570 int key_len = 128 + 64 * j;
571
572 for( i = 0; i < MAX_TESTS; i++ )
573 {
574 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
575 gcm_init( &ctx, key[key_index[i]], key_len );
576
577 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
578 pt_len[i],
579 iv[iv_index[i]], iv_len[i],
580 additional[add_index[i]], add_len[i],
581 pt[pt_index[i]], buf, 16, tag_buf );
582
583 if( ret != 0 ||
584 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
585 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
586 {
587 if( verbose != 0 )
588 printf( "failed\n" );
589
590 return( 1 );
591 }
592
593 if( verbose != 0 )
594 printf( "passed\n" );
595
596 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
597 gcm_init( &ctx, key[key_index[i]], key_len );
598
599 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
600 pt_len[i],
601 iv[iv_index[i]], iv_len[i],
602 additional[add_index[i]], add_len[i],
603 ct[j * 6 + i], buf, 16, tag_buf );
604
605 if( ret != 0 ||
606 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
607 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
608 {
609 if( verbose != 0 )
610 printf( "failed\n" );
611
612 return( 1 );
613 }
614
615 if( verbose != 0 )
616 printf( "passed\n" );
617 }
618 }
619
620 printf( "\n" );
621
622 return( 0 );
623}
624
625#endif
626
627#endif