blob: 43a5e1bec68d1c8cd9d1aa87512a7b5a268bb607 [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/*
Jens Wiklander817466c2018-05-22 13:49:31 +020062 * Initialize a context
63 */
64void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
65{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010066 GCM_VALIDATE( ctx != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +020067 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
68}
69
70/*
71 * Precompute small multiples of H, that is set
72 * HH[i] || HL[i] = H times i,
73 * where i is seen as a field element as in [MGV], ie high-order bits
74 * correspond to low powers of P. The result is stored in the same way, that
75 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
76 * corresponds to P^127.
77 */
78static int gcm_gen_table( mbedtls_gcm_context *ctx )
79{
80 int ret, i, j;
81 uint64_t hi, lo;
82 uint64_t vl, vh;
83 unsigned char h[16];
84 size_t olen = 0;
85
86 memset( h, 0, 16 );
87 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
88 return( ret );
89
90 /* pack h as two 64-bits ints, big-endian */
Jerome Forissier039e02d2022-08-09 17:10:15 +020091 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
92 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Jens Wiklander817466c2018-05-22 13:49:31 +020093 vh = (uint64_t) hi << 32 | lo;
94
Jerome Forissier039e02d2022-08-09 17:10:15 +020095 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
96 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Jens Wiklander817466c2018-05-22 13:49:31 +020097 vl = (uint64_t) hi << 32 | lo;
98
99 /* 8 = 1000 corresponds to 1 in GF(2^128) */
100 ctx->HL[8] = vl;
101 ctx->HH[8] = vh;
102
103#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
104 /* With CLMUL support, we need only h, not the rest of the table */
105 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
106 return( 0 );
107#endif
108
109 /* 0 corresponds to 0 in GF(2^128) */
110 ctx->HH[0] = 0;
111 ctx->HL[0] = 0;
112
113 for( i = 4; i > 0; i >>= 1 )
114 {
115 uint32_t T = ( vl & 1 ) * 0xe1000000U;
116 vl = ( vh << 63 ) | ( vl >> 1 );
117 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
118
119 ctx->HL[i] = vl;
120 ctx->HH[i] = vh;
121 }
122
123 for( i = 2; i <= 8; i *= 2 )
124 {
125 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
126 vh = *HiH;
127 vl = *HiL;
128 for( j = 1; j < i; j++ )
129 {
130 HiH[j] = vh ^ ctx->HH[j];
131 HiL[j] = vl ^ ctx->HL[j];
132 }
133 }
134
135 return( 0 );
136}
137
138int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
139 mbedtls_cipher_id_t cipher,
140 const unsigned char *key,
141 unsigned int keybits )
142{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200144 const mbedtls_cipher_info_t *cipher_info;
145
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100146 GCM_VALIDATE_RET( ctx != NULL );
147 GCM_VALIDATE_RET( key != NULL );
148 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
149
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200150 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
151 MBEDTLS_MODE_ECB );
Jens Wiklander817466c2018-05-22 13:49:31 +0200152 if( cipher_info == NULL )
153 return( MBEDTLS_ERR_GCM_BAD_INPUT );
154
155 if( cipher_info->block_size != 16 )
156 return( MBEDTLS_ERR_GCM_BAD_INPUT );
157
158 mbedtls_cipher_free( &ctx->cipher_ctx );
159
160 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
161 return( ret );
162
163 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
164 MBEDTLS_ENCRYPT ) ) != 0 )
165 {
166 return( ret );
167 }
168
169 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
170 return( ret );
171
172 return( 0 );
173}
174
175/*
176 * Shoup's method for multiplication use this table with
177 * last4[x] = x times P^128
178 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
179 */
180static const uint64_t last4[16] =
181{
182 0x0000, 0x1c20, 0x3840, 0x2460,
183 0x7080, 0x6ca0, 0x48c0, 0x54e0,
184 0xe100, 0xfd20, 0xd940, 0xc560,
185 0x9180, 0x8da0, 0xa9c0, 0xb5e0
186};
187
188/*
189 * Sets output to x times H using the precomputed tables.
190 * x and output are seen as elements of GF(2^128) as in [MGV].
191 */
192static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
193 unsigned char output[16] )
194{
195 int i = 0;
196 unsigned char lo, hi, rem;
197 uint64_t zh, zl;
198
199#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
200 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
201 unsigned char h[16];
202
Jerome Forissier039e02d2022-08-09 17:10:15 +0200203 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
204 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
205 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
206 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200207
208 mbedtls_aesni_gcm_mult( output, x, h );
209 return;
210 }
211#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
212
213 lo = x[15] & 0xf;
214
215 zh = ctx->HH[lo];
216 zl = ctx->HL[lo];
217
218 for( i = 15; i >= 0; i-- )
219 {
220 lo = x[i] & 0xf;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200221 hi = ( x[i] >> 4 ) & 0xf;
Jens Wiklander817466c2018-05-22 13:49:31 +0200222
223 if( i != 15 )
224 {
225 rem = (unsigned char) zl & 0xf;
226 zl = ( zh << 60 ) | ( zl >> 4 );
227 zh = ( zh >> 4 );
228 zh ^= (uint64_t) last4[rem] << 48;
229 zh ^= ctx->HH[lo];
230 zl ^= ctx->HL[lo];
231
232 }
233
234 rem = (unsigned char) zl & 0xf;
235 zl = ( zh << 60 ) | ( zl >> 4 );
236 zh = ( zh >> 4 );
237 zh ^= (uint64_t) last4[rem] << 48;
238 zh ^= ctx->HH[hi];
239 zl ^= ctx->HL[hi];
240 }
241
Jerome Forissier039e02d2022-08-09 17:10:15 +0200242 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
243 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
244 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
245 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200246}
247
248int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
249 int mode,
250 const unsigned char *iv,
251 size_t iv_len,
252 const unsigned char *add,
253 size_t add_len )
254{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200255 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200256 unsigned char work_buf[16];
257 size_t i;
258 const unsigned char *p;
259 size_t use_len, olen = 0;
Jerome Forissier039e02d2022-08-09 17:10:15 +0200260 uint64_t iv_bits;
Jens Wiklander817466c2018-05-22 13:49:31 +0200261
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100262 GCM_VALIDATE_RET( ctx != NULL );
263 GCM_VALIDATE_RET( iv != NULL );
264 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
265
Jens Wiklander817466c2018-05-22 13:49:31 +0200266 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
267 /* IV is not allowed to be zero length */
268 if( iv_len == 0 ||
269 ( (uint64_t) iv_len ) >> 61 != 0 ||
270 ( (uint64_t) add_len ) >> 61 != 0 )
271 {
272 return( MBEDTLS_ERR_GCM_BAD_INPUT );
273 }
274
275 memset( ctx->y, 0x00, sizeof(ctx->y) );
276 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
277
278 ctx->mode = mode;
279 ctx->len = 0;
280 ctx->add_len = 0;
281
282 if( iv_len == 12 )
283 {
284 memcpy( ctx->y, iv, iv_len );
285 ctx->y[15] = 1;
286 }
287 else
288 {
289 memset( work_buf, 0x00, 16 );
Jerome Forissier039e02d2022-08-09 17:10:15 +0200290 iv_bits = (uint64_t)iv_len * 8;
291 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200292
293 p = iv;
294 while( iv_len > 0 )
295 {
296 use_len = ( iv_len < 16 ) ? iv_len : 16;
297
298 for( i = 0; i < use_len; i++ )
299 ctx->y[i] ^= p[i];
300
301 gcm_mult( ctx, ctx->y, ctx->y );
302
303 iv_len -= use_len;
304 p += use_len;
305 }
306
307 for( i = 0; i < 16; i++ )
308 ctx->y[i] ^= work_buf[i];
309
310 gcm_mult( ctx, ctx->y, ctx->y );
311 }
312
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200313 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
314 ctx->base_ectr, &olen ) ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200315 {
316 return( ret );
317 }
318
319 ctx->add_len = add_len;
320 p = add;
321 while( add_len > 0 )
322 {
323 use_len = ( add_len < 16 ) ? add_len : 16;
324
325 for( i = 0; i < use_len; i++ )
326 ctx->buf[i] ^= p[i];
327
328 gcm_mult( ctx, ctx->buf, ctx->buf );
329
330 add_len -= use_len;
331 p += use_len;
332 }
333
334 return( 0 );
335}
336
337int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
338 size_t length,
339 const unsigned char *input,
340 unsigned char *output )
341{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200342 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200343 unsigned char ectr[16];
344 size_t i;
345 const unsigned char *p;
346 unsigned char *out_p = output;
347 size_t use_len, olen = 0;
348
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100349 GCM_VALIDATE_RET( ctx != NULL );
350 GCM_VALIDATE_RET( length == 0 || input != NULL );
351 GCM_VALIDATE_RET( length == 0 || output != NULL );
352
Jens Wiklander817466c2018-05-22 13:49:31 +0200353 if( output > input && (size_t) ( output - input ) < length )
354 return( MBEDTLS_ERR_GCM_BAD_INPUT );
355
356 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
357 * Also check for possible overflow */
358 if( ctx->len + length < ctx->len ||
359 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
360 {
361 return( MBEDTLS_ERR_GCM_BAD_INPUT );
362 }
363
364 ctx->len += length;
365
366 p = input;
367 while( length > 0 )
368 {
369 use_len = ( length < 16 ) ? length : 16;
370
371 for( i = 16; i > 12; i-- )
372 if( ++ctx->y[i - 1] != 0 )
373 break;
374
375 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
376 &olen ) ) != 0 )
377 {
378 return( ret );
379 }
380
381 for( i = 0; i < use_len; i++ )
382 {
383 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
384 ctx->buf[i] ^= p[i];
385 out_p[i] = ectr[i] ^ p[i];
386 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
387 ctx->buf[i] ^= out_p[i];
388 }
389
390 gcm_mult( ctx, ctx->buf, ctx->buf );
391
392 length -= use_len;
393 p += use_len;
394 out_p += use_len;
395 }
396
397 return( 0 );
398}
399
400int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
401 unsigned char *tag,
402 size_t tag_len )
403{
404 unsigned char work_buf[16];
405 size_t i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100406 uint64_t orig_len;
407 uint64_t orig_add_len;
408
409 GCM_VALIDATE_RET( ctx != NULL );
410 GCM_VALIDATE_RET( tag != NULL );
411
412 orig_len = ctx->len * 8;
413 orig_add_len = ctx->add_len * 8;
Jens Wiklander817466c2018-05-22 13:49:31 +0200414
415 if( tag_len > 16 || tag_len < 4 )
416 return( MBEDTLS_ERR_GCM_BAD_INPUT );
417
418 memcpy( tag, ctx->base_ectr, tag_len );
419
420 if( orig_len || orig_add_len )
421 {
422 memset( work_buf, 0x00, 16 );
423
Jerome Forissier039e02d2022-08-09 17:10:15 +0200424 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
425 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
426 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
427 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200428
429 for( i = 0; i < 16; i++ )
430 ctx->buf[i] ^= work_buf[i];
431
432 gcm_mult( ctx, ctx->buf, ctx->buf );
433
434 for( i = 0; i < tag_len; i++ )
435 tag[i] ^= ctx->buf[i];
436 }
437
438 return( 0 );
439}
440
441int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
442 int mode,
443 size_t length,
444 const unsigned char *iv,
445 size_t iv_len,
446 const unsigned char *add,
447 size_t add_len,
448 const unsigned char *input,
449 unsigned char *output,
450 size_t tag_len,
451 unsigned char *tag )
452{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200453 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200454
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100455 GCM_VALIDATE_RET( ctx != NULL );
456 GCM_VALIDATE_RET( iv != NULL );
457 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
458 GCM_VALIDATE_RET( length == 0 || input != NULL );
459 GCM_VALIDATE_RET( length == 0 || output != NULL );
460 GCM_VALIDATE_RET( tag != NULL );
461
Jens Wiklander817466c2018-05-22 13:49:31 +0200462 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
463 return( ret );
464
465 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
466 return( ret );
467
468 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
469 return( ret );
470
471 return( 0 );
472}
473
474int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
475 size_t length,
476 const unsigned char *iv,
477 size_t iv_len,
478 const unsigned char *add,
479 size_t add_len,
480 const unsigned char *tag,
481 size_t tag_len,
482 const unsigned char *input,
483 unsigned char *output )
484{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200485 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200486 unsigned char check_tag[16];
487 size_t i;
488 int diff;
489
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100490 GCM_VALIDATE_RET( ctx != NULL );
491 GCM_VALIDATE_RET( iv != NULL );
492 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
493 GCM_VALIDATE_RET( tag != NULL );
494 GCM_VALIDATE_RET( length == 0 || input != NULL );
495 GCM_VALIDATE_RET( length == 0 || output != NULL );
496
Jens Wiklander817466c2018-05-22 13:49:31 +0200497 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
498 iv, iv_len, add, add_len,
499 input, output, tag_len, check_tag ) ) != 0 )
500 {
501 return( ret );
502 }
503
504 /* Check tag in "constant-time" */
505 for( diff = 0, i = 0; i < tag_len; i++ )
506 diff |= tag[i] ^ check_tag[i];
507
508 if( diff != 0 )
509 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100510 mbedtls_platform_zeroize( output, length );
Jens Wiklander817466c2018-05-22 13:49:31 +0200511 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
512 }
513
514 return( 0 );
515}
516
517void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
518{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100519 if( ctx == NULL )
520 return;
Jens Wiklander817466c2018-05-22 13:49:31 +0200521 mbedtls_cipher_free( &ctx->cipher_ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100522 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200523}
524
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100525#endif /* !MBEDTLS_GCM_ALT */
526
Jens Wiklander817466c2018-05-22 13:49:31 +0200527#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
528/*
529 * AES-GCM test vectors from:
530 *
531 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
532 */
533#define MAX_TESTS 6
534
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200535static const int key_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200536 { 0, 0, 1, 1, 1, 1 };
537
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200538static const unsigned char key_test_data[MAX_TESTS][32] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200539{
540 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
544 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
545 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
546 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
547 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
548};
549
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200550static const size_t iv_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200551 { 12, 12, 12, 12, 8, 60 };
552
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200553static const int iv_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200554 { 0, 0, 1, 1, 1, 2 };
555
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200556static const unsigned char iv_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200557{
558 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00 },
560 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
561 0xde, 0xca, 0xf8, 0x88 },
562 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
563 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
564 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
565 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
566 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
567 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
568 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
569 0xa6, 0x37, 0xb3, 0x9b },
570};
571
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200572static const size_t add_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200573 { 0, 0, 0, 20, 20, 20 };
574
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200575static const int add_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200576 { 0, 0, 0, 1, 1, 1 };
577
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200578static const unsigned char additional_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200579{
580 { 0x00 },
581 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
582 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
583 0xab, 0xad, 0xda, 0xd2 },
584};
585
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200586static const size_t pt_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200587 { 0, 16, 64, 60, 60, 60 };
588
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200589static const int pt_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200590 { 0, 0, 1, 1, 1, 1 };
591
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200592static const unsigned char pt_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200593{
594 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
596 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
597 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
598 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
599 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
600 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
601 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
602 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
603 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
604};
605
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200606static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200607{
608 { 0x00 },
609 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
610 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
611 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
612 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
613 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
614 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
615 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
616 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
617 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
618 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
619 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
620 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
621 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
622 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
623 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
624 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
625 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
626 0x3d, 0x58, 0xe0, 0x91 },
627 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
628 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
629 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
630 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
631 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
632 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
633 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
634 0xc2, 0x3f, 0x45, 0x98 },
635 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
636 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
637 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
638 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
639 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
640 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
641 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
642 0x4c, 0x34, 0xae, 0xe5 },
643 { 0x00 },
644 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
645 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
646 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
647 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
648 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
649 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
650 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
651 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
652 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
653 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
654 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
655 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
656 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
657 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
658 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
659 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
660 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
661 0xcc, 0xda, 0x27, 0x10 },
662 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
663 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
664 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
665 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
666 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
667 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
668 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
669 0xa0, 0xf0, 0x62, 0xf7 },
670 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
671 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
672 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
673 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
674 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
675 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
676 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
677 0xe9, 0xb7, 0x37, 0x3b },
678 { 0x00 },
679 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
680 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
681 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
682 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
683 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
684 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
685 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
686 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
687 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
688 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
689 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
690 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
691 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
692 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
693 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
694 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
695 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
696 0xbc, 0xc9, 0xf6, 0x62 },
697 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
698 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
699 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
700 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
701 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
702 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
703 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
704 0xf4, 0x7c, 0x9b, 0x1f },
705 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
706 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
707 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
708 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
709 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
710 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
711 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
712 0x44, 0xae, 0x7e, 0x3f },
713};
714
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200715static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200716{
717 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
718 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
719 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
720 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
721 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
722 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
723 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
724 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
725 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
726 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
727 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
728 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
729 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
730 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
731 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
732 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
733 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
734 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
735 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
736 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
737 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
738 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
739 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
740 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
741 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
742 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
743 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
744 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
745 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
746 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
747 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
748 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
749 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
750 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
751 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
752 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
753};
754
755int mbedtls_gcm_self_test( int verbose )
756{
757 mbedtls_gcm_context ctx;
758 unsigned char buf[64];
759 unsigned char tag_buf[16];
760 int i, j, ret;
761 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
762
Jens Wiklander817466c2018-05-22 13:49:31 +0200763 for( j = 0; j < 3; j++ )
764 {
765 int key_len = 128 + 64 * j;
766
767 for( i = 0; i < MAX_TESTS; i++ )
768 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100769 mbedtls_gcm_init( &ctx );
770
Jens Wiklander817466c2018-05-22 13:49:31 +0200771 if( verbose != 0 )
772 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100773 key_len, i, "enc" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200774
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200775 ret = mbedtls_gcm_setkey( &ctx, cipher,
776 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100777 key_len );
778 /*
779 * AES-192 is an optional feature that may be unavailable when
780 * there is an alternative underlying implementation i.e. when
781 * MBEDTLS_AES_ALT is defined.
782 */
783 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
784 {
785 mbedtls_printf( "skipped\n" );
786 break;
787 }
788 else if( ret != 0 )
789 {
790 goto exit;
791 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200792
793 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200794 pt_len_test_data[i],
795 iv_test_data[iv_index_test_data[i]],
796 iv_len_test_data[i],
797 additional_test_data[add_index_test_data[i]],
798 add_len_test_data[i],
799 pt_test_data[pt_index_test_data[i]],
800 buf, 16, tag_buf );
Jerome Forissier79013242021-07-28 10:24:04 +0200801#if defined(MBEDTLS_GCM_ALT)
802 /* Allow alternative implementations to only support 12-byte nonces. */
803 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
804 iv_len_test_data[i] != 12 )
805 {
806 mbedtls_printf( "skipped\n" );
807 break;
808 }
809#endif /* defined(MBEDTLS_GCM_ALT) */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100810 if( ret != 0 )
811 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200812
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200813 if ( memcmp( buf, ct_test_data[j * 6 + i],
814 pt_len_test_data[i] ) != 0 ||
815 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200816 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100817 ret = 1;
818 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200819 }
820
821 mbedtls_gcm_free( &ctx );
822
823 if( verbose != 0 )
824 mbedtls_printf( "passed\n" );
825
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100826 mbedtls_gcm_init( &ctx );
827
Jens Wiklander817466c2018-05-22 13:49:31 +0200828 if( verbose != 0 )
829 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100830 key_len, i, "dec" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200831
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200832 ret = mbedtls_gcm_setkey( &ctx, cipher,
833 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100834 key_len );
835 if( ret != 0 )
836 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200837
838 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200839 pt_len_test_data[i],
840 iv_test_data[iv_index_test_data[i]],
841 iv_len_test_data[i],
842 additional_test_data[add_index_test_data[i]],
843 add_len_test_data[i],
844 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200845
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100846 if( ret != 0 )
847 goto exit;
848
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200849 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
850 pt_len_test_data[i] ) != 0 ||
851 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200852 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100853 ret = 1;
854 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200855 }
856
857 mbedtls_gcm_free( &ctx );
858
859 if( verbose != 0 )
860 mbedtls_printf( "passed\n" );
861
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100862 mbedtls_gcm_init( &ctx );
863
Jens Wiklander817466c2018-05-22 13:49:31 +0200864 if( verbose != 0 )
865 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100866 key_len, i, "enc" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200867
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200868 ret = mbedtls_gcm_setkey( &ctx, cipher,
869 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100870 key_len );
871 if( ret != 0 )
872 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200873
874 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200875 iv_test_data[iv_index_test_data[i]],
876 iv_len_test_data[i],
877 additional_test_data[add_index_test_data[i]],
878 add_len_test_data[i] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200879 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100880 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200881
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200882 if( pt_len_test_data[i] > 32 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200883 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200884 size_t rest_len = pt_len_test_data[i] - 32;
885 ret = mbedtls_gcm_update( &ctx, 32,
886 pt_test_data[pt_index_test_data[i]],
887 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200888 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100889 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200890
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200891 ret = mbedtls_gcm_update( &ctx, rest_len,
892 pt_test_data[pt_index_test_data[i]] + 32,
893 buf + 32 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200894 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100895 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200896 }
897 else
898 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200899 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
900 pt_test_data[pt_index_test_data[i]],
901 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200902 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100903 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200904 }
905
906 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100907 if( ret != 0 )
908 goto exit;
909
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200910 if( memcmp( buf, ct_test_data[j * 6 + i],
911 pt_len_test_data[i] ) != 0 ||
912 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200913 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100914 ret = 1;
915 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200916 }
917
918 mbedtls_gcm_free( &ctx );
919
920 if( verbose != 0 )
921 mbedtls_printf( "passed\n" );
922
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100923 mbedtls_gcm_init( &ctx );
924
Jens Wiklander817466c2018-05-22 13:49:31 +0200925 if( verbose != 0 )
926 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100927 key_len, i, "dec" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200928
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200929 ret = mbedtls_gcm_setkey( &ctx, cipher,
930 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100931 key_len );
932 if( ret != 0 )
933 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200934
935 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200936 iv_test_data[iv_index_test_data[i]],
937 iv_len_test_data[i],
938 additional_test_data[add_index_test_data[i]],
939 add_len_test_data[i] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200940 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100941 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200942
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200943 if( pt_len_test_data[i] > 32 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200944 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200945 size_t rest_len = pt_len_test_data[i] - 32;
946 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
947 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200948 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100949 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200950
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200951 ret = mbedtls_gcm_update( &ctx, rest_len,
952 ct_test_data[j * 6 + i] + 32,
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100953 buf + 32 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200954 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100955 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200956 }
957 else
958 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200959 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
960 ct_test_data[j * 6 + i],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100961 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200962 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100963 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200964 }
965
966 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100967 if( ret != 0 )
968 goto exit;
969
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200970 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
971 pt_len_test_data[i] ) != 0 ||
972 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200973 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100974 ret = 1;
975 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200976 }
977
978 mbedtls_gcm_free( &ctx );
979
980 if( verbose != 0 )
981 mbedtls_printf( "passed\n" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200982 }
983 }
984
985 if( verbose != 0 )
986 mbedtls_printf( "\n" );
987
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100988 ret = 0;
989
990exit:
991 if( ret != 0 )
992 {
993 if( verbose != 0 )
994 mbedtls_printf( "failed\n" );
995 mbedtls_gcm_free( &ctx );
996 }
997
998 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200999}
1000
1001#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1002
1003#endif /* MBEDTLS_GCM_C */