blob: e34f1dae4076ae5d5b45bdbaf38071bfce4e8bb4 [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"
Janos Follath24eed8d2019-11-22 13:21:35 +000042#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000043
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <string.h>
45
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010048#endif
49
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010051#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000052#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030053#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000054#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#define mbedtls_printf printf
56#endif /* MBEDTLS_PLATFORM_C */
57#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010058
Jaeden Amero15263302017-09-21 12:53:48 +010059#if !defined(MBEDTLS_GCM_ALT)
60
k-stachowiak8ffc92a2018-12-12 14:21:59 +010061/* Parameter validation macros */
62#define GCM_VALIDATE_RET( cond ) \
63 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
64#define GCM_VALIDATE( cond ) \
65 MBEDTLS_INTERNAL_VALIDATE( cond )
66
Paul Bakker89e80c92012-03-20 13:50:09 +000067/*
68 * 32-bit integer manipulation macros (big endian)
69 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000070#ifndef GET_UINT32_BE
71#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000072{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000073 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
74 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
75 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
76 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000077}
78#endif
79
Paul Bakker5c2364c2012-10-01 14:41:15 +000080#ifndef PUT_UINT32_BE
81#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000082{ \
83 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
84 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
85 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
86 (b)[(i) + 3] = (unsigned char) ( (n) ); \
87}
88#endif
89
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010090/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020091 * Initialize a context
92 */
93void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
94{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010095 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020096 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
97}
98
99/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100100 * Precompute small multiples of H, that is set
101 * HH[i] || HL[i] = H times i,
102 * where i is seen as a field element as in [MGV], ie high-order bits
103 * correspond to low powers of P. The result is stored in the same way, that
104 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
105 * corresponds to P^127.
106 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200107static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000108{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200109 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000110 uint64_t hi, lo;
111 uint64_t vl, vh;
112 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200113 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200114
Paul Bakker89e80c92012-03-20 13:50:09 +0000115 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200117 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000118
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100119 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000120 GET_UINT32_BE( hi, h, 0 );
121 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000122 vh = (uint64_t) hi << 32 | lo;
123
Paul Bakker5c2364c2012-10-01 14:41:15 +0000124 GET_UINT32_BE( hi, h, 8 );
125 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000126 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200127
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100128 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000129 ctx->HL[8] = vl;
130 ctx->HH[8] = vh;
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100133 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100134 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100135 return( 0 );
136#endif
137
138 /* 0 corresponds to 0 in GF(2^128) */
139 ctx->HH[0] = 0;
140 ctx->HL[0] = 0;
141
Paul Bakker89e80c92012-03-20 13:50:09 +0000142 for( i = 4; i > 0; i >>= 1 )
143 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200144 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000145 vl = ( vh << 63 ) | ( vl >> 1 );
146 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
147
148 ctx->HL[i] = vl;
149 ctx->HH[i] = vh;
150 }
151
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000152 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000153 {
154 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
155 vh = *HiH;
156 vl = *HiL;
157 for( j = 1; j < i; j++ )
158 {
159 HiH[j] = vh ^ ctx->HH[j];
160 HiL[j] = vl ^ ctx->HL[j];
161 }
162 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200163
164 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000165}
166
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200167int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
168 mbedtls_cipher_id_t cipher,
169 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200170 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000171{
Janos Follath24eed8d2019-11-22 13:21:35 +0000172 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000174
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100175 GCM_VALIDATE_RET( ctx != NULL );
176 GCM_VALIDATE_RET( key != NULL );
177 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
178
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500179 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
180 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200181 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200182 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200183
Paul Bakkera0558e02013-09-10 14:25:51 +0200184 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200186
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200187 mbedtls_cipher_free( &ctx->cipher_ctx );
188
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200189 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000190 return( ret );
191
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200192 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200193 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200194 {
195 return( ret );
196 }
197
198 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
199 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000200
201 return( 0 );
202}
203
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100204/*
205 * Shoup's method for multiplication use this table with
206 * last4[x] = x times P^128
207 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
208 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000209static const uint64_t last4[16] =
210{
211 0x0000, 0x1c20, 0x3840, 0x2460,
212 0x7080, 0x6ca0, 0x48c0, 0x54e0,
213 0xe100, 0xfd20, 0xd940, 0xc560,
214 0x9180, 0x8da0, 0xa9c0, 0xb5e0
215};
216
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100217/*
218 * Sets output to x times H using the precomputed tables.
219 * x and output are seen as elements of GF(2^128) as in [MGV].
220 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200222 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000223{
224 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000225 unsigned char lo, hi, rem;
226 uint64_t zh, zl;
227
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200228#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100229 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100230 unsigned char h[16];
231
232 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
233 PUT_UINT32_BE( ctx->HH[8], h, 4 );
234 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
235 PUT_UINT32_BE( ctx->HL[8], h, 12 );
236
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100238 return;
239 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100241
Paul Bakker89e80c92012-03-20 13:50:09 +0000242 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000243
244 zh = ctx->HH[lo];
245 zl = ctx->HL[lo];
246
247 for( i = 15; i >= 0; i-- )
248 {
249 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200250 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000251
252 if( i != 15 )
253 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000254 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000255 zl = ( zh << 60 ) | ( zl >> 4 );
256 zh = ( zh >> 4 );
257 zh ^= (uint64_t) last4[rem] << 48;
258 zh ^= ctx->HH[lo];
259 zl ^= ctx->HL[lo];
260
261 }
262
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000263 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000264 zl = ( zh << 60 ) | ( zl >> 4 );
265 zh = ( zh >> 4 );
266 zh ^= (uint64_t) last4[rem] << 48;
267 zh ^= ctx->HH[hi];
268 zl ^= ctx->HL[hi];
269 }
270
Paul Bakker5c2364c2012-10-01 14:41:15 +0000271 PUT_UINT32_BE( zh >> 32, output, 0 );
272 PUT_UINT32_BE( zh, output, 4 );
273 PUT_UINT32_BE( zl >> 32, output, 8 );
274 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000275}
276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200278 int mode,
279 const unsigned char *iv,
280 size_t iv_len,
281 const unsigned char *add,
282 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000283{
Janos Follath24eed8d2019-11-22 13:21:35 +0000284 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000285 unsigned char work_buf[16];
286 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000287 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200288 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000289
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100290 GCM_VALIDATE_RET( ctx != NULL );
291 GCM_VALIDATE_RET( iv != NULL );
292 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
293
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200294 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200295 /* IV is not allowed to be zero length */
296 if( iv_len == 0 ||
297 ( (uint64_t) iv_len ) >> 61 != 0 ||
298 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200299 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200301 }
302
Paul Bakker52cf16c2013-07-26 13:55:38 +0200303 memset( ctx->y, 0x00, sizeof(ctx->y) );
304 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
305
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200307 ctx->len = 0;
308 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000309
310 if( iv_len == 12 )
311 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200312 memcpy( ctx->y, iv, iv_len );
313 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000314 }
315 else
316 {
317 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000318 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000319
320 p = iv;
321 while( iv_len > 0 )
322 {
323 use_len = ( iv_len < 16 ) ? iv_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->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200327
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200328 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000329
330 iv_len -= use_len;
331 p += use_len;
332 }
333
Paul Bakker67f9d532012-10-23 11:49:05 +0000334 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200335 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000336
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200337 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000338 }
339
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500340 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
341 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200342 {
343 return( ret );
344 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000345
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200346 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000347 p = add;
348 while( add_len > 0 )
349 {
350 use_len = ( add_len < 16 ) ? add_len : 16;
351
Paul Bakker67f9d532012-10-23 11:49:05 +0000352 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200354
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200355 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000356
357 add_len -= use_len;
358 p += use_len;
359 }
360
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200361 return( 0 );
362}
363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200365 size_t length,
366 const unsigned char *input,
367 unsigned char *output )
368{
Janos Follath24eed8d2019-11-22 13:21:35 +0000369 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200370 unsigned char ectr[16];
371 size_t i;
372 const unsigned char *p;
373 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200374 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200375
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100376 GCM_VALIDATE_RET( ctx != NULL );
377 GCM_VALIDATE_RET( length == 0 || input != NULL );
378 GCM_VALIDATE_RET( length == 0 || output != NULL );
379
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200380 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200382
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200383 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
384 * Also check for possible overflow */
385 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100386 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200387 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200389 }
390
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200391 ctx->len += length;
392
Paul Bakker89e80c92012-03-20 13:50:09 +0000393 p = input;
394 while( length > 0 )
395 {
396 use_len = ( length < 16 ) ? length : 16;
397
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100398 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200399 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000400 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200403 &olen ) ) != 0 )
404 {
405 return( ret );
406 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000407
Paul Bakker67f9d532012-10-23 11:49:05 +0000408 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000409 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200410 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200411 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000412 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200414 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000415 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200416
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200417 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200418
Paul Bakker89e80c92012-03-20 13:50:09 +0000419 length -= use_len;
420 p += use_len;
421 out_p += use_len;
422 }
423
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424 return( 0 );
425}
426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200428 unsigned char *tag,
429 size_t tag_len )
430{
431 unsigned char work_buf[16];
432 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100433 uint64_t orig_len;
434 uint64_t orig_add_len;
435
436 GCM_VALIDATE_RET( ctx != NULL );
437 GCM_VALIDATE_RET( tag != NULL );
438
439 orig_len = ctx->len * 8;
440 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200441
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200442 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200444
Andres AG821da842016-09-26 10:09:30 +0100445 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200446
Paul Bakker89e80c92012-03-20 13:50:09 +0000447 if( orig_len || orig_add_len )
448 {
449 memset( work_buf, 0x00, 16 );
450
Paul Bakker0ecdb232013-04-09 11:36:42 +0200451 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
452 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
453 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
454 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000455
Paul Bakker67f9d532012-10-23 11:49:05 +0000456 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200457 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000458
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200459 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000460
Paul Bakker67f9d532012-10-23 11:49:05 +0000461 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200462 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000463 }
464
465 return( 0 );
466}
467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200469 int mode,
470 size_t length,
471 const unsigned char *iv,
472 size_t iv_len,
473 const unsigned char *add,
474 size_t add_len,
475 const unsigned char *input,
476 unsigned char *output,
477 size_t tag_len,
478 unsigned char *tag )
479{
Janos Follath24eed8d2019-11-22 13:21:35 +0000480 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200481
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100482 GCM_VALIDATE_RET( ctx != NULL );
483 GCM_VALIDATE_RET( iv != NULL );
484 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
485 GCM_VALIDATE_RET( length == 0 || input != NULL );
486 GCM_VALIDATE_RET( length == 0 || output != NULL );
487 GCM_VALIDATE_RET( tag != NULL );
488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200490 return( ret );
491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200493 return( ret );
494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200496 return( ret );
497
498 return( 0 );
499}
500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000502 size_t length,
503 const unsigned char *iv,
504 size_t iv_len,
505 const unsigned char *add,
506 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200507 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000508 size_t tag_len,
509 const unsigned char *input,
510 unsigned char *output )
511{
Janos Follath24eed8d2019-11-22 13:21:35 +0000512 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000513 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200514 size_t i;
515 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000516
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100517 GCM_VALIDATE_RET( ctx != NULL );
518 GCM_VALIDATE_RET( iv != NULL );
519 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
520 GCM_VALIDATE_RET( tag != NULL );
521 GCM_VALIDATE_RET( length == 0 || input != NULL );
522 GCM_VALIDATE_RET( length == 0 || output != NULL );
523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100525 iv, iv_len, add, add_len,
526 input, output, tag_len, check_tag ) ) != 0 )
527 {
528 return( ret );
529 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000530
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200531 /* Check tag in "constant-time" */
532 for( diff = 0, i = 0; i < tag_len; i++ )
533 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000534
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200535 if( diff != 0 )
536 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500537 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200539 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000540
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200541 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000542}
543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200545{
k-stachowiak21298a22018-12-13 17:11:58 +0100546 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100547 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200548 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500549 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200550}
551
Jaeden Amero15263302017-09-21 12:53:48 +0100552#endif /* !MBEDTLS_GCM_ALT */
553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000555/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200556 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 *
558 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
559 */
560#define MAX_TESTS 6
561
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100562static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000563 { 0, 0, 1, 1, 1, 1 };
564
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100565static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000566{
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
571 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
572 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
573 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200574 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000575};
576
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100577static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000578 { 12, 12, 12, 12, 8, 60 };
579
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100580static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000581 { 0, 0, 1, 1, 1, 2 };
582
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100583static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000584{
585 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00 },
587 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
588 0xde, 0xca, 0xf8, 0x88 },
589 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000595 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200596 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000597};
598
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100599static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000600 { 0, 0, 0, 20, 20, 20 };
601
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100602static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000603 { 0, 0, 0, 1, 1, 1 };
604
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100605static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000606{
607 { 0x00 },
608 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200609 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000610 0xab, 0xad, 0xda, 0xd2 },
611};
612
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100613static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000614 { 0, 16, 64, 60, 60, 60 };
615
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100616static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 { 0, 0, 1, 1, 1, 1 };
618
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100619static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000620{
621 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
623 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
624 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
625 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
626 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
627 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
628 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
629 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
630 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
631};
632
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100633static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000634{
635 { 0x00 },
636 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
637 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
638 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
645 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
646 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
653 0x3d, 0x58, 0xe0, 0x91 },
654 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
661 0xc2, 0x3f, 0x45, 0x98 },
662 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200667 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000668 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
669 0x4c, 0x34, 0xae, 0xe5 },
670 { 0x00 },
671 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200672 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200674 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200676 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000677 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
680 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
681 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200684 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
685 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
686 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
707 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
708 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
709 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
710 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
711 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
712 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
713 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
714 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
715 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
716 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
717 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
718 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
719 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
720 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
721 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
722 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
723 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000724 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000730 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200731 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000732 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200733 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000734 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200735 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200737 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000738 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200739 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000740};
741
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100742static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000743{
744 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
745 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
746 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
747 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
748 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200749 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000750 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
751 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
752 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
753 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
754 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
755 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
756 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
757 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
758 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200759 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000760 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
761 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
762 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200769 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200777 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000778 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200779 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000780};
781
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000783{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 unsigned char buf[64];
786 unsigned char tag_buf[16];
787 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000789
790 for( j = 0; j < 3; j++ )
791 {
792 int key_len = 128 + 64 * j;
793
794 for( i = 0; i < MAX_TESTS; i++ )
795 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100796 mbedtls_gcm_init( &ctx );
797
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200798 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100800 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200801
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500802 ret = mbedtls_gcm_setkey( &ctx, cipher,
803 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100804 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100805 /*
806 * AES-192 is an optional feature that may be unavailable when
807 * there is an alternative underlying implementation i.e. when
808 * MBEDTLS_AES_ALT is defined.
809 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300810 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100811 {
812 mbedtls_printf( "skipped\n" );
813 break;
814 }
815 else if( ret != 0 )
816 {
817 goto exit;
818 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000819
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500821 pt_len_test_data[i],
822 iv_test_data[iv_index_test_data[i]],
823 iv_len_test_data[i],
824 additional_test_data[add_index_test_data[i]],
825 add_len_test_data[i],
826 pt_test_data[pt_index_test_data[i]],
827 buf, 16, tag_buf );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100828 if( ret != 0 )
829 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000830
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500831 if ( memcmp( buf, ct_test_data[j * 6 + i],
832 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100833 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100835 ret = 1;
836 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000837 }
838
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200840
Paul Bakker89e80c92012-03-20 13:50:09 +0000841 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000843
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100844 mbedtls_gcm_init( &ctx );
845
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200846 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100848 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200849
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500850 ret = mbedtls_gcm_setkey( &ctx, cipher,
851 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100852 key_len );
853 if( ret != 0 )
854 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000855
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500857 pt_len_test_data[i],
858 iv_test_data[iv_index_test_data[i]],
859 iv_len_test_data[i],
860 additional_test_data[add_index_test_data[i]],
861 add_len_test_data[i],
862 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000863
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100864 if( ret != 0 )
865 goto exit;
866
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100867 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
868 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100869 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000870 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100871 ret = 1;
872 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000873 }
874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200876
Paul Bakker89e80c92012-03-20 13:50:09 +0000877 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200879
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100880 mbedtls_gcm_init( &ctx );
881
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200882 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100884 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200885
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500886 ret = mbedtls_gcm_setkey( &ctx, cipher,
887 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100888 key_len );
889 if( ret != 0 )
890 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200891
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500893 iv_test_data[iv_index_test_data[i]],
894 iv_len_test_data[i],
895 additional_test_data[add_index_test_data[i]],
896 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200897 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100898 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200899
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100900 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200901 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100902 size_t rest_len = pt_len_test_data[i] - 32;
903 ret = mbedtls_gcm_update( &ctx, 32,
904 pt_test_data[pt_index_test_data[i]],
905 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200906 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100907 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200908
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100909 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500910 pt_test_data[pt_index_test_data[i]] + 32,
911 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200912 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100913 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200914 }
915 else
916 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100917 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500918 pt_test_data[pt_index_test_data[i]],
919 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100921 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200922 }
923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100925 if( ret != 0 )
926 goto exit;
927
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500928 if( memcmp( buf, ct_test_data[j * 6 + i],
929 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100930 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200931 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100932 ret = 1;
933 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200934 }
935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200937
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200938 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200940
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100941 mbedtls_gcm_init( &ctx );
942
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200943 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100945 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200946
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100947 ret = mbedtls_gcm_setkey( &ctx, cipher,
948 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100949 key_len );
950 if( ret != 0 )
951 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200952
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100954 iv_test_data[iv_index_test_data[i]],
955 iv_len_test_data[i],
956 additional_test_data[add_index_test_data[i]],
957 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200958 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200960
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100961 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200962 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100963 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500964 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
965 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200966 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100967 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200968
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500969 ret = mbedtls_gcm_update( &ctx, rest_len,
970 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100971 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200972 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100973 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200974 }
975 else
976 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100977 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
978 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100979 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200980 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100981 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200982 }
983
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100985 if( ret != 0 )
986 goto exit;
987
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100988 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
989 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100990 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200991 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100992 ret = 1;
993 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200994 }
995
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200997
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200998 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001000 }
1001 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001002
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001003 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001005
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001006 ret = 0;
1007
1008exit:
1009 if( ret != 0 )
1010 {
1011 if( verbose != 0 )
1012 mbedtls_printf( "failed\n" );
1013 mbedtls_gcm_free( &ctx );
1014 }
1015
1016 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001017}
1018
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021#endif /* MBEDTLS_GCM_C */