blob: f1daaff276a9ffbdcbe68106712885c373f110eb [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakker89e80c92012-03-20 13:50:09 +00005 *
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
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200126static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
127 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000128{
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 Bakker0ecdb232013-04-09 11:36:42 +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 Bakker09d67252013-01-04 16:38:25 +0100200 if( output > input && (size_t) ( output - input ) < length )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000201 return( POLARSSL_ERR_GCM_BAD_INPUT );
Paul Bakker89e80c92012-03-20 13:50:09 +0000202
203 if( iv_len == 12 )
204 {
205 memcpy( y, iv, iv_len );
206 y[15] = 1;
207 }
208 else
209 {
210 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000211 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000212
213 p = iv;
214 while( iv_len > 0 )
215 {
216 use_len = ( iv_len < 16 ) ? iv_len : 16;
217
Paul Bakker67f9d532012-10-23 11:49:05 +0000218 for( i = 0; i < use_len; i++ )
219 y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200220
Paul Bakker89e80c92012-03-20 13:50:09 +0000221 gcm_mult( ctx, y, y );
222
223 iv_len -= use_len;
224 p += use_len;
225 }
226
Paul Bakker67f9d532012-10-23 11:49:05 +0000227 for( i = 0; i < 16; i++ )
228 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000229
230 gcm_mult( ctx, y, y );
231 }
232
233 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
234 memcpy( tag, ectr, tag_len );
235
236 p = add;
237 while( add_len > 0 )
238 {
239 use_len = ( add_len < 16 ) ? add_len : 16;
240
Paul Bakker67f9d532012-10-23 11:49:05 +0000241 for( i = 0; i < use_len; i++ )
242 buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200243
Paul Bakker89e80c92012-03-20 13:50:09 +0000244 gcm_mult( ctx, buf, buf );
245
246 add_len -= use_len;
247 p += use_len;
248 }
249
250 p = input;
251 while( length > 0 )
252 {
253 use_len = ( length < 16 ) ? length : 16;
254
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100255 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000256 if( ++y[i - 1] != 0 )
257 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258
259 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
260
Paul Bakker67f9d532012-10-23 11:49:05 +0000261 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000262 {
Paul Bakker09d67252013-01-04 16:38:25 +0100263 if( mode == GCM_DECRYPT )
264 buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000265 out_p[i] = ectr[i] ^ p[i];
Paul Bakker09d67252013-01-04 16:38:25 +0100266 if( mode == GCM_ENCRYPT )
267 buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000268 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200269
Paul Bakker89e80c92012-03-20 13:50:09 +0000270 gcm_mult( ctx, buf, buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200271
Paul Bakker89e80c92012-03-20 13:50:09 +0000272 length -= use_len;
273 p += use_len;
274 out_p += use_len;
275 }
276
277 if( orig_len || orig_add_len )
278 {
279 memset( work_buf, 0x00, 16 );
280
Paul Bakker0ecdb232013-04-09 11:36:42 +0200281 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
282 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
283 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200304 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000305 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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200344 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000345};
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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200360 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000361 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200362 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000363 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200364 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000365 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200366 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000367};
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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200379 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000380 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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200409 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000410 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200411 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000412 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200413 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000414 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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200417 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000418 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200419 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000420 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200421 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000422 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
423 0x3d, 0x58, 0xe0, 0x91 },
424 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200425 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000426 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200427 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000428 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200429 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000430 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
431 0xc2, 0x3f, 0x45, 0x98 },
432 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200433 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000434 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200435 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000436 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200437 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000438 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
439 0x4c, 0x34, 0xae, 0xe5 },
440 { 0x00 },
441 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200442 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000443 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200444 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000445 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200446 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000447 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200448 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000449 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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200452 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000453 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200454 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,
Paul Bakker89e80c92012-03-20 13:50:09 +0000457 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200458 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000459 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200460 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000461 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200462 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000463 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200464 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000465 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200466 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000467 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200468 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000469 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200470 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000471 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200472 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000473 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200474 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000475 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200476 { 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 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000494 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200495 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000496 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200497 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000498 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200499 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000500 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200501 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000502 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200503 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000504 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200505 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000506 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200507 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000508 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200509 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000510};
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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200519 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000520 { 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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200529 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000530 { 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,
Paul Bakker169b7f42013-06-25 14:58:00 +0200533 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000534 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200535 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000536 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200537 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000538 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200539 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000540 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200541 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000542 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200543 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000544 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200545 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000546 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200547 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000548 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200549 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000550};
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 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200610
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 printf( "\n" );
612
613 return( 0 );
614}
615
616#endif
617
618#endif