blob: a7e6706364e61a040c74fe6849bf63f5a8b59263 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-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úti4e9f7122020-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"
Paul Bakker89e80c92012-03-20 13:50:09 +000066
Rich Evans00ab4702015-02-06 13:43:58 +000067#include <string.h>
68
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000070#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010071#endif
72
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010074#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000076#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010077#else
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
Paul Bakker89e80c92012-03-20 13:50:09 +000085/*
86 * 32-bit integer manipulation macros (big endian)
87 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000088#ifndef GET_UINT32_BE
89#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000090{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000091 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
92 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
93 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
94 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000095}
96#endif
97
Paul Bakker5c2364c2012-10-01 14:41:15 +000098#ifndef PUT_UINT32_BE
99#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +0000100{ \
101 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
102 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
103 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
104 (b)[(i) + 3] = (unsigned char) ( (n) ); \
105}
106#endif
107
Paul Bakker34617722014-06-13 17:20:13 +0200108/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +0200110 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
111}
112
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100113/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200114 * Initialize a context
115 */
116void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
117{
118 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
119}
120
121/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100122 * Precompute small multiples of H, that is set
123 * HH[i] || HL[i] = H times i,
124 * where i is seen as a field element as in [MGV], ie high-order bits
125 * correspond to low powers of P. The result is stored in the same way, that
126 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
127 * corresponds to P^127.
128 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000130{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200131 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000132 uint64_t hi, lo;
133 uint64_t vl, vh;
134 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200135 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200136
Paul Bakker89e80c92012-03-20 13:50:09 +0000137 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200139 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000140
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100141 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000142 GET_UINT32_BE( hi, h, 0 );
143 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000144 vh = (uint64_t) hi << 32 | lo;
145
Paul Bakker5c2364c2012-10-01 14:41:15 +0000146 GET_UINT32_BE( hi, h, 8 );
147 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000148 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200149
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100150 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000151 ctx->HL[8] = vl;
152 ctx->HH[8] = vh;
153
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100155 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100156 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100157 return( 0 );
158#endif
159
160 /* 0 corresponds to 0 in GF(2^128) */
161 ctx->HH[0] = 0;
162 ctx->HL[0] = 0;
163
Paul Bakker89e80c92012-03-20 13:50:09 +0000164 for( i = 4; i > 0; i >>= 1 )
165 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200166 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000167 vl = ( vh << 63 ) | ( vl >> 1 );
168 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
169
170 ctx->HL[i] = vl;
171 ctx->HH[i] = vh;
172 }
173
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000174 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000175 {
176 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
177 vh = *HiH;
178 vl = *HiL;
179 for( j = 1; j < i; j++ )
180 {
181 HiH[j] = vh ^ ctx->HH[j];
182 HiL[j] = vl ^ ctx->HL[j];
183 }
184 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200185
186 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000187}
188
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200189int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
190 mbedtls_cipher_id_t cipher,
191 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200192 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000193{
194 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000196
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200197 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200198 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200200
Paul Bakkera0558e02013-09-10 14:25:51 +0200201 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200202 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200203
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200204 mbedtls_cipher_free( &ctx->cipher_ctx );
205
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200206 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000207 return( ret );
208
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200209 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200210 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200211 {
212 return( ret );
213 }
214
215 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
216 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000217
218 return( 0 );
219}
220
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100221/*
222 * Shoup's method for multiplication use this table with
223 * last4[x] = x times P^128
224 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
225 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000226static const uint64_t last4[16] =
227{
228 0x0000, 0x1c20, 0x3840, 0x2460,
229 0x7080, 0x6ca0, 0x48c0, 0x54e0,
230 0xe100, 0xfd20, 0xd940, 0xc560,
231 0x9180, 0x8da0, 0xa9c0, 0xb5e0
232};
233
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100234/*
235 * Sets output to x times H using the precomputed tables.
236 * x and output are seen as elements of GF(2^128) as in [MGV].
237 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200238static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200239 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000240{
241 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000242 unsigned char lo, hi, rem;
243 uint64_t zh, zl;
244
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100246 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100247 unsigned char h[16];
248
249 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
250 PUT_UINT32_BE( ctx->HH[8], h, 4 );
251 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
252 PUT_UINT32_BE( ctx->HL[8], h, 12 );
253
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100255 return;
256 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100258
Paul Bakker89e80c92012-03-20 13:50:09 +0000259 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000260
261 zh = ctx->HH[lo];
262 zl = ctx->HL[lo];
263
264 for( i = 15; i >= 0; i-- )
265 {
266 lo = x[i] & 0xf;
267 hi = x[i] >> 4;
268
269 if( i != 15 )
270 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000271 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000272 zl = ( zh << 60 ) | ( zl >> 4 );
273 zh = ( zh >> 4 );
274 zh ^= (uint64_t) last4[rem] << 48;
275 zh ^= ctx->HH[lo];
276 zl ^= ctx->HL[lo];
277
278 }
279
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000280 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000281 zl = ( zh << 60 ) | ( zl >> 4 );
282 zh = ( zh >> 4 );
283 zh ^= (uint64_t) last4[rem] << 48;
284 zh ^= ctx->HH[hi];
285 zl ^= ctx->HL[hi];
286 }
287
Paul Bakker5c2364c2012-10-01 14:41:15 +0000288 PUT_UINT32_BE( zh >> 32, output, 0 );
289 PUT_UINT32_BE( zh, output, 4 );
290 PUT_UINT32_BE( zl >> 32, output, 8 );
291 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000292}
293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200295 int mode,
296 const unsigned char *iv,
297 size_t iv_len,
298 const unsigned char *add,
299 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000300{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200301 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000302 unsigned char work_buf[16];
303 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000304 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200305 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000306
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200307 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200308 /* IV is not allowed to be zero length */
309 if( iv_len == 0 ||
310 ( (uint64_t) iv_len ) >> 61 != 0 ||
311 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200312 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200314 }
315
Paul Bakker52cf16c2013-07-26 13:55:38 +0200316 memset( ctx->y, 0x00, sizeof(ctx->y) );
317 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
318
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200319 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200320 ctx->len = 0;
321 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000322
323 if( iv_len == 12 )
324 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200325 memcpy( ctx->y, iv, iv_len );
326 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000327 }
328 else
329 {
330 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000331 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000332
333 p = iv;
334 while( iv_len > 0 )
335 {
336 use_len = ( iv_len < 16 ) ? iv_len : 16;
337
Paul Bakker67f9d532012-10-23 11:49:05 +0000338 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200339 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200340
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200341 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000342
343 iv_len -= use_len;
344 p += use_len;
345 }
346
Paul Bakker67f9d532012-10-23 11:49:05 +0000347 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200348 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000349
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200350 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000351 }
352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200354 &olen ) ) != 0 )
355 {
356 return( ret );
357 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000358
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200359 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000360 p = add;
361 while( add_len > 0 )
362 {
363 use_len = ( add_len < 16 ) ? add_len : 16;
364
Paul Bakker67f9d532012-10-23 11:49:05 +0000365 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200366 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200367
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200368 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000369
370 add_len -= use_len;
371 p += use_len;
372 }
373
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200374 return( 0 );
375}
376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200378 size_t length,
379 const unsigned char *input,
380 unsigned char *output )
381{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200382 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200383 unsigned char ectr[16];
384 size_t i;
385 const unsigned char *p;
386 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200387 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200388
389 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200391
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200392 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
393 * Also check for possible overflow */
394 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100395 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200396 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200398 }
399
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200400 ctx->len += length;
401
Paul Bakker89e80c92012-03-20 13:50:09 +0000402 p = input;
403 while( length > 0 )
404 {
405 use_len = ( length < 16 ) ? length : 16;
406
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100407 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200408 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000409 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200412 &olen ) ) != 0 )
413 {
414 return( ret );
415 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000416
Paul Bakker67f9d532012-10-23 11:49:05 +0000417 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000418 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200420 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000421 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200423 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000424 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200425
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200426 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200427
Paul Bakker89e80c92012-03-20 13:50:09 +0000428 length -= use_len;
429 p += use_len;
430 out_p += use_len;
431 }
432
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200433 return( 0 );
434}
435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200437 unsigned char *tag,
438 size_t tag_len )
439{
440 unsigned char work_buf[16];
441 size_t i;
442 uint64_t orig_len = ctx->len * 8;
443 uint64_t orig_add_len = ctx->add_len * 8;
444
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200445 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200447
Andres AG821da842016-09-26 10:09:30 +0100448 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200449
Paul Bakker89e80c92012-03-20 13:50:09 +0000450 if( orig_len || orig_add_len )
451 {
452 memset( work_buf, 0x00, 16 );
453
Paul Bakker0ecdb232013-04-09 11:36:42 +0200454 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
455 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
456 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
457 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000458
Paul Bakker67f9d532012-10-23 11:49:05 +0000459 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200460 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000461
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200462 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000463
Paul Bakker67f9d532012-10-23 11:49:05 +0000464 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200465 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000466 }
467
468 return( 0 );
469}
470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200472 int mode,
473 size_t length,
474 const unsigned char *iv,
475 size_t iv_len,
476 const unsigned char *add,
477 size_t add_len,
478 const unsigned char *input,
479 unsigned char *output,
480 size_t tag_len,
481 unsigned char *tag )
482{
483 int ret;
484
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200486 return( ret );
487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200489 return( ret );
490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200492 return( ret );
493
494 return( 0 );
495}
496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000498 size_t length,
499 const unsigned char *iv,
500 size_t iv_len,
501 const unsigned char *add,
502 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200503 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000504 size_t tag_len,
505 const unsigned char *input,
506 unsigned char *output )
507{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100508 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000509 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200510 size_t i;
511 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100514 iv, iv_len, add, add_len,
515 input, output, tag_len, check_tag ) ) != 0 )
516 {
517 return( ret );
518 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000519
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200520 /* Check tag in "constant-time" */
521 for( diff = 0, i = 0; i < tag_len; i++ )
522 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000523
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200524 if( diff != 0 )
525 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 mbedtls_zeroize( output, length );
527 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200528 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000529
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200530 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000531}
532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200534{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535 mbedtls_cipher_free( &ctx->cipher_ctx );
536 mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200537}
538
Jaeden Amero15263302017-09-21 12:53:48 +0100539#endif /* !MBEDTLS_GCM_ALT */
540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000542/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200543 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000544 *
545 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
546 */
547#define MAX_TESTS 6
548
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000549static const int key_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000550 { 0, 0, 1, 1, 1, 1 };
551
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000552static const unsigned char key[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000553{
554 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
558 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
559 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
560 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200561 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000562};
563
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000564static const size_t iv_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000565 { 12, 12, 12, 12, 8, 60 };
566
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000567static const int iv_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000568 { 0, 0, 1, 1, 1, 2 };
569
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000570static const unsigned char iv[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000571{
572 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00 },
574 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
575 0xde, 0xca, 0xf8, 0x88 },
576 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200577 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000578 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200579 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200581 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200583 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000584};
585
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000586static const size_t add_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 { 0, 0, 0, 20, 20, 20 };
588
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000589static const int add_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 { 0, 0, 0, 1, 1, 1 };
591
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000592static const unsigned char additional[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000593{
594 { 0x00 },
595 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200596 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000597 0xab, 0xad, 0xda, 0xd2 },
598};
599
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000600static const size_t pt_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000601 { 0, 16, 64, 60, 60, 60 };
602
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000603static const int pt_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000604 { 0, 0, 1, 1, 1, 1 };
605
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000606static const unsigned char pt[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, 0x00, 0x00, 0x00, 0x00 },
610 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
611 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
612 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
613 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
614 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
615 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
616 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
617 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
618};
619
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000620static const unsigned char ct[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000621{
622 { 0x00 },
623 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
624 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
625 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200630 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000631 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
632 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
633 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200634 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000635 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200636 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200638 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
640 0x3d, 0x58, 0xe0, 0x91 },
641 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200642 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000643 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200644 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000645 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200646 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000647 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
648 0xc2, 0x3f, 0x45, 0x98 },
649 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200650 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000651 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200652 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000653 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200654 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000655 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
656 0x4c, 0x34, 0xae, 0xe5 },
657 { 0x00 },
658 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
667 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
668 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200669 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000670 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
672 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
673 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000674 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200677 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000678 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200679 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000680 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200681 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200683 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000684 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200685 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000686 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200687 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000688 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200689 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000690 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
694 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
695 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
696 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
697 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
698 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
699 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
700 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
701 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
702 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
703 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
704 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
705 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
706 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
707 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
708 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
709 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
710 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000713 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200718 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000727};
728
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000729static const unsigned char tag[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000730{
731 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
732 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
733 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
734 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
735 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
738 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
739 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
740 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
741 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
742 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
743 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
744 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
745 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
748 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
749 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000767};
768
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000770{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 unsigned char buf[64];
773 unsigned char tag_buf[16];
774 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000776
777 for( j = 0; j < 3; j++ )
778 {
779 int key_len = 128 + 64 * j;
780
781 for( i = 0; i < MAX_TESTS; i++ )
782 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100783 mbedtls_gcm_init( &ctx );
784
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200785 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100787 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200788
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100789 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
790 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100791 /*
792 * AES-192 is an optional feature that may be unavailable when
793 * there is an alternative underlying implementation i.e. when
794 * MBEDTLS_AES_ALT is defined.
795 */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100796 if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && key_len == 192 )
797 {
798 mbedtls_printf( "skipped\n" );
799 break;
800 }
801 else if( ret != 0 )
802 {
803 goto exit;
804 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000805
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100807 pt_len[i],
808 iv[iv_index[i]], iv_len[i],
809 additional[add_index[i]], add_len[i],
810 pt[pt_index[i]], buf, 16, tag_buf );
811 if( ret != 0 )
812 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000813
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100814 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
815 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000816 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100817 ret = 1;
818 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000819 }
820
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200822
Paul Bakker89e80c92012-03-20 13:50:09 +0000823 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000825
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100826 mbedtls_gcm_init( &ctx );
827
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200828 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100830 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200831
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100832 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
833 key_len );
834 if( ret != 0 )
835 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000836
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100838 pt_len[i],
839 iv[iv_index[i]], iv_len[i],
840 additional[add_index[i]], add_len[i],
841 ct[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000842
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100843 if( ret != 0 )
844 goto exit;
845
846 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
848 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100849 ret = 1;
850 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000851 }
852
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200854
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200857
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100858 mbedtls_gcm_init( &ctx );
859
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200860 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100862 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200863
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100864 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
865 key_len );
866 if( ret != 0 )
867 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200868
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100870 iv[iv_index[i]], iv_len[i],
871 additional[add_index[i]], add_len[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200872 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100873 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200874
875 if( pt_len[i] > 32 )
876 {
877 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200879 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100880 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200881
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200883 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200884 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100885 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200886 }
887 else
888 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200890 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100891 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200892 }
893
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100895 if( ret != 0 )
896 goto exit;
897
898 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200899 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
900 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100901 ret = 1;
902 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200903 }
904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200906
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200907 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200909
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100910 mbedtls_gcm_init( &ctx );
911
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200912 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100914 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200915
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100916 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
917 key_len );
918 if( ret != 0 )
919 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200922 iv[iv_index[i]], iv_len[i],
923 additional[add_index[i]], add_len[i] );
924 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100925 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926
927 if( pt_len[i] > 32 )
928 {
929 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200931 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100932 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200933
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100935 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200936 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100937 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200938 }
939 else
940 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100941 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
942 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200943 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100944 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200945 }
946
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100948 if( ret != 0 )
949 goto exit;
950
951 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200952 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
953 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100954 ret = 1;
955 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200956 }
957
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200959
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200960 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000962 }
963 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200964
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200965 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000967
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100968 ret = 0;
969
970exit:
971 if( ret != 0 )
972 {
973 if( verbose != 0 )
974 mbedtls_printf( "failed\n" );
975 mbedtls_gcm_free( &ctx );
976 }
977
978 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000979}
980
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983#endif /* MBEDTLS_GCM_C */