blob: 43a5e1bec68d1c8cd9d1aa87512a7b5a268bb607 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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é-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050035#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000036#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#endif
43
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010045#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030047#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Jaeden Amero15263302017-09-21 12:53:48 +010053#if !defined(MBEDTLS_GCM_ALT)
54
k-stachowiak8ffc92a2018-12-12 14:21:59 +010055/* Parameter validation macros */
56#define GCM_VALIDATE_RET( cond ) \
57 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
58#define GCM_VALIDATE( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE( cond )
60
Paul Bakker89e80c92012-03-20 13:50:09 +000061/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020062 * Initialize a context
63 */
64void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
65{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010066 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020067 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
68}
69
70/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010071 * Precompute small multiples of H, that is set
72 * HH[i] || HL[i] = H times i,
73 * where i is seen as a field element as in [MGV], ie high-order bits
74 * correspond to low powers of P. The result is stored in the same way, that
75 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
76 * corresponds to P^127.
77 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000079{
Paul Bakker43aff2a2013-09-09 00:10:27 +020080 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000081 uint64_t hi, lo;
82 uint64_t vl, vh;
83 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020084 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020085
Paul Bakker89e80c92012-03-20 13:50:09 +000086 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020088 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000089
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010090 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani9231d5f2021-07-07 16:56:29 +010091 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
92 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000093 vh = (uint64_t) hi << 32 | lo;
94
Joe Subbiani9231d5f2021-07-07 16:56:29 +010095 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
96 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000097 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020098
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010099 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000100 ctx->HL[8] = vl;
101 ctx->HH[8] = vh;
102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100104 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100105 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100106 return( 0 );
107#endif
108
109 /* 0 corresponds to 0 in GF(2^128) */
110 ctx->HH[0] = 0;
111 ctx->HL[0] = 0;
112
Paul Bakker89e80c92012-03-20 13:50:09 +0000113 for( i = 4; i > 0; i >>= 1 )
114 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200115 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 vl = ( vh << 63 ) | ( vl >> 1 );
117 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
118
119 ctx->HL[i] = vl;
120 ctx->HH[i] = vh;
121 }
122
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000123 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000124 {
125 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
126 vh = *HiH;
127 vl = *HiL;
128 for( j = 1; j < i; j++ )
129 {
130 HiH[j] = vh ^ ctx->HH[j];
131 HiL[j] = vl ^ ctx->HL[j];
132 }
133 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200134
135 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000136}
137
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200138int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
139 mbedtls_cipher_id_t cipher,
140 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200141 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000142{
Janos Follath24eed8d2019-11-22 13:21:35 +0000143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000145
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100146 GCM_VALIDATE_RET( ctx != NULL );
147 GCM_VALIDATE_RET( key != NULL );
148 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
149
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500150 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
151 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200152 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200153 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200154
Paul Bakkera0558e02013-09-10 14:25:51 +0200155 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200157
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200158 mbedtls_cipher_free( &ctx->cipher_ctx );
159
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200160 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000161 return( ret );
162
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200163 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200165 {
166 return( ret );
167 }
168
169 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
170 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000171
172 return( 0 );
173}
174
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100175/*
176 * Shoup's method for multiplication use this table with
177 * last4[x] = x times P^128
178 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
179 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000180static const uint64_t last4[16] =
181{
182 0x0000, 0x1c20, 0x3840, 0x2460,
183 0x7080, 0x6ca0, 0x48c0, 0x54e0,
184 0xe100, 0xfd20, 0xd940, 0xc560,
185 0x9180, 0x8da0, 0xa9c0, 0xb5e0
186};
187
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100188/*
189 * Sets output to x times H using the precomputed tables.
190 * x and output are seen as elements of GF(2^128) as in [MGV].
191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200193 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000194{
195 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000196 unsigned char lo, hi, rem;
197 uint64_t zh, zl;
198
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100200 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100201 unsigned char h[16];
202
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100203 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
204 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
205 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
206 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100209 return;
210 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100212
Paul Bakker89e80c92012-03-20 13:50:09 +0000213 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000214
215 zh = ctx->HH[lo];
216 zl = ctx->HL[lo];
217
218 for( i = 15; i >= 0; i-- )
219 {
220 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200221 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000222
223 if( i != 15 )
224 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000225 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000226 zl = ( zh << 60 ) | ( zl >> 4 );
227 zh = ( zh >> 4 );
228 zh ^= (uint64_t) last4[rem] << 48;
229 zh ^= ctx->HH[lo];
230 zl ^= ctx->HL[lo];
231
232 }
233
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000234 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000235 zl = ( zh << 60 ) | ( zl >> 4 );
236 zh = ( zh >> 4 );
237 zh ^= (uint64_t) last4[rem] << 48;
238 zh ^= ctx->HH[hi];
239 zl ^= ctx->HL[hi];
240 }
241
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100242 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
243 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
244 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
245 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000246}
247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200249 int mode,
250 const unsigned char *iv,
251 size_t iv_len,
252 const unsigned char *add,
253 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000254{
Janos Follath24eed8d2019-11-22 13:21:35 +0000255 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000256 unsigned char work_buf[16];
257 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200259 size_t use_len, olen = 0;
openluopworld5d5f5202021-11-05 00:13:43 +0800260 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000261
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100262 GCM_VALIDATE_RET( ctx != NULL );
263 GCM_VALIDATE_RET( iv != NULL );
264 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
265
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200266 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200267 /* IV is not allowed to be zero length */
268 if( iv_len == 0 ||
269 ( (uint64_t) iv_len ) >> 61 != 0 ||
270 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200271 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200273 }
274
Paul Bakker52cf16c2013-07-26 13:55:38 +0200275 memset( ctx->y, 0x00, sizeof(ctx->y) );
276 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
277
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200278 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200279 ctx->len = 0;
280 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000281
282 if( iv_len == 12 )
283 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200284 memcpy( ctx->y, iv, iv_len );
285 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000286 }
287 else
288 {
289 memset( work_buf, 0x00, 16 );
openluopworld5d5f5202021-11-05 00:13:43 +0800290 iv_bits = (uint64_t)iv_len * 8;
291 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000292
293 p = iv;
294 while( iv_len > 0 )
295 {
296 use_len = ( iv_len < 16 ) ? iv_len : 16;
297
Paul Bakker67f9d532012-10-23 11:49:05 +0000298 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200299 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200300
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200301 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000302
303 iv_len -= use_len;
304 p += use_len;
305 }
306
Paul Bakker67f9d532012-10-23 11:49:05 +0000307 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200308 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000309
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200310 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000311 }
312
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500313 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
314 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200315 {
316 return( ret );
317 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000318
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200319 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000320 p = add;
321 while( add_len > 0 )
322 {
323 use_len = ( add_len < 16 ) ? add_len : 16;
324
Paul Bakker67f9d532012-10-23 11:49:05 +0000325 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200326 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200327
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200328 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000329
330 add_len -= use_len;
331 p += use_len;
332 }
333
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200334 return( 0 );
335}
336
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200338 size_t length,
339 const unsigned char *input,
340 unsigned char *output )
341{
Janos Follath24eed8d2019-11-22 13:21:35 +0000342 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200343 unsigned char ectr[16];
344 size_t i;
345 const unsigned char *p;
346 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200347 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200348
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100349 GCM_VALIDATE_RET( ctx != NULL );
350 GCM_VALIDATE_RET( length == 0 || input != NULL );
351 GCM_VALIDATE_RET( length == 0 || output != NULL );
352
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200355
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200356 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
357 * Also check for possible overflow */
358 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100359 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200360 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200362 }
363
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200364 ctx->len += length;
365
Paul Bakker89e80c92012-03-20 13:50:09 +0000366 p = input;
367 while( length > 0 )
368 {
369 use_len = ( length < 16 ) ? length : 16;
370
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100371 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200372 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000373 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200376 &olen ) ) != 0 )
377 {
378 return( ret );
379 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000380
Paul Bakker67f9d532012-10-23 11:49:05 +0000381 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000382 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000385 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200387 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000388 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200389
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200390 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200391
Paul Bakker89e80c92012-03-20 13:50:09 +0000392 length -= use_len;
393 p += use_len;
394 out_p += use_len;
395 }
396
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200397 return( 0 );
398}
399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200401 unsigned char *tag,
402 size_t tag_len )
403{
404 unsigned char work_buf[16];
405 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100406 uint64_t orig_len;
407 uint64_t orig_add_len;
408
409 GCM_VALIDATE_RET( ctx != NULL );
410 GCM_VALIDATE_RET( tag != NULL );
411
412 orig_len = ctx->len * 8;
413 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200414
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200415 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200417
Andres AG821da842016-09-26 10:09:30 +0100418 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200419
Paul Bakker89e80c92012-03-20 13:50:09 +0000420 if( orig_len || orig_add_len )
421 {
422 memset( work_buf, 0x00, 16 );
423
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100424 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
425 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
426 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
427 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000428
Paul Bakker67f9d532012-10-23 11:49:05 +0000429 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200430 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000431
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200432 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000433
Paul Bakker67f9d532012-10-23 11:49:05 +0000434 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200435 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000436 }
437
438 return( 0 );
439}
440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200442 int mode,
443 size_t length,
444 const unsigned char *iv,
445 size_t iv_len,
446 const unsigned char *add,
447 size_t add_len,
448 const unsigned char *input,
449 unsigned char *output,
450 size_t tag_len,
451 unsigned char *tag )
452{
Janos Follath24eed8d2019-11-22 13:21:35 +0000453 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200454
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100455 GCM_VALIDATE_RET( ctx != NULL );
456 GCM_VALIDATE_RET( iv != NULL );
457 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
458 GCM_VALIDATE_RET( length == 0 || input != NULL );
459 GCM_VALIDATE_RET( length == 0 || output != NULL );
460 GCM_VALIDATE_RET( tag != NULL );
461
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200463 return( ret );
464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200466 return( ret );
467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200469 return( ret );
470
471 return( 0 );
472}
473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000475 size_t length,
476 const unsigned char *iv,
477 size_t iv_len,
478 const unsigned char *add,
479 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200480 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000481 size_t tag_len,
482 const unsigned char *input,
483 unsigned char *output )
484{
Janos Follath24eed8d2019-11-22 13:21:35 +0000485 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000486 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200487 size_t i;
488 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000489
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100490 GCM_VALIDATE_RET( ctx != NULL );
491 GCM_VALIDATE_RET( iv != NULL );
492 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
493 GCM_VALIDATE_RET( tag != NULL );
494 GCM_VALIDATE_RET( length == 0 || input != NULL );
495 GCM_VALIDATE_RET( length == 0 || output != NULL );
496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100498 iv, iv_len, add, add_len,
499 input, output, tag_len, check_tag ) ) != 0 )
500 {
501 return( ret );
502 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000503
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200504 /* Check tag in "constant-time" */
505 for( diff = 0, i = 0; i < tag_len; i++ )
506 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000507
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200508 if( diff != 0 )
509 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500510 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200512 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000513
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200514 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000515}
516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200518{
k-stachowiak21298a22018-12-13 17:11:58 +0100519 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100520 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500522 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200523}
524
Jaeden Amero15263302017-09-21 12:53:48 +0100525#endif /* !MBEDTLS_GCM_ALT */
526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000528/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200529 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000530 *
531 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
532 */
533#define MAX_TESTS 6
534
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100535static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000536 { 0, 0, 1, 1, 1, 1 };
537
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100538static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000539{
540 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
544 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
545 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
546 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200547 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000548};
549
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100550static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 { 12, 12, 12, 12, 8, 60 };
552
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100553static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000554 { 0, 0, 1, 1, 1, 2 };
555
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100556static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000557{
558 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00 },
560 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
561 0xde, 0xca, 0xf8, 0x88 },
562 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200563 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200565 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200567 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000568 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200569 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000570};
571
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100572static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000573 { 0, 0, 0, 20, 20, 20 };
574
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100575static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000576 { 0, 0, 0, 1, 1, 1 };
577
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100578static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000579{
580 { 0x00 },
581 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200582 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000583 0xab, 0xad, 0xda, 0xd2 },
584};
585
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100586static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 { 0, 16, 64, 60, 60, 60 };
588
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100589static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 { 0, 0, 1, 1, 1, 1 };
591
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100592static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000593{
594 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
596 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
597 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
598 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
599 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
600 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
601 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
602 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
603 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
604};
605
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100606static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000607{
608 { 0x00 },
609 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
610 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
611 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
618 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
619 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
626 0x3d, 0x58, 0xe0, 0x91 },
627 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200630 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000631 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200632 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
634 0xc2, 0x3f, 0x45, 0x98 },
635 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200636 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200638 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200640 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000641 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
642 0x4c, 0x34, 0xae, 0xe5 },
643 { 0x00 },
644 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
653 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
654 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
658 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
659 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200667 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000668 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200669 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000670 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000672 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200673 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000674 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200677 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000678 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200679 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
680 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
681 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
682 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
683 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
684 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
685 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
686 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
687 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
688 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
689 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
690 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
691 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
692 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
693 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
694 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
695 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
696 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200710 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000713};
714
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100715static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000716{
717 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
718 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
719 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
720 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
721 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
724 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
725 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
726 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
727 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
728 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
729 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
730 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
731 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200732 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
734 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
735 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000753};
754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000756{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200757 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000758 unsigned char buf[64];
759 unsigned char tag_buf[16];
760 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000762
763 for( j = 0; j < 3; j++ )
764 {
765 int key_len = 128 + 64 * j;
766
767 for( i = 0; i < MAX_TESTS; i++ )
768 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100769 mbedtls_gcm_init( &ctx );
770
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200771 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100773 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200774
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500775 ret = mbedtls_gcm_setkey( &ctx, cipher,
776 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100777 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100778 /*
779 * AES-192 is an optional feature that may be unavailable when
780 * there is an alternative underlying implementation i.e. when
781 * MBEDTLS_AES_ALT is defined.
782 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300783 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100784 {
785 mbedtls_printf( "skipped\n" );
786 break;
787 }
788 else if( ret != 0 )
789 {
790 goto exit;
791 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000792
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500794 pt_len_test_data[i],
795 iv_test_data[iv_index_test_data[i]],
796 iv_len_test_data[i],
797 additional_test_data[add_index_test_data[i]],
798 add_len_test_data[i],
799 pt_test_data[pt_index_test_data[i]],
800 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100801#if defined(MBEDTLS_GCM_ALT)
802 /* Allow alternative implementations to only support 12-byte nonces. */
803 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
804 iv_len_test_data[i] != 12 )
805 {
806 mbedtls_printf( "skipped\n" );
807 break;
808 }
809#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100810 if( ret != 0 )
811 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000812
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500813 if ( memcmp( buf, ct_test_data[j * 6 + i],
814 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100815 memcmp( tag_buf, tag_test_data[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
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500832 ret = mbedtls_gcm_setkey( &ctx, cipher,
833 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100834 key_len );
835 if( ret != 0 )
836 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000837
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500839 pt_len_test_data[i],
840 iv_test_data[iv_index_test_data[i]],
841 iv_len_test_data[i],
842 additional_test_data[add_index_test_data[i]],
843 add_len_test_data[i],
844 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000845
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100846 if( ret != 0 )
847 goto exit;
848
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100849 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
850 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100851 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000852 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100853 ret = 1;
854 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 }
856
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200858
Paul Bakker89e80c92012-03-20 13:50:09 +0000859 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200861
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100862 mbedtls_gcm_init( &ctx );
863
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200864 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100866 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200867
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500868 ret = mbedtls_gcm_setkey( &ctx, cipher,
869 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100870 key_len );
871 if( ret != 0 )
872 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200873
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500875 iv_test_data[iv_index_test_data[i]],
876 iv_len_test_data[i],
877 additional_test_data[add_index_test_data[i]],
878 add_len_test_data[i] );
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
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100882 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200883 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100884 size_t rest_len = pt_len_test_data[i] - 32;
885 ret = mbedtls_gcm_update( &ctx, 32,
886 pt_test_data[pt_index_test_data[i]],
887 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200888 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100889 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200890
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100891 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500892 pt_test_data[pt_index_test_data[i]] + 32,
893 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200894 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100895 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200896 }
897 else
898 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100899 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500900 pt_test_data[pt_index_test_data[i]],
901 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200902 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100903 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200904 }
905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100907 if( ret != 0 )
908 goto exit;
909
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500910 if( memcmp( buf, ct_test_data[j * 6 + i],
911 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100912 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200913 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100914 ret = 1;
915 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200916 }
917
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200919
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200922
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100923 mbedtls_gcm_init( &ctx );
924
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200925 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100927 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200928
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100929 ret = mbedtls_gcm_setkey( &ctx, cipher,
930 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100931 key_len );
932 if( ret != 0 )
933 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200934
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100936 iv_test_data[iv_index_test_data[i]],
937 iv_len_test_data[i],
938 additional_test_data[add_index_test_data[i]],
939 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200940 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100941 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100943 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200944 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100945 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500946 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
947 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200948 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100949 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200950
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500951 ret = mbedtls_gcm_update( &ctx, rest_len,
952 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100953 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200954 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100955 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200956 }
957 else
958 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100959 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
960 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100961 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200962 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100963 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200964 }
965
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100967 if( ret != 0 )
968 goto exit;
969
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100970 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
971 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100972 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200973 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100974 ret = 1;
975 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200976 }
977
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200979
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200980 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000982 }
983 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200984
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200985 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000987
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100988 ret = 0;
989
990exit:
991 if( ret != 0 )
992 {
993 if( verbose != 0 )
994 mbedtls_printf( "failed\n" );
995 mbedtls_gcm_free( &ctx );
996 }
997
998 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000999}
1000
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001002
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001003#endif /* MBEDTLS_GCM_C */