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