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