blob: f237bab7de50700f46a9a0090b38021799571f59 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
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
Jerome Forissier79013242021-07-28 10:24:04 +020030#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020031
32#if defined(MBEDTLS_GCM_C)
33
34#include "mbedtls/gcm.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010035#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020036#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020037
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)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010045#include "mbedtls/aes.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020046#include "mbedtls/platform.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010047#if !defined(MBEDTLS_PLATFORM_C)
Jens Wiklander817466c2018-05-22 13:49:31 +020048#include <stdio.h>
49#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
52
Jens Wiklander3d3b0592019-03-20 15:30:29 +010053#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
Jens Wiklander817466c2018-05-22 13:49:31 +020061/*
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
Jens Wiklander817466c2018-05-22 13:49:31 +020084/*
85 * Initialize a context
86 */
87void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
88{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010089 GCM_VALIDATE( ctx != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +020090 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{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200166 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200167 const mbedtls_cipher_info_t *cipher_info;
168
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100169 GCM_VALIDATE_RET( ctx != NULL );
170 GCM_VALIDATE_RET( key != NULL );
171 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
172
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200173 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
174 MBEDTLS_MODE_ECB );
Jens Wiklander817466c2018-05-22 13:49:31 +0200175 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 */
203static 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 */
215static 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;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200244 hi = ( x[i] >> 4 ) & 0xf;
Jens Wiklander817466c2018-05-22 13:49:31 +0200245
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
271int 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{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200278 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200279 unsigned char work_buf[16];
280 size_t i;
281 const unsigned char *p;
282 size_t use_len, olen = 0;
283
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100284 GCM_VALIDATE_RET( ctx != NULL );
285 GCM_VALIDATE_RET( iv != NULL );
286 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
287
Jens Wiklander817466c2018-05-22 13:49:31 +0200288 /* 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
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200334 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
335 ctx->base_ectr, &olen ) ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200336 {
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
358int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
359 size_t length,
360 const unsigned char *input,
361 unsigned char *output )
362{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200363 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200364 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
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100370 GCM_VALIDATE_RET( ctx != NULL );
371 GCM_VALIDATE_RET( length == 0 || input != NULL );
372 GCM_VALIDATE_RET( length == 0 || output != NULL );
373
Jens Wiklander817466c2018-05-22 13:49:31 +0200374 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
421int 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;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100427 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;
Jens Wiklander817466c2018-05-22 13:49:31 +0200435
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
462int 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{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200474 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200475
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100476 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
Jens Wiklander817466c2018-05-22 13:49:31 +0200483 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
495int 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{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200506 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200507 unsigned char check_tag[16];
508 size_t i;
509 int diff;
510
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100511 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
Jens Wiklander817466c2018-05-22 13:49:31 +0200518 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 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100531 mbedtls_platform_zeroize( output, length );
Jens Wiklander817466c2018-05-22 13:49:31 +0200532 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
533 }
534
535 return( 0 );
536}
537
538void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
539{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100540 if( ctx == NULL )
541 return;
Jens Wiklander817466c2018-05-22 13:49:31 +0200542 mbedtls_cipher_free( &ctx->cipher_ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100543 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200544}
545
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100546#endif /* !MBEDTLS_GCM_ALT */
547
Jens Wiklander817466c2018-05-22 13:49:31 +0200548#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
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200556static const int key_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200557 { 0, 0, 1, 1, 1, 1 };
558
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200559static const unsigned char key_test_data[MAX_TESTS][32] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200560{
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
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200571static const size_t iv_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200572 { 12, 12, 12, 12, 8, 60 };
573
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200574static const int iv_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200575 { 0, 0, 1, 1, 1, 2 };
576
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200577static const unsigned char iv_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200578{
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
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200593static const size_t add_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200594 { 0, 0, 0, 20, 20, 20 };
595
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200596static const int add_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200597 { 0, 0, 0, 1, 1, 1 };
598
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200599static const unsigned char additional_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200600{
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
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200607static const size_t pt_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200608 { 0, 16, 64, 60, 60, 60 };
609
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200610static const int pt_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200611 { 0, 0, 1, 1, 1, 1 };
612
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200613static const unsigned char pt_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200614{
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
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200627static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200628{
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
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200736static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200737{
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
776int 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
Jens Wiklander817466c2018-05-22 13:49:31 +0200784 for( j = 0; j < 3; j++ )
785 {
786 int key_len = 128 + 64 * j;
787
788 for( i = 0; i < MAX_TESTS; i++ )
789 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100790 mbedtls_gcm_init( &ctx );
791
Jens Wiklander817466c2018-05-22 13:49:31 +0200792 if( verbose != 0 )
793 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100794 key_len, i, "enc" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200795
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200796 ret = mbedtls_gcm_setkey( &ctx, cipher,
797 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100798 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 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200813
814 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200815 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 );
Jerome Forissier79013242021-07-28 10:24:04 +0200822#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) */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100831 if( ret != 0 )
832 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200833
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200834 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 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200837 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100838 ret = 1;
839 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200840 }
841
842 mbedtls_gcm_free( &ctx );
843
844 if( verbose != 0 )
845 mbedtls_printf( "passed\n" );
846
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100847 mbedtls_gcm_init( &ctx );
848
Jens Wiklander817466c2018-05-22 13:49:31 +0200849 if( verbose != 0 )
850 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100851 key_len, i, "dec" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200852
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200853 ret = mbedtls_gcm_setkey( &ctx, cipher,
854 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100855 key_len );
856 if( ret != 0 )
857 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200858
859 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200860 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 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200866
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100867 if( ret != 0 )
868 goto exit;
869
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200870 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 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200873 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100874 ret = 1;
875 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200876 }
877
878 mbedtls_gcm_free( &ctx );
879
880 if( verbose != 0 )
881 mbedtls_printf( "passed\n" );
882
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100883 mbedtls_gcm_init( &ctx );
884
Jens Wiklander817466c2018-05-22 13:49:31 +0200885 if( verbose != 0 )
886 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100887 key_len, i, "enc" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200888
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200889 ret = mbedtls_gcm_setkey( &ctx, cipher,
890 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100891 key_len );
892 if( ret != 0 )
893 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200894
895 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200896 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] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200900 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100901 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200902
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200903 if( pt_len_test_data[i] > 32 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200904 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200905 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 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200909 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100910 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200911
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200912 ret = mbedtls_gcm_update( &ctx, rest_len,
913 pt_test_data[pt_index_test_data[i]] + 32,
914 buf + 32 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200915 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100916 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200917 }
918 else
919 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200920 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
921 pt_test_data[pt_index_test_data[i]],
922 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200923 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100924 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200925 }
926
927 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100928 if( ret != 0 )
929 goto exit;
930
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200931 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 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200934 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100935 ret = 1;
936 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200937 }
938
939 mbedtls_gcm_free( &ctx );
940
941 if( verbose != 0 )
942 mbedtls_printf( "passed\n" );
943
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100944 mbedtls_gcm_init( &ctx );
945
Jens Wiklander817466c2018-05-22 13:49:31 +0200946 if( verbose != 0 )
947 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100948 key_len, i, "dec" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200949
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200950 ret = mbedtls_gcm_setkey( &ctx, cipher,
951 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100952 key_len );
953 if( ret != 0 )
954 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200955
956 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200957 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] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200961 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100962 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200963
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200964 if( pt_len_test_data[i] > 32 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200965 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200966 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 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200969 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100970 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200971
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200972 ret = mbedtls_gcm_update( &ctx, rest_len,
973 ct_test_data[j * 6 + i] + 32,
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100974 buf + 32 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200975 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100976 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200977 }
978 else
979 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200980 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
981 ct_test_data[j * 6 + i],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100982 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200983 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100984 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200985 }
986
987 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100988 if( ret != 0 )
989 goto exit;
990
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200991 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 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200994 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100995 ret = 1;
996 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200997 }
998
999 mbedtls_gcm_free( &ctx );
1000
1001 if( verbose != 0 )
1002 mbedtls_printf( "passed\n" );
Jens Wiklander817466c2018-05-22 13:49:31 +02001003 }
1004 }
1005
1006 if( verbose != 0 )
1007 mbedtls_printf( "\n" );
1008
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001009 ret = 0;
1010
1011exit:
1012 if( ret != 0 )
1013 {
1014 if( verbose != 0 )
1015 mbedtls_printf( "failed\n" );
1016 mbedtls_gcm_free( &ctx );
1017 }
1018
1019 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02001020}
1021
1022#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1023
1024#endif /* MBEDTLS_GCM_C */