blob: 5121a7ac7e8fb628ce9672a64e8201ec0aa448f1 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker89e80c92012-03-20 13:50:09 +000020 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021
Paul Bakker89e80c92012-03-20 13:50:09 +000022/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010023 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
24 *
25 * See also:
26 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
27 *
28 * We use the algorithm described as Shoup's method with 4-bit tables in
29 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000030 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020034#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020036#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000039
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050041#include "mbedtls/platform_util.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000042
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <string.h>
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010047#endif
48
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010050#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000051#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030052#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000053#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#define mbedtls_printf printf
55#endif /* MBEDTLS_PLATFORM_C */
56#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010057
Jaeden Amero15263302017-09-21 12:53:48 +010058#if !defined(MBEDTLS_GCM_ALT)
59
k-stachowiak8ffc92a2018-12-12 14:21:59 +010060/* Parameter validation macros */
61#define GCM_VALIDATE_RET( cond ) \
62 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
63#define GCM_VALIDATE( cond ) \
64 MBEDTLS_INTERNAL_VALIDATE( cond )
65
Paul Bakker89e80c92012-03-20 13:50:09 +000066/*
67 * 32-bit integer manipulation macros (big endian)
68 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000069#ifndef GET_UINT32_BE
70#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000071{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000072 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
73 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
74 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
75 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000076}
77#endif
78
Paul Bakker5c2364c2012-10-01 14:41:15 +000079#ifndef PUT_UINT32_BE
80#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000081{ \
82 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
83 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
84 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
85 (b)[(i) + 3] = (unsigned char) ( (n) ); \
86}
87#endif
88
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010089/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020090 * Initialize a context
91 */
92void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
93{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010094 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020095 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
96}
97
98/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010099 * Precompute small multiples of H, that is set
100 * HH[i] || HL[i] = H times i,
101 * where i is seen as a field element as in [MGV], ie high-order bits
102 * correspond to low powers of P. The result is stored in the same way, that
103 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
104 * corresponds to P^127.
105 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000107{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200108 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 uint64_t hi, lo;
110 uint64_t vl, vh;
111 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200112 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200113
Paul Bakker89e80c92012-03-20 13:50:09 +0000114 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200116 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000117
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100118 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000119 GET_UINT32_BE( hi, h, 0 );
120 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000121 vh = (uint64_t) hi << 32 | lo;
122
Paul Bakker5c2364c2012-10-01 14:41:15 +0000123 GET_UINT32_BE( hi, h, 8 );
124 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000125 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200126
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100127 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000128 ctx->HL[8] = vl;
129 ctx->HH[8] = vh;
130
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100132 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100133 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100134 return( 0 );
135#endif
136
137 /* 0 corresponds to 0 in GF(2^128) */
138 ctx->HH[0] = 0;
139 ctx->HL[0] = 0;
140
Paul Bakker89e80c92012-03-20 13:50:09 +0000141 for( i = 4; i > 0; i >>= 1 )
142 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200143 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000144 vl = ( vh << 63 ) | ( vl >> 1 );
145 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
146
147 ctx->HL[i] = vl;
148 ctx->HH[i] = vh;
149 }
150
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000151 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000152 {
153 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
154 vh = *HiH;
155 vl = *HiL;
156 for( j = 1; j < i; j++ )
157 {
158 HiH[j] = vh ^ ctx->HH[j];
159 HiL[j] = vl ^ ctx->HL[j];
160 }
161 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200162
163 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000164}
165
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200166int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
167 mbedtls_cipher_id_t cipher,
168 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200169 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000170{
171 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000173
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100174 GCM_VALIDATE_RET( ctx != NULL );
175 GCM_VALIDATE_RET( key != NULL );
176 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
177
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500178 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
179 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200180 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200182
Paul Bakkera0558e02013-09-10 14:25:51 +0200183 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200184 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200185
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200186 mbedtls_cipher_free( &ctx->cipher_ctx );
187
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200188 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000189 return( ret );
190
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200191 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200193 {
194 return( ret );
195 }
196
197 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
198 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000199
200 return( 0 );
201}
202
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100203/*
204 * Shoup's method for multiplication use this table with
205 * last4[x] = x times P^128
206 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
207 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000208static const uint64_t last4[16] =
209{
210 0x0000, 0x1c20, 0x3840, 0x2460,
211 0x7080, 0x6ca0, 0x48c0, 0x54e0,
212 0xe100, 0xfd20, 0xd940, 0xc560,
213 0x9180, 0x8da0, 0xa9c0, 0xb5e0
214};
215
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100216/*
217 * Sets output to x times H using the precomputed tables.
218 * x and output are seen as elements of GF(2^128) as in [MGV].
219 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200221 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000222{
223 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000224 unsigned char lo, hi, rem;
225 uint64_t zh, zl;
226
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100228 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100229 unsigned char h[16];
230
231 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
232 PUT_UINT32_BE( ctx->HH[8], h, 4 );
233 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
234 PUT_UINT32_BE( ctx->HL[8], h, 12 );
235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100237 return;
238 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100240
Paul Bakker89e80c92012-03-20 13:50:09 +0000241 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000242
243 zh = ctx->HH[lo];
244 zl = ctx->HL[lo];
245
246 for( i = 15; i >= 0; i-- )
247 {
248 lo = x[i] & 0xf;
249 hi = x[i] >> 4;
250
251 if( i != 15 )
252 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000253 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000254 zl = ( zh << 60 ) | ( zl >> 4 );
255 zh = ( zh >> 4 );
256 zh ^= (uint64_t) last4[rem] << 48;
257 zh ^= ctx->HH[lo];
258 zl ^= ctx->HL[lo];
259
260 }
261
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000262 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000263 zl = ( zh << 60 ) | ( zl >> 4 );
264 zh = ( zh >> 4 );
265 zh ^= (uint64_t) last4[rem] << 48;
266 zh ^= ctx->HH[hi];
267 zl ^= ctx->HL[hi];
268 }
269
Paul Bakker5c2364c2012-10-01 14:41:15 +0000270 PUT_UINT32_BE( zh >> 32, output, 0 );
271 PUT_UINT32_BE( zh, output, 4 );
272 PUT_UINT32_BE( zl >> 32, output, 8 );
273 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000274}
275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200277 int mode,
278 const unsigned char *iv,
279 size_t iv_len,
280 const unsigned char *add,
281 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000282{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200283 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000284 unsigned char work_buf[16];
285 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000286 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200287 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000288
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100289 GCM_VALIDATE_RET( ctx != NULL );
290 GCM_VALIDATE_RET( iv != NULL );
291 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
292
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200293 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200294 /* IV is not allowed to be zero length */
295 if( iv_len == 0 ||
296 ( (uint64_t) iv_len ) >> 61 != 0 ||
297 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200298 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200300 }
301
Paul Bakker52cf16c2013-07-26 13:55:38 +0200302 memset( ctx->y, 0x00, sizeof(ctx->y) );
303 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
304
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200305 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200306 ctx->len = 0;
307 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000308
309 if( iv_len == 12 )
310 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200311 memcpy( ctx->y, iv, iv_len );
312 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000313 }
314 else
315 {
316 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000317 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000318
319 p = iv;
320 while( iv_len > 0 )
321 {
322 use_len = ( iv_len < 16 ) ? iv_len : 16;
323
Paul Bakker67f9d532012-10-23 11:49:05 +0000324 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200325 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200326
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200327 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000328
329 iv_len -= use_len;
330 p += use_len;
331 }
332
Paul Bakker67f9d532012-10-23 11:49:05 +0000333 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200334 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000335
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200336 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000337 }
338
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500339 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
340 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200341 {
342 return( ret );
343 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000344
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200345 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000346 p = add;
347 while( add_len > 0 )
348 {
349 use_len = ( add_len < 16 ) ? add_len : 16;
350
Paul Bakker67f9d532012-10-23 11:49:05 +0000351 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200352 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200353
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200354 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000355
356 add_len -= use_len;
357 p += use_len;
358 }
359
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200360 return( 0 );
361}
362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200364 size_t length,
365 const unsigned char *input,
366 unsigned char *output )
367{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200368 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200369 unsigned char ectr[16];
370 size_t i;
371 const unsigned char *p;
372 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200373 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200374
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100375 GCM_VALIDATE_RET( ctx != NULL );
376 GCM_VALIDATE_RET( length == 0 || input != NULL );
377 GCM_VALIDATE_RET( length == 0 || output != NULL );
378
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200379 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200381
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200382 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
383 * Also check for possible overflow */
384 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100385 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200386 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200388 }
389
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200390 ctx->len += length;
391
Paul Bakker89e80c92012-03-20 13:50:09 +0000392 p = input;
393 while( length > 0 )
394 {
395 use_len = ( length < 16 ) ? length : 16;
396
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100397 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200398 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000399 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000400
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200402 &olen ) ) != 0 )
403 {
404 return( ret );
405 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000406
Paul Bakker67f9d532012-10-23 11:49:05 +0000407 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000408 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200410 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000411 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200413 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000414 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200415
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200416 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200417
Paul Bakker89e80c92012-03-20 13:50:09 +0000418 length -= use_len;
419 p += use_len;
420 out_p += use_len;
421 }
422
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200423 return( 0 );
424}
425
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200427 unsigned char *tag,
428 size_t tag_len )
429{
430 unsigned char work_buf[16];
431 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100432 uint64_t orig_len;
433 uint64_t orig_add_len;
434
435 GCM_VALIDATE_RET( ctx != NULL );
436 GCM_VALIDATE_RET( tag != NULL );
437
438 orig_len = ctx->len * 8;
439 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200440
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200441 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200443
Andres AG821da842016-09-26 10:09:30 +0100444 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200445
Paul Bakker89e80c92012-03-20 13:50:09 +0000446 if( orig_len || orig_add_len )
447 {
448 memset( work_buf, 0x00, 16 );
449
Paul Bakker0ecdb232013-04-09 11:36:42 +0200450 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
451 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
452 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
453 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000454
Paul Bakker67f9d532012-10-23 11:49:05 +0000455 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200456 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000457
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200458 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000459
Paul Bakker67f9d532012-10-23 11:49:05 +0000460 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200461 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000462 }
463
464 return( 0 );
465}
466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200468 int mode,
469 size_t length,
470 const unsigned char *iv,
471 size_t iv_len,
472 const unsigned char *add,
473 size_t add_len,
474 const unsigned char *input,
475 unsigned char *output,
476 size_t tag_len,
477 unsigned char *tag )
478{
479 int ret;
480
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100481 GCM_VALIDATE_RET( ctx != NULL );
482 GCM_VALIDATE_RET( iv != NULL );
483 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
484 GCM_VALIDATE_RET( length == 0 || input != NULL );
485 GCM_VALIDATE_RET( length == 0 || output != NULL );
486 GCM_VALIDATE_RET( tag != NULL );
487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 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_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200492 return( ret );
493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200495 return( ret );
496
497 return( 0 );
498}
499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000501 size_t length,
502 const unsigned char *iv,
503 size_t iv_len,
504 const unsigned char *add,
505 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200506 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000507 size_t tag_len,
508 const unsigned char *input,
509 unsigned char *output )
510{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100511 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000512 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200513 size_t i;
514 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000515
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100516 GCM_VALIDATE_RET( ctx != NULL );
517 GCM_VALIDATE_RET( iv != NULL );
518 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
519 GCM_VALIDATE_RET( tag != NULL );
520 GCM_VALIDATE_RET( length == 0 || input != NULL );
521 GCM_VALIDATE_RET( length == 0 || output != NULL );
522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100524 iv, iv_len, add, add_len,
525 input, output, tag_len, check_tag ) ) != 0 )
526 {
527 return( ret );
528 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000529
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200530 /* Check tag in "constant-time" */
531 for( diff = 0, i = 0; i < tag_len; i++ )
532 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000533
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200534 if( diff != 0 )
535 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500536 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200538 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000539
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200540 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000541}
542
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200544{
k-stachowiak21298a22018-12-13 17:11:58 +0100545 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100546 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500548 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200549}
550
Jaeden Amero15263302017-09-21 12:53:48 +0100551#endif /* !MBEDTLS_GCM_ALT */
552
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000554/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200555 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000556 *
557 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
558 */
559#define MAX_TESTS 6
560
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100561static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000562 { 0, 0, 1, 1, 1, 1 };
563
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100564static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000565{
566 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
570 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
571 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
572 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200573 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000574};
575
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100576static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000577 { 12, 12, 12, 12, 8, 60 };
578
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100579static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 { 0, 0, 1, 1, 1, 2 };
581
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100582static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000583{
584 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00 },
586 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
587 0xde, 0xca, 0xf8, 0x88 },
588 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200589 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200593 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000594 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200595 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000596};
597
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100598static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 { 0, 0, 0, 20, 20, 20 };
600
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100601static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000602 { 0, 0, 0, 1, 1, 1 };
603
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100604static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000605{
606 { 0x00 },
607 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0xab, 0xad, 0xda, 0xd2 },
610};
611
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100612static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 { 0, 16, 64, 60, 60, 60 };
614
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100615static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000616 { 0, 0, 1, 1, 1, 1 };
617
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100618static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000619{
620 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
622 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
623 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
624 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
625 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
626 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
627 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
628 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
629 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
630};
631
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100632static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000633{
634 { 0x00 },
635 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
636 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
637 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200638 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200640 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000641 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200642 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000643 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
644 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
645 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200646 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000647 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200648 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000649 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200650 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000651 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
652 0x3d, 0x58, 0xe0, 0x91 },
653 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200654 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000655 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200656 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000657 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200658 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000659 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
660 0xc2, 0x3f, 0x45, 0x98 },
661 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200662 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000663 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200664 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200666 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000667 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
668 0x4c, 0x34, 0xae, 0xe5 },
669 { 0x00 },
670 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000672 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200673 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000674 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200677 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000678 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
679 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
680 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200681 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200683 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
684 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
685 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000686 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200687 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000688 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200689 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000690 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000694 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200703 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200705 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
706 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
707 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
708 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
709 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
710 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
711 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
712 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
713 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
714 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
715 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
716 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
717 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
718 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
719 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
720 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
721 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
722 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000727 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200730 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000731 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200732 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200734 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000735 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000739};
740
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100741static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000742{
743 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
744 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
745 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
746 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
747 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
750 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
751 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
752 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
753 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
754 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
755 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
756 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
757 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
760 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
761 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000779};
780
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200781int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000782{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 unsigned char buf[64];
785 unsigned char tag_buf[16];
786 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000788
789 for( j = 0; j < 3; j++ )
790 {
791 int key_len = 128 + 64 * j;
792
793 for( i = 0; i < MAX_TESTS; i++ )
794 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100795 mbedtls_gcm_init( &ctx );
796
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200797 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100799 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200800
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500801 ret = mbedtls_gcm_setkey( &ctx, cipher,
802 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100803 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100804 /*
805 * AES-192 is an optional feature that may be unavailable when
806 * there is an alternative underlying implementation i.e. when
807 * MBEDTLS_AES_ALT is defined.
808 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300809 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100810 {
811 mbedtls_printf( "skipped\n" );
812 break;
813 }
814 else if( ret != 0 )
815 {
816 goto exit;
817 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000818
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200819 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500820 pt_len_test_data[i],
821 iv_test_data[iv_index_test_data[i]],
822 iv_len_test_data[i],
823 additional_test_data[add_index_test_data[i]],
824 add_len_test_data[i],
825 pt_test_data[pt_index_test_data[i]],
826 buf, 16, tag_buf );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100827 if( ret != 0 )
828 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000829
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500830 if ( memcmp( buf, ct_test_data[j * 6 + i],
831 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100832 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100834 ret = 1;
835 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000836 }
837
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200839
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000842
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100843 mbedtls_gcm_init( &ctx );
844
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200845 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100847 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200848
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500849 ret = mbedtls_gcm_setkey( &ctx, cipher,
850 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100851 key_len );
852 if( ret != 0 )
853 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000854
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500856 pt_len_test_data[i],
857 iv_test_data[iv_index_test_data[i]],
858 iv_len_test_data[i],
859 additional_test_data[add_index_test_data[i]],
860 add_len_test_data[i],
861 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000862
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100863 if( ret != 0 )
864 goto exit;
865
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100866 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
867 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100868 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000869 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100870 ret = 1;
871 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000872 }
873
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200875
Paul Bakker89e80c92012-03-20 13:50:09 +0000876 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200878
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100879 mbedtls_gcm_init( &ctx );
880
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200881 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100883 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200884
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500885 ret = mbedtls_gcm_setkey( &ctx, cipher,
886 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100887 key_len );
888 if( ret != 0 )
889 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500892 iv_test_data[iv_index_test_data[i]],
893 iv_len_test_data[i],
894 additional_test_data[add_index_test_data[i]],
895 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200896 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100897 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200898
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100899 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200900 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100901 size_t rest_len = pt_len_test_data[i] - 32;
902 ret = mbedtls_gcm_update( &ctx, 32,
903 pt_test_data[pt_index_test_data[i]],
904 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200905 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100906 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200907
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100908 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500909 pt_test_data[pt_index_test_data[i]] + 32,
910 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200911 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100912 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200913 }
914 else
915 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100916 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500917 pt_test_data[pt_index_test_data[i]],
918 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200919 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100920 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200921 }
922
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200923 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100924 if( ret != 0 )
925 goto exit;
926
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500927 if( memcmp( buf, ct_test_data[j * 6 + i],
928 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100929 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200930 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100931 ret = 1;
932 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200933 }
934
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200936
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200937 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200939
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100940 mbedtls_gcm_init( &ctx );
941
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100944 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200945
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100946 ret = mbedtls_gcm_setkey( &ctx, cipher,
947 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100948 key_len );
949 if( ret != 0 )
950 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200951
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100953 iv_test_data[iv_index_test_data[i]],
954 iv_len_test_data[i],
955 additional_test_data[add_index_test_data[i]],
956 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200957 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100958 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200959
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100960 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200961 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100962 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500963 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
964 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200965 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100966 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200967
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500968 ret = mbedtls_gcm_update( &ctx, rest_len,
969 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100970 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200971 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100972 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200973 }
974 else
975 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100976 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
977 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100978 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
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100987 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
988 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100989 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200990 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100991 ret = 1;
992 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200993 }
994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200996
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200997 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000999 }
1000 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001001
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001002 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001003 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001004
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001005 ret = 0;
1006
1007exit:
1008 if( ret != 0 )
1009 {
1010 if( verbose != 0 )
1011 mbedtls_printf( "failed\n" );
1012 mbedtls_gcm_free( &ctx );
1013 }
1014
1015 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001016}
1017
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020#endif /* MBEDTLS_GCM_C */