blob: 2afe5025a09e32ef049208e9e6be9525b4c47d94 [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
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100114/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200115 * Initialize a context
116 */
117void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
118{
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100119 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200120 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
121}
122
123/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100124 * Precompute small multiples of H, that is set
125 * HH[i] || HL[i] = H times i,
126 * where i is seen as a field element as in [MGV], ie high-order bits
127 * correspond to low powers of P. The result is stored in the same way, that
128 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
129 * corresponds to P^127.
130 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000132{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200133 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000134 uint64_t hi, lo;
135 uint64_t vl, vh;
136 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200137 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200138
Paul Bakker89e80c92012-03-20 13:50:09 +0000139 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200141 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000142
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100143 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000144 GET_UINT32_BE( hi, h, 0 );
145 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000146 vh = (uint64_t) hi << 32 | lo;
147
Paul Bakker5c2364c2012-10-01 14:41:15 +0000148 GET_UINT32_BE( hi, h, 8 );
149 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000150 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200151
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100152 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000153 ctx->HL[8] = vl;
154 ctx->HH[8] = vh;
155
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100157 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100158 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100159 return( 0 );
160#endif
161
162 /* 0 corresponds to 0 in GF(2^128) */
163 ctx->HH[0] = 0;
164 ctx->HL[0] = 0;
165
Paul Bakker89e80c92012-03-20 13:50:09 +0000166 for( i = 4; i > 0; i >>= 1 )
167 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200168 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000169 vl = ( vh << 63 ) | ( vl >> 1 );
170 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
171
172 ctx->HL[i] = vl;
173 ctx->HH[i] = vh;
174 }
175
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000176 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000177 {
178 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
179 vh = *HiH;
180 vl = *HiL;
181 for( j = 1; j < i; j++ )
182 {
183 HiH[j] = vh ^ ctx->HH[j];
184 HiL[j] = vl ^ ctx->HL[j];
185 }
186 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200187
188 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000189}
190
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200191int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
192 mbedtls_cipher_id_t cipher,
193 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200194 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000195{
196 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000198
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100199 GCM_VALIDATE_RET( ctx != NULL );
200 GCM_VALIDATE_RET( key != NULL );
201 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
202
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200203 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200204 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200206
Paul Bakkera0558e02013-09-10 14:25:51 +0200207 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200209
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200210 mbedtls_cipher_free( &ctx->cipher_ctx );
211
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200212 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000213 return( ret );
214
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200215 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200217 {
218 return( ret );
219 }
220
221 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
222 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000223
224 return( 0 );
225}
226
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100227/*
228 * Shoup's method for multiplication use this table with
229 * last4[x] = x times P^128
230 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
231 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000232static const uint64_t last4[16] =
233{
234 0x0000, 0x1c20, 0x3840, 0x2460,
235 0x7080, 0x6ca0, 0x48c0, 0x54e0,
236 0xe100, 0xfd20, 0xd940, 0xc560,
237 0x9180, 0x8da0, 0xa9c0, 0xb5e0
238};
239
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100240/*
241 * Sets output to x times H using the precomputed tables.
242 * x and output are seen as elements of GF(2^128) as in [MGV].
243 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200245 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000246{
247 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000248 unsigned char lo, hi, rem;
249 uint64_t zh, zl;
250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100252 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100253 unsigned char h[16];
254
255 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
256 PUT_UINT32_BE( ctx->HH[8], h, 4 );
257 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
258 PUT_UINT32_BE( ctx->HL[8], h, 12 );
259
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100261 return;
262 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200263#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100264
Paul Bakker89e80c92012-03-20 13:50:09 +0000265 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000266
267 zh = ctx->HH[lo];
268 zl = ctx->HL[lo];
269
270 for( i = 15; i >= 0; i-- )
271 {
272 lo = x[i] & 0xf;
273 hi = x[i] >> 4;
274
275 if( i != 15 )
276 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000277 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000278 zl = ( zh << 60 ) | ( zl >> 4 );
279 zh = ( zh >> 4 );
280 zh ^= (uint64_t) last4[rem] << 48;
281 zh ^= ctx->HH[lo];
282 zl ^= ctx->HL[lo];
283
284 }
285
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000286 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000287 zl = ( zh << 60 ) | ( zl >> 4 );
288 zh = ( zh >> 4 );
289 zh ^= (uint64_t) last4[rem] << 48;
290 zh ^= ctx->HH[hi];
291 zl ^= ctx->HL[hi];
292 }
293
Paul Bakker5c2364c2012-10-01 14:41:15 +0000294 PUT_UINT32_BE( zh >> 32, output, 0 );
295 PUT_UINT32_BE( zh, output, 4 );
296 PUT_UINT32_BE( zl >> 32, output, 8 );
297 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000298}
299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200301 int mode,
302 const unsigned char *iv,
303 size_t iv_len,
304 const unsigned char *add,
305 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000306{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200307 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000308 unsigned char work_buf[16];
309 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000310 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200311 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000312
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100313 GCM_VALIDATE_RET( ctx != NULL );
314 GCM_VALIDATE_RET( iv != NULL );
315 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
316
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200317 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200318 /* IV is not allowed to be zero length */
319 if( iv_len == 0 ||
320 ( (uint64_t) iv_len ) >> 61 != 0 ||
321 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200322 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200324 }
325
Paul Bakker52cf16c2013-07-26 13:55:38 +0200326 memset( ctx->y, 0x00, sizeof(ctx->y) );
327 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
328
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200329 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200330 ctx->len = 0;
331 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000332
333 if( iv_len == 12 )
334 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200335 memcpy( ctx->y, iv, iv_len );
336 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000337 }
338 else
339 {
340 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000341 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000342
343 p = iv;
344 while( iv_len > 0 )
345 {
346 use_len = ( iv_len < 16 ) ? iv_len : 16;
347
Paul Bakker67f9d532012-10-23 11:49:05 +0000348 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200349 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200350
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200351 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000352
353 iv_len -= use_len;
354 p += use_len;
355 }
356
Paul Bakker67f9d532012-10-23 11:49:05 +0000357 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200358 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000359
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200360 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000361 }
362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200364 &olen ) ) != 0 )
365 {
366 return( ret );
367 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000368
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200369 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000370 p = add;
371 while( add_len > 0 )
372 {
373 use_len = ( add_len < 16 ) ? add_len : 16;
374
Paul Bakker67f9d532012-10-23 11:49:05 +0000375 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200376 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200377
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200378 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000379
380 add_len -= use_len;
381 p += use_len;
382 }
383
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384 return( 0 );
385}
386
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200388 size_t length,
389 const unsigned char *input,
390 unsigned char *output )
391{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200392 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200393 unsigned char ectr[16];
394 size_t i;
395 const unsigned char *p;
396 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200397 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200398
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100399 GCM_VALIDATE_RET( ctx != NULL );
400 GCM_VALIDATE_RET( length == 0 || input != NULL );
401 GCM_VALIDATE_RET( length == 0 || output != NULL );
402
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200403 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200405
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200406 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
407 * Also check for possible overflow */
408 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100409 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200410 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200412 }
413
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200414 ctx->len += length;
415
Paul Bakker89e80c92012-03-20 13:50:09 +0000416 p = input;
417 while( length > 0 )
418 {
419 use_len = ( length < 16 ) ? length : 16;
420
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100421 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200422 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000423 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200426 &olen ) ) != 0 )
427 {
428 return( ret );
429 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000430
Paul Bakker67f9d532012-10-23 11:49:05 +0000431 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000432 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200434 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000435 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200437 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000438 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200439
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200440 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200441
Paul Bakker89e80c92012-03-20 13:50:09 +0000442 length -= use_len;
443 p += use_len;
444 out_p += use_len;
445 }
446
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200447 return( 0 );
448}
449
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200451 unsigned char *tag,
452 size_t tag_len )
453{
454 unsigned char work_buf[16];
455 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100456 uint64_t orig_len;
457 uint64_t orig_add_len;
458
459 GCM_VALIDATE_RET( ctx != NULL );
460 GCM_VALIDATE_RET( tag != NULL );
461
462 orig_len = ctx->len * 8;
463 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200464
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200465 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200467
Andres AG821da842016-09-26 10:09:30 +0100468 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200469
Paul Bakker89e80c92012-03-20 13:50:09 +0000470 if( orig_len || orig_add_len )
471 {
472 memset( work_buf, 0x00, 16 );
473
Paul Bakker0ecdb232013-04-09 11:36:42 +0200474 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
475 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
476 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
477 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000478
Paul Bakker67f9d532012-10-23 11:49:05 +0000479 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200480 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000481
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200482 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000483
Paul Bakker67f9d532012-10-23 11:49:05 +0000484 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200485 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000486 }
487
488 return( 0 );
489}
490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200492 int mode,
493 size_t length,
494 const unsigned char *iv,
495 size_t iv_len,
496 const unsigned char *add,
497 size_t add_len,
498 const unsigned char *input,
499 unsigned char *output,
500 size_t tag_len,
501 unsigned char *tag )
502{
503 int ret;
504
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100505 GCM_VALIDATE_RET( ctx != NULL );
506 GCM_VALIDATE_RET( iv != NULL );
507 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
508 GCM_VALIDATE_RET( length == 0 || input != NULL );
509 GCM_VALIDATE_RET( length == 0 || output != NULL );
510 GCM_VALIDATE_RET( tag != NULL );
511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200513 return( ret );
514
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200516 return( ret );
517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200519 return( ret );
520
521 return( 0 );
522}
523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000525 size_t length,
526 const unsigned char *iv,
527 size_t iv_len,
528 const unsigned char *add,
529 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200530 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000531 size_t tag_len,
532 const unsigned char *input,
533 unsigned char *output )
534{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100535 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000536 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200537 size_t i;
538 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000539
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100540 GCM_VALIDATE_RET( ctx != NULL );
541 GCM_VALIDATE_RET( iv != NULL );
542 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
543 GCM_VALIDATE_RET( tag != NULL );
544 GCM_VALIDATE_RET( length == 0 || input != NULL );
545 GCM_VALIDATE_RET( length == 0 || output != NULL );
546
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100548 iv, iv_len, add, add_len,
549 input, output, tag_len, check_tag ) ) != 0 )
550 {
551 return( ret );
552 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000553
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200554 /* Check tag in "constant-time" */
555 for( diff = 0, i = 0; i < tag_len; i++ )
556 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000557
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200558 if( diff != 0 )
559 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500560 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200562 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000563
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200564 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000565}
566
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200568{
k-stachowiak21298a22018-12-13 17:11:58 +0100569 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100570 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500572 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200573}
574
Jaeden Amero15263302017-09-21 12:53:48 +0100575#endif /* !MBEDTLS_GCM_ALT */
576
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000578/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200579 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 *
581 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
582 */
583#define MAX_TESTS 6
584
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000585static const int key_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000586 { 0, 0, 1, 1, 1, 1 };
587
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000588static const unsigned char key[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000589{
590 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
594 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
595 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
596 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200597 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000598};
599
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000600static const size_t iv_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000601 { 12, 12, 12, 12, 8, 60 };
602
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000603static const int iv_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000604 { 0, 0, 1, 1, 1, 2 };
605
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000606static const unsigned char iv[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000607{
608 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00 },
610 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
611 0xde, 0xca, 0xf8, 0x88 },
612 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200613 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000614 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200615 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000616 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200617 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000618 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200619 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000620};
621
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000622static const size_t add_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 { 0, 0, 0, 20, 20, 20 };
624
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000625static const int add_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 { 0, 0, 0, 1, 1, 1 };
627
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000628static const unsigned char additional[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000629{
630 { 0x00 },
631 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200632 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 0xab, 0xad, 0xda, 0xd2 },
634};
635
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000636static const size_t pt_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 { 0, 16, 64, 60, 60, 60 };
638
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000639static const int pt_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 { 0, 0, 1, 1, 1, 1 };
641
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000642static const unsigned char pt[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000643{
644 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
646 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
647 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
648 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
649 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
650 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
651 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
652 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
653 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
654};
655
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000656static const unsigned char ct[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000657{
658 { 0x00 },
659 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
660 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
661 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200662 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000663 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200664 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200666 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000667 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
668 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
669 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200670 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000671 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200672 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200674 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
676 0x3d, 0x58, 0xe0, 0x91 },
677 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
684 0xc2, 0x3f, 0x45, 0x98 },
685 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200686 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
692 0x4c, 0x34, 0xae, 0xe5 },
693 { 0x00 },
694 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
703 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
704 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200705 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200707 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
708 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
709 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200711 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000712 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200715 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000716 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200719 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200721 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200723 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000724 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
730 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
731 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
732 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
733 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
734 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
735 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
736 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
737 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
738 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
739 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
740 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
741 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
742 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
743 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
744 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
745 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
746 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000763};
764
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000765static const unsigned char tag[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000766{
767 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
768 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
769 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
770 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
771 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
774 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
775 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
776 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
777 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
778 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
779 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
780 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
781 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
784 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
785 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200790 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000791 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200792 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000793 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200794 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000795 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000803};
804
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000806{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 unsigned char buf[64];
809 unsigned char tag_buf[16];
810 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000812
813 for( j = 0; j < 3; j++ )
814 {
815 int key_len = 128 + 64 * j;
816
817 for( i = 0; i < MAX_TESTS; i++ )
818 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100819 mbedtls_gcm_init( &ctx );
820
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200821 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100823 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200824
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100825 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
826 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100827 /*
828 * AES-192 is an optional feature that may be unavailable when
829 * there is an alternative underlying implementation i.e. when
830 * MBEDTLS_AES_ALT is defined.
831 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300832 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100833 {
834 mbedtls_printf( "skipped\n" );
835 break;
836 }
837 else if( ret != 0 )
838 {
839 goto exit;
840 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100843 pt_len[i],
844 iv[iv_index[i]], iv_len[i],
845 additional[add_index[i]], add_len[i],
846 pt[pt_index[i]], buf, 16, tag_buf );
847 if( ret != 0 )
848 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000849
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100850 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
851 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000852 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100853 ret = 1;
854 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 }
856
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200858
Paul Bakker89e80c92012-03-20 13:50:09 +0000859 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000861
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100862 mbedtls_gcm_init( &ctx );
863
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200864 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100866 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200867
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100868 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
869 key_len );
870 if( ret != 0 )
871 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100874 pt_len[i],
875 iv[iv_index[i]], iv_len[i],
876 additional[add_index[i]], add_len[i],
877 ct[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000878
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100879 if( ret != 0 )
880 goto exit;
881
882 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakker89e80c92012-03-20 13:50:09 +0000883 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
884 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100885 ret = 1;
886 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000887 }
888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200890
Paul Bakker89e80c92012-03-20 13:50:09 +0000891 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200893
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100894 mbedtls_gcm_init( &ctx );
895
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200896 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100898 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200899
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100900 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
901 key_len );
902 if( ret != 0 )
903 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100906 iv[iv_index[i]], iv_len[i],
907 additional[add_index[i]], add_len[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200908 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100909 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200910
911 if( pt_len[i] > 32 )
912 {
913 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200915 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100916 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200917
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200919 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100921 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200922 }
923 else
924 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100927 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200928 }
929
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100931 if( ret != 0 )
932 goto exit;
933
934 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200935 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
936 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100937 ret = 1;
938 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200939 }
940
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200942
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200943 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200945
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100946 mbedtls_gcm_init( &ctx );
947
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200948 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100950 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200951
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100952 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
953 key_len );
954 if( ret != 0 )
955 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200956
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200958 iv[iv_index[i]], iv_len[i],
959 additional[add_index[i]], add_len[i] );
960 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100961 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200962
963 if( pt_len[i] > 32 )
964 {
965 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200967 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100968 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200969
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100971 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200972 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100973 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200974 }
975 else
976 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100977 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
978 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200979 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100980 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200981 }
982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100984 if( ret != 0 )
985 goto exit;
986
987 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200988 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
989 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100990 ret = 1;
991 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200992 }
993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200995
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200996 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000998 }
999 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001000
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001001 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001003
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001004 ret = 0;
1005
1006exit:
1007 if( ret != 0 )
1008 {
1009 if( verbose != 0 )
1010 mbedtls_printf( "failed\n" );
1011 mbedtls_gcm_free( &ctx );
1012 }
1013
1014 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001015}
1016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001018
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019#endif /* MBEDTLS_GCM_C */