blob: eae9eed77351e45f1b84d75ff8eba8d64802c4e1 [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
Gilles Peskinedb09ef62020-06-03 01:43:33 +020032#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050037#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000038#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000039
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <string.h>
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010044#endif
45
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010047#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030049#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#define mbedtls_printf printf
52#endif /* MBEDTLS_PLATFORM_C */
53#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010054
Jaeden Amero15263302017-09-21 12:53:48 +010055#if !defined(MBEDTLS_GCM_ALT)
56
k-stachowiak8ffc92a2018-12-12 14:21:59 +010057/* Parameter validation macros */
58#define GCM_VALIDATE_RET( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
60#define GCM_VALIDATE( cond ) \
61 MBEDTLS_INTERNAL_VALIDATE( cond )
62
Paul Bakker89e80c92012-03-20 13:50:09 +000063/*
64 * 32-bit integer manipulation macros (big endian)
65 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000066#ifndef GET_UINT32_BE
67#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000068{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000069 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
70 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
71 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
72 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000073}
74#endif
75
Paul Bakker5c2364c2012-10-01 14:41:15 +000076#ifndef PUT_UINT32_BE
77#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000078{ \
79 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
80 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
81 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
82 (b)[(i) + 3] = (unsigned char) ( (n) ); \
83}
84#endif
85
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010086/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020087 * Initialize a context
88 */
89void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
90{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010091 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020092 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
93}
94
95/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010096 * Precompute small multiples of H, that is set
97 * HH[i] || HL[i] = H times i,
98 * where i is seen as a field element as in [MGV], ie high-order bits
99 * correspond to low powers of P. The result is stored in the same way, that
100 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
101 * corresponds to P^127.
102 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000104{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200105 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000106 uint64_t hi, lo;
107 uint64_t vl, vh;
108 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200109 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200110
Paul Bakker89e80c92012-03-20 13:50:09 +0000111 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200113 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000114
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100115 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000116 GET_UINT32_BE( hi, h, 0 );
117 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000118 vh = (uint64_t) hi << 32 | lo;
119
Paul Bakker5c2364c2012-10-01 14:41:15 +0000120 GET_UINT32_BE( hi, h, 8 );
121 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000122 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200123
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100124 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000125 ctx->HL[8] = vl;
126 ctx->HH[8] = vh;
127
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100129 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100130 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100131 return( 0 );
132#endif
133
134 /* 0 corresponds to 0 in GF(2^128) */
135 ctx->HH[0] = 0;
136 ctx->HL[0] = 0;
137
Paul Bakker89e80c92012-03-20 13:50:09 +0000138 for( i = 4; i > 0; i >>= 1 )
139 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200140 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000141 vl = ( vh << 63 ) | ( vl >> 1 );
142 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
143
144 ctx->HL[i] = vl;
145 ctx->HH[i] = vh;
146 }
147
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000148 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000149 {
150 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
151 vh = *HiH;
152 vl = *HiL;
153 for( j = 1; j < i; j++ )
154 {
155 HiH[j] = vh ^ ctx->HH[j];
156 HiL[j] = vl ^ ctx->HL[j];
157 }
158 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200159
160 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000161}
162
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200163int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
164 mbedtls_cipher_id_t cipher,
165 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200166 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000167{
Janos Follath24eed8d2019-11-22 13:21:35 +0000168 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000170
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100171 GCM_VALIDATE_RET( ctx != NULL );
172 GCM_VALIDATE_RET( key != NULL );
173 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
174
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500175 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
176 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200177 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200179
Paul Bakkera0558e02013-09-10 14:25:51 +0200180 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200182
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200183 mbedtls_cipher_free( &ctx->cipher_ctx );
184
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200185 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000186 return( ret );
187
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200188 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200190 {
191 return( ret );
192 }
193
194 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
195 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000196
197 return( 0 );
198}
199
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100200/*
201 * Shoup's method for multiplication use this table with
202 * last4[x] = x times P^128
203 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
204 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000205static const uint64_t last4[16] =
206{
207 0x0000, 0x1c20, 0x3840, 0x2460,
208 0x7080, 0x6ca0, 0x48c0, 0x54e0,
209 0xe100, 0xfd20, 0xd940, 0xc560,
210 0x9180, 0x8da0, 0xa9c0, 0xb5e0
211};
212
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100213/*
214 * Sets output to x times H using the precomputed tables.
215 * x and output are seen as elements of GF(2^128) as in [MGV].
216 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200217static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200218 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000219{
220 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000221 unsigned char lo, hi, rem;
222 uint64_t zh, zl;
223
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100225 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100226 unsigned char h[16];
227
228 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
229 PUT_UINT32_BE( ctx->HH[8], h, 4 );
230 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
231 PUT_UINT32_BE( ctx->HL[8], h, 12 );
232
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100234 return;
235 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100237
Paul Bakker89e80c92012-03-20 13:50:09 +0000238 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000239
240 zh = ctx->HH[lo];
241 zl = ctx->HL[lo];
242
243 for( i = 15; i >= 0; i-- )
244 {
245 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200246 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000247
248 if( i != 15 )
249 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000250 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000251 zl = ( zh << 60 ) | ( zl >> 4 );
252 zh = ( zh >> 4 );
253 zh ^= (uint64_t) last4[rem] << 48;
254 zh ^= ctx->HH[lo];
255 zl ^= ctx->HL[lo];
256
257 }
258
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000259 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000260 zl = ( zh << 60 ) | ( zl >> 4 );
261 zh = ( zh >> 4 );
262 zh ^= (uint64_t) last4[rem] << 48;
263 zh ^= ctx->HH[hi];
264 zl ^= ctx->HL[hi];
265 }
266
Paul Bakker5c2364c2012-10-01 14:41:15 +0000267 PUT_UINT32_BE( zh >> 32, output, 0 );
268 PUT_UINT32_BE( zh, output, 4 );
269 PUT_UINT32_BE( zl >> 32, output, 8 );
270 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000271}
272
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200274 int mode,
275 const unsigned char *iv,
276 size_t iv_len,
277 const unsigned char *add,
278 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000279{
Janos Follath24eed8d2019-11-22 13:21:35 +0000280 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000281 unsigned char work_buf[16];
282 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000283 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200284 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000285
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100286 GCM_VALIDATE_RET( ctx != NULL );
287 GCM_VALIDATE_RET( iv != NULL );
288 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
289
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200290 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200291 /* IV is not allowed to be zero length */
292 if( iv_len == 0 ||
293 ( (uint64_t) iv_len ) >> 61 != 0 ||
294 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200295 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200296 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200297 }
298
Paul Bakker52cf16c2013-07-26 13:55:38 +0200299 memset( ctx->y, 0x00, sizeof(ctx->y) );
300 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
301
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200302 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200303 ctx->len = 0;
304 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000305
306 if( iv_len == 12 )
307 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200308 memcpy( ctx->y, iv, iv_len );
309 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000310 }
311 else
312 {
313 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000314 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000315
316 p = iv;
317 while( iv_len > 0 )
318 {
319 use_len = ( iv_len < 16 ) ? iv_len : 16;
320
Paul Bakker67f9d532012-10-23 11:49:05 +0000321 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200322 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200323
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200324 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000325
326 iv_len -= use_len;
327 p += use_len;
328 }
329
Paul Bakker67f9d532012-10-23 11:49:05 +0000330 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200331 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000332
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200333 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000334 }
335
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500336 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
337 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200338 {
339 return( ret );
340 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000341
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200342 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000343 p = add;
344 while( add_len > 0 )
345 {
346 use_len = ( add_len < 16 ) ? add_len : 16;
347
Paul Bakker67f9d532012-10-23 11:49:05 +0000348 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200349 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200350
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200351 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000352
353 add_len -= use_len;
354 p += use_len;
355 }
356
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200357 return( 0 );
358}
359
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200361 size_t length,
362 const unsigned char *input,
363 unsigned char *output )
364{
Janos Follath24eed8d2019-11-22 13:21:35 +0000365 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200366 unsigned char ectr[16];
367 size_t i;
368 const unsigned char *p;
369 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200370 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200371
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100372 GCM_VALIDATE_RET( ctx != NULL );
373 GCM_VALIDATE_RET( length == 0 || input != NULL );
374 GCM_VALIDATE_RET( length == 0 || output != NULL );
375
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200376 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200378
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200379 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
380 * Also check for possible overflow */
381 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100382 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200383 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200385 }
386
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200387 ctx->len += length;
388
Paul Bakker89e80c92012-03-20 13:50:09 +0000389 p = input;
390 while( length > 0 )
391 {
392 use_len = ( length < 16 ) ? length : 16;
393
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100394 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200395 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000396 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200399 &olen ) ) != 0 )
400 {
401 return( ret );
402 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000403
Paul Bakker67f9d532012-10-23 11:49:05 +0000404 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000405 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200407 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000408 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200410 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000411 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200412
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200413 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200414
Paul Bakker89e80c92012-03-20 13:50:09 +0000415 length -= use_len;
416 p += use_len;
417 out_p += use_len;
418 }
419
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200420 return( 0 );
421}
422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424 unsigned char *tag,
425 size_t tag_len )
426{
427 unsigned char work_buf[16];
428 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100429 uint64_t orig_len;
430 uint64_t orig_add_len;
431
432 GCM_VALIDATE_RET( ctx != NULL );
433 GCM_VALIDATE_RET( tag != NULL );
434
435 orig_len = ctx->len * 8;
436 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200437
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200438 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200440
Andres AG821da842016-09-26 10:09:30 +0100441 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200442
Paul Bakker89e80c92012-03-20 13:50:09 +0000443 if( orig_len || orig_add_len )
444 {
445 memset( work_buf, 0x00, 16 );
446
Paul Bakker0ecdb232013-04-09 11:36:42 +0200447 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
448 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
449 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
450 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000451
Paul Bakker67f9d532012-10-23 11:49:05 +0000452 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200453 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000454
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200455 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000456
Paul Bakker67f9d532012-10-23 11:49:05 +0000457 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200458 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000459 }
460
461 return( 0 );
462}
463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200465 int mode,
466 size_t length,
467 const unsigned char *iv,
468 size_t iv_len,
469 const unsigned char *add,
470 size_t add_len,
471 const unsigned char *input,
472 unsigned char *output,
473 size_t tag_len,
474 unsigned char *tag )
475{
Janos Follath24eed8d2019-11-22 13:21:35 +0000476 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200477
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100478 GCM_VALIDATE_RET( ctx != NULL );
479 GCM_VALIDATE_RET( iv != NULL );
480 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
481 GCM_VALIDATE_RET( length == 0 || input != NULL );
482 GCM_VALIDATE_RET( length == 0 || output != NULL );
483 GCM_VALIDATE_RET( tag != NULL );
484
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200486 return( ret );
487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200489 return( ret );
490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200492 return( ret );
493
494 return( 0 );
495}
496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000498 size_t length,
499 const unsigned char *iv,
500 size_t iv_len,
501 const unsigned char *add,
502 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200503 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000504 size_t tag_len,
505 const unsigned char *input,
506 unsigned char *output )
507{
Janos Follath24eed8d2019-11-22 13:21:35 +0000508 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000509 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200510 size_t i;
511 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000512
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100513 GCM_VALIDATE_RET( ctx != NULL );
514 GCM_VALIDATE_RET( iv != NULL );
515 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
516 GCM_VALIDATE_RET( tag != NULL );
517 GCM_VALIDATE_RET( length == 0 || input != NULL );
518 GCM_VALIDATE_RET( length == 0 || output != NULL );
519
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100521 iv, iv_len, add, add_len,
522 input, output, tag_len, check_tag ) ) != 0 )
523 {
524 return( ret );
525 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000526
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200527 /* Check tag in "constant-time" */
528 for( diff = 0, i = 0; i < tag_len; i++ )
529 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000530
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200531 if( diff != 0 )
532 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500533 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200535 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000536
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200537 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000538}
539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200541{
k-stachowiak21298a22018-12-13 17:11:58 +0100542 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100543 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500545 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200546}
547
Jaeden Amero15263302017-09-21 12:53:48 +0100548#endif /* !MBEDTLS_GCM_ALT */
549
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000551/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200552 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000553 *
554 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
555 */
556#define MAX_TESTS 6
557
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100558static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 { 0, 0, 1, 1, 1, 1 };
560
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100561static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000562{
563 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
567 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
568 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
569 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200570 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000571};
572
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100573static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000574 { 12, 12, 12, 12, 8, 60 };
575
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100576static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000577 { 0, 0, 1, 1, 1, 2 };
578
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100579static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000580{
581 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00 },
583 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
584 0xde, 0xca, 0xf8, 0x88 },
585 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200586 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200588 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000589 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000593};
594
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100595static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 { 0, 0, 0, 20, 20, 20 };
597
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100598static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 { 0, 0, 0, 1, 1, 1 };
600
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100601static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000602{
603 { 0x00 },
604 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200605 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000606 0xab, 0xad, 0xda, 0xd2 },
607};
608
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100609static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000610 { 0, 16, 64, 60, 60, 60 };
611
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100612static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 { 0, 0, 1, 1, 1, 1 };
614
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100615static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000616{
617 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
619 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
620 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
621 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
622 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
623 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
624 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
625 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
626 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
627};
628
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100629static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000630{
631 { 0x00 },
632 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
633 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
634 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000636 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200637 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000638 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
641 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
642 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
649 0x3d, 0x58, 0xe0, 0x91 },
650 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
657 0xc2, 0x3f, 0x45, 0x98 },
658 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
665 0x4c, 0x34, 0xae, 0xe5 },
666 { 0x00 },
667 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200668 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000669 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200670 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000671 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200672 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200674 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
676 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
677 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
681 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
682 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200684 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000685 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200686 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
703 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
704 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
705 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
706 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
707 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
708 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
709 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
710 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
711 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
712 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
713 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
714 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
715 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
716 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
717 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
718 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
719 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200721 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200723 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000724 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000730 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200731 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000732 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200733 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000734 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200735 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000736};
737
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100738static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000739{
740 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
741 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
742 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
743 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
744 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200745 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000746 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
747 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
748 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
749 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
750 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
751 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
752 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
753 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
754 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200755 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000756 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
757 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
758 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200759 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000760 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200761 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000762 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200769 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000776};
777
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200778int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000779{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200780 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 unsigned char buf[64];
782 unsigned char tag_buf[16];
783 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000785
786 for( j = 0; j < 3; j++ )
787 {
788 int key_len = 128 + 64 * j;
789
790 for( i = 0; i < MAX_TESTS; i++ )
791 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100792 mbedtls_gcm_init( &ctx );
793
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200794 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200795 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100796 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200797
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500798 ret = mbedtls_gcm_setkey( &ctx, cipher,
799 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100800 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100801 /*
802 * AES-192 is an optional feature that may be unavailable when
803 * there is an alternative underlying implementation i.e. when
804 * MBEDTLS_AES_ALT is defined.
805 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300806 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100807 {
808 mbedtls_printf( "skipped\n" );
809 break;
810 }
811 else if( ret != 0 )
812 {
813 goto exit;
814 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000815
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200816 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500817 pt_len_test_data[i],
818 iv_test_data[iv_index_test_data[i]],
819 iv_len_test_data[i],
820 additional_test_data[add_index_test_data[i]],
821 add_len_test_data[i],
822 pt_test_data[pt_index_test_data[i]],
823 buf, 16, tag_buf );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100824 if( ret != 0 )
825 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000826
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500827 if ( memcmp( buf, ct_test_data[j * 6 + i],
828 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100829 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000830 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100831 ret = 1;
832 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 }
834
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200835 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200836
Paul Bakker89e80c92012-03-20 13:50:09 +0000837 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000839
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100840 mbedtls_gcm_init( &ctx );
841
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200842 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100844 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200845
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500846 ret = mbedtls_gcm_setkey( &ctx, cipher,
847 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100848 key_len );
849 if( ret != 0 )
850 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500853 pt_len_test_data[i],
854 iv_test_data[iv_index_test_data[i]],
855 iv_len_test_data[i],
856 additional_test_data[add_index_test_data[i]],
857 add_len_test_data[i],
858 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000859
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100860 if( ret != 0 )
861 goto exit;
862
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100863 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
864 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100865 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000866 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100867 ret = 1;
868 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000869 }
870
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200872
Paul Bakker89e80c92012-03-20 13:50:09 +0000873 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200875
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100876 mbedtls_gcm_init( &ctx );
877
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200878 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100880 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200881
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500882 ret = mbedtls_gcm_setkey( &ctx, cipher,
883 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100884 key_len );
885 if( ret != 0 )
886 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200887
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500889 iv_test_data[iv_index_test_data[i]],
890 iv_len_test_data[i],
891 additional_test_data[add_index_test_data[i]],
892 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200893 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100894 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200895
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100896 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200897 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100898 size_t rest_len = pt_len_test_data[i] - 32;
899 ret = mbedtls_gcm_update( &ctx, 32,
900 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
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100905 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500906 pt_test_data[pt_index_test_data[i]] + 32,
907 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200908 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100909 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200910 }
911 else
912 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100913 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500914 pt_test_data[pt_index_test_data[i]],
915 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200916 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100917 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200918 }
919
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100921 if( ret != 0 )
922 goto exit;
923
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500924 if( memcmp( buf, ct_test_data[j * 6 + i],
925 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100926 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200927 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100928 ret = 1;
929 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200930 }
931
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200933
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200934 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200936
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100937 mbedtls_gcm_init( &ctx );
938
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200939 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100941 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100943 ret = mbedtls_gcm_setkey( &ctx, cipher,
944 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100945 key_len );
946 if( ret != 0 )
947 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200948
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100950 iv_test_data[iv_index_test_data[i]],
951 iv_len_test_data[i],
952 additional_test_data[add_index_test_data[i]],
953 add_len_test_data[i] );
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
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100957 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200958 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100959 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500960 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
961 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
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500965 ret = mbedtls_gcm_update( &ctx, rest_len,
966 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100967 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200968 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100969 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200970 }
971 else
972 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100973 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
974 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100975 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200976 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100977 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200978 }
979
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200980 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100981 if( ret != 0 )
982 goto exit;
983
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100984 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
985 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100986 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200987 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100988 ret = 1;
989 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200990 }
991
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200993
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200994 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000996 }
997 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200998
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200999 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001000 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001001
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001002 ret = 0;
1003
1004exit:
1005 if( ret != 0 )
1006 {
1007 if( verbose != 0 )
1008 mbedtls_printf( "failed\n" );
1009 mbedtls_gcm_free( &ctx );
1010 }
1011
1012 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001013}
1014
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001015#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017#endif /* MBEDTLS_GCM_C */