blob: ddd2d4eeffffbcf470f8ff02061f8c74d8e5b141 [file] [log] [blame]
Edison Aic6672fd2018-02-28 15:01:47 +08001// SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02002/*
3 * NIST SP800-38D compliant GCM implementation
4 *
5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
23 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
24 *
25 * See also:
26 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
27 *
28 * We use the algorithm described as Shoup's method with 4-bit tables in
29 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
30 */
31
32#if !defined(MBEDTLS_CONFIG_FILE)
33#include "mbedtls/config.h"
34#else
35#include MBEDTLS_CONFIG_FILE
36#endif
37
38#if defined(MBEDTLS_GCM_C)
39
40#include "mbedtls/gcm.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010041#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020042#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020043
44#include <string.h>
45
46#if defined(MBEDTLS_AESNI_C)
47#include "mbedtls/aesni.h"
48#endif
49
50#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010051#include "mbedtls/aes.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020052#include "mbedtls/platform.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010053#if !defined(MBEDTLS_PLATFORM_C)
Jens Wiklander817466c2018-05-22 13:49:31 +020054#include <stdio.h>
55#define mbedtls_printf printf
56#endif /* MBEDTLS_PLATFORM_C */
57#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
58
Jens Wiklander3d3b0592019-03-20 15:30:29 +010059#if !defined(MBEDTLS_GCM_ALT)
60
61/* Parameter validation macros */
62#define GCM_VALIDATE_RET( cond ) \
63 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
64#define GCM_VALIDATE( cond ) \
65 MBEDTLS_INTERNAL_VALIDATE( cond )
66
Jens Wiklander817466c2018-05-22 13:49:31 +020067/*
68 * 32-bit integer manipulation macros (big endian)
69 */
70#ifndef GET_UINT32_BE
71#define GET_UINT32_BE(n,b,i) \
72{ \
73 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
74 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
75 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
76 | ( (uint32_t) (b)[(i) + 3] ); \
77}
78#endif
79
80#ifndef PUT_UINT32_BE
81#define PUT_UINT32_BE(n,b,i) \
82{ \
83 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
84 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
85 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
86 (b)[(i) + 3] = (unsigned char) ( (n) ); \
87}
88#endif
89
Jens Wiklander817466c2018-05-22 13:49:31 +020090/*
91 * Initialize a context
92 */
93void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
94{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010095 GCM_VALIDATE( ctx != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +020096 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
97}
98
99/*
100 * Precompute small multiples of H, that is set
101 * HH[i] || HL[i] = H times i,
102 * where i is seen as a field element as in [MGV], ie high-order bits
103 * correspond to low powers of P. The result is stored in the same way, that
104 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
105 * corresponds to P^127.
106 */
107static int gcm_gen_table( mbedtls_gcm_context *ctx )
108{
109 int ret, i, j;
110 uint64_t hi, lo;
111 uint64_t vl, vh;
112 unsigned char h[16];
113 size_t olen = 0;
114
115 memset( h, 0, 16 );
116 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
117 return( ret );
118
119 /* pack h as two 64-bits ints, big-endian */
120 GET_UINT32_BE( hi, h, 0 );
121 GET_UINT32_BE( lo, h, 4 );
122 vh = (uint64_t) hi << 32 | lo;
123
124 GET_UINT32_BE( hi, h, 8 );
125 GET_UINT32_BE( lo, h, 12 );
126 vl = (uint64_t) hi << 32 | lo;
127
128 /* 8 = 1000 corresponds to 1 in GF(2^128) */
129 ctx->HL[8] = vl;
130 ctx->HH[8] = vh;
131
132#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
133 /* With CLMUL support, we need only h, not the rest of the table */
134 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
135 return( 0 );
136#endif
137
138 /* 0 corresponds to 0 in GF(2^128) */
139 ctx->HH[0] = 0;
140 ctx->HL[0] = 0;
141
142 for( i = 4; i > 0; i >>= 1 )
143 {
144 uint32_t T = ( vl & 1 ) * 0xe1000000U;
145 vl = ( vh << 63 ) | ( vl >> 1 );
146 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
147
148 ctx->HL[i] = vl;
149 ctx->HH[i] = vh;
150 }
151
152 for( i = 2; i <= 8; i *= 2 )
153 {
154 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
155 vh = *HiH;
156 vl = *HiL;
157 for( j = 1; j < i; j++ )
158 {
159 HiH[j] = vh ^ ctx->HH[j];
160 HiL[j] = vl ^ ctx->HL[j];
161 }
162 }
163
164 return( 0 );
165}
166
167int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
168 mbedtls_cipher_id_t cipher,
169 const unsigned char *key,
170 unsigned int keybits )
171{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200172 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200173 const mbedtls_cipher_info_t *cipher_info;
174
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100175 GCM_VALIDATE_RET( ctx != NULL );
176 GCM_VALIDATE_RET( key != NULL );
177 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
178
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200179 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
180 MBEDTLS_MODE_ECB );
Jens Wiklander817466c2018-05-22 13:49:31 +0200181 if( cipher_info == NULL )
182 return( MBEDTLS_ERR_GCM_BAD_INPUT );
183
184 if( cipher_info->block_size != 16 )
185 return( MBEDTLS_ERR_GCM_BAD_INPUT );
186
187 mbedtls_cipher_free( &ctx->cipher_ctx );
188
189 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
190 return( ret );
191
192 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
193 MBEDTLS_ENCRYPT ) ) != 0 )
194 {
195 return( ret );
196 }
197
198 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
199 return( ret );
200
201 return( 0 );
202}
203
204/*
205 * Shoup's method for multiplication use this table with
206 * last4[x] = x times P^128
207 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
208 */
209static const uint64_t last4[16] =
210{
211 0x0000, 0x1c20, 0x3840, 0x2460,
212 0x7080, 0x6ca0, 0x48c0, 0x54e0,
213 0xe100, 0xfd20, 0xd940, 0xc560,
214 0x9180, 0x8da0, 0xa9c0, 0xb5e0
215};
216
217/*
218 * Sets output to x times H using the precomputed tables.
219 * x and output are seen as elements of GF(2^128) as in [MGV].
220 */
221static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
222 unsigned char output[16] )
223{
224 int i = 0;
225 unsigned char lo, hi, rem;
226 uint64_t zh, zl;
227
228#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
229 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
230 unsigned char h[16];
231
232 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
233 PUT_UINT32_BE( ctx->HH[8], h, 4 );
234 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
235 PUT_UINT32_BE( ctx->HL[8], h, 12 );
236
237 mbedtls_aesni_gcm_mult( output, x, h );
238 return;
239 }
240#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
241
242 lo = x[15] & 0xf;
243
244 zh = ctx->HH[lo];
245 zl = ctx->HL[lo];
246
247 for( i = 15; i >= 0; i-- )
248 {
249 lo = x[i] & 0xf;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200250 hi = ( x[i] >> 4 ) & 0xf;
Jens Wiklander817466c2018-05-22 13:49:31 +0200251
252 if( i != 15 )
253 {
254 rem = (unsigned char) zl & 0xf;
255 zl = ( zh << 60 ) | ( zl >> 4 );
256 zh = ( zh >> 4 );
257 zh ^= (uint64_t) last4[rem] << 48;
258 zh ^= ctx->HH[lo];
259 zl ^= ctx->HL[lo];
260
261 }
262
263 rem = (unsigned char) zl & 0xf;
264 zl = ( zh << 60 ) | ( zl >> 4 );
265 zh = ( zh >> 4 );
266 zh ^= (uint64_t) last4[rem] << 48;
267 zh ^= ctx->HH[hi];
268 zl ^= ctx->HL[hi];
269 }
270
271 PUT_UINT32_BE( zh >> 32, output, 0 );
272 PUT_UINT32_BE( zh, output, 4 );
273 PUT_UINT32_BE( zl >> 32, output, 8 );
274 PUT_UINT32_BE( zl, output, 12 );
275}
276
277int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
278 int mode,
279 const unsigned char *iv,
280 size_t iv_len,
281 const unsigned char *add,
282 size_t add_len )
283{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200284 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200285 unsigned char work_buf[16];
286 size_t i;
287 const unsigned char *p;
288 size_t use_len, olen = 0;
289
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100290 GCM_VALIDATE_RET( ctx != NULL );
291 GCM_VALIDATE_RET( iv != NULL );
292 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
293
Jens Wiklander817466c2018-05-22 13:49:31 +0200294 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
295 /* IV is not allowed to be zero length */
296 if( iv_len == 0 ||
297 ( (uint64_t) iv_len ) >> 61 != 0 ||
298 ( (uint64_t) add_len ) >> 61 != 0 )
299 {
300 return( MBEDTLS_ERR_GCM_BAD_INPUT );
301 }
302
303 memset( ctx->y, 0x00, sizeof(ctx->y) );
304 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
305
306 ctx->mode = mode;
307 ctx->len = 0;
308 ctx->add_len = 0;
309
310 if( iv_len == 12 )
311 {
312 memcpy( ctx->y, iv, iv_len );
313 ctx->y[15] = 1;
314 }
315 else
316 {
317 memset( work_buf, 0x00, 16 );
318 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
319
320 p = iv;
321 while( iv_len > 0 )
322 {
323 use_len = ( iv_len < 16 ) ? iv_len : 16;
324
325 for( i = 0; i < use_len; i++ )
326 ctx->y[i] ^= p[i];
327
328 gcm_mult( ctx, ctx->y, ctx->y );
329
330 iv_len -= use_len;
331 p += use_len;
332 }
333
334 for( i = 0; i < 16; i++ )
335 ctx->y[i] ^= work_buf[i];
336
337 gcm_mult( ctx, ctx->y, ctx->y );
338 }
339
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200340 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
341 ctx->base_ectr, &olen ) ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200342 {
343 return( ret );
344 }
345
346 ctx->add_len = add_len;
347 p = add;
348 while( add_len > 0 )
349 {
350 use_len = ( add_len < 16 ) ? add_len : 16;
351
352 for( i = 0; i < use_len; i++ )
353 ctx->buf[i] ^= p[i];
354
355 gcm_mult( ctx, ctx->buf, ctx->buf );
356
357 add_len -= use_len;
358 p += use_len;
359 }
360
361 return( 0 );
362}
363
364int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
365 size_t length,
366 const unsigned char *input,
367 unsigned char *output )
368{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200369 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200370 unsigned char ectr[16];
371 size_t i;
372 const unsigned char *p;
373 unsigned char *out_p = output;
374 size_t use_len, olen = 0;
375
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100376 GCM_VALIDATE_RET( ctx != NULL );
377 GCM_VALIDATE_RET( length == 0 || input != NULL );
378 GCM_VALIDATE_RET( length == 0 || output != NULL );
379
Jens Wiklander817466c2018-05-22 13:49:31 +0200380 if( output > input && (size_t) ( output - input ) < length )
381 return( MBEDTLS_ERR_GCM_BAD_INPUT );
382
383 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
384 * Also check for possible overflow */
385 if( ctx->len + length < ctx->len ||
386 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
387 {
388 return( MBEDTLS_ERR_GCM_BAD_INPUT );
389 }
390
391 ctx->len += length;
392
393 p = input;
394 while( length > 0 )
395 {
396 use_len = ( length < 16 ) ? length : 16;
397
398 for( i = 16; i > 12; i-- )
399 if( ++ctx->y[i - 1] != 0 )
400 break;
401
402 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
403 &olen ) ) != 0 )
404 {
405 return( ret );
406 }
407
408 for( i = 0; i < use_len; i++ )
409 {
410 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
411 ctx->buf[i] ^= p[i];
412 out_p[i] = ectr[i] ^ p[i];
413 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
414 ctx->buf[i] ^= out_p[i];
415 }
416
417 gcm_mult( ctx, ctx->buf, ctx->buf );
418
419 length -= use_len;
420 p += use_len;
421 out_p += use_len;
422 }
423
424 return( 0 );
425}
426
427int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
428 unsigned char *tag,
429 size_t tag_len )
430{
431 unsigned char work_buf[16];
432 size_t i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100433 uint64_t orig_len;
434 uint64_t orig_add_len;
435
436 GCM_VALIDATE_RET( ctx != NULL );
437 GCM_VALIDATE_RET( tag != NULL );
438
439 orig_len = ctx->len * 8;
440 orig_add_len = ctx->add_len * 8;
Jens Wiklander817466c2018-05-22 13:49:31 +0200441
442 if( tag_len > 16 || tag_len < 4 )
443 return( MBEDTLS_ERR_GCM_BAD_INPUT );
444
445 memcpy( tag, ctx->base_ectr, tag_len );
446
447 if( orig_len || orig_add_len )
448 {
449 memset( work_buf, 0x00, 16 );
450
451 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
452 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
453 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
454 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
455
456 for( i = 0; i < 16; i++ )
457 ctx->buf[i] ^= work_buf[i];
458
459 gcm_mult( ctx, ctx->buf, ctx->buf );
460
461 for( i = 0; i < tag_len; i++ )
462 tag[i] ^= ctx->buf[i];
463 }
464
465 return( 0 );
466}
467
468int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
469 int mode,
470 size_t length,
471 const unsigned char *iv,
472 size_t iv_len,
473 const unsigned char *add,
474 size_t add_len,
475 const unsigned char *input,
476 unsigned char *output,
477 size_t tag_len,
478 unsigned char *tag )
479{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200480 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200481
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100482 GCM_VALIDATE_RET( ctx != NULL );
483 GCM_VALIDATE_RET( iv != NULL );
484 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
485 GCM_VALIDATE_RET( length == 0 || input != NULL );
486 GCM_VALIDATE_RET( length == 0 || output != NULL );
487 GCM_VALIDATE_RET( tag != NULL );
488
Jens Wiklander817466c2018-05-22 13:49:31 +0200489 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
490 return( ret );
491
492 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
493 return( ret );
494
495 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
496 return( ret );
497
498 return( 0 );
499}
500
501int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
502 size_t length,
503 const unsigned char *iv,
504 size_t iv_len,
505 const unsigned char *add,
506 size_t add_len,
507 const unsigned char *tag,
508 size_t tag_len,
509 const unsigned char *input,
510 unsigned char *output )
511{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200512 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200513 unsigned char check_tag[16];
514 size_t i;
515 int diff;
516
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100517 GCM_VALIDATE_RET( ctx != NULL );
518 GCM_VALIDATE_RET( iv != NULL );
519 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
520 GCM_VALIDATE_RET( tag != NULL );
521 GCM_VALIDATE_RET( length == 0 || input != NULL );
522 GCM_VALIDATE_RET( length == 0 || output != NULL );
523
Jens Wiklander817466c2018-05-22 13:49:31 +0200524 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
525 iv, iv_len, add, add_len,
526 input, output, tag_len, check_tag ) ) != 0 )
527 {
528 return( ret );
529 }
530
531 /* Check tag in "constant-time" */
532 for( diff = 0, i = 0; i < tag_len; i++ )
533 diff |= tag[i] ^ check_tag[i];
534
535 if( diff != 0 )
536 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100537 mbedtls_platform_zeroize( output, length );
Jens Wiklander817466c2018-05-22 13:49:31 +0200538 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
539 }
540
541 return( 0 );
542}
543
544void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
545{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100546 if( ctx == NULL )
547 return;
Jens Wiklander817466c2018-05-22 13:49:31 +0200548 mbedtls_cipher_free( &ctx->cipher_ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100549 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200550}
551
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100552#endif /* !MBEDTLS_GCM_ALT */
553
Jens Wiklander817466c2018-05-22 13:49:31 +0200554#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
555/*
556 * AES-GCM test vectors from:
557 *
558 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
559 */
560#define MAX_TESTS 6
561
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200562static const int key_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200563 { 0, 0, 1, 1, 1, 1 };
564
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200565static const unsigned char key_test_data[MAX_TESTS][32] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200566{
567 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
571 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
572 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
573 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
574 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
575};
576
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200577static const size_t iv_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200578 { 12, 12, 12, 12, 8, 60 };
579
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200580static const int iv_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200581 { 0, 0, 1, 1, 1, 2 };
582
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200583static const unsigned char iv_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200584{
585 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00 },
587 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
588 0xde, 0xca, 0xf8, 0x88 },
589 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
590 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
591 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
592 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
593 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
594 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
595 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
596 0xa6, 0x37, 0xb3, 0x9b },
597};
598
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200599static const size_t add_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200600 { 0, 0, 0, 20, 20, 20 };
601
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200602static const int add_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200603 { 0, 0, 0, 1, 1, 1 };
604
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200605static const unsigned char additional_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200606{
607 { 0x00 },
608 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
609 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
610 0xab, 0xad, 0xda, 0xd2 },
611};
612
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200613static const size_t pt_len_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200614 { 0, 16, 64, 60, 60, 60 };
615
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200616static const int pt_index_test_data[MAX_TESTS] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200617 { 0, 0, 1, 1, 1, 1 };
618
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200619static const unsigned char pt_test_data[MAX_TESTS][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200620{
621 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
623 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
624 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
625 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
626 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
627 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
628 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
629 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
630 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
631};
632
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200633static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200634{
635 { 0x00 },
636 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
637 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
638 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
639 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
640 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
641 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
642 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
643 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
644 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
645 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
646 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
647 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
648 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
649 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
650 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
651 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
652 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
653 0x3d, 0x58, 0xe0, 0x91 },
654 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
655 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
656 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
657 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
658 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
659 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
660 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
661 0xc2, 0x3f, 0x45, 0x98 },
662 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
663 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
664 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
665 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
666 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
667 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
668 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
669 0x4c, 0x34, 0xae, 0xe5 },
670 { 0x00 },
671 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
672 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
673 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
674 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
675 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
676 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
677 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
678 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
679 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
680 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
681 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
682 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
683 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
684 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
685 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
686 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
687 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
688 0xcc, 0xda, 0x27, 0x10 },
689 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
690 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
691 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
692 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
693 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
694 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
695 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
696 0xa0, 0xf0, 0x62, 0xf7 },
697 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
698 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
699 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
700 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
701 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
702 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
703 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
704 0xe9, 0xb7, 0x37, 0x3b },
705 { 0x00 },
706 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
707 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
708 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
709 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
710 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
711 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
712 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
713 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
714 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
715 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
716 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
717 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
718 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
719 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
720 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
721 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
722 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
723 0xbc, 0xc9, 0xf6, 0x62 },
724 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
725 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
726 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
727 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
728 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
729 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
730 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
731 0xf4, 0x7c, 0x9b, 0x1f },
732 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
733 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
734 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
735 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
736 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
737 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
738 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
739 0x44, 0xae, 0x7e, 0x3f },
740};
741
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200742static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200743{
744 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
745 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
746 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
747 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
748 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
749 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
750 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
751 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
752 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
753 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
754 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
755 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
756 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
757 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
758 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
759 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
760 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
761 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
762 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
763 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
764 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
765 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
766 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
767 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
768 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
769 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
770 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
771 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
772 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
773 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
774 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
775 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
776 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
777 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
778 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
779 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
780};
781
782int mbedtls_gcm_self_test( int verbose )
783{
784 mbedtls_gcm_context ctx;
785 unsigned char buf[64];
786 unsigned char tag_buf[16];
787 int i, j, ret;
788 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
789
Jens Wiklander817466c2018-05-22 13:49:31 +0200790 for( j = 0; j < 3; j++ )
791 {
792 int key_len = 128 + 64 * j;
793
794 for( i = 0; i < MAX_TESTS; i++ )
795 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100796 mbedtls_gcm_init( &ctx );
797
Jens Wiklander817466c2018-05-22 13:49:31 +0200798 if( verbose != 0 )
799 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100800 key_len, i, "enc" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200801
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200802 ret = mbedtls_gcm_setkey( &ctx, cipher,
803 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100804 key_len );
805 /*
806 * AES-192 is an optional feature that may be unavailable when
807 * there is an alternative underlying implementation i.e. when
808 * MBEDTLS_AES_ALT is defined.
809 */
810 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
811 {
812 mbedtls_printf( "skipped\n" );
813 break;
814 }
815 else if( ret != 0 )
816 {
817 goto exit;
818 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200819
820 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200821 pt_len_test_data[i],
822 iv_test_data[iv_index_test_data[i]],
823 iv_len_test_data[i],
824 additional_test_data[add_index_test_data[i]],
825 add_len_test_data[i],
826 pt_test_data[pt_index_test_data[i]],
827 buf, 16, tag_buf );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100828 if( ret != 0 )
829 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200830
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200831 if ( memcmp( buf, ct_test_data[j * 6 + i],
832 pt_len_test_data[i] ) != 0 ||
833 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200834 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100835 ret = 1;
836 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200837 }
838
839 mbedtls_gcm_free( &ctx );
840
841 if( verbose != 0 )
842 mbedtls_printf( "passed\n" );
843
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100844 mbedtls_gcm_init( &ctx );
845
Jens Wiklander817466c2018-05-22 13:49:31 +0200846 if( verbose != 0 )
847 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100848 key_len, i, "dec" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200849
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200850 ret = mbedtls_gcm_setkey( &ctx, cipher,
851 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100852 key_len );
853 if( ret != 0 )
854 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200855
856 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200857 pt_len_test_data[i],
858 iv_test_data[iv_index_test_data[i]],
859 iv_len_test_data[i],
860 additional_test_data[add_index_test_data[i]],
861 add_len_test_data[i],
862 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200863
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100864 if( ret != 0 )
865 goto exit;
866
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200867 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
868 pt_len_test_data[i] ) != 0 ||
869 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200870 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100871 ret = 1;
872 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200873 }
874
875 mbedtls_gcm_free( &ctx );
876
877 if( verbose != 0 )
878 mbedtls_printf( "passed\n" );
879
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100880 mbedtls_gcm_init( &ctx );
881
Jens Wiklander817466c2018-05-22 13:49:31 +0200882 if( verbose != 0 )
883 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100884 key_len, i, "enc" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200885
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200886 ret = mbedtls_gcm_setkey( &ctx, cipher,
887 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100888 key_len );
889 if( ret != 0 )
890 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200891
892 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200893 iv_test_data[iv_index_test_data[i]],
894 iv_len_test_data[i],
895 additional_test_data[add_index_test_data[i]],
896 add_len_test_data[i] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200897 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100898 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200899
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200900 if( pt_len_test_data[i] > 32 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200901 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200902 size_t rest_len = pt_len_test_data[i] - 32;
903 ret = mbedtls_gcm_update( &ctx, 32,
904 pt_test_data[pt_index_test_data[i]],
905 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200906 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100907 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200908
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200909 ret = mbedtls_gcm_update( &ctx, rest_len,
910 pt_test_data[pt_index_test_data[i]] + 32,
911 buf + 32 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200912 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100913 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200914 }
915 else
916 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200917 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
918 pt_test_data[pt_index_test_data[i]],
919 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200920 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100921 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200922 }
923
924 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100925 if( ret != 0 )
926 goto exit;
927
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200928 if( memcmp( buf, ct_test_data[j * 6 + i],
929 pt_len_test_data[i] ) != 0 ||
930 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200931 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100932 ret = 1;
933 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200934 }
935
936 mbedtls_gcm_free( &ctx );
937
938 if( verbose != 0 )
939 mbedtls_printf( "passed\n" );
940
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100941 mbedtls_gcm_init( &ctx );
942
Jens Wiklander817466c2018-05-22 13:49:31 +0200943 if( verbose != 0 )
944 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100945 key_len, i, "dec" );
Jens Wiklander817466c2018-05-22 13:49:31 +0200946
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200947 ret = mbedtls_gcm_setkey( &ctx, cipher,
948 key_test_data[key_index_test_data[i]],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100949 key_len );
950 if( ret != 0 )
951 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200952
953 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200954 iv_test_data[iv_index_test_data[i]],
955 iv_len_test_data[i],
956 additional_test_data[add_index_test_data[i]],
957 add_len_test_data[i] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200958 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100959 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200960
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200961 if( pt_len_test_data[i] > 32 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200962 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200963 size_t rest_len = pt_len_test_data[i] - 32;
964 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
965 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200966 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100967 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200968
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200969 ret = mbedtls_gcm_update( &ctx, rest_len,
970 ct_test_data[j * 6 + i] + 32,
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100971 buf + 32 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200972 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100973 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200974 }
975 else
976 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200977 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
978 ct_test_data[j * 6 + i],
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100979 buf );
Jens Wiklander817466c2018-05-22 13:49:31 +0200980 if( ret != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100981 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200982 }
983
984 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100985 if( ret != 0 )
986 goto exit;
987
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200988 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
989 pt_len_test_data[i] ) != 0 ||
990 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200991 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100992 ret = 1;
993 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200994 }
995
996 mbedtls_gcm_free( &ctx );
997
998 if( verbose != 0 )
999 mbedtls_printf( "passed\n" );
Jens Wiklander817466c2018-05-22 13:49:31 +02001000 }
1001 }
1002
1003 if( verbose != 0 )
1004 mbedtls_printf( "\n" );
1005
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001006 ret = 0;
1007
1008exit:
1009 if( ret != 0 )
1010 {
1011 if( verbose != 0 )
1012 mbedtls_printf( "failed\n" );
1013 mbedtls_gcm_free( &ctx );
1014 }
1015
1016 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02001017}
1018
1019#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1020
1021#endif /* MBEDTLS_GCM_C */