blob: 7edc6da366225f86d2ac57f0ff97c3a6bd639a4c [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker89e80c92012-03-20 13:50:09 +000047 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010048
Paul Bakker89e80c92012-03-20 13:50:09 +000049/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010050 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
51 *
52 * See also:
53 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
54 *
55 * We use the algorithm described as Shoup's method with 4-bit tables in
56 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000057 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000060#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020061#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020063#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000064
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000066
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050068#include "mbedtls/platform_util.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000069
Rich Evans00ab4702015-02-06 13:43:58 +000070#include <string.h>
71
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000073#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010074#endif
75
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010077#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000078#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030079#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000080#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081#define mbedtls_printf printf
82#endif /* MBEDTLS_PLATFORM_C */
83#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010084
Jaeden Amero15263302017-09-21 12:53:48 +010085#if !defined(MBEDTLS_GCM_ALT)
86
k-stachowiak8ffc92a2018-12-12 14:21:59 +010087/* Parameter validation macros */
88#define GCM_VALIDATE_RET( cond ) \
89 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
90#define GCM_VALIDATE( cond ) \
91 MBEDTLS_INTERNAL_VALIDATE( cond )
92
Paul Bakker89e80c92012-03-20 13:50:09 +000093/*
94 * 32-bit integer manipulation macros (big endian)
95 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000096#ifndef GET_UINT32_BE
97#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000098{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000099 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
100 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
101 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
102 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +0000103}
104#endif
105
Paul Bakker5c2364c2012-10-01 14:41:15 +0000106#ifndef PUT_UINT32_BE
107#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +0000108{ \
109 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
110 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
111 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
112 (b)[(i) + 3] = (unsigned char) ( (n) ); \
113}
114#endif
115
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100116/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200117 * Initialize a context
118 */
119void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
120{
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100121 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200122 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
123}
124
125/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100126 * Precompute small multiples of H, that is set
127 * HH[i] || HL[i] = H times i,
128 * where i is seen as a field element as in [MGV], ie high-order bits
129 * correspond to low powers of P. The result is stored in the same way, that
130 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
131 * corresponds to P^127.
132 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000134{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200135 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000136 uint64_t hi, lo;
137 uint64_t vl, vh;
138 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200139 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200140
Paul Bakker89e80c92012-03-20 13:50:09 +0000141 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200143 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000144
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100145 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000146 GET_UINT32_BE( hi, h, 0 );
147 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000148 vh = (uint64_t) hi << 32 | lo;
149
Paul Bakker5c2364c2012-10-01 14:41:15 +0000150 GET_UINT32_BE( hi, h, 8 );
151 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000152 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200153
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100154 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000155 ctx->HL[8] = vl;
156 ctx->HH[8] = vh;
157
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100159 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100160 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100161 return( 0 );
162#endif
163
164 /* 0 corresponds to 0 in GF(2^128) */
165 ctx->HH[0] = 0;
166 ctx->HL[0] = 0;
167
Paul Bakker89e80c92012-03-20 13:50:09 +0000168 for( i = 4; i > 0; i >>= 1 )
169 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200170 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000171 vl = ( vh << 63 ) | ( vl >> 1 );
172 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
173
174 ctx->HL[i] = vl;
175 ctx->HH[i] = vh;
176 }
177
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000178 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000179 {
180 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
181 vh = *HiH;
182 vl = *HiL;
183 for( j = 1; j < i; j++ )
184 {
185 HiH[j] = vh ^ ctx->HH[j];
186 HiL[j] = vl ^ ctx->HL[j];
187 }
188 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200189
190 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000191}
192
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200193int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
194 mbedtls_cipher_id_t cipher,
195 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200196 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000197{
198 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000200
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100201 GCM_VALIDATE_RET( ctx != NULL );
202 GCM_VALIDATE_RET( key != NULL );
203 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
204
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200205 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200206 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200208
Paul Bakkera0558e02013-09-10 14:25:51 +0200209 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200210 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200211
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200212 mbedtls_cipher_free( &ctx->cipher_ctx );
213
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200214 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000215 return( ret );
216
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200217 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200219 {
220 return( ret );
221 }
222
223 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
224 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000225
226 return( 0 );
227}
228
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100229/*
230 * Shoup's method for multiplication use this table with
231 * last4[x] = x times P^128
232 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
233 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000234static const uint64_t last4[16] =
235{
236 0x0000, 0x1c20, 0x3840, 0x2460,
237 0x7080, 0x6ca0, 0x48c0, 0x54e0,
238 0xe100, 0xfd20, 0xd940, 0xc560,
239 0x9180, 0x8da0, 0xa9c0, 0xb5e0
240};
241
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100242/*
243 * Sets output to x times H using the precomputed tables.
244 * x and output are seen as elements of GF(2^128) as in [MGV].
245 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200247 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000248{
249 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000250 unsigned char lo, hi, rem;
251 uint64_t zh, zl;
252
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100254 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100255 unsigned char h[16];
256
257 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
258 PUT_UINT32_BE( ctx->HH[8], h, 4 );
259 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
260 PUT_UINT32_BE( ctx->HL[8], h, 12 );
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100263 return;
264 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100266
Paul Bakker89e80c92012-03-20 13:50:09 +0000267 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000268
269 zh = ctx->HH[lo];
270 zl = ctx->HL[lo];
271
272 for( i = 15; i >= 0; i-- )
273 {
274 lo = x[i] & 0xf;
275 hi = x[i] >> 4;
276
277 if( i != 15 )
278 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000279 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000280 zl = ( zh << 60 ) | ( zl >> 4 );
281 zh = ( zh >> 4 );
282 zh ^= (uint64_t) last4[rem] << 48;
283 zh ^= ctx->HH[lo];
284 zl ^= ctx->HL[lo];
285
286 }
287
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000288 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000289 zl = ( zh << 60 ) | ( zl >> 4 );
290 zh = ( zh >> 4 );
291 zh ^= (uint64_t) last4[rem] << 48;
292 zh ^= ctx->HH[hi];
293 zl ^= ctx->HL[hi];
294 }
295
Paul Bakker5c2364c2012-10-01 14:41:15 +0000296 PUT_UINT32_BE( zh >> 32, output, 0 );
297 PUT_UINT32_BE( zh, output, 4 );
298 PUT_UINT32_BE( zl >> 32, output, 8 );
299 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000300}
301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200303 int mode,
304 const unsigned char *iv,
305 size_t iv_len,
306 const unsigned char *add,
307 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000308{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200309 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000310 unsigned char work_buf[16];
311 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000312 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200313 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000314
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100315 GCM_VALIDATE_RET( ctx != NULL );
316 GCM_VALIDATE_RET( iv != NULL );
317 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
318
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200319 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200320 /* IV is not allowed to be zero length */
321 if( iv_len == 0 ||
322 ( (uint64_t) iv_len ) >> 61 != 0 ||
323 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200324 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200326 }
327
Paul Bakker52cf16c2013-07-26 13:55:38 +0200328 memset( ctx->y, 0x00, sizeof(ctx->y) );
329 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
330
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200331 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200332 ctx->len = 0;
333 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000334
335 if( iv_len == 12 )
336 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200337 memcpy( ctx->y, iv, iv_len );
338 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000339 }
340 else
341 {
342 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000343 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000344
345 p = iv;
346 while( iv_len > 0 )
347 {
348 use_len = ( iv_len < 16 ) ? iv_len : 16;
349
Paul Bakker67f9d532012-10-23 11:49:05 +0000350 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200351 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200352
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000354
355 iv_len -= use_len;
356 p += use_len;
357 }
358
Paul Bakker67f9d532012-10-23 11:49:05 +0000359 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200360 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000361
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200362 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000363 }
364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200366 &olen ) ) != 0 )
367 {
368 return( ret );
369 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000370
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200371 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000372 p = add;
373 while( add_len > 0 )
374 {
375 use_len = ( add_len < 16 ) ? add_len : 16;
376
Paul Bakker67f9d532012-10-23 11:49:05 +0000377 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200378 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200379
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200380 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000381
382 add_len -= use_len;
383 p += use_len;
384 }
385
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200386 return( 0 );
387}
388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200390 size_t length,
391 const unsigned char *input,
392 unsigned char *output )
393{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200394 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200395 unsigned char ectr[16];
396 size_t i;
397 const unsigned char *p;
398 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200399 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200400
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100401 GCM_VALIDATE_RET( ctx != NULL );
402 GCM_VALIDATE_RET( length == 0 || input != NULL );
403 GCM_VALIDATE_RET( length == 0 || output != NULL );
404
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200405 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200407
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200408 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
409 * Also check for possible overflow */
410 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100411 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200412 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200414 }
415
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200416 ctx->len += length;
417
Paul Bakker89e80c92012-03-20 13:50:09 +0000418 p = input;
419 while( length > 0 )
420 {
421 use_len = ( length < 16 ) ? length : 16;
422
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100423 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000425 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200428 &olen ) ) != 0 )
429 {
430 return( ret );
431 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000432
Paul Bakker67f9d532012-10-23 11:49:05 +0000433 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000434 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200436 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000437 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200439 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000440 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200441
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200442 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200443
Paul Bakker89e80c92012-03-20 13:50:09 +0000444 length -= use_len;
445 p += use_len;
446 out_p += use_len;
447 }
448
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200449 return( 0 );
450}
451
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200453 unsigned char *tag,
454 size_t tag_len )
455{
456 unsigned char work_buf[16];
457 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100458 uint64_t orig_len;
459 uint64_t orig_add_len;
460
461 GCM_VALIDATE_RET( ctx != NULL );
462 GCM_VALIDATE_RET( tag != NULL );
463
464 orig_len = ctx->len * 8;
465 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200466
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200467 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200469
Andres AG821da842016-09-26 10:09:30 +0100470 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200471
Paul Bakker89e80c92012-03-20 13:50:09 +0000472 if( orig_len || orig_add_len )
473 {
474 memset( work_buf, 0x00, 16 );
475
Paul Bakker0ecdb232013-04-09 11:36:42 +0200476 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
477 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
478 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
479 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000480
Paul Bakker67f9d532012-10-23 11:49:05 +0000481 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200482 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000483
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200484 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000485
Paul Bakker67f9d532012-10-23 11:49:05 +0000486 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200487 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000488 }
489
490 return( 0 );
491}
492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200494 int mode,
495 size_t length,
496 const unsigned char *iv,
497 size_t iv_len,
498 const unsigned char *add,
499 size_t add_len,
500 const unsigned char *input,
501 unsigned char *output,
502 size_t tag_len,
503 unsigned char *tag )
504{
505 int ret;
506
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100507 GCM_VALIDATE_RET( ctx != NULL );
508 GCM_VALIDATE_RET( iv != NULL );
509 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
510 GCM_VALIDATE_RET( length == 0 || input != NULL );
511 GCM_VALIDATE_RET( length == 0 || output != NULL );
512 GCM_VALIDATE_RET( tag != NULL );
513
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200514 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200515 return( ret );
516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200518 return( ret );
519
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200521 return( ret );
522
523 return( 0 );
524}
525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000527 size_t length,
528 const unsigned char *iv,
529 size_t iv_len,
530 const unsigned char *add,
531 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200532 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000533 size_t tag_len,
534 const unsigned char *input,
535 unsigned char *output )
536{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100537 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000538 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200539 size_t i;
540 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000541
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100542 GCM_VALIDATE_RET( ctx != NULL );
543 GCM_VALIDATE_RET( iv != NULL );
544 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
545 GCM_VALIDATE_RET( tag != NULL );
546 GCM_VALIDATE_RET( length == 0 || input != NULL );
547 GCM_VALIDATE_RET( length == 0 || output != NULL );
548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100550 iv, iv_len, add, add_len,
551 input, output, tag_len, check_tag ) ) != 0 )
552 {
553 return( ret );
554 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000555
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200556 /* Check tag in "constant-time" */
557 for( diff = 0, i = 0; i < tag_len; i++ )
558 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000559
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200560 if( diff != 0 )
561 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500562 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200564 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000565
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200566 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000567}
568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200570{
k-stachowiak21298a22018-12-13 17:11:58 +0100571 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100572 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500574 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200575}
576
Jaeden Amero15263302017-09-21 12:53:48 +0100577#endif /* !MBEDTLS_GCM_ALT */
578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000580/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200581 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 *
583 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
584 */
585#define MAX_TESTS 6
586
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000587static const int key_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 { 0, 0, 1, 1, 1, 1 };
589
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000590static const unsigned char key[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000591{
592 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
596 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
597 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
598 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200599 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000600};
601
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000602static const size_t iv_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000603 { 12, 12, 12, 12, 8, 60 };
604
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000605static const int iv_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000606 { 0, 0, 1, 1, 1, 2 };
607
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000608static const unsigned char iv[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000609{
610 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00 },
612 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
613 0xde, 0xca, 0xf8, 0x88 },
614 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200615 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000616 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200617 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000618 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200619 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000620 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200621 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000622};
623
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000624static const size_t add_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 { 0, 0, 0, 20, 20, 20 };
626
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000627static const int add_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000628 { 0, 0, 0, 1, 1, 1 };
629
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000630static const unsigned char additional[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000631{
632 { 0x00 },
633 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200634 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000635 0xab, 0xad, 0xda, 0xd2 },
636};
637
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000638static const size_t pt_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 { 0, 16, 64, 60, 60, 60 };
640
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000641static const int pt_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 { 0, 0, 1, 1, 1, 1 };
643
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000644static const unsigned char pt[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000645{
646 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
648 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
649 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
650 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
651 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
652 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
653 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
654 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
655 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
656};
657
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000658static const unsigned char ct[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000659{
660 { 0x00 },
661 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
662 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
663 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200664 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200666 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000667 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200668 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000669 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
670 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
671 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200672 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200674 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200676 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000677 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
678 0x3d, 0x58, 0xe0, 0x91 },
679 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200684 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000685 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
686 0xc2, 0x3f, 0x45, 0x98 },
687 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
694 0x4c, 0x34, 0xae, 0xe5 },
695 { 0x00 },
696 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200703 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
705 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
706 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200707 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000708 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200709 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
710 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
711 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000712 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200715 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000716 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200719 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200721 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200723 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000724 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000730 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200731 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
732 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
733 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
734 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
735 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
736 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
737 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
738 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
739 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
740 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
741 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
742 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
743 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
744 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
745 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
746 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
747 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
748 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000765};
766
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000767static const unsigned char tag[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000768{
769 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
770 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
771 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
772 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
773 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
776 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
777 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
778 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
779 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
780 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
781 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
782 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
783 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
786 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
787 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200790 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000791 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200792 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000793 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200794 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000795 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200804 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000805};
806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000808{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200809 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 unsigned char buf[64];
811 unsigned char tag_buf[16];
812 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000814
815 for( j = 0; j < 3; j++ )
816 {
817 int key_len = 128 + 64 * j;
818
819 for( i = 0; i < MAX_TESTS; i++ )
820 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100821 mbedtls_gcm_init( &ctx );
822
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200823 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100825 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200826
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100827 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
828 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100829 /*
830 * AES-192 is an optional feature that may be unavailable when
831 * there is an alternative underlying implementation i.e. when
832 * MBEDTLS_AES_ALT is defined.
833 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300834 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100835 {
836 mbedtls_printf( "skipped\n" );
837 break;
838 }
839 else if( ret != 0 )
840 {
841 goto exit;
842 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000843
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100845 pt_len[i],
846 iv[iv_index[i]], iv_len[i],
847 additional[add_index[i]], add_len[i],
848 pt[pt_index[i]], buf, 16, tag_buf );
849 if( ret != 0 )
850 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000851
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100852 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
853 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000854 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100855 ret = 1;
856 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000857 }
858
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200860
Paul Bakker89e80c92012-03-20 13:50:09 +0000861 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000863
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100864 mbedtls_gcm_init( &ctx );
865
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200866 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100868 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200869
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100870 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
871 key_len );
872 if( ret != 0 )
873 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100876 pt_len[i],
877 iv[iv_index[i]], iv_len[i],
878 additional[add_index[i]], add_len[i],
879 ct[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000880
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100881 if( ret != 0 )
882 goto exit;
883
884 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakker89e80c92012-03-20 13:50:09 +0000885 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
886 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100887 ret = 1;
888 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000889 }
890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200892
Paul Bakker89e80c92012-03-20 13:50:09 +0000893 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200895
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100896 mbedtls_gcm_init( &ctx );
897
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200898 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100900 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200901
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100902 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
903 key_len );
904 if( ret != 0 )
905 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200906
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200907 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100908 iv[iv_index[i]], iv_len[i],
909 additional[add_index[i]], add_len[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200910 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100911 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200912
913 if( pt_len[i] > 32 )
914 {
915 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200917 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100918 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200919
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200921 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200922 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100923 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200924 }
925 else
926 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200928 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100929 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200930 }
931
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100933 if( ret != 0 )
934 goto exit;
935
936 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200937 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
938 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100939 ret = 1;
940 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200941 }
942
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200944
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200945 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200947
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100948 mbedtls_gcm_init( &ctx );
949
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200950 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100952 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200953
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100954 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
955 key_len );
956 if( ret != 0 )
957 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200958
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200960 iv[iv_index[i]], iv_len[i],
961 additional[add_index[i]], add_len[i] );
962 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100963 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200964
965 if( pt_len[i] > 32 )
966 {
967 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200969 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100970 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100973 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200974 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100975 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200976 }
977 else
978 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100979 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
980 buf );
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100986 if( ret != 0 )
987 goto exit;
988
989 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200990 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
991 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100992 ret = 1;
993 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200994 }
995
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200997
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200998 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001000 }
1001 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001002
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001003 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001005
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001006 ret = 0;
1007
1008exit:
1009 if( ret != 0 )
1010 {
1011 if( verbose != 0 )
1012 mbedtls_printf( "failed\n" );
1013 mbedtls_gcm_free( &ctx );
1014 }
1015
1016 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001017}
1018
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021#endif /* MBEDTLS_GCM_C */