blob: 441ed69a82f7e611c89c6cfd1f442bf25fe8fedc [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Paul Bakker89e80c92012-03-20 13:50:09 +000045 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010046
Paul Bakker89e80c92012-03-20 13:50:09 +000047/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010048 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
49 *
50 * See also:
51 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
52 *
53 * We use the algorithm described as Shoup's method with 4-bit tables in
54 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000055 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000058#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020059#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020061#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000062
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000064
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000065#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050066#include "mbedtls/platform_util.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000067
Rich Evans00ab4702015-02-06 13:43:58 +000068#include <string.h>
69
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000071#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010072#endif
73
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010075#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000076#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030077#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000078#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079#define mbedtls_printf printf
80#endif /* MBEDTLS_PLATFORM_C */
81#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010082
Jaeden Amero15263302017-09-21 12:53:48 +010083#if !defined(MBEDTLS_GCM_ALT)
84
k-stachowiak8ffc92a2018-12-12 14:21:59 +010085/* Parameter validation macros */
86#define GCM_VALIDATE_RET( cond ) \
87 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
88#define GCM_VALIDATE( cond ) \
89 MBEDTLS_INTERNAL_VALIDATE( cond )
90
Paul Bakker89e80c92012-03-20 13:50:09 +000091/*
92 * 32-bit integer manipulation macros (big endian)
93 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000094#ifndef GET_UINT32_BE
95#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000096{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000097 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
98 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
99 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
100 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +0000101}
102#endif
103
Paul Bakker5c2364c2012-10-01 14:41:15 +0000104#ifndef PUT_UINT32_BE
105#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +0000106{ \
107 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
108 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
109 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
110 (b)[(i) + 3] = (unsigned char) ( (n) ); \
111}
112#endif
113
openluopworlded798a92021-11-05 19:40:40 +0800114#ifndef PUT_UINT64_BE
115#define PUT_UINT64_BE( n, b, i ) \
116{ \
117 ( b )[( i ) ] = (unsigned char) ( ( (n) >> 56 ) & 0xff ); \
118 ( b )[( i ) + 1] = (unsigned char) ( ( (n) >> 48 ) & 0xff ); \
119 ( b )[( i ) + 2] = (unsigned char) ( ( (n) >> 40 ) & 0xff ); \
120 ( b )[( i ) + 3] = (unsigned char) ( ( (n) >> 32 ) & 0xff ); \
121 ( b )[( i ) + 4] = (unsigned char) ( ( (n) >> 24 ) & 0xff ); \
122 ( b )[( i ) + 5] = (unsigned char) ( ( (n) >> 16 ) & 0xff ); \
123 ( b )[( i ) + 6] = (unsigned char) ( ( (n) >> 8 ) & 0xff ); \
124 ( b )[( i ) + 7] = (unsigned char) ( ( (n) ) & 0xff ); \
125}
126#endif
127
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100128/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200129 * Initialize a context
130 */
131void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
132{
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100133 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200134 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
135}
136
137/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100138 * Precompute small multiples of H, that is set
139 * HH[i] || HL[i] = H times i,
140 * where i is seen as a field element as in [MGV], ie high-order bits
141 * correspond to low powers of P. The result is stored in the same way, that
142 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
143 * corresponds to P^127.
144 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000146{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200147 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000148 uint64_t hi, lo;
149 uint64_t vl, vh;
150 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200151 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200152
Paul Bakker89e80c92012-03-20 13:50:09 +0000153 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200155 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000156
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100157 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000158 GET_UINT32_BE( hi, h, 0 );
159 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000160 vh = (uint64_t) hi << 32 | lo;
161
Paul Bakker5c2364c2012-10-01 14:41:15 +0000162 GET_UINT32_BE( hi, h, 8 );
163 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000164 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200165
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100166 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000167 ctx->HL[8] = vl;
168 ctx->HH[8] = vh;
169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100171 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100172 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100173 return( 0 );
174#endif
175
176 /* 0 corresponds to 0 in GF(2^128) */
177 ctx->HH[0] = 0;
178 ctx->HL[0] = 0;
179
Paul Bakker89e80c92012-03-20 13:50:09 +0000180 for( i = 4; i > 0; i >>= 1 )
181 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200182 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000183 vl = ( vh << 63 ) | ( vl >> 1 );
184 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
185
186 ctx->HL[i] = vl;
187 ctx->HH[i] = vh;
188 }
189
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000190 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000191 {
192 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
193 vh = *HiH;
194 vl = *HiL;
195 for( j = 1; j < i; j++ )
196 {
197 HiH[j] = vh ^ ctx->HH[j];
198 HiL[j] = vl ^ ctx->HL[j];
199 }
200 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200201
202 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000203}
204
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200205int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
206 mbedtls_cipher_id_t cipher,
207 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200208 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000209{
210 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000212
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100213 GCM_VALIDATE_RET( ctx != NULL );
214 GCM_VALIDATE_RET( key != NULL );
215 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
216
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200217 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200218 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200220
Paul Bakkera0558e02013-09-10 14:25:51 +0200221 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200223
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200224 mbedtls_cipher_free( &ctx->cipher_ctx );
225
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200226 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000227 return( ret );
228
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200229 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200231 {
232 return( ret );
233 }
234
235 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
236 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000237
238 return( 0 );
239}
240
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100241/*
242 * Shoup's method for multiplication use this table with
243 * last4[x] = x times P^128
244 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
245 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000246static const uint64_t last4[16] =
247{
248 0x0000, 0x1c20, 0x3840, 0x2460,
249 0x7080, 0x6ca0, 0x48c0, 0x54e0,
250 0xe100, 0xfd20, 0xd940, 0xc560,
251 0x9180, 0x8da0, 0xa9c0, 0xb5e0
252};
253
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100254/*
255 * Sets output to x times H using the precomputed tables.
256 * x and output are seen as elements of GF(2^128) as in [MGV].
257 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200259 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000260{
261 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000262 unsigned char lo, hi, rem;
263 uint64_t zh, zl;
264
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100266 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100267 unsigned char h[16];
268
269 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
270 PUT_UINT32_BE( ctx->HH[8], h, 4 );
271 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
272 PUT_UINT32_BE( ctx->HL[8], h, 12 );
273
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100275 return;
276 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100278
Paul Bakker89e80c92012-03-20 13:50:09 +0000279 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000280
281 zh = ctx->HH[lo];
282 zl = ctx->HL[lo];
283
284 for( i = 15; i >= 0; i-- )
285 {
286 lo = x[i] & 0xf;
287 hi = x[i] >> 4;
288
289 if( i != 15 )
290 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000291 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000292 zl = ( zh << 60 ) | ( zl >> 4 );
293 zh = ( zh >> 4 );
294 zh ^= (uint64_t) last4[rem] << 48;
295 zh ^= ctx->HH[lo];
296 zl ^= ctx->HL[lo];
297
298 }
299
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000300 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000301 zl = ( zh << 60 ) | ( zl >> 4 );
302 zh = ( zh >> 4 );
303 zh ^= (uint64_t) last4[rem] << 48;
304 zh ^= ctx->HH[hi];
305 zl ^= ctx->HL[hi];
306 }
307
Paul Bakker5c2364c2012-10-01 14:41:15 +0000308 PUT_UINT32_BE( zh >> 32, output, 0 );
309 PUT_UINT32_BE( zh, output, 4 );
310 PUT_UINT32_BE( zl >> 32, output, 8 );
311 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000312}
313
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200315 int mode,
316 const unsigned char *iv,
317 size_t iv_len,
318 const unsigned char *add,
319 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000320{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200321 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000322 unsigned char work_buf[16];
323 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000324 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200325 size_t use_len, olen = 0;
openluopworlded798a92021-11-05 19:40:40 +0800326 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000327
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100328 GCM_VALIDATE_RET( ctx != NULL );
329 GCM_VALIDATE_RET( iv != NULL );
330 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
331
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200332 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200333 /* IV is not allowed to be zero length */
334 if( iv_len == 0 ||
335 ( (uint64_t) iv_len ) >> 61 != 0 ||
336 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200337 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200339 }
340
Paul Bakker52cf16c2013-07-26 13:55:38 +0200341 memset( ctx->y, 0x00, sizeof(ctx->y) );
342 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
343
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200344 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200345 ctx->len = 0;
346 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000347
348 if( iv_len == 12 )
349 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200350 memcpy( ctx->y, iv, iv_len );
351 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000352 }
353 else
354 {
355 memset( work_buf, 0x00, 16 );
openluopworlded798a92021-11-05 19:40:40 +0800356 iv_bits = (uint64_t)iv_len * 8;
357 PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000358
359 p = iv;
360 while( iv_len > 0 )
361 {
362 use_len = ( iv_len < 16 ) ? iv_len : 16;
363
Paul Bakker67f9d532012-10-23 11:49:05 +0000364 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200365 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200366
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200367 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000368
369 iv_len -= use_len;
370 p += use_len;
371 }
372
Paul Bakker67f9d532012-10-23 11:49:05 +0000373 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200374 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000375
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200376 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000377 }
378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200380 &olen ) ) != 0 )
381 {
382 return( ret );
383 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000384
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200385 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000386 p = add;
387 while( add_len > 0 )
388 {
389 use_len = ( add_len < 16 ) ? add_len : 16;
390
Paul Bakker67f9d532012-10-23 11:49:05 +0000391 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200392 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200393
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200394 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000395
396 add_len -= use_len;
397 p += use_len;
398 }
399
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200400 return( 0 );
401}
402
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200404 size_t length,
405 const unsigned char *input,
406 unsigned char *output )
407{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200408 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200409 unsigned char ectr[16];
410 size_t i;
411 const unsigned char *p;
412 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200413 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200414
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100415 GCM_VALIDATE_RET( ctx != NULL );
416 GCM_VALIDATE_RET( length == 0 || input != NULL );
417 GCM_VALIDATE_RET( length == 0 || output != NULL );
418
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200419 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200421
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200422 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
423 * Also check for possible overflow */
424 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100425 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200426 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200428 }
429
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200430 ctx->len += length;
431
Paul Bakker89e80c92012-03-20 13:50:09 +0000432 p = input;
433 while( length > 0 )
434 {
435 use_len = ( length < 16 ) ? length : 16;
436
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100437 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200438 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000439 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200442 &olen ) ) != 0 )
443 {
444 return( ret );
445 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000446
Paul Bakker67f9d532012-10-23 11:49:05 +0000447 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000448 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200450 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000451 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200453 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000454 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200455
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200456 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200457
Paul Bakker89e80c92012-03-20 13:50:09 +0000458 length -= use_len;
459 p += use_len;
460 out_p += use_len;
461 }
462
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200463 return( 0 );
464}
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200467 unsigned char *tag,
468 size_t tag_len )
469{
470 unsigned char work_buf[16];
471 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100472 uint64_t orig_len;
473 uint64_t orig_add_len;
474
475 GCM_VALIDATE_RET( ctx != NULL );
476 GCM_VALIDATE_RET( tag != NULL );
477
478 orig_len = ctx->len * 8;
479 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200480
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200481 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200483
Andres AG821da842016-09-26 10:09:30 +0100484 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200485
Paul Bakker89e80c92012-03-20 13:50:09 +0000486 if( orig_len || orig_add_len )
487 {
488 memset( work_buf, 0x00, 16 );
489
Paul Bakker0ecdb232013-04-09 11:36:42 +0200490 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
491 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
492 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
493 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000494
Paul Bakker67f9d532012-10-23 11:49:05 +0000495 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200496 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000497
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200498 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000499
Paul Bakker67f9d532012-10-23 11:49:05 +0000500 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200501 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000502 }
503
504 return( 0 );
505}
506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200508 int mode,
509 size_t length,
510 const unsigned char *iv,
511 size_t iv_len,
512 const unsigned char *add,
513 size_t add_len,
514 const unsigned char *input,
515 unsigned char *output,
516 size_t tag_len,
517 unsigned char *tag )
518{
519 int ret;
520
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100521 GCM_VALIDATE_RET( ctx != NULL );
522 GCM_VALIDATE_RET( iv != NULL );
523 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
524 GCM_VALIDATE_RET( length == 0 || input != NULL );
525 GCM_VALIDATE_RET( length == 0 || output != NULL );
526 GCM_VALIDATE_RET( tag != NULL );
527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200529 return( ret );
530
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200531 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200532 return( ret );
533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200535 return( ret );
536
537 return( 0 );
538}
539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000541 size_t length,
542 const unsigned char *iv,
543 size_t iv_len,
544 const unsigned char *add,
545 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200546 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000547 size_t tag_len,
548 const unsigned char *input,
549 unsigned char *output )
550{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100551 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000552 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200553 size_t i;
554 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000555
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100556 GCM_VALIDATE_RET( ctx != NULL );
557 GCM_VALIDATE_RET( iv != NULL );
558 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
559 GCM_VALIDATE_RET( tag != NULL );
560 GCM_VALIDATE_RET( length == 0 || input != NULL );
561 GCM_VALIDATE_RET( length == 0 || output != NULL );
562
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100564 iv, iv_len, add, add_len,
565 input, output, tag_len, check_tag ) ) != 0 )
566 {
567 return( ret );
568 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000569
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200570 /* Check tag in "constant-time" */
571 for( diff = 0, i = 0; i < tag_len; i++ )
572 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000573
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200574 if( diff != 0 )
575 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500576 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200578 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000579
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200580 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000581}
582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200584{
k-stachowiak21298a22018-12-13 17:11:58 +0100585 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100586 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500588 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200589}
590
Jaeden Amero15263302017-09-21 12:53:48 +0100591#endif /* !MBEDTLS_GCM_ALT */
592
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000594/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200595 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 *
597 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
598 */
599#define MAX_TESTS 6
600
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000601static const int key_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000602 { 0, 0, 1, 1, 1, 1 };
603
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000604static const unsigned char key[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000605{
606 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
610 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
611 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
612 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200613 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000614};
615
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000616static const size_t iv_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 { 12, 12, 12, 12, 8, 60 };
618
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000619static const int iv_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000620 { 0, 0, 1, 1, 1, 2 };
621
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000622static const unsigned char iv[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000623{
624 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00 },
626 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
627 0xde, 0xca, 0xf8, 0x88 },
628 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200629 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200631 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000632 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200633 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000634 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000636};
637
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000638static const size_t add_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 { 0, 0, 0, 20, 20, 20 };
640
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000641static const int add_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 { 0, 0, 0, 1, 1, 1 };
643
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000644static const unsigned char additional[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000645{
646 { 0x00 },
647 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200648 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000649 0xab, 0xad, 0xda, 0xd2 },
650};
651
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000652static const size_t pt_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000653 { 0, 16, 64, 60, 60, 60 };
654
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000655static const int pt_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 { 0, 0, 1, 1, 1, 1 };
657
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000658static const unsigned char pt[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000659{
660 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
662 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
663 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
664 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
665 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
666 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
667 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
668 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
669 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
670};
671
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000672static const unsigned char ct[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000673{
674 { 0x00 },
675 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
676 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
677 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
684 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
685 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200686 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
692 0x3d, 0x58, 0xe0, 0x91 },
693 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
700 0xc2, 0x3f, 0x45, 0x98 },
701 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
708 0x4c, 0x34, 0xae, 0xe5 },
709 { 0x00 },
710 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200711 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000712 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200715 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000716 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
719 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
720 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200721 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200723 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
724 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
725 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000730 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200731 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000732 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200733 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000734 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200735 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200737 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000738 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200739 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000740 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200741 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000742 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200743 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000744 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200745 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
746 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
747 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
748 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
749 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
750 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
751 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
752 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
753 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
754 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
755 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
756 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
757 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
758 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
759 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
760 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
761 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
762 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000779};
780
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000781static const unsigned char tag[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000782{
783 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
784 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
785 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
786 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
787 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
790 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
791 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
792 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
793 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
794 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
795 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
796 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
797 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
800 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
801 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200804 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000805 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200806 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000807 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000809 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200810 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000811 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200812 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000813 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200814 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000815 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200816 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000817 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200818 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000819};
820
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000822{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000824 unsigned char buf[64];
825 unsigned char tag_buf[16];
826 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000828
829 for( j = 0; j < 3; j++ )
830 {
831 int key_len = 128 + 64 * j;
832
833 for( i = 0; i < MAX_TESTS; i++ )
834 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100835 mbedtls_gcm_init( &ctx );
836
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200837 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100839 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200840
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100841 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
842 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100843 /*
844 * AES-192 is an optional feature that may be unavailable when
845 * there is an alternative underlying implementation i.e. when
846 * MBEDTLS_AES_ALT is defined.
847 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300848 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100849 {
850 mbedtls_printf( "skipped\n" );
851 break;
852 }
853 else if( ret != 0 )
854 {
855 goto exit;
856 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000857
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100859 pt_len[i],
860 iv[iv_index[i]], iv_len[i],
861 additional[add_index[i]], add_len[i],
862 pt[pt_index[i]], buf, 16, tag_buf );
863 if( ret != 0 )
864 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000865
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100866 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
867 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000868 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100869 ret = 1;
870 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000871 }
872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200874
Paul Bakker89e80c92012-03-20 13:50:09 +0000875 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000877
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100878 mbedtls_gcm_init( &ctx );
879
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200880 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100882 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200883
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100884 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
885 key_len );
886 if( ret != 0 )
887 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100890 pt_len[i],
891 iv[iv_index[i]], iv_len[i],
892 additional[add_index[i]], add_len[i],
893 ct[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000894
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100895 if( ret != 0 )
896 goto exit;
897
898 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakker89e80c92012-03-20 13:50:09 +0000899 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
900 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100901 ret = 1;
902 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000903 }
904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200906
Paul Bakker89e80c92012-03-20 13:50:09 +0000907 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200909
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100910 mbedtls_gcm_init( &ctx );
911
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200912 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100914 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200915
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100916 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
917 key_len );
918 if( ret != 0 )
919 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100922 iv[iv_index[i]], iv_len[i],
923 additional[add_index[i]], add_len[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200924 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100925 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926
927 if( pt_len[i] > 32 )
928 {
929 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200931 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100932 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200933
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200935 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200936 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100937 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200938 }
939 else
940 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100943 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200944 }
945
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100947 if( ret != 0 )
948 goto exit;
949
950 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200951 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
952 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100953 ret = 1;
954 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200955 }
956
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200958
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200959 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200961
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100962 mbedtls_gcm_init( &ctx );
963
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200964 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100966 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200967
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100968 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
969 key_len );
970 if( ret != 0 )
971 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200972
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200974 iv[iv_index[i]], iv_len[i],
975 additional[add_index[i]], add_len[i] );
976 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100977 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200978
979 if( pt_len[i] > 32 )
980 {
981 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200983 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100984 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100987 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200988 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100989 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200990 }
991 else
992 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100993 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
994 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200995 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100996 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200997 }
998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001000 if( ret != 0 )
1001 goto exit;
1002
1003 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001004 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
1005 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001006 ret = 1;
1007 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001008 }
1009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001011
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001012 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001014 }
1015 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001016
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001017 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001019
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001020 ret = 0;
1021
1022exit:
1023 if( ret != 0 )
1024 {
1025 if( verbose != 0 )
1026 mbedtls_printf( "failed\n" );
1027 mbedtls_gcm_free( &ctx );
1028 }
1029
1030 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001031}
1032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001034
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035#endif /* MBEDTLS_GCM_C */