blob: 7fd9ad922d85b81fee14f0f1738773632df979d7 [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];
Paul Bakker169b7f42013-06-25 14:58:00 +020063
Paul Bakker89e80c92012-03-20 13:50:09 +000064 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;
Paul Bakker169b7f42013-06-25 14:58:00 +020077
Paul Bakker89e80c92012-03-20 13:50:09 +000078 ctx->HL[8] = vl;
79 ctx->HH[8] = vh;
80
81 for( i = 4; i > 0; i >>= 1 )
82 {
Paul Bakker0ecdb232013-04-09 11:36:42 +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 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000102}
103
104int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize )
105{
106 int ret;
107
108 memset( ctx, 0, sizeof(gcm_context) );
109
110 if( ( ret = aes_setkey_enc( &ctx->aes_ctx, key, keysize ) ) != 0 )
111 return( ret );
112
113 gcm_gen_table( ctx );
114
115 return( 0 );
116}
117
118static const uint64_t last4[16] =
119{
120 0x0000, 0x1c20, 0x3840, 0x2460,
121 0x7080, 0x6ca0, 0x48c0, 0x54e0,
122 0xe100, 0xfd20, 0xd940, 0xc560,
123 0x9180, 0x8da0, 0xa9c0, 0xb5e0
124};
125
126void gcm_mult( gcm_context *ctx, const unsigned char x[16], unsigned char output[16] )
127{
128 int i = 0;
129 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000130 unsigned char lo, hi, rem;
131 uint64_t zh, zl;
132
133 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000134
135 lo = x[15] & 0xf;
136 hi = x[15] >> 4;
137
138 zh = ctx->HH[lo];
139 zl = ctx->HL[lo];
140
141 for( i = 15; i >= 0; i-- )
142 {
143 lo = x[i] & 0xf;
144 hi = x[i] >> 4;
145
146 if( i != 15 )
147 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000148 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000149 zl = ( zh << 60 ) | ( zl >> 4 );
150 zh = ( zh >> 4 );
151 zh ^= (uint64_t) last4[rem] << 48;
152 zh ^= ctx->HH[lo];
153 zl ^= ctx->HL[lo];
154
155 }
156
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000157 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000158 zl = ( zh << 60 ) | ( zl >> 4 );
159 zh = ( zh >> 4 );
160 zh ^= (uint64_t) last4[rem] << 48;
161 zh ^= ctx->HH[hi];
162 zl ^= ctx->HL[hi];
163 }
164
Paul Bakker5c2364c2012-10-01 14:41:15 +0000165 PUT_UINT32_BE( zh >> 32, output, 0 );
166 PUT_UINT32_BE( zh, output, 4 );
167 PUT_UINT32_BE( zl >> 32, output, 8 );
168 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000169}
170
171int gcm_crypt_and_tag( gcm_context *ctx,
172 int mode,
173 size_t length,
174 const unsigned char *iv,
175 size_t iv_len,
176 const unsigned char *add,
177 size_t add_len,
178 const unsigned char *input,
179 unsigned char *output,
180 size_t tag_len,
181 unsigned char *tag )
182{
Paul Bakker89e80c92012-03-20 13:50:09 +0000183 unsigned char y[16];
184 unsigned char ectr[16];
185 unsigned char buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000186 unsigned char work_buf[16];
187 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000188 const unsigned char *p;
189 unsigned char *out_p = output;
190 size_t use_len;
Paul Bakker0ecdb232013-04-09 11:36:42 +0200191 uint64_t orig_len = length * 8;
192 uint64_t orig_add_len = add_len * 8;
Paul Bakker89e80c92012-03-20 13:50:09 +0000193
Paul Bakker89e80c92012-03-20 13:50:09 +0000194 memset( y, 0x00, 16 );
195 memset( work_buf, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000196 memset( tag, 0x00, tag_len );
197 memset( buf, 0x00, 16 );
198
Paul Bakker09d67252013-01-04 16:38:25 +0100199 if( output > input && (size_t) ( output - input ) < length )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000200 return( POLARSSL_ERR_GCM_BAD_INPUT );
Paul Bakker89e80c92012-03-20 13:50:09 +0000201
202 if( iv_len == 12 )
203 {
204 memcpy( y, iv, iv_len );
205 y[15] = 1;
206 }
207 else
208 {
209 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000210 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000211
212 p = iv;
213 while( iv_len > 0 )
214 {
215 use_len = ( iv_len < 16 ) ? iv_len : 16;
216
Paul Bakker67f9d532012-10-23 11:49:05 +0000217 for( i = 0; i < use_len; i++ )
218 y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200219
Paul Bakker89e80c92012-03-20 13:50:09 +0000220 gcm_mult( ctx, y, y );
221
222 iv_len -= use_len;
223 p += use_len;
224 }
225
Paul Bakker67f9d532012-10-23 11:49:05 +0000226 for( i = 0; i < 16; i++ )
227 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000228
229 gcm_mult( ctx, y, y );
230 }
231
232 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
233 memcpy( tag, ectr, tag_len );
234
235 p = add;
236 while( add_len > 0 )
237 {
238 use_len = ( add_len < 16 ) ? add_len : 16;
239
Paul Bakker67f9d532012-10-23 11:49:05 +0000240 for( i = 0; i < use_len; i++ )
241 buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200242
Paul Bakker89e80c92012-03-20 13:50:09 +0000243 gcm_mult( ctx, buf, buf );
244
245 add_len -= use_len;
246 p += use_len;
247 }
248
249 p = input;
250 while( length > 0 )
251 {
252 use_len = ( length < 16 ) ? length : 16;
253
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100254 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000255 if( ++y[i - 1] != 0 )
256 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000257
258 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
259
Paul Bakker67f9d532012-10-23 11:49:05 +0000260 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000261 {
Paul Bakker09d67252013-01-04 16:38:25 +0100262 if( mode == GCM_DECRYPT )
263 buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000264 out_p[i] = ectr[i] ^ p[i];
Paul Bakker09d67252013-01-04 16:38:25 +0100265 if( mode == GCM_ENCRYPT )
266 buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000267 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200268
Paul Bakker89e80c92012-03-20 13:50:09 +0000269 gcm_mult( ctx, buf, buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200270
Paul Bakker89e80c92012-03-20 13:50:09 +0000271 length -= use_len;
272 p += use_len;
273 out_p += use_len;
274 }
275
276 if( orig_len || orig_add_len )
277 {
278 memset( work_buf, 0x00, 16 );
279
Paul Bakker0ecdb232013-04-09 11:36:42 +0200280 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
281 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
282 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
283 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000284
Paul Bakker67f9d532012-10-23 11:49:05 +0000285 for( i = 0; i < 16; i++ )
286 buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000287
288 gcm_mult( ctx, buf, buf );
289
Paul Bakker67f9d532012-10-23 11:49:05 +0000290 for( i = 0; i < tag_len; i++ )
291 tag[i] ^= buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000292 }
293
294 return( 0 );
295}
296
297int gcm_auth_decrypt( gcm_context *ctx,
298 size_t length,
299 const unsigned char *iv,
300 size_t iv_len,
301 const unsigned char *add,
302 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200303 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000304 size_t tag_len,
305 const unsigned char *input,
306 unsigned char *output )
307{
308 unsigned char check_tag[16];
309
310 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
311
312 if( memcmp( check_tag, tag, tag_len ) == 0 )
313 return( 0 );
314
315 memset( output, 0, length );
316
317 return( POLARSSL_ERR_GCM_AUTH_FAILED );
318}
319
320#if defined(POLARSSL_SELF_TEST)
321
322#include <stdio.h>
323
324/*
325 * GCM test vectors from:
326 *
327 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
328 */
329#define MAX_TESTS 6
330
331int key_index[MAX_TESTS] =
332 { 0, 0, 1, 1, 1, 1 };
333
334unsigned char key[MAX_TESTS][32] =
335{
336 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
341 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
342 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200343 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000344};
345
346size_t iv_len[MAX_TESTS] =
347 { 12, 12, 12, 12, 8, 60 };
348
349int iv_index[MAX_TESTS] =
350 { 0, 0, 1, 1, 1, 2 };
351
352unsigned char iv[MAX_TESTS][64] =
353{
354 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00 },
356 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
357 0xde, 0xca, 0xf8, 0x88 },
358 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200359 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000360 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200361 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000362 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200363 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000364 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200365 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000366};
367
368size_t add_len[MAX_TESTS] =
369 { 0, 0, 0, 20, 20, 20 };
370
371int add_index[MAX_TESTS] =
372 { 0, 0, 0, 1, 1, 1 };
373
374unsigned char additional[MAX_TESTS][64] =
375{
376 { 0x00 },
377 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200378 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000379 0xab, 0xad, 0xda, 0xd2 },
380};
381
382size_t pt_len[MAX_TESTS] =
383 { 0, 16, 64, 60, 60, 60 };
384
385int pt_index[MAX_TESTS] =
386 { 0, 0, 1, 1, 1, 1 };
387
388unsigned char pt[MAX_TESTS][64] =
389{
390 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
392 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
393 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
394 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
395 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
396 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
397 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
398 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
399 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
400};
401
402unsigned char ct[MAX_TESTS * 3][64] =
403{
404 { 0x00 },
405 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
406 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
407 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200408 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000409 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200410 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000411 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200412 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000413 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
414 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
415 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200416 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000417 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200418 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000419 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200420 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000421 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
422 0x3d, 0x58, 0xe0, 0x91 },
423 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200424 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000425 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200426 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000427 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200428 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000429 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
430 0xc2, 0x3f, 0x45, 0x98 },
431 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200432 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000433 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200434 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000435 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200436 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000437 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
438 0x4c, 0x34, 0xae, 0xe5 },
439 { 0x00 },
440 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200441 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000442 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200443 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000444 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200445 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000446 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200447 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000448 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
449 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
450 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200451 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000452 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200453 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
454 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
455 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000456 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200457 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000458 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200459 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000460 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200461 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000462 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200463 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000464 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200465 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000466 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200467 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000468 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200469 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000470 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200471 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000472 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200473 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000474 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200475 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
476 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
477 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
478 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
479 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
480 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
481 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
482 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
483 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
484 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
485 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
486 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
487 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
488 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
489 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
490 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
491 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
492 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000493 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200494 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000495 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200496 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000497 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200498 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000499 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200500 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000501 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200502 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000503 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200504 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000505 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200506 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000507 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200508 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000509};
510
511unsigned char tag[MAX_TESTS * 3][16] =
512{
513 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
514 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
515 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
516 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
517 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200518 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000519 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
520 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
521 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
522 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
523 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
524 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
525 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
526 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
527 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200528 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000529 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
530 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
531 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200532 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000533 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200534 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000535 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200536 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000537 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200538 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000539 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200540 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000541 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200542 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000543 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200544 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000545 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200546 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000547 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200548 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000549};
550
551int gcm_self_test( int verbose )
552{
553 gcm_context ctx;
554 unsigned char buf[64];
555 unsigned char tag_buf[16];
556 int i, j, ret;
557
558 for( j = 0; j < 3; j++ )
559 {
560 int key_len = 128 + 64 * j;
561
562 for( i = 0; i < MAX_TESTS; i++ )
563 {
564 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
565 gcm_init( &ctx, key[key_index[i]], key_len );
566
567 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
568 pt_len[i],
569 iv[iv_index[i]], iv_len[i],
570 additional[add_index[i]], add_len[i],
571 pt[pt_index[i]], buf, 16, tag_buf );
572
573 if( ret != 0 ||
574 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
575 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
576 {
577 if( verbose != 0 )
578 printf( "failed\n" );
579
580 return( 1 );
581 }
582
583 if( verbose != 0 )
584 printf( "passed\n" );
585
586 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
587 gcm_init( &ctx, key[key_index[i]], key_len );
588
589 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
590 pt_len[i],
591 iv[iv_index[i]], iv_len[i],
592 additional[add_index[i]], add_len[i],
593 ct[j * 6 + i], buf, 16, tag_buf );
594
595 if( ret != 0 ||
596 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
597 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
598 {
599 if( verbose != 0 )
600 printf( "failed\n" );
601
602 return( 1 );
603 }
604
605 if( verbose != 0 )
606 printf( "passed\n" );
607 }
608 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200609
Paul Bakker89e80c92012-03-20 13:50:09 +0000610 printf( "\n" );
611
612 return( 0 );
613}
614
615#endif
616
617#endif