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