blob: 7d79f1a154fce2f9df45f9210ee4e02d83a0fa24 [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 {
83 uint32_t T = ( vl & 1 ) ? 0xe1000000U : 0;
84 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];
131 unsigned char v[16];
132 unsigned char lo, hi, rem;
133 uint64_t zh, zl;
134
135 memset( z, 0x00, 16 );
136 memcpy( v, x, 16 );
137
138 lo = x[15] & 0xf;
139 hi = x[15] >> 4;
140
141 zh = ctx->HH[lo];
142 zl = ctx->HL[lo];
143
144 for( i = 15; i >= 0; i-- )
145 {
146 lo = x[i] & 0xf;
147 hi = x[i] >> 4;
148
149 if( i != 15 )
150 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000151 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000152 zl = ( zh << 60 ) | ( zl >> 4 );
153 zh = ( zh >> 4 );
154 zh ^= (uint64_t) last4[rem] << 48;
155 zh ^= ctx->HH[lo];
156 zl ^= ctx->HL[lo];
157
158 }
159
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000160 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000161 zl = ( zh << 60 ) | ( zl >> 4 );
162 zh = ( zh >> 4 );
163 zh ^= (uint64_t) last4[rem] << 48;
164 zh ^= ctx->HH[hi];
165 zl ^= ctx->HL[hi];
166 }
167
Paul Bakker5c2364c2012-10-01 14:41:15 +0000168 PUT_UINT32_BE( zh >> 32, output, 0 );
169 PUT_UINT32_BE( zh, output, 4 );
170 PUT_UINT32_BE( zl >> 32, output, 8 );
171 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000172}
173
174int gcm_crypt_and_tag( gcm_context *ctx,
175 int mode,
176 size_t length,
177 const unsigned char *iv,
178 size_t iv_len,
179 const unsigned char *add,
180 size_t add_len,
181 const unsigned char *input,
182 unsigned char *output,
183 size_t tag_len,
184 unsigned char *tag )
185{
Paul Bakker89e80c92012-03-20 13:50:09 +0000186 unsigned char y[16];
187 unsigned char ectr[16];
188 unsigned char buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000189 unsigned char work_buf[16];
190 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000191 const unsigned char *p;
192 unsigned char *out_p = output;
193 size_t use_len;
194 size_t orig_len = length * 8;
195 size_t orig_add_len = add_len * 8;
Paul Bakker89e80c92012-03-20 13:50:09 +0000196
Paul Bakker89e80c92012-03-20 13:50:09 +0000197 memset( y, 0x00, 16 );
198 memset( work_buf, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000199 memset( tag, 0x00, tag_len );
200 memset( buf, 0x00, 16 );
201
Paul Bakker09d67252013-01-04 16:38:25 +0100202 if( output > input && (size_t) ( output - input ) < length )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000203 return( POLARSSL_ERR_GCM_BAD_INPUT );
Paul Bakker89e80c92012-03-20 13:50:09 +0000204
205 if( iv_len == 12 )
206 {
207 memcpy( y, iv, iv_len );
208 y[15] = 1;
209 }
210 else
211 {
212 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000214
215 p = iv;
216 while( iv_len > 0 )
217 {
218 use_len = ( iv_len < 16 ) ? iv_len : 16;
219
Paul Bakker67f9d532012-10-23 11:49:05 +0000220 for( i = 0; i < use_len; i++ )
221 y[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000222
223 gcm_mult( ctx, y, y );
224
225 iv_len -= use_len;
226 p += use_len;
227 }
228
Paul Bakker67f9d532012-10-23 11:49:05 +0000229 for( i = 0; i < 16; i++ )
230 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000231
232 gcm_mult( ctx, y, y );
233 }
234
235 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
236 memcpy( tag, ectr, tag_len );
237
238 p = add;
239 while( add_len > 0 )
240 {
241 use_len = ( add_len < 16 ) ? add_len : 16;
242
Paul Bakker67f9d532012-10-23 11:49:05 +0000243 for( i = 0; i < use_len; i++ )
244 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000245
246 gcm_mult( ctx, buf, buf );
247
248 add_len -= use_len;
249 p += use_len;
250 }
251
252 p = input;
253 while( length > 0 )
254 {
255 use_len = ( length < 16 ) ? length : 16;
256
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100257 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000258 if( ++y[i - 1] != 0 )
259 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000260
261 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
262
Paul Bakker67f9d532012-10-23 11:49:05 +0000263 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000264 {
Paul Bakker09d67252013-01-04 16:38:25 +0100265 if( mode == GCM_DECRYPT )
266 buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000267 out_p[i] = ectr[i] ^ p[i];
Paul Bakker09d67252013-01-04 16:38:25 +0100268 if( mode == GCM_ENCRYPT )
269 buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000270 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000271
272 gcm_mult( ctx, buf, buf );
273
274 length -= use_len;
275 p += use_len;
276 out_p += use_len;
277 }
278
279 if( orig_len || orig_add_len )
280 {
281 memset( work_buf, 0x00, 16 );
282
Paul Bakker5c2364c2012-10-01 14:41:15 +0000283 PUT_UINT32_BE( orig_add_len , work_buf, 4 );
284 PUT_UINT32_BE( orig_len , work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000285
Paul Bakker67f9d532012-10-23 11:49:05 +0000286 for( i = 0; i < 16; i++ )
287 buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000288
289 gcm_mult( ctx, buf, buf );
290
Paul Bakker67f9d532012-10-23 11:49:05 +0000291 for( i = 0; i < tag_len; i++ )
292 tag[i] ^= buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000293 }
294
295 return( 0 );
296}
297
298int gcm_auth_decrypt( gcm_context *ctx,
299 size_t length,
300 const unsigned char *iv,
301 size_t iv_len,
302 const unsigned char *add,
303 size_t add_len,
304 const unsigned char *tag,
305 size_t tag_len,
306 const unsigned char *input,
307 unsigned char *output )
308{
309 unsigned char check_tag[16];
310
311 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
312
313 if( memcmp( check_tag, tag, tag_len ) == 0 )
314 return( 0 );
315
316 memset( output, 0, length );
317
318 return( POLARSSL_ERR_GCM_AUTH_FAILED );
319}
320
321#if defined(POLARSSL_SELF_TEST)
322
323#include <stdio.h>
324
325/*
326 * GCM test vectors from:
327 *
328 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
329 */
330#define MAX_TESTS 6
331
332int key_index[MAX_TESTS] =
333 { 0, 0, 1, 1, 1, 1 };
334
335unsigned char key[MAX_TESTS][32] =
336{
337 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
341 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
342 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
343 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
344 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
345};
346
347size_t iv_len[MAX_TESTS] =
348 { 12, 12, 12, 12, 8, 60 };
349
350int iv_index[MAX_TESTS] =
351 { 0, 0, 1, 1, 1, 2 };
352
353unsigned char iv[MAX_TESTS][64] =
354{
355 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00 },
357 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
358 0xde, 0xca, 0xf8, 0x88 },
359 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
360 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
361 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
362 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
363 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
364 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
365 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
366 0xa6, 0x37, 0xb3, 0x9b },
367};
368
369size_t add_len[MAX_TESTS] =
370 { 0, 0, 0, 20, 20, 20 };
371
372int add_index[MAX_TESTS] =
373 { 0, 0, 0, 1, 1, 1 };
374
375unsigned char additional[MAX_TESTS][64] =
376{
377 { 0x00 },
378 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
379 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
380 0xab, 0xad, 0xda, 0xd2 },
381};
382
383size_t pt_len[MAX_TESTS] =
384 { 0, 16, 64, 60, 60, 60 };
385
386int pt_index[MAX_TESTS] =
387 { 0, 0, 1, 1, 1, 1 };
388
389unsigned char pt[MAX_TESTS][64] =
390{
391 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
393 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
394 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
395 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
396 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
397 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
398 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
399 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
400 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
401};
402
403unsigned char ct[MAX_TESTS * 3][64] =
404{
405 { 0x00 },
406 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
407 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
408 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
409 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
410 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
411 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
412 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
413 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
414 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
415 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
416 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
417 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
418 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
419 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
420 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
421 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
422 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
423 0x3d, 0x58, 0xe0, 0x91 },
424 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
425 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
426 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
427 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
428 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
429 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
430 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
431 0xc2, 0x3f, 0x45, 0x98 },
432 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
433 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
434 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
435 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
436 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
437 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
438 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
439 0x4c, 0x34, 0xae, 0xe5 },
440 { 0x00 },
441 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
442 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
443 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
444 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
445 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
446 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
447 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
448 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
449 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
450 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
451 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
452 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
453 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
454 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
455 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
456 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
457 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
458 0xcc, 0xda, 0x27, 0x10 },
459 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
460 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
461 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
462 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
463 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
464 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
465 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
466 0xa0, 0xf0, 0x62, 0xf7 },
467 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
468 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
469 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
470 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
471 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
472 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
473 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
474 0xe9, 0xb7, 0x37, 0x3b },
475 { 0x00 },
476 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
477 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
478 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
479 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
480 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
481 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
482 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
483 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
484 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
485 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
486 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
487 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
488 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
489 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
490 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
491 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
492 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
493 0xbc, 0xc9, 0xf6, 0x62 },
494 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
495 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
496 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
497 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
498 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
499 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
500 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
501 0xf4, 0x7c, 0x9b, 0x1f },
502 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
503 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
504 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
505 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
506 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
507 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
508 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
509 0x44, 0xae, 0x7e, 0x3f },
510};
511
512unsigned char tag[MAX_TESTS * 3][16] =
513{
514 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
515 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
516 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
517 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
518 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
519 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
520 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
521 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
522 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
523 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
524 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
525 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
526 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
527 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
528 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
529 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
530 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
531 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
532 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
533 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
534 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
535 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
536 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
537 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
538 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
539 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
540 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
541 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
542 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
543 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
544 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
545 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
546 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
547 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
548 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
549 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
550};
551
552int gcm_self_test( int verbose )
553{
554 gcm_context ctx;
555 unsigned char buf[64];
556 unsigned char tag_buf[16];
557 int i, j, ret;
558
559 for( j = 0; j < 3; j++ )
560 {
561 int key_len = 128 + 64 * j;
562
563 for( i = 0; i < MAX_TESTS; i++ )
564 {
565 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
566 gcm_init( &ctx, key[key_index[i]], key_len );
567
568 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
569 pt_len[i],
570 iv[iv_index[i]], iv_len[i],
571 additional[add_index[i]], add_len[i],
572 pt[pt_index[i]], buf, 16, tag_buf );
573
574 if( ret != 0 ||
575 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
576 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
577 {
578 if( verbose != 0 )
579 printf( "failed\n" );
580
581 return( 1 );
582 }
583
584 if( verbose != 0 )
585 printf( "passed\n" );
586
587 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
588 gcm_init( &ctx, key[key_index[i]], key_len );
589
590 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
591 pt_len[i],
592 iv[iv_index[i]], iv_len[i],
593 additional[add_index[i]], add_len[i],
594 ct[j * 6 + i], buf, 16, tag_buf );
595
596 if( ret != 0 ||
597 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
598 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
599 {
600 if( verbose != 0 )
601 printf( "failed\n" );
602
603 return( 1 );
604 }
605
606 if( verbose != 0 )
607 printf( "passed\n" );
608 }
609 }
610
611 printf( "\n" );
612
613 return( 0 );
614}
615
616#endif
617
618#endif