blob: 82940194374e4919b235a2aa161ee6ccd6c6cdb8 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker89e80c92012-03-20 13:50:09 +000020 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021
Paul Bakker89e80c92012-03-20 13:50:09 +000022/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010023 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
24 *
25 * See also:
26 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
27 *
28 * We use the algorithm described as Shoup's method with 4-bit tables in
29 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000030 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020034#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020036#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000039
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050041#include "mbedtls/platform_util.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000042
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <string.h>
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010047#endif
48
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010050#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000051#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030052#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000053#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#define mbedtls_printf printf
55#endif /* MBEDTLS_PLATFORM_C */
56#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010057
Jaeden Amero15263302017-09-21 12:53:48 +010058#if !defined(MBEDTLS_GCM_ALT)
59
k-stachowiak8ffc92a2018-12-12 14:21:59 +010060/* Parameter validation macros */
61#define GCM_VALIDATE_RET( cond ) \
62 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
63#define GCM_VALIDATE( cond ) \
64 MBEDTLS_INTERNAL_VALIDATE( cond )
65
Paul Bakker89e80c92012-03-20 13:50:09 +000066/*
67 * 32-bit integer manipulation macros (big endian)
68 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000069#ifndef GET_UINT32_BE
70#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000071{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000072 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
73 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
74 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
75 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000076}
77#endif
78
Paul Bakker5c2364c2012-10-01 14:41:15 +000079#ifndef PUT_UINT32_BE
80#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000081{ \
82 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
83 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
84 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
85 (b)[(i) + 3] = (unsigned char) ( (n) ); \
86}
87#endif
88
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010089/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020090 * Initialize a context
91 */
92void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
93{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010094 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020095 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
96}
97
98/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010099 * Precompute small multiples of H, that is set
100 * HH[i] || HL[i] = H times i,
101 * where i is seen as a field element as in [MGV], ie high-order bits
102 * correspond to low powers of P. The result is stored in the same way, that
103 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
104 * corresponds to P^127.
105 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000107{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200108 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 uint64_t hi, lo;
110 uint64_t vl, vh;
111 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200112 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200113
Paul Bakker89e80c92012-03-20 13:50:09 +0000114 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200116 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000117
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100118 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000119 GET_UINT32_BE( hi, h, 0 );
120 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000121 vh = (uint64_t) hi << 32 | lo;
122
Paul Bakker5c2364c2012-10-01 14:41:15 +0000123 GET_UINT32_BE( hi, h, 8 );
124 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000125 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200126
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100127 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000128 ctx->HL[8] = vl;
129 ctx->HH[8] = vh;
130
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100132 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100133 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100134 return( 0 );
135#endif
136
137 /* 0 corresponds to 0 in GF(2^128) */
138 ctx->HH[0] = 0;
139 ctx->HL[0] = 0;
140
Paul Bakker89e80c92012-03-20 13:50:09 +0000141 for( i = 4; i > 0; i >>= 1 )
142 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200143 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000144 vl = ( vh << 63 ) | ( vl >> 1 );
145 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
146
147 ctx->HL[i] = vl;
148 ctx->HH[i] = vh;
149 }
150
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000151 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000152 {
153 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
154 vh = *HiH;
155 vl = *HiL;
156 for( j = 1; j < i; j++ )
157 {
158 HiH[j] = vh ^ ctx->HH[j];
159 HiL[j] = vl ^ ctx->HL[j];
160 }
161 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200162
163 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000164}
165
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200166int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
167 mbedtls_cipher_id_t cipher,
168 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200169 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000170{
171 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000173
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100174 GCM_VALIDATE_RET( ctx != NULL );
175 GCM_VALIDATE_RET( key != NULL );
176 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
177
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200178 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200179 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200181
Paul Bakkera0558e02013-09-10 14:25:51 +0200182 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200184
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200185 mbedtls_cipher_free( &ctx->cipher_ctx );
186
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200187 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000188 return( ret );
189
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200190 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200192 {
193 return( ret );
194 }
195
196 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
197 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000198
199 return( 0 );
200}
201
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100202/*
203 * Shoup's method for multiplication use this table with
204 * last4[x] = x times P^128
205 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
206 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000207static const uint64_t last4[16] =
208{
209 0x0000, 0x1c20, 0x3840, 0x2460,
210 0x7080, 0x6ca0, 0x48c0, 0x54e0,
211 0xe100, 0xfd20, 0xd940, 0xc560,
212 0x9180, 0x8da0, 0xa9c0, 0xb5e0
213};
214
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100215/*
216 * Sets output to x times H using the precomputed tables.
217 * x and output are seen as elements of GF(2^128) as in [MGV].
218 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200220 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000221{
222 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000223 unsigned char lo, hi, rem;
224 uint64_t zh, zl;
225
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200226#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100227 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100228 unsigned char h[16];
229
230 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
231 PUT_UINT32_BE( ctx->HH[8], h, 4 );
232 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
233 PUT_UINT32_BE( ctx->HL[8], h, 12 );
234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200235 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100236 return;
237 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200238#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100239
Paul Bakker89e80c92012-03-20 13:50:09 +0000240 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000241
242 zh = ctx->HH[lo];
243 zl = ctx->HL[lo];
244
245 for( i = 15; i >= 0; i-- )
246 {
247 lo = x[i] & 0xf;
248 hi = x[i] >> 4;
249
250 if( i != 15 )
251 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000252 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000253 zl = ( zh << 60 ) | ( zl >> 4 );
254 zh = ( zh >> 4 );
255 zh ^= (uint64_t) last4[rem] << 48;
256 zh ^= ctx->HH[lo];
257 zl ^= ctx->HL[lo];
258
259 }
260
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000261 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000262 zl = ( zh << 60 ) | ( zl >> 4 );
263 zh = ( zh >> 4 );
264 zh ^= (uint64_t) last4[rem] << 48;
265 zh ^= ctx->HH[hi];
266 zl ^= ctx->HL[hi];
267 }
268
Paul Bakker5c2364c2012-10-01 14:41:15 +0000269 PUT_UINT32_BE( zh >> 32, output, 0 );
270 PUT_UINT32_BE( zh, output, 4 );
271 PUT_UINT32_BE( zl >> 32, output, 8 );
272 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000273}
274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200276 int mode,
277 const unsigned char *iv,
278 size_t iv_len,
279 const unsigned char *add,
280 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000281{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200282 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000283 unsigned char work_buf[16];
284 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000285 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200286 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000287
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100288 GCM_VALIDATE_RET( ctx != NULL );
289 GCM_VALIDATE_RET( iv != NULL );
290 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
291
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200292 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200293 /* IV is not allowed to be zero length */
294 if( iv_len == 0 ||
295 ( (uint64_t) iv_len ) >> 61 != 0 ||
296 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200297 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200299 }
300
Paul Bakker52cf16c2013-07-26 13:55:38 +0200301 memset( ctx->y, 0x00, sizeof(ctx->y) );
302 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
303
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200304 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200305 ctx->len = 0;
306 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000307
308 if( iv_len == 12 )
309 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200310 memcpy( ctx->y, iv, iv_len );
311 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000312 }
313 else
314 {
315 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000316 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000317
318 p = iv;
319 while( iv_len > 0 )
320 {
321 use_len = ( iv_len < 16 ) ? iv_len : 16;
322
Paul Bakker67f9d532012-10-23 11:49:05 +0000323 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200324 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200325
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200326 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000327
328 iv_len -= use_len;
329 p += use_len;
330 }
331
Paul Bakker67f9d532012-10-23 11:49:05 +0000332 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200333 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000334
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200335 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000336 }
337
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200339 &olen ) ) != 0 )
340 {
341 return( ret );
342 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000343
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200344 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000345 p = add;
346 while( add_len > 0 )
347 {
348 use_len = ( add_len < 16 ) ? add_len : 16;
349
Paul Bakker67f9d532012-10-23 11:49:05 +0000350 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200351 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200352
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000354
355 add_len -= use_len;
356 p += use_len;
357 }
358
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200359 return( 0 );
360}
361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200363 size_t length,
364 const unsigned char *input,
365 unsigned char *output )
366{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200367 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200368 unsigned char ectr[16];
369 size_t i;
370 const unsigned char *p;
371 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200372 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200373
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100374 GCM_VALIDATE_RET( ctx != NULL );
375 GCM_VALIDATE_RET( length == 0 || input != NULL );
376 GCM_VALIDATE_RET( length == 0 || output != NULL );
377
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200378 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200380
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200381 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
382 * Also check for possible overflow */
383 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100384 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200385 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200387 }
388
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200389 ctx->len += length;
390
Paul Bakker89e80c92012-03-20 13:50:09 +0000391 p = input;
392 while( length > 0 )
393 {
394 use_len = ( length < 16 ) ? length : 16;
395
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100396 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200397 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000398 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200401 &olen ) ) != 0 )
402 {
403 return( ret );
404 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000405
Paul Bakker67f9d532012-10-23 11:49:05 +0000406 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000407 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200409 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000410 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200412 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000413 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200414
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200415 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200416
Paul Bakker89e80c92012-03-20 13:50:09 +0000417 length -= use_len;
418 p += use_len;
419 out_p += use_len;
420 }
421
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200422 return( 0 );
423}
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200426 unsigned char *tag,
427 size_t tag_len )
428{
429 unsigned char work_buf[16];
430 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100431 uint64_t orig_len;
432 uint64_t orig_add_len;
433
434 GCM_VALIDATE_RET( ctx != NULL );
435 GCM_VALIDATE_RET( tag != NULL );
436
437 orig_len = ctx->len * 8;
438 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200439
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200440 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200442
Andres AG821da842016-09-26 10:09:30 +0100443 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200444
Paul Bakker89e80c92012-03-20 13:50:09 +0000445 if( orig_len || orig_add_len )
446 {
447 memset( work_buf, 0x00, 16 );
448
Paul Bakker0ecdb232013-04-09 11:36:42 +0200449 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
450 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
451 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
452 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000453
Paul Bakker67f9d532012-10-23 11:49:05 +0000454 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200455 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000456
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200457 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000458
Paul Bakker67f9d532012-10-23 11:49:05 +0000459 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200460 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000461 }
462
463 return( 0 );
464}
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200467 int mode,
468 size_t length,
469 const unsigned char *iv,
470 size_t iv_len,
471 const unsigned char *add,
472 size_t add_len,
473 const unsigned char *input,
474 unsigned char *output,
475 size_t tag_len,
476 unsigned char *tag )
477{
478 int ret;
479
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100480 GCM_VALIDATE_RET( ctx != NULL );
481 GCM_VALIDATE_RET( iv != NULL );
482 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
483 GCM_VALIDATE_RET( length == 0 || input != NULL );
484 GCM_VALIDATE_RET( length == 0 || output != NULL );
485 GCM_VALIDATE_RET( tag != NULL );
486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200488 return( ret );
489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200491 return( ret );
492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200494 return( ret );
495
496 return( 0 );
497}
498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000500 size_t length,
501 const unsigned char *iv,
502 size_t iv_len,
503 const unsigned char *add,
504 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200505 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000506 size_t tag_len,
507 const unsigned char *input,
508 unsigned char *output )
509{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100510 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000511 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200512 size_t i;
513 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000514
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100515 GCM_VALIDATE_RET( ctx != NULL );
516 GCM_VALIDATE_RET( iv != NULL );
517 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
518 GCM_VALIDATE_RET( tag != NULL );
519 GCM_VALIDATE_RET( length == 0 || input != NULL );
520 GCM_VALIDATE_RET( length == 0 || output != NULL );
521
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100523 iv, iv_len, add, add_len,
524 input, output, tag_len, check_tag ) ) != 0 )
525 {
526 return( ret );
527 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000528
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200529 /* Check tag in "constant-time" */
530 for( diff = 0, i = 0; i < tag_len; i++ )
531 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000532
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200533 if( diff != 0 )
534 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500535 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200537 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000538
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200539 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000540}
541
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200543{
k-stachowiak21298a22018-12-13 17:11:58 +0100544 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100545 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200546 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500547 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200548}
549
Jaeden Amero15263302017-09-21 12:53:48 +0100550#endif /* !MBEDTLS_GCM_ALT */
551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000553/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200554 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000555 *
556 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
557 */
558#define MAX_TESTS 6
559
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000560static const int key_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000561 { 0, 0, 1, 1, 1, 1 };
562
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100563static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000564{
565 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
569 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
570 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
571 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200572 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000573};
574
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100575static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000576 { 12, 12, 12, 12, 8, 60 };
577
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000578static const int iv_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000579 { 0, 0, 1, 1, 1, 2 };
580
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100581static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000582{
583 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00 },
585 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
586 0xde, 0xca, 0xf8, 0x88 },
587 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200588 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000589 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000595};
596
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100597static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000598 { 0, 0, 0, 20, 20, 20 };
599
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000600static const int add_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000601 { 0, 0, 0, 1, 1, 1 };
602
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000603static const unsigned char additional[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000604{
605 { 0x00 },
606 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200607 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000608 0xab, 0xad, 0xda, 0xd2 },
609};
610
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000611static const size_t pt_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000612 { 0, 16, 64, 60, 60, 60 };
613
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000614static const int pt_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 { 0, 0, 1, 1, 1, 1 };
616
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000617static const unsigned char pt[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000618{
619 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
621 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
622 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
623 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
624 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
625 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
626 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
627 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
628 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
629};
630
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000631static const unsigned char ct[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000632{
633 { 0x00 },
634 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
635 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
636 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200637 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000638 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
643 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
644 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
651 0x3d, 0x58, 0xe0, 0x91 },
652 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
659 0xc2, 0x3f, 0x45, 0x98 },
660 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
667 0x4c, 0x34, 0xae, 0xe5 },
668 { 0x00 },
669 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200670 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000671 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200672 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200674 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200676 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000677 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
678 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
679 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
683 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
684 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000685 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200686 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
705 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
706 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
707 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
708 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
709 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
710 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
711 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
712 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
713 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
714 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
715 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
716 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
717 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
718 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
719 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
720 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
721 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200723 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000724 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000730 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200731 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000732 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200733 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000734 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200735 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200737 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000738};
739
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100740static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000741{
742 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
743 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
744 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
745 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
746 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200747 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000748 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
749 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
750 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
751 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
752 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
753 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
754 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
755 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
756 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200757 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000758 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
759 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
760 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200761 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000762 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200769 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200777 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000778};
779
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200780int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000781{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 unsigned char buf[64];
784 unsigned char tag_buf[16];
785 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000787
788 for( j = 0; j < 3; j++ )
789 {
790 int key_len = 128 + 64 * j;
791
792 for( i = 0; i < MAX_TESTS; i++ )
793 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100794 mbedtls_gcm_init( &ctx );
795
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200796 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100798 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200799
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100800 ret = mbedtls_gcm_setkey( &ctx, cipher, key_test_data[key_index[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100801 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100802 /*
803 * AES-192 is an optional feature that may be unavailable when
804 * there is an alternative underlying implementation i.e. when
805 * MBEDTLS_AES_ALT is defined.
806 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300807 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100808 {
809 mbedtls_printf( "skipped\n" );
810 break;
811 }
812 else if( ret != 0 )
813 {
814 goto exit;
815 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000816
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100818 pt_len[i],
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100819 iv_test_data[iv_index[i]], iv_len_test_data[i],
820 additional[add_index[i]], add_len_test_data[i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100821 pt[pt_index[i]], buf, 16, tag_buf );
822 if( ret != 0 )
823 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000824
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100825 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100826 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000827 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100828 ret = 1;
829 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000830 }
831
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200833
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200835 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000836
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100837 mbedtls_gcm_init( &ctx );
838
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200839 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200840 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100841 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200842
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100843 ret = mbedtls_gcm_setkey( &ctx, cipher, key_test_data[key_index[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100844 key_len );
845 if( ret != 0 )
846 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000847
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100849 pt_len[i],
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100850 iv_test_data[iv_index[i]], iv_len_test_data[i],
851 additional[add_index[i]], add_len_test_data[i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100852 ct[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000853
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100854 if( ret != 0 )
855 goto exit;
856
857 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100858 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000859 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100860 ret = 1;
861 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000862 }
863
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200864 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200865
Paul Bakker89e80c92012-03-20 13:50:09 +0000866 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200868
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100869 mbedtls_gcm_init( &ctx );
870
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200871 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100873 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200874
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100875 ret = mbedtls_gcm_setkey( &ctx, cipher, key_test_data[key_index[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100876 key_len );
877 if( ret != 0 )
878 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200880 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100881 iv_test_data[iv_index[i]], iv_len_test_data[i],
882 additional[add_index[i]], add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200883 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100884 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200885
886 if( pt_len[i] > 32 )
887 {
888 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200890 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100891 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200892
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200894 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200895 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100896 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200897 }
898 else
899 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200901 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100902 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200903 }
904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100906 if( ret != 0 )
907 goto exit;
908
909 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100910 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200911 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100912 ret = 1;
913 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200914 }
915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200917
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200918 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100921 mbedtls_gcm_init( &ctx );
922
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200923 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100925 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100927 ret = mbedtls_gcm_setkey( &ctx, cipher, key_test_data[key_index[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100928 key_len );
929 if( ret != 0 )
930 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200931
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100933 iv_test_data[iv_index[i]], iv_len_test_data[i],
934 additional[add_index[i]], add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200935 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100936 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200937
938 if( pt_len[i] > 32 )
939 {
940 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100943 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200944
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100946 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200947 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100948 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200949 }
950 else
951 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100952 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
953 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200954 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100955 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200956 }
957
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 if( ret != 0 )
960 goto exit;
961
962 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100963 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200964 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100965 ret = 1;
966 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200967 }
968
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200970
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200971 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000973 }
974 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200975
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200976 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000978
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100979 ret = 0;
980
981exit:
982 if( ret != 0 )
983 {
984 if( verbose != 0 )
985 mbedtls_printf( "failed\n" );
986 mbedtls_gcm_free( &ctx );
987 }
988
989 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000990}
991
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994#endif /* MBEDTLS_GCM_C */