blob: fccb092bdd01836b99cc84d1e789f2e50ce95339 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
23 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
24 *
25 * See also:
26 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
27 *
28 * We use the algorithm described as Shoup's method with 4-bit tables in
29 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
30 */
31
32#if !defined(MBEDTLS_CONFIG_FILE)
33#include "mbedtls/config.h"
34#else
35#include MBEDTLS_CONFIG_FILE
36#endif
37
38#if defined(MBEDTLS_GCM_C)
39
40#include "mbedtls/gcm.h"
41
42#include <string.h>
43
44#if defined(MBEDTLS_AESNI_C)
45#include "mbedtls/aesni.h"
46#endif
47
48#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
49#if defined(MBEDTLS_PLATFORM_C)
50#include "mbedtls/platform.h"
51#else
52#include <stdio.h>
53#define mbedtls_printf printf
54#endif /* MBEDTLS_PLATFORM_C */
55#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
56
57/*
58 * 32-bit integer manipulation macros (big endian)
59 */
60#ifndef GET_UINT32_BE
61#define GET_UINT32_BE(n,b,i) \
62{ \
63 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
64 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
65 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
66 | ( (uint32_t) (b)[(i) + 3] ); \
67}
68#endif
69
70#ifndef PUT_UINT32_BE
71#define PUT_UINT32_BE(n,b,i) \
72{ \
73 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
74 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
75 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
76 (b)[(i) + 3] = (unsigned char) ( (n) ); \
77}
78#endif
79
80/* Implementation that should never be optimized out by the compiler */
81static void mbedtls_zeroize( void *v, size_t n ) {
82 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
83}
84
85/*
86 * Initialize a context
87 */
88void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
89{
90 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
91}
92
93/*
94 * Precompute small multiples of H, that is set
95 * HH[i] || HL[i] = H times i,
96 * where i is seen as a field element as in [MGV], ie high-order bits
97 * correspond to low powers of P. The result is stored in the same way, that
98 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
99 * corresponds to P^127.
100 */
101static int gcm_gen_table( mbedtls_gcm_context *ctx )
102{
103 int ret, i, j;
104 uint64_t hi, lo;
105 uint64_t vl, vh;
106 unsigned char h[16];
107 size_t olen = 0;
108
109 memset( h, 0, 16 );
110 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
111 return( ret );
112
113 /* pack h as two 64-bits ints, big-endian */
114 GET_UINT32_BE( hi, h, 0 );
115 GET_UINT32_BE( lo, h, 4 );
116 vh = (uint64_t) hi << 32 | lo;
117
118 GET_UINT32_BE( hi, h, 8 );
119 GET_UINT32_BE( lo, h, 12 );
120 vl = (uint64_t) hi << 32 | lo;
121
122 /* 8 = 1000 corresponds to 1 in GF(2^128) */
123 ctx->HL[8] = vl;
124 ctx->HH[8] = vh;
125
126#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
127 /* With CLMUL support, we need only h, not the rest of the table */
128 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
129 return( 0 );
130#endif
131
132 /* 0 corresponds to 0 in GF(2^128) */
133 ctx->HH[0] = 0;
134 ctx->HL[0] = 0;
135
136 for( i = 4; i > 0; i >>= 1 )
137 {
138 uint32_t T = ( vl & 1 ) * 0xe1000000U;
139 vl = ( vh << 63 ) | ( vl >> 1 );
140 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
141
142 ctx->HL[i] = vl;
143 ctx->HH[i] = vh;
144 }
145
146 for( i = 2; i <= 8; i *= 2 )
147 {
148 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
149 vh = *HiH;
150 vl = *HiL;
151 for( j = 1; j < i; j++ )
152 {
153 HiH[j] = vh ^ ctx->HH[j];
154 HiL[j] = vl ^ ctx->HL[j];
155 }
156 }
157
158 return( 0 );
159}
160
161int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
162 mbedtls_cipher_id_t cipher,
163 const unsigned char *key,
164 unsigned int keybits )
165{
166 int ret;
167 const mbedtls_cipher_info_t *cipher_info;
168
169 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
170 if( cipher_info == NULL )
171 return( MBEDTLS_ERR_GCM_BAD_INPUT );
172
173 if( cipher_info->block_size != 16 )
174 return( MBEDTLS_ERR_GCM_BAD_INPUT );
175
176 mbedtls_cipher_free( &ctx->cipher_ctx );
177
178 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
179 return( ret );
180
181 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
182 MBEDTLS_ENCRYPT ) ) != 0 )
183 {
184 return( ret );
185 }
186
187 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
188 return( ret );
189
190 return( 0 );
191}
192
193/*
194 * Shoup's method for multiplication use this table with
195 * last4[x] = x times P^128
196 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
197 */
198static const uint64_t last4[16] =
199{
200 0x0000, 0x1c20, 0x3840, 0x2460,
201 0x7080, 0x6ca0, 0x48c0, 0x54e0,
202 0xe100, 0xfd20, 0xd940, 0xc560,
203 0x9180, 0x8da0, 0xa9c0, 0xb5e0
204};
205
206/*
207 * Sets output to x times H using the precomputed tables.
208 * x and output are seen as elements of GF(2^128) as in [MGV].
209 */
210static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
211 unsigned char output[16] )
212{
213 int i = 0;
214 unsigned char lo, hi, rem;
215 uint64_t zh, zl;
216
217#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
218 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
219 unsigned char h[16];
220
221 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
222 PUT_UINT32_BE( ctx->HH[8], h, 4 );
223 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
224 PUT_UINT32_BE( ctx->HL[8], h, 12 );
225
226 mbedtls_aesni_gcm_mult( output, x, h );
227 return;
228 }
229#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
230
231 lo = x[15] & 0xf;
232
233 zh = ctx->HH[lo];
234 zl = ctx->HL[lo];
235
236 for( i = 15; i >= 0; i-- )
237 {
238 lo = x[i] & 0xf;
239 hi = x[i] >> 4;
240
241 if( i != 15 )
242 {
243 rem = (unsigned char) zl & 0xf;
244 zl = ( zh << 60 ) | ( zl >> 4 );
245 zh = ( zh >> 4 );
246 zh ^= (uint64_t) last4[rem] << 48;
247 zh ^= ctx->HH[lo];
248 zl ^= ctx->HL[lo];
249
250 }
251
252 rem = (unsigned char) zl & 0xf;
253 zl = ( zh << 60 ) | ( zl >> 4 );
254 zh = ( zh >> 4 );
255 zh ^= (uint64_t) last4[rem] << 48;
256 zh ^= ctx->HH[hi];
257 zl ^= ctx->HL[hi];
258 }
259
260 PUT_UINT32_BE( zh >> 32, output, 0 );
261 PUT_UINT32_BE( zh, output, 4 );
262 PUT_UINT32_BE( zl >> 32, output, 8 );
263 PUT_UINT32_BE( zl, output, 12 );
264}
265
266int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
267 int mode,
268 const unsigned char *iv,
269 size_t iv_len,
270 const unsigned char *add,
271 size_t add_len )
272{
273 int ret;
274 unsigned char work_buf[16];
275 size_t i;
276 const unsigned char *p;
277 size_t use_len, olen = 0;
278
279 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
280 /* IV is not allowed to be zero length */
281 if( iv_len == 0 ||
282 ( (uint64_t) iv_len ) >> 61 != 0 ||
283 ( (uint64_t) add_len ) >> 61 != 0 )
284 {
285 return( MBEDTLS_ERR_GCM_BAD_INPUT );
286 }
287
288 memset( ctx->y, 0x00, sizeof(ctx->y) );
289 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
290
291 ctx->mode = mode;
292 ctx->len = 0;
293 ctx->add_len = 0;
294
295 if( iv_len == 12 )
296 {
297 memcpy( ctx->y, iv, iv_len );
298 ctx->y[15] = 1;
299 }
300 else
301 {
302 memset( work_buf, 0x00, 16 );
303 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
304
305 p = iv;
306 while( iv_len > 0 )
307 {
308 use_len = ( iv_len < 16 ) ? iv_len : 16;
309
310 for( i = 0; i < use_len; i++ )
311 ctx->y[i] ^= p[i];
312
313 gcm_mult( ctx, ctx->y, ctx->y );
314
315 iv_len -= use_len;
316 p += use_len;
317 }
318
319 for( i = 0; i < 16; i++ )
320 ctx->y[i] ^= work_buf[i];
321
322 gcm_mult( ctx, ctx->y, ctx->y );
323 }
324
325 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
326 &olen ) ) != 0 )
327 {
328 return( ret );
329 }
330
331 ctx->add_len = add_len;
332 p = add;
333 while( add_len > 0 )
334 {
335 use_len = ( add_len < 16 ) ? add_len : 16;
336
337 for( i = 0; i < use_len; i++ )
338 ctx->buf[i] ^= p[i];
339
340 gcm_mult( ctx, ctx->buf, ctx->buf );
341
342 add_len -= use_len;
343 p += use_len;
344 }
345
346 return( 0 );
347}
348
349int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
350 size_t length,
351 const unsigned char *input,
352 unsigned char *output )
353{
354 int ret;
355 unsigned char ectr[16];
356 size_t i;
357 const unsigned char *p;
358 unsigned char *out_p = output;
359 size_t use_len, olen = 0;
360
361 if( output > input && (size_t) ( output - input ) < length )
362 return( MBEDTLS_ERR_GCM_BAD_INPUT );
363
364 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
365 * Also check for possible overflow */
366 if( ctx->len + length < ctx->len ||
367 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
368 {
369 return( MBEDTLS_ERR_GCM_BAD_INPUT );
370 }
371
372 ctx->len += length;
373
374 p = input;
375 while( length > 0 )
376 {
377 use_len = ( length < 16 ) ? length : 16;
378
379 for( i = 16; i > 12; i-- )
380 if( ++ctx->y[i - 1] != 0 )
381 break;
382
383 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
384 &olen ) ) != 0 )
385 {
386 return( ret );
387 }
388
389 for( i = 0; i < use_len; i++ )
390 {
391 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
392 ctx->buf[i] ^= p[i];
393 out_p[i] = ectr[i] ^ p[i];
394 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
395 ctx->buf[i] ^= out_p[i];
396 }
397
398 gcm_mult( ctx, ctx->buf, ctx->buf );
399
400 length -= use_len;
401 p += use_len;
402 out_p += use_len;
403 }
404
405 return( 0 );
406}
407
408int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
409 unsigned char *tag,
410 size_t tag_len )
411{
412 unsigned char work_buf[16];
413 size_t i;
414 uint64_t orig_len = ctx->len * 8;
415 uint64_t orig_add_len = ctx->add_len * 8;
416
417 if( tag_len > 16 || tag_len < 4 )
418 return( MBEDTLS_ERR_GCM_BAD_INPUT );
419
420 memcpy( tag, ctx->base_ectr, tag_len );
421
422 if( orig_len || orig_add_len )
423 {
424 memset( work_buf, 0x00, 16 );
425
426 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
427 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
428 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
429 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
430
431 for( i = 0; i < 16; i++ )
432 ctx->buf[i] ^= work_buf[i];
433
434 gcm_mult( ctx, ctx->buf, ctx->buf );
435
436 for( i = 0; i < tag_len; i++ )
437 tag[i] ^= ctx->buf[i];
438 }
439
440 return( 0 );
441}
442
443int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
444 int mode,
445 size_t length,
446 const unsigned char *iv,
447 size_t iv_len,
448 const unsigned char *add,
449 size_t add_len,
450 const unsigned char *input,
451 unsigned char *output,
452 size_t tag_len,
453 unsigned char *tag )
454{
455 int ret;
456
457 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
458 return( ret );
459
460 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
461 return( ret );
462
463 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
464 return( ret );
465
466 return( 0 );
467}
468
469int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
470 size_t length,
471 const unsigned char *iv,
472 size_t iv_len,
473 const unsigned char *add,
474 size_t add_len,
475 const unsigned char *tag,
476 size_t tag_len,
477 const unsigned char *input,
478 unsigned char *output )
479{
480 int ret;
481 unsigned char check_tag[16];
482 size_t i;
483 int diff;
484
485 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
486 iv, iv_len, add, add_len,
487 input, output, tag_len, check_tag ) ) != 0 )
488 {
489 return( ret );
490 }
491
492 /* Check tag in "constant-time" */
493 for( diff = 0, i = 0; i < tag_len; i++ )
494 diff |= tag[i] ^ check_tag[i];
495
496 if( diff != 0 )
497 {
498 mbedtls_zeroize( output, length );
499 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
500 }
501
502 return( 0 );
503}
504
505void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
506{
507 mbedtls_cipher_free( &ctx->cipher_ctx );
508 mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
509}
510
511#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
512/*
513 * AES-GCM test vectors from:
514 *
515 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
516 */
517#define MAX_TESTS 6
518
519static const int key_index[MAX_TESTS] =
520 { 0, 0, 1, 1, 1, 1 };
521
522static const unsigned char key[MAX_TESTS][32] =
523{
524 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
528 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
529 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
530 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
531 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
532};
533
534static const size_t iv_len[MAX_TESTS] =
535 { 12, 12, 12, 12, 8, 60 };
536
537static const int iv_index[MAX_TESTS] =
538 { 0, 0, 1, 1, 1, 2 };
539
540static const unsigned char iv[MAX_TESTS][64] =
541{
542 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00 },
544 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
545 0xde, 0xca, 0xf8, 0x88 },
546 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
547 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
548 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
549 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
550 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
551 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
552 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
553 0xa6, 0x37, 0xb3, 0x9b },
554};
555
556static const size_t add_len[MAX_TESTS] =
557 { 0, 0, 0, 20, 20, 20 };
558
559static const int add_index[MAX_TESTS] =
560 { 0, 0, 0, 1, 1, 1 };
561
562static const unsigned char additional[MAX_TESTS][64] =
563{
564 { 0x00 },
565 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
566 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
567 0xab, 0xad, 0xda, 0xd2 },
568};
569
570static const size_t pt_len[MAX_TESTS] =
571 { 0, 16, 64, 60, 60, 60 };
572
573static const int pt_index[MAX_TESTS] =
574 { 0, 0, 1, 1, 1, 1 };
575
576static const unsigned char pt[MAX_TESTS][64] =
577{
578 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
580 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
581 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
582 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
583 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
584 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
585 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
586 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
587 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
588};
589
590static const unsigned char ct[MAX_TESTS * 3][64] =
591{
592 { 0x00 },
593 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
594 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
595 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
596 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
597 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
598 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
599 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
600 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
601 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
602 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
603 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
604 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
605 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
606 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
607 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
608 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
609 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
610 0x3d, 0x58, 0xe0, 0x91 },
611 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
612 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
613 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
614 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
615 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
616 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
617 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
618 0xc2, 0x3f, 0x45, 0x98 },
619 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
620 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
621 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
622 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
623 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
624 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
625 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
626 0x4c, 0x34, 0xae, 0xe5 },
627 { 0x00 },
628 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
629 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
630 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
631 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
632 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
633 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
634 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
635 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
636 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
637 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
638 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
639 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
640 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
641 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
642 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
643 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
644 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
645 0xcc, 0xda, 0x27, 0x10 },
646 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
647 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
648 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
649 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
650 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
651 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
652 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
653 0xa0, 0xf0, 0x62, 0xf7 },
654 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
655 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
656 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
657 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
658 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
659 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
660 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
661 0xe9, 0xb7, 0x37, 0x3b },
662 { 0x00 },
663 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
664 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
665 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
666 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
667 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
668 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
669 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
670 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
671 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
672 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
673 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
674 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
675 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
676 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
677 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
678 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
679 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
680 0xbc, 0xc9, 0xf6, 0x62 },
681 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
682 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
683 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
684 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
685 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
686 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
687 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
688 0xf4, 0x7c, 0x9b, 0x1f },
689 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
690 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
691 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
692 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
693 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
694 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
695 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
696 0x44, 0xae, 0x7e, 0x3f },
697};
698
699static const unsigned char tag[MAX_TESTS * 3][16] =
700{
701 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
702 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
703 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
704 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
705 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
706 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
707 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
708 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
709 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
710 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
711 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
712 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
713 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
714 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
715 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
716 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
717 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
718 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
719 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
720 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
721 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
722 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
723 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
724 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
725 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
726 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
727 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
728 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
729 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
730 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
731 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
732 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
733 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
734 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
735 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
736 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
737};
738
739int mbedtls_gcm_self_test( int verbose )
740{
741 mbedtls_gcm_context ctx;
742 unsigned char buf[64];
743 unsigned char tag_buf[16];
744 int i, j, ret;
745 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
746
747 mbedtls_gcm_init( &ctx );
748
749 for( j = 0; j < 3; j++ )
750 {
751 int key_len = 128 + 64 * j;
752
753 for( i = 0; i < MAX_TESTS; i++ )
754 {
755 if( verbose != 0 )
756 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
757 key_len, i, "enc" );
758
759 mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
760
761 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
762 pt_len[i],
763 iv[iv_index[i]], iv_len[i],
764 additional[add_index[i]], add_len[i],
765 pt[pt_index[i]], buf, 16, tag_buf );
766
767 if( ret != 0 ||
768 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
769 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
770 {
771 if( verbose != 0 )
772 mbedtls_printf( "failed\n" );
773
774 return( 1 );
775 }
776
777 mbedtls_gcm_free( &ctx );
778
779 if( verbose != 0 )
780 mbedtls_printf( "passed\n" );
781
782 if( verbose != 0 )
783 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
784 key_len, i, "dec" );
785
786 mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
787
788 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
789 pt_len[i],
790 iv[iv_index[i]], iv_len[i],
791 additional[add_index[i]], add_len[i],
792 ct[j * 6 + i], buf, 16, tag_buf );
793
794 if( ret != 0 ||
795 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
796 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
797 {
798 if( verbose != 0 )
799 mbedtls_printf( "failed\n" );
800
801 return( 1 );
802 }
803
804 mbedtls_gcm_free( &ctx );
805
806 if( verbose != 0 )
807 mbedtls_printf( "passed\n" );
808
809 if( verbose != 0 )
810 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
811 key_len, i, "enc" );
812
813 mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
814
815 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
816 iv[iv_index[i]], iv_len[i],
817 additional[add_index[i]], add_len[i] );
818 if( ret != 0 )
819 {
820 if( verbose != 0 )
821 mbedtls_printf( "failed\n" );
822
823 return( 1 );
824 }
825
826 if( pt_len[i] > 32 )
827 {
828 size_t rest_len = pt_len[i] - 32;
829 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
830 if( ret != 0 )
831 {
832 if( verbose != 0 )
833 mbedtls_printf( "failed\n" );
834
835 return( 1 );
836 }
837
838 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
839 buf + 32 );
840 if( ret != 0 )
841 {
842 if( verbose != 0 )
843 mbedtls_printf( "failed\n" );
844
845 return( 1 );
846 }
847 }
848 else
849 {
850 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
851 if( ret != 0 )
852 {
853 if( verbose != 0 )
854 mbedtls_printf( "failed\n" );
855
856 return( 1 );
857 }
858 }
859
860 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
861 if( ret != 0 ||
862 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
863 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
864 {
865 if( verbose != 0 )
866 mbedtls_printf( "failed\n" );
867
868 return( 1 );
869 }
870
871 mbedtls_gcm_free( &ctx );
872
873 if( verbose != 0 )
874 mbedtls_printf( "passed\n" );
875
876 if( verbose != 0 )
877 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
878 key_len, i, "dec" );
879
880 mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
881
882 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
883 iv[iv_index[i]], iv_len[i],
884 additional[add_index[i]], add_len[i] );
885 if( ret != 0 )
886 {
887 if( verbose != 0 )
888 mbedtls_printf( "failed\n" );
889
890 return( 1 );
891 }
892
893 if( pt_len[i] > 32 )
894 {
895 size_t rest_len = pt_len[i] - 32;
896 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
897 if( ret != 0 )
898 {
899 if( verbose != 0 )
900 mbedtls_printf( "failed\n" );
901
902 return( 1 );
903 }
904
905 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
906 buf + 32 );
907 if( ret != 0 )
908 {
909 if( verbose != 0 )
910 mbedtls_printf( "failed\n" );
911
912 return( 1 );
913 }
914 }
915 else
916 {
917 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
918 if( ret != 0 )
919 {
920 if( verbose != 0 )
921 mbedtls_printf( "failed\n" );
922
923 return( 1 );
924 }
925 }
926
927 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
928 if( ret != 0 ||
929 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
930 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
931 {
932 if( verbose != 0 )
933 mbedtls_printf( "failed\n" );
934
935 return( 1 );
936 }
937
938 mbedtls_gcm_free( &ctx );
939
940 if( verbose != 0 )
941 mbedtls_printf( "passed\n" );
942
943 }
944 }
945
946 if( verbose != 0 )
947 mbedtls_printf( "\n" );
948
949 return( 0 );
950}
951
952#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
953
954#endif /* MBEDTLS_GCM_C */