blob: cae69525e16e2d159d714a8933813f84bc59f7d0 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * 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.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050035#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000036#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#endif
43
Markku-Juhani O. Saarinen63f21392017-11-20 14:59:12 +000044#if defined(MBEDTLS_ARMV8CE_AES_C)
45#include "mbedtls/armv8ce_aes.h"
46#endif
47
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010049#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000050#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030051#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000052#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#define mbedtls_printf printf
54#endif /* MBEDTLS_PLATFORM_C */
55#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010056
Jaeden Amero15263302017-09-21 12:53:48 +010057#if !defined(MBEDTLS_GCM_ALT)
58
k-stachowiak8ffc92a2018-12-12 14:21:59 +010059/* Parameter validation macros */
60#define GCM_VALIDATE_RET( cond ) \
61 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
62#define GCM_VALIDATE( cond ) \
63 MBEDTLS_INTERNAL_VALIDATE( cond )
64
Paul Bakker89e80c92012-03-20 13:50:09 +000065/*
66 * 32-bit integer manipulation macros (big endian)
67 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000068#ifndef GET_UINT32_BE
69#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000070{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000071 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
72 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
73 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
74 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000075}
76#endif
77
Paul Bakker5c2364c2012-10-01 14:41:15 +000078#ifndef PUT_UINT32_BE
79#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000080{ \
81 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
82 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
83 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
84 (b)[(i) + 3] = (unsigned char) ( (n) ); \
85}
86#endif
87
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010088/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020089 * Initialize a context
90 */
91void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
92{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010093 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020094 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
95}
96
97/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010098 * Precompute small multiples of H, that is set
99 * HH[i] || HL[i] = H times i,
100 * where i is seen as a field element as in [MGV], ie high-order bits
101 * correspond to low powers of P. The result is stored in the same way, that
102 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
103 * corresponds to P^127.
104 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000106{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200107 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000108 uint64_t hi, lo;
109 uint64_t vl, vh;
110 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200111 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200112
Paul Bakker89e80c92012-03-20 13:50:09 +0000113 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200115 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000116
Markku-Juhani O. Saarinen63f21392017-11-20 14:59:12 +0000117#if defined(MBEDTLS_ARMV8CE_AES_C)
118 // we don't do feature testing with ARMv8 cryptography extensions
119 memcpy( ctx ->HL, h, 16 ); // put H at the beginning of buffer
120 return( 0 ); // that's all we need
121#endif
122
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100123 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000124 GET_UINT32_BE( hi, h, 0 );
125 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000126 vh = (uint64_t) hi << 32 | lo;
127
Paul Bakker5c2364c2012-10-01 14:41:15 +0000128 GET_UINT32_BE( hi, h, 8 );
129 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000130 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200131
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100132 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000133 ctx->HL[8] = vl;
134 ctx->HH[8] = vh;
135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200136#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100137 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100138 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100139 return( 0 );
140#endif
141
142 /* 0 corresponds to 0 in GF(2^128) */
143 ctx->HH[0] = 0;
144 ctx->HL[0] = 0;
145
Paul Bakker89e80c92012-03-20 13:50:09 +0000146 for( i = 4; i > 0; i >>= 1 )
147 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200148 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000149 vl = ( vh << 63 ) | ( vl >> 1 );
150 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
151
152 ctx->HL[i] = vl;
153 ctx->HH[i] = vh;
154 }
155
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000156 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000157 {
158 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
159 vh = *HiH;
160 vl = *HiL;
161 for( j = 1; j < i; j++ )
162 {
163 HiH[j] = vh ^ ctx->HH[j];
164 HiL[j] = vl ^ ctx->HL[j];
165 }
166 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200167
168 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000169}
170
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200171int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
172 mbedtls_cipher_id_t cipher,
173 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200174 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000175{
Janos Follath24eed8d2019-11-22 13:21:35 +0000176 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000178
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100179 GCM_VALIDATE_RET( ctx != NULL );
180 GCM_VALIDATE_RET( key != NULL );
181 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
182
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500183 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
184 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200185 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200187
Paul Bakkera0558e02013-09-10 14:25:51 +0200188 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200190
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200191 mbedtls_cipher_free( &ctx->cipher_ctx );
192
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200193 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000194 return( ret );
195
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200196 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200198 {
199 return( ret );
200 }
201
202 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
203 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000204
205 return( 0 );
206}
207
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100208/*
209 * Shoup's method for multiplication use this table with
210 * last4[x] = x times P^128
211 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
212 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000213static const uint64_t last4[16] =
214{
215 0x0000, 0x1c20, 0x3840, 0x2460,
216 0x7080, 0x6ca0, 0x48c0, 0x54e0,
217 0xe100, 0xfd20, 0xd940, 0xc560,
218 0x9180, 0x8da0, 0xa9c0, 0xb5e0
219};
220
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100221/*
222 * Sets output to x times H using the precomputed tables.
223 * x and output are seen as elements of GF(2^128) as in [MGV].
224 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200226 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000227{
228 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000229 unsigned char lo, hi, rem;
230 uint64_t zh, zl;
231
Markku-Juhani O. Saarinen63f21392017-11-20 14:59:12 +0000232#if defined(MBEDTLS_ARMV8CE_AES_C)
233 mbedtls_armv8ce_gcm_mult( output, x, (const unsigned char *) ctx->HL );
234 return;
235#endif
236
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100238 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100239 unsigned char h[16];
240
241 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
242 PUT_UINT32_BE( ctx->HH[8], h, 4 );
243 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
244 PUT_UINT32_BE( ctx->HL[8], h, 12 );
245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100247 return;
248 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100250
Paul Bakker89e80c92012-03-20 13:50:09 +0000251 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000252
253 zh = ctx->HH[lo];
254 zl = ctx->HL[lo];
255
256 for( i = 15; i >= 0; i-- )
257 {
258 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200259 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000260
261 if( i != 15 )
262 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000263 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000264 zl = ( zh << 60 ) | ( zl >> 4 );
265 zh = ( zh >> 4 );
266 zh ^= (uint64_t) last4[rem] << 48;
267 zh ^= ctx->HH[lo];
268 zl ^= ctx->HL[lo];
269
270 }
271
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000272 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000273 zl = ( zh << 60 ) | ( zl >> 4 );
274 zh = ( zh >> 4 );
275 zh ^= (uint64_t) last4[rem] << 48;
276 zh ^= ctx->HH[hi];
277 zl ^= ctx->HL[hi];
278 }
279
Paul Bakker5c2364c2012-10-01 14:41:15 +0000280 PUT_UINT32_BE( zh >> 32, output, 0 );
281 PUT_UINT32_BE( zh, output, 4 );
282 PUT_UINT32_BE( zl >> 32, output, 8 );
283 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000284}
285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200287 int mode,
288 const unsigned char *iv,
289 size_t iv_len,
290 const unsigned char *add,
291 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000292{
Janos Follath24eed8d2019-11-22 13:21:35 +0000293 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000294 unsigned char work_buf[16];
295 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000296 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200297 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000298
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100299 GCM_VALIDATE_RET( ctx != NULL );
300 GCM_VALIDATE_RET( iv != NULL );
301 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
302
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200303 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200304 /* IV is not allowed to be zero length */
305 if( iv_len == 0 ||
306 ( (uint64_t) iv_len ) >> 61 != 0 ||
307 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200308 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200310 }
311
Paul Bakker52cf16c2013-07-26 13:55:38 +0200312 memset( ctx->y, 0x00, sizeof(ctx->y) );
313 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
314
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200315 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200316 ctx->len = 0;
317 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000318
319 if( iv_len == 12 )
320 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200321 memcpy( ctx->y, iv, iv_len );
322 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000323 }
324 else
325 {
326 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000327 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000328
329 p = iv;
330 while( iv_len > 0 )
331 {
332 use_len = ( iv_len < 16 ) ? iv_len : 16;
333
Paul Bakker67f9d532012-10-23 11:49:05 +0000334 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200335 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200336
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200337 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000338
339 iv_len -= use_len;
340 p += use_len;
341 }
342
Paul Bakker67f9d532012-10-23 11:49:05 +0000343 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200344 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000345
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200346 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000347 }
348
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500349 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
350 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200351 {
352 return( ret );
353 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000354
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200355 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000356 p = add;
357 while( add_len > 0 )
358 {
359 use_len = ( add_len < 16 ) ? add_len : 16;
360
Paul Bakker67f9d532012-10-23 11:49:05 +0000361 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200362 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200363
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200364 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000365
366 add_len -= use_len;
367 p += use_len;
368 }
369
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200370 return( 0 );
371}
372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200374 size_t length,
375 const unsigned char *input,
376 unsigned char *output )
377{
Janos Follath24eed8d2019-11-22 13:21:35 +0000378 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200379 unsigned char ectr[16];
380 size_t i;
381 const unsigned char *p;
382 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200383 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100385 GCM_VALIDATE_RET( ctx != NULL );
386 GCM_VALIDATE_RET( length == 0 || input != NULL );
387 GCM_VALIDATE_RET( length == 0 || output != NULL );
388
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200389 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200391
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200392 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
393 * Also check for possible overflow */
394 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100395 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200396 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200398 }
399
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200400 ctx->len += length;
401
Paul Bakker89e80c92012-03-20 13:50:09 +0000402 p = input;
403 while( length > 0 )
404 {
405 use_len = ( length < 16 ) ? length : 16;
406
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100407 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200408 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000409 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200412 &olen ) ) != 0 )
413 {
414 return( ret );
415 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000416
Paul Bakker67f9d532012-10-23 11:49:05 +0000417 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000418 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200420 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000421 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200423 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000424 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200425
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200426 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200427
Paul Bakker89e80c92012-03-20 13:50:09 +0000428 length -= use_len;
429 p += use_len;
430 out_p += use_len;
431 }
432
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200433 return( 0 );
434}
435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200437 unsigned char *tag,
438 size_t tag_len )
439{
440 unsigned char work_buf[16];
441 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100442 uint64_t orig_len;
443 uint64_t orig_add_len;
444
445 GCM_VALIDATE_RET( ctx != NULL );
446 GCM_VALIDATE_RET( tag != NULL );
447
448 orig_len = ctx->len * 8;
449 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200450
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200451 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200453
Andres AG821da842016-09-26 10:09:30 +0100454 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200455
Paul Bakker89e80c92012-03-20 13:50:09 +0000456 if( orig_len || orig_add_len )
457 {
458 memset( work_buf, 0x00, 16 );
459
Paul Bakker0ecdb232013-04-09 11:36:42 +0200460 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
461 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
462 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
463 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000464
Paul Bakker67f9d532012-10-23 11:49:05 +0000465 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200466 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000467
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200468 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000469
Paul Bakker67f9d532012-10-23 11:49:05 +0000470 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200471 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000472 }
473
474 return( 0 );
475}
476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200478 int mode,
479 size_t length,
480 const unsigned char *iv,
481 size_t iv_len,
482 const unsigned char *add,
483 size_t add_len,
484 const unsigned char *input,
485 unsigned char *output,
486 size_t tag_len,
487 unsigned char *tag )
488{
Janos Follath24eed8d2019-11-22 13:21:35 +0000489 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200490
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100491 GCM_VALIDATE_RET( ctx != NULL );
492 GCM_VALIDATE_RET( iv != NULL );
493 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
494 GCM_VALIDATE_RET( length == 0 || input != NULL );
495 GCM_VALIDATE_RET( length == 0 || output != NULL );
496 GCM_VALIDATE_RET( tag != NULL );
497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200499 return( ret );
500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200502 return( ret );
503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200505 return( ret );
506
507 return( 0 );
508}
509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000511 size_t length,
512 const unsigned char *iv,
513 size_t iv_len,
514 const unsigned char *add,
515 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200516 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000517 size_t tag_len,
518 const unsigned char *input,
519 unsigned char *output )
520{
Janos Follath24eed8d2019-11-22 13:21:35 +0000521 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000522 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200523 size_t i;
524 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000525
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100526 GCM_VALIDATE_RET( ctx != NULL );
527 GCM_VALIDATE_RET( iv != NULL );
528 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
529 GCM_VALIDATE_RET( tag != NULL );
530 GCM_VALIDATE_RET( length == 0 || input != NULL );
531 GCM_VALIDATE_RET( length == 0 || output != NULL );
532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100534 iv, iv_len, add, add_len,
535 input, output, tag_len, check_tag ) ) != 0 )
536 {
537 return( ret );
538 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000539
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200540 /* Check tag in "constant-time" */
541 for( diff = 0, i = 0; i < tag_len; i++ )
542 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000543
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200544 if( diff != 0 )
545 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500546 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200548 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000549
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200550 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000551}
552
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200554{
k-stachowiak21298a22018-12-13 17:11:58 +0100555 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100556 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500558 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200559}
560
Jaeden Amero15263302017-09-21 12:53:48 +0100561#endif /* !MBEDTLS_GCM_ALT */
562
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000564/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200565 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 *
567 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
568 */
569#define MAX_TESTS 6
570
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100571static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000572 { 0, 0, 1, 1, 1, 1 };
573
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100574static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000575{
576 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
580 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
581 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
582 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200583 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000584};
585
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100586static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 { 12, 12, 12, 12, 8, 60 };
588
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100589static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 { 0, 0, 1, 1, 1, 2 };
591
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100592static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000593{
594 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00 },
596 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
597 0xde, 0xca, 0xf8, 0x88 },
598 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200599 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000600 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200601 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000602 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200603 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000604 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200605 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000606};
607
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100608static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 { 0, 0, 0, 20, 20, 20 };
610
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100611static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000612 { 0, 0, 0, 1, 1, 1 };
613
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100614static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000615{
616 { 0x00 },
617 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 0xab, 0xad, 0xda, 0xd2 },
620};
621
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100622static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 { 0, 16, 64, 60, 60, 60 };
624
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100625static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 { 0, 0, 1, 1, 1, 1 };
627
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100628static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000629{
630 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
632 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
633 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
634 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
635 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
636 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
637 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
638 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
639 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
640};
641
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100642static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000643{
644 { 0x00 },
645 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
646 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
647 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200648 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000649 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200650 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000651 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200652 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000653 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
654 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
655 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200656 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000657 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200658 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000659 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200660 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000661 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
662 0x3d, 0x58, 0xe0, 0x91 },
663 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200664 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200666 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000667 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200668 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000669 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
670 0xc2, 0x3f, 0x45, 0x98 },
671 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200672 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200674 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200676 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000677 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
678 0x4c, 0x34, 0xae, 0xe5 },
679 { 0x00 },
680 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200681 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200683 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000684 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200685 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000686 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200687 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000688 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
689 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
690 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
694 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
695 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200703 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200705 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200707 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000708 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200709 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200711 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000712 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200715 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
716 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
717 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
718 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
719 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
720 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
721 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
722 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
723 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
724 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
725 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
726 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
727 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
728 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
729 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
730 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
731 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
732 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200734 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000735 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000749};
750
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100751static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000752{
753 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
754 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
755 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
756 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
757 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
760 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
761 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
762 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
763 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
764 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
765 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
766 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
767 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
770 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
771 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200780 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000789};
790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000792{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 unsigned char buf[64];
795 unsigned char tag_buf[16];
796 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000798
799 for( j = 0; j < 3; j++ )
800 {
801 int key_len = 128 + 64 * j;
802
803 for( i = 0; i < MAX_TESTS; i++ )
804 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100805 mbedtls_gcm_init( &ctx );
806
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200807 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100809 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200810
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500811 ret = mbedtls_gcm_setkey( &ctx, cipher,
812 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100813 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100814 /*
815 * AES-192 is an optional feature that may be unavailable when
816 * there is an alternative underlying implementation i.e. when
817 * MBEDTLS_AES_ALT is defined.
818 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300819 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100820 {
821 mbedtls_printf( "skipped\n" );
822 break;
823 }
824 else if( ret != 0 )
825 {
826 goto exit;
827 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000828
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500830 pt_len_test_data[i],
831 iv_test_data[iv_index_test_data[i]],
832 iv_len_test_data[i],
833 additional_test_data[add_index_test_data[i]],
834 add_len_test_data[i],
835 pt_test_data[pt_index_test_data[i]],
836 buf, 16, tag_buf );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100837 if( ret != 0 )
838 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000839
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500840 if ( memcmp( buf, ct_test_data[j * 6 + i],
841 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100842 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000843 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100844 ret = 1;
845 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000846 }
847
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200849
Paul Bakker89e80c92012-03-20 13:50:09 +0000850 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000852
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100853 mbedtls_gcm_init( &ctx );
854
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200855 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100857 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200858
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500859 ret = mbedtls_gcm_setkey( &ctx, cipher,
860 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100861 key_len );
862 if( ret != 0 )
863 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000864
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500866 pt_len_test_data[i],
867 iv_test_data[iv_index_test_data[i]],
868 iv_len_test_data[i],
869 additional_test_data[add_index_test_data[i]],
870 add_len_test_data[i],
871 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000872
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100873 if( ret != 0 )
874 goto exit;
875
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100876 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
877 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100878 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000879 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100880 ret = 1;
881 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000882 }
883
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200885
Paul Bakker89e80c92012-03-20 13:50:09 +0000886 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200888
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100889 mbedtls_gcm_init( &ctx );
890
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200891 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100893 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200894
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500895 ret = mbedtls_gcm_setkey( &ctx, cipher,
896 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100897 key_len );
898 if( ret != 0 )
899 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200900
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500902 iv_test_data[iv_index_test_data[i]],
903 iv_len_test_data[i],
904 additional_test_data[add_index_test_data[i]],
905 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200906 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100907 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200908
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100909 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200910 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100911 size_t rest_len = pt_len_test_data[i] - 32;
912 ret = mbedtls_gcm_update( &ctx, 32,
913 pt_test_data[pt_index_test_data[i]],
914 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200915 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100916 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200917
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100918 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500919 pt_test_data[pt_index_test_data[i]] + 32,
920 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200921 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100922 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200923 }
924 else
925 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100926 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500927 pt_test_data[pt_index_test_data[i]],
928 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200929 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100930 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200931 }
932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100934 if( ret != 0 )
935 goto exit;
936
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500937 if( memcmp( buf, ct_test_data[j * 6 + i],
938 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100939 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200940 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100941 ret = 1;
942 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200943 }
944
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200946
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200947 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200949
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100950 mbedtls_gcm_init( &ctx );
951
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200952 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100954 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200955
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100956 ret = mbedtls_gcm_setkey( &ctx, cipher,
957 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100958 key_len );
959 if( ret != 0 )
960 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200961
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100963 iv_test_data[iv_index_test_data[i]],
964 iv_len_test_data[i],
965 additional_test_data[add_index_test_data[i]],
966 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200967 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100968 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200969
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100970 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200971 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100972 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500973 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
974 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200975 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100976 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200977
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500978 ret = mbedtls_gcm_update( &ctx, rest_len,
979 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100980 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200981 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100982 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200983 }
984 else
985 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100986 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
987 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100988 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200989 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100990 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200991 }
992
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100994 if( ret != 0 )
995 goto exit;
996
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100997 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
998 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100999 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001000 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001001 ret = 1;
1002 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001003 }
1004
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001006
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001007 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001008 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001009 }
1010 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001011
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001012 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001014
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001015 ret = 0;
1016
1017exit:
1018 if( ret != 0 )
1019 {
1020 if( verbose != 0 )
1021 mbedtls_printf( "failed\n" );
1022 mbedtls_gcm_free( &ctx );
1023 }
1024
1025 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001026}
1027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030#endif /* MBEDTLS_GCM_C */