Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Committer:
HannesTschofenig
Date:
Thu Sep 27 06:34:22 2018 +0000
Revision:
0:796d0f61a05b
Example AES-GCM test program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HannesTschofenig 0:796d0f61a05b 1 /*
HannesTschofenig 0:796d0f61a05b 2 * NIST SP800-38D compliant GCM implementation
HannesTschofenig 0:796d0f61a05b 3 *
HannesTschofenig 0:796d0f61a05b 4 * Copyright (C) 2006-2014, Brainspark B.V.
HannesTschofenig 0:796d0f61a05b 5 *
HannesTschofenig 0:796d0f61a05b 6 * This file is part of PolarSSL (http://www.polarssl.org)
HannesTschofenig 0:796d0f61a05b 7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
HannesTschofenig 0:796d0f61a05b 8 *
HannesTschofenig 0:796d0f61a05b 9 * All rights reserved.
HannesTschofenig 0:796d0f61a05b 10 *
HannesTschofenig 0:796d0f61a05b 11 * This program is free software; you can redistribute it and/or modify
HannesTschofenig 0:796d0f61a05b 12 * it under the terms of the GNU General Public License as published by
HannesTschofenig 0:796d0f61a05b 13 * the Free Software Foundation; either version 2 of the License, or
HannesTschofenig 0:796d0f61a05b 14 * (at your option) any later version.
HannesTschofenig 0:796d0f61a05b 15 *
HannesTschofenig 0:796d0f61a05b 16 * This program is distributed in the hope that it will be useful,
HannesTschofenig 0:796d0f61a05b 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
HannesTschofenig 0:796d0f61a05b 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
HannesTschofenig 0:796d0f61a05b 19 * GNU General Public License for more details.
HannesTschofenig 0:796d0f61a05b 20 *
HannesTschofenig 0:796d0f61a05b 21 * You should have received a copy of the GNU General Public License along
HannesTschofenig 0:796d0f61a05b 22 * with this program; if not, write to the Free Software Foundation, Inc.,
HannesTschofenig 0:796d0f61a05b 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
HannesTschofenig 0:796d0f61a05b 24 */
HannesTschofenig 0:796d0f61a05b 25
HannesTschofenig 0:796d0f61a05b 26 /*
HannesTschofenig 0:796d0f61a05b 27 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
HannesTschofenig 0:796d0f61a05b 28 *
HannesTschofenig 0:796d0f61a05b 29 * See also:
HannesTschofenig 0:796d0f61a05b 30 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
HannesTschofenig 0:796d0f61a05b 31 *
HannesTschofenig 0:796d0f61a05b 32 * We use the algorithm described as Shoup's method with 4-bit tables in
HannesTschofenig 0:796d0f61a05b 33 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
HannesTschofenig 0:796d0f61a05b 34 */
HannesTschofenig 0:796d0f61a05b 35
HannesTschofenig 0:796d0f61a05b 36 #if !defined(POLARSSL_CONFIG_FILE)
HannesTschofenig 0:796d0f61a05b 37 #include "polarssl/config.h"
HannesTschofenig 0:796d0f61a05b 38 #else
HannesTschofenig 0:796d0f61a05b 39 #include POLARSSL_CONFIG_FILE
HannesTschofenig 0:796d0f61a05b 40 #endif
HannesTschofenig 0:796d0f61a05b 41
HannesTschofenig 0:796d0f61a05b 42 #if defined(POLARSSL_GCM_C)
HannesTschofenig 0:796d0f61a05b 43
HannesTschofenig 0:796d0f61a05b 44 #include "polarssl/gcm.h"
HannesTschofenig 0:796d0f61a05b 45
HannesTschofenig 0:796d0f61a05b 46 #if defined(POLARSSL_AESNI_C)
HannesTschofenig 0:796d0f61a05b 47 #include "polarssl/aesni.h"
HannesTschofenig 0:796d0f61a05b 48 #endif
HannesTschofenig 0:796d0f61a05b 49
HannesTschofenig 0:796d0f61a05b 50 #if defined(POLARSSL_PLATFORM_C)
HannesTschofenig 0:796d0f61a05b 51 #include "polarssl/platform.h"
HannesTschofenig 0:796d0f61a05b 52 #else
HannesTschofenig 0:796d0f61a05b 53 #define polarssl_printf printf
HannesTschofenig 0:796d0f61a05b 54 #endif
HannesTschofenig 0:796d0f61a05b 55
HannesTschofenig 0:796d0f61a05b 56 /*
HannesTschofenig 0:796d0f61a05b 57 * 32-bit integer manipulation macros (big endian)
HannesTschofenig 0:796d0f61a05b 58 */
HannesTschofenig 0:796d0f61a05b 59 #ifndef GET_UINT32_BE
HannesTschofenig 0:796d0f61a05b 60 #define GET_UINT32_BE(n,b,i) \
HannesTschofenig 0:796d0f61a05b 61 { \
HannesTschofenig 0:796d0f61a05b 62 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
HannesTschofenig 0:796d0f61a05b 63 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
HannesTschofenig 0:796d0f61a05b 64 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
HannesTschofenig 0:796d0f61a05b 65 | ( (uint32_t) (b)[(i) + 3] ); \
HannesTschofenig 0:796d0f61a05b 66 }
HannesTschofenig 0:796d0f61a05b 67 #endif
HannesTschofenig 0:796d0f61a05b 68
HannesTschofenig 0:796d0f61a05b 69 #ifndef PUT_UINT32_BE
HannesTschofenig 0:796d0f61a05b 70 #define PUT_UINT32_BE(n,b,i) \
HannesTschofenig 0:796d0f61a05b 71 { \
HannesTschofenig 0:796d0f61a05b 72 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
HannesTschofenig 0:796d0f61a05b 73 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
HannesTschofenig 0:796d0f61a05b 74 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
HannesTschofenig 0:796d0f61a05b 75 (b)[(i) + 3] = (unsigned char) ( (n) ); \
HannesTschofenig 0:796d0f61a05b 76 }
HannesTschofenig 0:796d0f61a05b 77 #endif
HannesTschofenig 0:796d0f61a05b 78
HannesTschofenig 0:796d0f61a05b 79 /*
HannesTschofenig 0:796d0f61a05b 80 * Precompute small multiples of H, that is set
HannesTschofenig 0:796d0f61a05b 81 * HH[i] || HL[i] = H times i,
HannesTschofenig 0:796d0f61a05b 82 * where i is seen as a field element as in [MGV], ie high-order bits
HannesTschofenig 0:796d0f61a05b 83 * correspond to low powers of P. The result is stored in the same way, that
HannesTschofenig 0:796d0f61a05b 84 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
HannesTschofenig 0:796d0f61a05b 85 * corresponds to P^127.
HannesTschofenig 0:796d0f61a05b 86 */
HannesTschofenig 0:796d0f61a05b 87 static int gcm_gen_table( gcm_context *ctx )
HannesTschofenig 0:796d0f61a05b 88 {
HannesTschofenig 0:796d0f61a05b 89 int ret, i, j;
HannesTschofenig 0:796d0f61a05b 90 uint64_t hi, lo;
HannesTschofenig 0:796d0f61a05b 91 uint64_t vl, vh;
HannesTschofenig 0:796d0f61a05b 92 unsigned char h[16];
HannesTschofenig 0:796d0f61a05b 93 size_t olen = 0;
HannesTschofenig 0:796d0f61a05b 94
HannesTschofenig 0:796d0f61a05b 95 memset( h, 0, 16 );
HannesTschofenig 0:796d0f61a05b 96 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 97 return( ret );
HannesTschofenig 0:796d0f61a05b 98
HannesTschofenig 0:796d0f61a05b 99 /* pack h as two 64-bits ints, big-endian */
HannesTschofenig 0:796d0f61a05b 100 GET_UINT32_BE( hi, h, 0 );
HannesTschofenig 0:796d0f61a05b 101 GET_UINT32_BE( lo, h, 4 );
HannesTschofenig 0:796d0f61a05b 102 vh = (uint64_t) hi << 32 | lo;
HannesTschofenig 0:796d0f61a05b 103
HannesTschofenig 0:796d0f61a05b 104 GET_UINT32_BE( hi, h, 8 );
HannesTschofenig 0:796d0f61a05b 105 GET_UINT32_BE( lo, h, 12 );
HannesTschofenig 0:796d0f61a05b 106 vl = (uint64_t) hi << 32 | lo;
HannesTschofenig 0:796d0f61a05b 107
HannesTschofenig 0:796d0f61a05b 108 /* 8 = 1000 corresponds to 1 in GF(2^128) */
HannesTschofenig 0:796d0f61a05b 109 ctx->HL[8] = vl;
HannesTschofenig 0:796d0f61a05b 110 ctx->HH[8] = vh;
HannesTschofenig 0:796d0f61a05b 111
HannesTschofenig 0:796d0f61a05b 112 #if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
HannesTschofenig 0:796d0f61a05b 113 /* With CLMUL support, we need only h, not the rest of the table */
HannesTschofenig 0:796d0f61a05b 114 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
HannesTschofenig 0:796d0f61a05b 115 return( 0 );
HannesTschofenig 0:796d0f61a05b 116 #endif
HannesTschofenig 0:796d0f61a05b 117
HannesTschofenig 0:796d0f61a05b 118 /* 0 corresponds to 0 in GF(2^128) */
HannesTschofenig 0:796d0f61a05b 119 ctx->HH[0] = 0;
HannesTschofenig 0:796d0f61a05b 120 ctx->HL[0] = 0;
HannesTschofenig 0:796d0f61a05b 121
HannesTschofenig 0:796d0f61a05b 122 for( i = 4; i > 0; i >>= 1 )
HannesTschofenig 0:796d0f61a05b 123 {
HannesTschofenig 0:796d0f61a05b 124 uint32_t T = ( vl & 1 ) * 0xe1000000U;
HannesTschofenig 0:796d0f61a05b 125 vl = ( vh << 63 ) | ( vl >> 1 );
HannesTschofenig 0:796d0f61a05b 126 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
HannesTschofenig 0:796d0f61a05b 127
HannesTschofenig 0:796d0f61a05b 128 ctx->HL[i] = vl;
HannesTschofenig 0:796d0f61a05b 129 ctx->HH[i] = vh;
HannesTschofenig 0:796d0f61a05b 130 }
HannesTschofenig 0:796d0f61a05b 131
HannesTschofenig 0:796d0f61a05b 132 for (i = 2; i < 16; i <<= 1 )
HannesTschofenig 0:796d0f61a05b 133 {
HannesTschofenig 0:796d0f61a05b 134 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
HannesTschofenig 0:796d0f61a05b 135 vh = *HiH;
HannesTschofenig 0:796d0f61a05b 136 vl = *HiL;
HannesTschofenig 0:796d0f61a05b 137 for( j = 1; j < i; j++ )
HannesTschofenig 0:796d0f61a05b 138 {
HannesTschofenig 0:796d0f61a05b 139 HiH[j] = vh ^ ctx->HH[j];
HannesTschofenig 0:796d0f61a05b 140 HiL[j] = vl ^ ctx->HL[j];
HannesTschofenig 0:796d0f61a05b 141 }
HannesTschofenig 0:796d0f61a05b 142 }
HannesTschofenig 0:796d0f61a05b 143
HannesTschofenig 0:796d0f61a05b 144 return( 0 );
HannesTschofenig 0:796d0f61a05b 145 }
HannesTschofenig 0:796d0f61a05b 146
HannesTschofenig 0:796d0f61a05b 147 int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
HannesTschofenig 0:796d0f61a05b 148 unsigned int keysize )
HannesTschofenig 0:796d0f61a05b 149 {
HannesTschofenig 0:796d0f61a05b 150 int ret;
HannesTschofenig 0:796d0f61a05b 151 const cipher_info_t *cipher_info;
HannesTschofenig 0:796d0f61a05b 152
HannesTschofenig 0:796d0f61a05b 153 memset( ctx, 0, sizeof(gcm_context) );
HannesTschofenig 0:796d0f61a05b 154
HannesTschofenig 0:796d0f61a05b 155 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
HannesTschofenig 0:796d0f61a05b 156 if( cipher_info == NULL )
HannesTschofenig 0:796d0f61a05b 157 return( POLARSSL_ERR_GCM_BAD_INPUT );
HannesTschofenig 0:796d0f61a05b 158
HannesTschofenig 0:796d0f61a05b 159 if( cipher_info->block_size != 16 )
HannesTschofenig 0:796d0f61a05b 160 return( POLARSSL_ERR_GCM_BAD_INPUT );
HannesTschofenig 0:796d0f61a05b 161
HannesTschofenig 0:796d0f61a05b 162 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 163 return( ret );
HannesTschofenig 0:796d0f61a05b 164
HannesTschofenig 0:796d0f61a05b 165 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
HannesTschofenig 0:796d0f61a05b 166 POLARSSL_ENCRYPT ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 167 {
HannesTschofenig 0:796d0f61a05b 168 return( ret );
HannesTschofenig 0:796d0f61a05b 169 }
HannesTschofenig 0:796d0f61a05b 170
HannesTschofenig 0:796d0f61a05b 171 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 172 return( ret );
HannesTschofenig 0:796d0f61a05b 173
HannesTschofenig 0:796d0f61a05b 174 return( 0 );
HannesTschofenig 0:796d0f61a05b 175 }
HannesTschofenig 0:796d0f61a05b 176
HannesTschofenig 0:796d0f61a05b 177 /*
HannesTschofenig 0:796d0f61a05b 178 * Shoup's method for multiplication use this table with
HannesTschofenig 0:796d0f61a05b 179 * last4[x] = x times P^128
HannesTschofenig 0:796d0f61a05b 180 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
HannesTschofenig 0:796d0f61a05b 181 */
HannesTschofenig 0:796d0f61a05b 182 static const uint64_t last4[16] =
HannesTschofenig 0:796d0f61a05b 183 {
HannesTschofenig 0:796d0f61a05b 184 0x0000, 0x1c20, 0x3840, 0x2460,
HannesTschofenig 0:796d0f61a05b 185 0x7080, 0x6ca0, 0x48c0, 0x54e0,
HannesTschofenig 0:796d0f61a05b 186 0xe100, 0xfd20, 0xd940, 0xc560,
HannesTschofenig 0:796d0f61a05b 187 0x9180, 0x8da0, 0xa9c0, 0xb5e0
HannesTschofenig 0:796d0f61a05b 188 };
HannesTschofenig 0:796d0f61a05b 189
HannesTschofenig 0:796d0f61a05b 190 /*
HannesTschofenig 0:796d0f61a05b 191 * Sets output to x times H using the precomputed tables.
HannesTschofenig 0:796d0f61a05b 192 * x and output are seen as elements of GF(2^128) as in [MGV].
HannesTschofenig 0:796d0f61a05b 193 */
HannesTschofenig 0:796d0f61a05b 194 static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
HannesTschofenig 0:796d0f61a05b 195 unsigned char output[16] )
HannesTschofenig 0:796d0f61a05b 196 {
HannesTschofenig 0:796d0f61a05b 197 int i = 0;
HannesTschofenig 0:796d0f61a05b 198 unsigned char z[16];
HannesTschofenig 0:796d0f61a05b 199 unsigned char lo, hi, rem;
HannesTschofenig 0:796d0f61a05b 200 uint64_t zh, zl;
HannesTschofenig 0:796d0f61a05b 201
HannesTschofenig 0:796d0f61a05b 202 #if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
HannesTschofenig 0:796d0f61a05b 203 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
HannesTschofenig 0:796d0f61a05b 204 unsigned char h[16];
HannesTschofenig 0:796d0f61a05b 205
HannesTschofenig 0:796d0f61a05b 206 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
HannesTschofenig 0:796d0f61a05b 207 PUT_UINT32_BE( ctx->HH[8], h, 4 );
HannesTschofenig 0:796d0f61a05b 208 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
HannesTschofenig 0:796d0f61a05b 209 PUT_UINT32_BE( ctx->HL[8], h, 12 );
HannesTschofenig 0:796d0f61a05b 210
HannesTschofenig 0:796d0f61a05b 211 aesni_gcm_mult( output, x, h );
HannesTschofenig 0:796d0f61a05b 212 return;
HannesTschofenig 0:796d0f61a05b 213 }
HannesTschofenig 0:796d0f61a05b 214 #endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
HannesTschofenig 0:796d0f61a05b 215
HannesTschofenig 0:796d0f61a05b 216 memset( z, 0x00, 16 );
HannesTschofenig 0:796d0f61a05b 217
HannesTschofenig 0:796d0f61a05b 218 lo = x[15] & 0xf;
HannesTschofenig 0:796d0f61a05b 219 hi = x[15] >> 4;
HannesTschofenig 0:796d0f61a05b 220
HannesTschofenig 0:796d0f61a05b 221 zh = ctx->HH[lo];
HannesTschofenig 0:796d0f61a05b 222 zl = ctx->HL[lo];
HannesTschofenig 0:796d0f61a05b 223
HannesTschofenig 0:796d0f61a05b 224 for( i = 15; i >= 0; i-- )
HannesTschofenig 0:796d0f61a05b 225 {
HannesTschofenig 0:796d0f61a05b 226 lo = x[i] & 0xf;
HannesTschofenig 0:796d0f61a05b 227 hi = x[i] >> 4;
HannesTschofenig 0:796d0f61a05b 228
HannesTschofenig 0:796d0f61a05b 229 if( i != 15 )
HannesTschofenig 0:796d0f61a05b 230 {
HannesTschofenig 0:796d0f61a05b 231 rem = (unsigned char) zl & 0xf;
HannesTschofenig 0:796d0f61a05b 232 zl = ( zh << 60 ) | ( zl >> 4 );
HannesTschofenig 0:796d0f61a05b 233 zh = ( zh >> 4 );
HannesTschofenig 0:796d0f61a05b 234 zh ^= (uint64_t) last4[rem] << 48;
HannesTschofenig 0:796d0f61a05b 235 zh ^= ctx->HH[lo];
HannesTschofenig 0:796d0f61a05b 236 zl ^= ctx->HL[lo];
HannesTschofenig 0:796d0f61a05b 237
HannesTschofenig 0:796d0f61a05b 238 }
HannesTschofenig 0:796d0f61a05b 239
HannesTschofenig 0:796d0f61a05b 240 rem = (unsigned char) zl & 0xf;
HannesTschofenig 0:796d0f61a05b 241 zl = ( zh << 60 ) | ( zl >> 4 );
HannesTschofenig 0:796d0f61a05b 242 zh = ( zh >> 4 );
HannesTschofenig 0:796d0f61a05b 243 zh ^= (uint64_t) last4[rem] << 48;
HannesTschofenig 0:796d0f61a05b 244 zh ^= ctx->HH[hi];
HannesTschofenig 0:796d0f61a05b 245 zl ^= ctx->HL[hi];
HannesTschofenig 0:796d0f61a05b 246 }
HannesTschofenig 0:796d0f61a05b 247
HannesTschofenig 0:796d0f61a05b 248 PUT_UINT32_BE( zh >> 32, output, 0 );
HannesTschofenig 0:796d0f61a05b 249 PUT_UINT32_BE( zh, output, 4 );
HannesTschofenig 0:796d0f61a05b 250 PUT_UINT32_BE( zl >> 32, output, 8 );
HannesTschofenig 0:796d0f61a05b 251 PUT_UINT32_BE( zl, output, 12 );
HannesTschofenig 0:796d0f61a05b 252 }
HannesTschofenig 0:796d0f61a05b 253
HannesTschofenig 0:796d0f61a05b 254 int gcm_starts( gcm_context *ctx,
HannesTschofenig 0:796d0f61a05b 255 int mode,
HannesTschofenig 0:796d0f61a05b 256 const unsigned char *iv,
HannesTschofenig 0:796d0f61a05b 257 size_t iv_len,
HannesTschofenig 0:796d0f61a05b 258 const unsigned char *add,
HannesTschofenig 0:796d0f61a05b 259 size_t add_len )
HannesTschofenig 0:796d0f61a05b 260 {
HannesTschofenig 0:796d0f61a05b 261 int ret;
HannesTschofenig 0:796d0f61a05b 262 unsigned char work_buf[16];
HannesTschofenig 0:796d0f61a05b 263 size_t i;
HannesTschofenig 0:796d0f61a05b 264 const unsigned char *p;
HannesTschofenig 0:796d0f61a05b 265 size_t use_len, olen = 0;
HannesTschofenig 0:796d0f61a05b 266
HannesTschofenig 0:796d0f61a05b 267 memset( ctx->y, 0x00, sizeof(ctx->y) );
HannesTschofenig 0:796d0f61a05b 268 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
HannesTschofenig 0:796d0f61a05b 269
HannesTschofenig 0:796d0f61a05b 270 ctx->mode = mode;
HannesTschofenig 0:796d0f61a05b 271 ctx->len = 0;
HannesTschofenig 0:796d0f61a05b 272 ctx->add_len = 0;
HannesTschofenig 0:796d0f61a05b 273
HannesTschofenig 0:796d0f61a05b 274 if( iv_len == 12 )
HannesTschofenig 0:796d0f61a05b 275 {
HannesTschofenig 0:796d0f61a05b 276 memcpy( ctx->y, iv, iv_len );
HannesTschofenig 0:796d0f61a05b 277 ctx->y[15] = 1;
HannesTschofenig 0:796d0f61a05b 278 }
HannesTschofenig 0:796d0f61a05b 279 else
HannesTschofenig 0:796d0f61a05b 280 {
HannesTschofenig 0:796d0f61a05b 281 memset( work_buf, 0x00, 16 );
HannesTschofenig 0:796d0f61a05b 282 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
HannesTschofenig 0:796d0f61a05b 283
HannesTschofenig 0:796d0f61a05b 284 p = iv;
HannesTschofenig 0:796d0f61a05b 285 while( iv_len > 0 )
HannesTschofenig 0:796d0f61a05b 286 {
HannesTschofenig 0:796d0f61a05b 287 use_len = ( iv_len < 16 ) ? iv_len : 16;
HannesTschofenig 0:796d0f61a05b 288
HannesTschofenig 0:796d0f61a05b 289 for( i = 0; i < use_len; i++ )
HannesTschofenig 0:796d0f61a05b 290 ctx->y[i] ^= p[i];
HannesTschofenig 0:796d0f61a05b 291
HannesTschofenig 0:796d0f61a05b 292 gcm_mult( ctx, ctx->y, ctx->y );
HannesTschofenig 0:796d0f61a05b 293
HannesTschofenig 0:796d0f61a05b 294 iv_len -= use_len;
HannesTschofenig 0:796d0f61a05b 295 p += use_len;
HannesTschofenig 0:796d0f61a05b 296 }
HannesTschofenig 0:796d0f61a05b 297
HannesTschofenig 0:796d0f61a05b 298 for( i = 0; i < 16; i++ )
HannesTschofenig 0:796d0f61a05b 299 ctx->y[i] ^= work_buf[i];
HannesTschofenig 0:796d0f61a05b 300
HannesTschofenig 0:796d0f61a05b 301 gcm_mult( ctx, ctx->y, ctx->y );
HannesTschofenig 0:796d0f61a05b 302 }
HannesTschofenig 0:796d0f61a05b 303
HannesTschofenig 0:796d0f61a05b 304 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
HannesTschofenig 0:796d0f61a05b 305 &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 306 {
HannesTschofenig 0:796d0f61a05b 307 return( ret );
HannesTschofenig 0:796d0f61a05b 308 }
HannesTschofenig 0:796d0f61a05b 309
HannesTschofenig 0:796d0f61a05b 310 ctx->add_len = add_len;
HannesTschofenig 0:796d0f61a05b 311 p = add;
HannesTschofenig 0:796d0f61a05b 312 while( add_len > 0 )
HannesTschofenig 0:796d0f61a05b 313 {
HannesTschofenig 0:796d0f61a05b 314 use_len = ( add_len < 16 ) ? add_len : 16;
HannesTschofenig 0:796d0f61a05b 315
HannesTschofenig 0:796d0f61a05b 316 for( i = 0; i < use_len; i++ )
HannesTschofenig 0:796d0f61a05b 317 ctx->buf[i] ^= p[i];
HannesTschofenig 0:796d0f61a05b 318
HannesTschofenig 0:796d0f61a05b 319 gcm_mult( ctx, ctx->buf, ctx->buf );
HannesTschofenig 0:796d0f61a05b 320
HannesTschofenig 0:796d0f61a05b 321 add_len -= use_len;
HannesTschofenig 0:796d0f61a05b 322 p += use_len;
HannesTschofenig 0:796d0f61a05b 323 }
HannesTschofenig 0:796d0f61a05b 324
HannesTschofenig 0:796d0f61a05b 325 return( 0 );
HannesTschofenig 0:796d0f61a05b 326 }
HannesTschofenig 0:796d0f61a05b 327
HannesTschofenig 0:796d0f61a05b 328 int gcm_update( gcm_context *ctx,
HannesTschofenig 0:796d0f61a05b 329 size_t length,
HannesTschofenig 0:796d0f61a05b 330 const unsigned char *input,
HannesTschofenig 0:796d0f61a05b 331 unsigned char *output )
HannesTschofenig 0:796d0f61a05b 332 {
HannesTschofenig 0:796d0f61a05b 333 int ret;
HannesTschofenig 0:796d0f61a05b 334 unsigned char ectr[16];
HannesTschofenig 0:796d0f61a05b 335 size_t i;
HannesTschofenig 0:796d0f61a05b 336 const unsigned char *p;
HannesTschofenig 0:796d0f61a05b 337 unsigned char *out_p = output;
HannesTschofenig 0:796d0f61a05b 338 size_t use_len, olen = 0;
HannesTschofenig 0:796d0f61a05b 339
HannesTschofenig 0:796d0f61a05b 340 if( output > input && (size_t) ( output - input ) < length )
HannesTschofenig 0:796d0f61a05b 341 return( POLARSSL_ERR_GCM_BAD_INPUT );
HannesTschofenig 0:796d0f61a05b 342
HannesTschofenig 0:796d0f61a05b 343 ctx->len += length;
HannesTschofenig 0:796d0f61a05b 344
HannesTschofenig 0:796d0f61a05b 345 p = input;
HannesTschofenig 0:796d0f61a05b 346 while( length > 0 )
HannesTschofenig 0:796d0f61a05b 347 {
HannesTschofenig 0:796d0f61a05b 348 use_len = ( length < 16 ) ? length : 16;
HannesTschofenig 0:796d0f61a05b 349
HannesTschofenig 0:796d0f61a05b 350 for( i = 16; i > 12; i-- )
HannesTschofenig 0:796d0f61a05b 351 if( ++ctx->y[i - 1] != 0 )
HannesTschofenig 0:796d0f61a05b 352 break;
HannesTschofenig 0:796d0f61a05b 353
HannesTschofenig 0:796d0f61a05b 354 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
HannesTschofenig 0:796d0f61a05b 355 &olen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 356 {
HannesTschofenig 0:796d0f61a05b 357 return( ret );
HannesTschofenig 0:796d0f61a05b 358 }
HannesTschofenig 0:796d0f61a05b 359
HannesTschofenig 0:796d0f61a05b 360 for( i = 0; i < use_len; i++ )
HannesTschofenig 0:796d0f61a05b 361 {
HannesTschofenig 0:796d0f61a05b 362 if( ctx->mode == GCM_DECRYPT )
HannesTschofenig 0:796d0f61a05b 363 ctx->buf[i] ^= p[i];
HannesTschofenig 0:796d0f61a05b 364 out_p[i] = ectr[i] ^ p[i];
HannesTschofenig 0:796d0f61a05b 365 if( ctx->mode == GCM_ENCRYPT )
HannesTschofenig 0:796d0f61a05b 366 ctx->buf[i] ^= out_p[i];
HannesTschofenig 0:796d0f61a05b 367 }
HannesTschofenig 0:796d0f61a05b 368
HannesTschofenig 0:796d0f61a05b 369 gcm_mult( ctx, ctx->buf, ctx->buf );
HannesTschofenig 0:796d0f61a05b 370
HannesTschofenig 0:796d0f61a05b 371 length -= use_len;
HannesTschofenig 0:796d0f61a05b 372 p += use_len;
HannesTschofenig 0:796d0f61a05b 373 out_p += use_len;
HannesTschofenig 0:796d0f61a05b 374 }
HannesTschofenig 0:796d0f61a05b 375
HannesTschofenig 0:796d0f61a05b 376 return( 0 );
HannesTschofenig 0:796d0f61a05b 377 }
HannesTschofenig 0:796d0f61a05b 378
HannesTschofenig 0:796d0f61a05b 379 int gcm_finish( gcm_context *ctx,
HannesTschofenig 0:796d0f61a05b 380 unsigned char *tag,
HannesTschofenig 0:796d0f61a05b 381 size_t tag_len )
HannesTschofenig 0:796d0f61a05b 382 {
HannesTschofenig 0:796d0f61a05b 383 unsigned char work_buf[16];
HannesTschofenig 0:796d0f61a05b 384 size_t i;
HannesTschofenig 0:796d0f61a05b 385 uint64_t orig_len = ctx->len * 8;
HannesTschofenig 0:796d0f61a05b 386 uint64_t orig_add_len = ctx->add_len * 8;
HannesTschofenig 0:796d0f61a05b 387
HannesTschofenig 0:796d0f61a05b 388 if( tag_len > 16 )
HannesTschofenig 0:796d0f61a05b 389 return( POLARSSL_ERR_GCM_BAD_INPUT );
HannesTschofenig 0:796d0f61a05b 390
HannesTschofenig 0:796d0f61a05b 391 if( tag_len != 0 )
HannesTschofenig 0:796d0f61a05b 392 memcpy( tag, ctx->base_ectr, tag_len );
HannesTschofenig 0:796d0f61a05b 393
HannesTschofenig 0:796d0f61a05b 394 if( orig_len || orig_add_len )
HannesTschofenig 0:796d0f61a05b 395 {
HannesTschofenig 0:796d0f61a05b 396 memset( work_buf, 0x00, 16 );
HannesTschofenig 0:796d0f61a05b 397
HannesTschofenig 0:796d0f61a05b 398 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
HannesTschofenig 0:796d0f61a05b 399 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
HannesTschofenig 0:796d0f61a05b 400 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
HannesTschofenig 0:796d0f61a05b 401 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
HannesTschofenig 0:796d0f61a05b 402
HannesTschofenig 0:796d0f61a05b 403 for( i = 0; i < 16; i++ )
HannesTschofenig 0:796d0f61a05b 404 ctx->buf[i] ^= work_buf[i];
HannesTschofenig 0:796d0f61a05b 405
HannesTschofenig 0:796d0f61a05b 406 gcm_mult( ctx, ctx->buf, ctx->buf );
HannesTschofenig 0:796d0f61a05b 407
HannesTschofenig 0:796d0f61a05b 408 for( i = 0; i < tag_len; i++ )
HannesTschofenig 0:796d0f61a05b 409 tag[i] ^= ctx->buf[i];
HannesTschofenig 0:796d0f61a05b 410 }
HannesTschofenig 0:796d0f61a05b 411
HannesTschofenig 0:796d0f61a05b 412 return( 0 );
HannesTschofenig 0:796d0f61a05b 413 }
HannesTschofenig 0:796d0f61a05b 414
HannesTschofenig 0:796d0f61a05b 415 int gcm_crypt_and_tag( gcm_context *ctx,
HannesTschofenig 0:796d0f61a05b 416 int mode,
HannesTschofenig 0:796d0f61a05b 417 size_t length,
HannesTschofenig 0:796d0f61a05b 418 const unsigned char *iv,
HannesTschofenig 0:796d0f61a05b 419 size_t iv_len,
HannesTschofenig 0:796d0f61a05b 420 const unsigned char *add,
HannesTschofenig 0:796d0f61a05b 421 size_t add_len,
HannesTschofenig 0:796d0f61a05b 422 const unsigned char *input,
HannesTschofenig 0:796d0f61a05b 423 unsigned char *output,
HannesTschofenig 0:796d0f61a05b 424 size_t tag_len,
HannesTschofenig 0:796d0f61a05b 425 unsigned char *tag )
HannesTschofenig 0:796d0f61a05b 426 {
HannesTschofenig 0:796d0f61a05b 427 int ret;
HannesTschofenig 0:796d0f61a05b 428
HannesTschofenig 0:796d0f61a05b 429 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 430 return( ret );
HannesTschofenig 0:796d0f61a05b 431
HannesTschofenig 0:796d0f61a05b 432 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 433 return( ret );
HannesTschofenig 0:796d0f61a05b 434
HannesTschofenig 0:796d0f61a05b 435 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 436 return( ret );
HannesTschofenig 0:796d0f61a05b 437
HannesTschofenig 0:796d0f61a05b 438 return( 0 );
HannesTschofenig 0:796d0f61a05b 439 }
HannesTschofenig 0:796d0f61a05b 440
HannesTschofenig 0:796d0f61a05b 441 int gcm_auth_decrypt( gcm_context *ctx,
HannesTschofenig 0:796d0f61a05b 442 size_t length,
HannesTschofenig 0:796d0f61a05b 443 const unsigned char *iv,
HannesTschofenig 0:796d0f61a05b 444 size_t iv_len,
HannesTschofenig 0:796d0f61a05b 445 const unsigned char *add,
HannesTschofenig 0:796d0f61a05b 446 size_t add_len,
HannesTschofenig 0:796d0f61a05b 447 const unsigned char *tag,
HannesTschofenig 0:796d0f61a05b 448 size_t tag_len,
HannesTschofenig 0:796d0f61a05b 449 const unsigned char *input,
HannesTschofenig 0:796d0f61a05b 450 unsigned char *output )
HannesTschofenig 0:796d0f61a05b 451 {
HannesTschofenig 0:796d0f61a05b 452 int ret;
HannesTschofenig 0:796d0f61a05b 453 unsigned char check_tag[16];
HannesTschofenig 0:796d0f61a05b 454 size_t i;
HannesTschofenig 0:796d0f61a05b 455 int diff;
HannesTschofenig 0:796d0f61a05b 456
HannesTschofenig 0:796d0f61a05b 457 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
HannesTschofenig 0:796d0f61a05b 458 iv, iv_len, add, add_len,
HannesTschofenig 0:796d0f61a05b 459 input, output, tag_len, check_tag ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 460 {
HannesTschofenig 0:796d0f61a05b 461 return( ret );
HannesTschofenig 0:796d0f61a05b 462 }
HannesTschofenig 0:796d0f61a05b 463
HannesTschofenig 0:796d0f61a05b 464 /* Check tag in "constant-time" */
HannesTschofenig 0:796d0f61a05b 465 for( diff = 0, i = 0; i < tag_len; i++ )
HannesTschofenig 0:796d0f61a05b 466 diff |= tag[i] ^ check_tag[i];
HannesTschofenig 0:796d0f61a05b 467
HannesTschofenig 0:796d0f61a05b 468 if( diff != 0 )
HannesTschofenig 0:796d0f61a05b 469 {
HannesTschofenig 0:796d0f61a05b 470 memset( output, 0, length );
HannesTschofenig 0:796d0f61a05b 471 return( POLARSSL_ERR_GCM_AUTH_FAILED );
HannesTschofenig 0:796d0f61a05b 472 }
HannesTschofenig 0:796d0f61a05b 473
HannesTschofenig 0:796d0f61a05b 474 return( 0 );
HannesTschofenig 0:796d0f61a05b 475 }
HannesTschofenig 0:796d0f61a05b 476
HannesTschofenig 0:796d0f61a05b 477 void gcm_free( gcm_context *ctx )
HannesTschofenig 0:796d0f61a05b 478 {
HannesTschofenig 0:796d0f61a05b 479 (void) cipher_free_ctx( &ctx->cipher_ctx );
HannesTschofenig 0:796d0f61a05b 480 memset( ctx, 0, sizeof( gcm_context ) );
HannesTschofenig 0:796d0f61a05b 481 }
HannesTschofenig 0:796d0f61a05b 482
HannesTschofenig 0:796d0f61a05b 483 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
HannesTschofenig 0:796d0f61a05b 484
HannesTschofenig 0:796d0f61a05b 485 #include <stdio.h>
HannesTschofenig 0:796d0f61a05b 486
HannesTschofenig 0:796d0f61a05b 487 /*
HannesTschofenig 0:796d0f61a05b 488 * AES-GCM test vectors from:
HannesTschofenig 0:796d0f61a05b 489 *
HannesTschofenig 0:796d0f61a05b 490 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
HannesTschofenig 0:796d0f61a05b 491 */
HannesTschofenig 0:796d0f61a05b 492 #define MAX_TESTS 6
HannesTschofenig 0:796d0f61a05b 493
HannesTschofenig 0:796d0f61a05b 494 int key_index[MAX_TESTS] =
HannesTschofenig 0:796d0f61a05b 495 { 0, 0, 1, 1, 1, 1 };
HannesTschofenig 0:796d0f61a05b 496
HannesTschofenig 0:796d0f61a05b 497 unsigned char key[MAX_TESTS][32] =
HannesTschofenig 0:796d0f61a05b 498 {
HannesTschofenig 0:796d0f61a05b 499 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
HannesTschofenig 0:796d0f61a05b 500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
HannesTschofenig 0:796d0f61a05b 501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
HannesTschofenig 0:796d0f61a05b 502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
HannesTschofenig 0:796d0f61a05b 503 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
HannesTschofenig 0:796d0f61a05b 504 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
HannesTschofenig 0:796d0f61a05b 505 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
HannesTschofenig 0:796d0f61a05b 506 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
HannesTschofenig 0:796d0f61a05b 507 };
HannesTschofenig 0:796d0f61a05b 508
HannesTschofenig 0:796d0f61a05b 509 size_t iv_len[MAX_TESTS] =
HannesTschofenig 0:796d0f61a05b 510 { 12, 12, 12, 12, 8, 60 };
HannesTschofenig 0:796d0f61a05b 511
HannesTschofenig 0:796d0f61a05b 512 int iv_index[MAX_TESTS] =
HannesTschofenig 0:796d0f61a05b 513 { 0, 0, 1, 1, 1, 2 };
HannesTschofenig 0:796d0f61a05b 514
HannesTschofenig 0:796d0f61a05b 515 unsigned char iv[MAX_TESTS][64] =
HannesTschofenig 0:796d0f61a05b 516 {
HannesTschofenig 0:796d0f61a05b 517 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
HannesTschofenig 0:796d0f61a05b 518 0x00, 0x00, 0x00, 0x00 },
HannesTschofenig 0:796d0f61a05b 519 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
HannesTschofenig 0:796d0f61a05b 520 0xde, 0xca, 0xf8, 0x88 },
HannesTschofenig 0:796d0f61a05b 521 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
HannesTschofenig 0:796d0f61a05b 522 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
HannesTschofenig 0:796d0f61a05b 523 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
HannesTschofenig 0:796d0f61a05b 524 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
HannesTschofenig 0:796d0f61a05b 525 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
HannesTschofenig 0:796d0f61a05b 526 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
HannesTschofenig 0:796d0f61a05b 527 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
HannesTschofenig 0:796d0f61a05b 528 0xa6, 0x37, 0xb3, 0x9b },
HannesTschofenig 0:796d0f61a05b 529 };
HannesTschofenig 0:796d0f61a05b 530
HannesTschofenig 0:796d0f61a05b 531 size_t add_len[MAX_TESTS] =
HannesTschofenig 0:796d0f61a05b 532 { 0, 0, 0, 20, 20, 20 };
HannesTschofenig 0:796d0f61a05b 533
HannesTschofenig 0:796d0f61a05b 534 int add_index[MAX_TESTS] =
HannesTschofenig 0:796d0f61a05b 535 { 0, 0, 0, 1, 1, 1 };
HannesTschofenig 0:796d0f61a05b 536
HannesTschofenig 0:796d0f61a05b 537 unsigned char additional[MAX_TESTS][64] =
HannesTschofenig 0:796d0f61a05b 538 {
HannesTschofenig 0:796d0f61a05b 539 { 0x00 },
HannesTschofenig 0:796d0f61a05b 540 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
HannesTschofenig 0:796d0f61a05b 541 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
HannesTschofenig 0:796d0f61a05b 542 0xab, 0xad, 0xda, 0xd2 },
HannesTschofenig 0:796d0f61a05b 543 };
HannesTschofenig 0:796d0f61a05b 544
HannesTschofenig 0:796d0f61a05b 545 size_t pt_len[MAX_TESTS] =
HannesTschofenig 0:796d0f61a05b 546 { 0, 16, 64, 60, 60, 60 };
HannesTschofenig 0:796d0f61a05b 547
HannesTschofenig 0:796d0f61a05b 548 int pt_index[MAX_TESTS] =
HannesTschofenig 0:796d0f61a05b 549 { 0, 0, 1, 1, 1, 1 };
HannesTschofenig 0:796d0f61a05b 550
HannesTschofenig 0:796d0f61a05b 551 unsigned char pt[MAX_TESTS][64] =
HannesTschofenig 0:796d0f61a05b 552 {
HannesTschofenig 0:796d0f61a05b 553 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
HannesTschofenig 0:796d0f61a05b 554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
HannesTschofenig 0:796d0f61a05b 555 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
HannesTschofenig 0:796d0f61a05b 556 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
HannesTschofenig 0:796d0f61a05b 557 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
HannesTschofenig 0:796d0f61a05b 558 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
HannesTschofenig 0:796d0f61a05b 559 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
HannesTschofenig 0:796d0f61a05b 560 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
HannesTschofenig 0:796d0f61a05b 561 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
HannesTschofenig 0:796d0f61a05b 562 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
HannesTschofenig 0:796d0f61a05b 563 };
HannesTschofenig 0:796d0f61a05b 564
HannesTschofenig 0:796d0f61a05b 565 unsigned char ct[MAX_TESTS * 3][64] =
HannesTschofenig 0:796d0f61a05b 566 {
HannesTschofenig 0:796d0f61a05b 567 { 0x00 },
HannesTschofenig 0:796d0f61a05b 568 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
HannesTschofenig 0:796d0f61a05b 569 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
HannesTschofenig 0:796d0f61a05b 570 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
HannesTschofenig 0:796d0f61a05b 571 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
HannesTschofenig 0:796d0f61a05b 572 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
HannesTschofenig 0:796d0f61a05b 573 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
HannesTschofenig 0:796d0f61a05b 574 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
HannesTschofenig 0:796d0f61a05b 575 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
HannesTschofenig 0:796d0f61a05b 576 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
HannesTschofenig 0:796d0f61a05b 577 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
HannesTschofenig 0:796d0f61a05b 578 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
HannesTschofenig 0:796d0f61a05b 579 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
HannesTschofenig 0:796d0f61a05b 580 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
HannesTschofenig 0:796d0f61a05b 581 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
HannesTschofenig 0:796d0f61a05b 582 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
HannesTschofenig 0:796d0f61a05b 583 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
HannesTschofenig 0:796d0f61a05b 584 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
HannesTschofenig 0:796d0f61a05b 585 0x3d, 0x58, 0xe0, 0x91 },
HannesTschofenig 0:796d0f61a05b 586 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
HannesTschofenig 0:796d0f61a05b 587 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
HannesTschofenig 0:796d0f61a05b 588 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
HannesTschofenig 0:796d0f61a05b 589 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
HannesTschofenig 0:796d0f61a05b 590 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
HannesTschofenig 0:796d0f61a05b 591 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
HannesTschofenig 0:796d0f61a05b 592 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
HannesTschofenig 0:796d0f61a05b 593 0xc2, 0x3f, 0x45, 0x98 },
HannesTschofenig 0:796d0f61a05b 594 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
HannesTschofenig 0:796d0f61a05b 595 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
HannesTschofenig 0:796d0f61a05b 596 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
HannesTschofenig 0:796d0f61a05b 597 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
HannesTschofenig 0:796d0f61a05b 598 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
HannesTschofenig 0:796d0f61a05b 599 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
HannesTschofenig 0:796d0f61a05b 600 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
HannesTschofenig 0:796d0f61a05b 601 0x4c, 0x34, 0xae, 0xe5 },
HannesTschofenig 0:796d0f61a05b 602 { 0x00 },
HannesTschofenig 0:796d0f61a05b 603 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
HannesTschofenig 0:796d0f61a05b 604 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
HannesTschofenig 0:796d0f61a05b 605 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
HannesTschofenig 0:796d0f61a05b 606 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
HannesTschofenig 0:796d0f61a05b 607 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
HannesTschofenig 0:796d0f61a05b 608 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
HannesTschofenig 0:796d0f61a05b 609 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
HannesTschofenig 0:796d0f61a05b 610 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
HannesTschofenig 0:796d0f61a05b 611 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
HannesTschofenig 0:796d0f61a05b 612 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
HannesTschofenig 0:796d0f61a05b 613 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
HannesTschofenig 0:796d0f61a05b 614 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
HannesTschofenig 0:796d0f61a05b 615 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
HannesTschofenig 0:796d0f61a05b 616 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
HannesTschofenig 0:796d0f61a05b 617 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
HannesTschofenig 0:796d0f61a05b 618 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
HannesTschofenig 0:796d0f61a05b 619 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
HannesTschofenig 0:796d0f61a05b 620 0xcc, 0xda, 0x27, 0x10 },
HannesTschofenig 0:796d0f61a05b 621 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
HannesTschofenig 0:796d0f61a05b 622 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
HannesTschofenig 0:796d0f61a05b 623 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
HannesTschofenig 0:796d0f61a05b 624 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
HannesTschofenig 0:796d0f61a05b 625 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
HannesTschofenig 0:796d0f61a05b 626 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
HannesTschofenig 0:796d0f61a05b 627 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
HannesTschofenig 0:796d0f61a05b 628 0xa0, 0xf0, 0x62, 0xf7 },
HannesTschofenig 0:796d0f61a05b 629 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
HannesTschofenig 0:796d0f61a05b 630 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
HannesTschofenig 0:796d0f61a05b 631 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
HannesTschofenig 0:796d0f61a05b 632 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
HannesTschofenig 0:796d0f61a05b 633 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
HannesTschofenig 0:796d0f61a05b 634 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
HannesTschofenig 0:796d0f61a05b 635 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
HannesTschofenig 0:796d0f61a05b 636 0xe9, 0xb7, 0x37, 0x3b },
HannesTschofenig 0:796d0f61a05b 637 { 0x00 },
HannesTschofenig 0:796d0f61a05b 638 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
HannesTschofenig 0:796d0f61a05b 639 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
HannesTschofenig 0:796d0f61a05b 640 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
HannesTschofenig 0:796d0f61a05b 641 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
HannesTschofenig 0:796d0f61a05b 642 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
HannesTschofenig 0:796d0f61a05b 643 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
HannesTschofenig 0:796d0f61a05b 644 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
HannesTschofenig 0:796d0f61a05b 645 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
HannesTschofenig 0:796d0f61a05b 646 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
HannesTschofenig 0:796d0f61a05b 647 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
HannesTschofenig 0:796d0f61a05b 648 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
HannesTschofenig 0:796d0f61a05b 649 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
HannesTschofenig 0:796d0f61a05b 650 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
HannesTschofenig 0:796d0f61a05b 651 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
HannesTschofenig 0:796d0f61a05b 652 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
HannesTschofenig 0:796d0f61a05b 653 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
HannesTschofenig 0:796d0f61a05b 654 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
HannesTschofenig 0:796d0f61a05b 655 0xbc, 0xc9, 0xf6, 0x62 },
HannesTschofenig 0:796d0f61a05b 656 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
HannesTschofenig 0:796d0f61a05b 657 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
HannesTschofenig 0:796d0f61a05b 658 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
HannesTschofenig 0:796d0f61a05b 659 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
HannesTschofenig 0:796d0f61a05b 660 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
HannesTschofenig 0:796d0f61a05b 661 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
HannesTschofenig 0:796d0f61a05b 662 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
HannesTschofenig 0:796d0f61a05b 663 0xf4, 0x7c, 0x9b, 0x1f },
HannesTschofenig 0:796d0f61a05b 664 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
HannesTschofenig 0:796d0f61a05b 665 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
HannesTschofenig 0:796d0f61a05b 666 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
HannesTschofenig 0:796d0f61a05b 667 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
HannesTschofenig 0:796d0f61a05b 668 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
HannesTschofenig 0:796d0f61a05b 669 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
HannesTschofenig 0:796d0f61a05b 670 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
HannesTschofenig 0:796d0f61a05b 671 0x44, 0xae, 0x7e, 0x3f },
HannesTschofenig 0:796d0f61a05b 672 };
HannesTschofenig 0:796d0f61a05b 673
HannesTschofenig 0:796d0f61a05b 674 unsigned char tag[MAX_TESTS * 3][16] =
HannesTschofenig 0:796d0f61a05b 675 {
HannesTschofenig 0:796d0f61a05b 676 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
HannesTschofenig 0:796d0f61a05b 677 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
HannesTschofenig 0:796d0f61a05b 678 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
HannesTschofenig 0:796d0f61a05b 679 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
HannesTschofenig 0:796d0f61a05b 680 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
HannesTschofenig 0:796d0f61a05b 681 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
HannesTschofenig 0:796d0f61a05b 682 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
HannesTschofenig 0:796d0f61a05b 683 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
HannesTschofenig 0:796d0f61a05b 684 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
HannesTschofenig 0:796d0f61a05b 685 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
HannesTschofenig 0:796d0f61a05b 686 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
HannesTschofenig 0:796d0f61a05b 687 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
HannesTschofenig 0:796d0f61a05b 688 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
HannesTschofenig 0:796d0f61a05b 689 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
HannesTschofenig 0:796d0f61a05b 690 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
HannesTschofenig 0:796d0f61a05b 691 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
HannesTschofenig 0:796d0f61a05b 692 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
HannesTschofenig 0:796d0f61a05b 693 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
HannesTschofenig 0:796d0f61a05b 694 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
HannesTschofenig 0:796d0f61a05b 695 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
HannesTschofenig 0:796d0f61a05b 696 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
HannesTschofenig 0:796d0f61a05b 697 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
HannesTschofenig 0:796d0f61a05b 698 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
HannesTschofenig 0:796d0f61a05b 699 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
HannesTschofenig 0:796d0f61a05b 700 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
HannesTschofenig 0:796d0f61a05b 701 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
HannesTschofenig 0:796d0f61a05b 702 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
HannesTschofenig 0:796d0f61a05b 703 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
HannesTschofenig 0:796d0f61a05b 704 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
HannesTschofenig 0:796d0f61a05b 705 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
HannesTschofenig 0:796d0f61a05b 706 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
HannesTschofenig 0:796d0f61a05b 707 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
HannesTschofenig 0:796d0f61a05b 708 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
HannesTschofenig 0:796d0f61a05b 709 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
HannesTschofenig 0:796d0f61a05b 710 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
HannesTschofenig 0:796d0f61a05b 711 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
HannesTschofenig 0:796d0f61a05b 712 };
HannesTschofenig 0:796d0f61a05b 713
HannesTschofenig 0:796d0f61a05b 714 int gcm_self_test( int verbose )
HannesTschofenig 0:796d0f61a05b 715 {
HannesTschofenig 0:796d0f61a05b 716 gcm_context ctx;
HannesTschofenig 0:796d0f61a05b 717 unsigned char buf[64];
HannesTschofenig 0:796d0f61a05b 718 unsigned char tag_buf[16];
HannesTschofenig 0:796d0f61a05b 719 int i, j, ret;
HannesTschofenig 0:796d0f61a05b 720 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
HannesTschofenig 0:796d0f61a05b 721
HannesTschofenig 0:796d0f61a05b 722 for( j = 0; j < 3; j++ )
HannesTschofenig 0:796d0f61a05b 723 {
HannesTschofenig 0:796d0f61a05b 724 int key_len = 128 + 64 * j;
HannesTschofenig 0:796d0f61a05b 725
HannesTschofenig 0:796d0f61a05b 726 for( i = 0; i < MAX_TESTS; i++ )
HannesTschofenig 0:796d0f61a05b 727 {
HannesTschofenig 0:796d0f61a05b 728 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 729 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
HannesTschofenig 0:796d0f61a05b 730 key_len, i, "enc" );
HannesTschofenig 0:796d0f61a05b 731
HannesTschofenig 0:796d0f61a05b 732 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
HannesTschofenig 0:796d0f61a05b 733
HannesTschofenig 0:796d0f61a05b 734 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
HannesTschofenig 0:796d0f61a05b 735 pt_len[i],
HannesTschofenig 0:796d0f61a05b 736 iv[iv_index[i]], iv_len[i],
HannesTschofenig 0:796d0f61a05b 737 additional[add_index[i]], add_len[i],
HannesTschofenig 0:796d0f61a05b 738 pt[pt_index[i]], buf, 16, tag_buf );
HannesTschofenig 0:796d0f61a05b 739
HannesTschofenig 0:796d0f61a05b 740 if( ret != 0 ||
HannesTschofenig 0:796d0f61a05b 741 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
HannesTschofenig 0:796d0f61a05b 742 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
HannesTschofenig 0:796d0f61a05b 743 {
HannesTschofenig 0:796d0f61a05b 744 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 745 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 746
HannesTschofenig 0:796d0f61a05b 747 return( 1 );
HannesTschofenig 0:796d0f61a05b 748 }
HannesTschofenig 0:796d0f61a05b 749
HannesTschofenig 0:796d0f61a05b 750 gcm_free( &ctx );
HannesTschofenig 0:796d0f61a05b 751
HannesTschofenig 0:796d0f61a05b 752 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 753 polarssl_printf( "passed\n" );
HannesTschofenig 0:796d0f61a05b 754
HannesTschofenig 0:796d0f61a05b 755 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 756 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
HannesTschofenig 0:796d0f61a05b 757 key_len, i, "dec" );
HannesTschofenig 0:796d0f61a05b 758
HannesTschofenig 0:796d0f61a05b 759 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
HannesTschofenig 0:796d0f61a05b 760
HannesTschofenig 0:796d0f61a05b 761 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
HannesTschofenig 0:796d0f61a05b 762 pt_len[i],
HannesTschofenig 0:796d0f61a05b 763 iv[iv_index[i]], iv_len[i],
HannesTschofenig 0:796d0f61a05b 764 additional[add_index[i]], add_len[i],
HannesTschofenig 0:796d0f61a05b 765 ct[j * 6 + i], buf, 16, tag_buf );
HannesTschofenig 0:796d0f61a05b 766
HannesTschofenig 0:796d0f61a05b 767 if( ret != 0 ||
HannesTschofenig 0:796d0f61a05b 768 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
HannesTschofenig 0:796d0f61a05b 769 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
HannesTschofenig 0:796d0f61a05b 770 {
HannesTschofenig 0:796d0f61a05b 771 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 772 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 773
HannesTschofenig 0:796d0f61a05b 774 return( 1 );
HannesTschofenig 0:796d0f61a05b 775 }
HannesTschofenig 0:796d0f61a05b 776
HannesTschofenig 0:796d0f61a05b 777 gcm_free( &ctx );
HannesTschofenig 0:796d0f61a05b 778
HannesTschofenig 0:796d0f61a05b 779 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 780 polarssl_printf( "passed\n" );
HannesTschofenig 0:796d0f61a05b 781
HannesTschofenig 0:796d0f61a05b 782 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 783 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
HannesTschofenig 0:796d0f61a05b 784 key_len, i, "enc" );
HannesTschofenig 0:796d0f61a05b 785
HannesTschofenig 0:796d0f61a05b 786 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
HannesTschofenig 0:796d0f61a05b 787
HannesTschofenig 0:796d0f61a05b 788 ret = gcm_starts( &ctx, GCM_ENCRYPT,
HannesTschofenig 0:796d0f61a05b 789 iv[iv_index[i]], iv_len[i],
HannesTschofenig 0:796d0f61a05b 790 additional[add_index[i]], add_len[i] );
HannesTschofenig 0:796d0f61a05b 791 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 792 {
HannesTschofenig 0:796d0f61a05b 793 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 794 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 795
HannesTschofenig 0:796d0f61a05b 796 return( 1 );
HannesTschofenig 0:796d0f61a05b 797 }
HannesTschofenig 0:796d0f61a05b 798
HannesTschofenig 0:796d0f61a05b 799 if( pt_len[i] > 32 )
HannesTschofenig 0:796d0f61a05b 800 {
HannesTschofenig 0:796d0f61a05b 801 size_t rest_len = pt_len[i] - 32;
HannesTschofenig 0:796d0f61a05b 802 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
HannesTschofenig 0:796d0f61a05b 803 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 804 {
HannesTschofenig 0:796d0f61a05b 805 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 806 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 807
HannesTschofenig 0:796d0f61a05b 808 return( 1 );
HannesTschofenig 0:796d0f61a05b 809 }
HannesTschofenig 0:796d0f61a05b 810
HannesTschofenig 0:796d0f61a05b 811 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
HannesTschofenig 0:796d0f61a05b 812 buf + 32 );
HannesTschofenig 0:796d0f61a05b 813 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 814 {
HannesTschofenig 0:796d0f61a05b 815 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 816 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 817
HannesTschofenig 0:796d0f61a05b 818 return( 1 );
HannesTschofenig 0:796d0f61a05b 819 }
HannesTschofenig 0:796d0f61a05b 820 }
HannesTschofenig 0:796d0f61a05b 821 else
HannesTschofenig 0:796d0f61a05b 822 {
HannesTschofenig 0:796d0f61a05b 823 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
HannesTschofenig 0:796d0f61a05b 824 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 825 {
HannesTschofenig 0:796d0f61a05b 826 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 827 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 828
HannesTschofenig 0:796d0f61a05b 829 return( 1 );
HannesTschofenig 0:796d0f61a05b 830 }
HannesTschofenig 0:796d0f61a05b 831 }
HannesTschofenig 0:796d0f61a05b 832
HannesTschofenig 0:796d0f61a05b 833 ret = gcm_finish( &ctx, tag_buf, 16 );
HannesTschofenig 0:796d0f61a05b 834 if( ret != 0 ||
HannesTschofenig 0:796d0f61a05b 835 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
HannesTschofenig 0:796d0f61a05b 836 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
HannesTschofenig 0:796d0f61a05b 837 {
HannesTschofenig 0:796d0f61a05b 838 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 839 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 840
HannesTschofenig 0:796d0f61a05b 841 return( 1 );
HannesTschofenig 0:796d0f61a05b 842 }
HannesTschofenig 0:796d0f61a05b 843
HannesTschofenig 0:796d0f61a05b 844 gcm_free( &ctx );
HannesTschofenig 0:796d0f61a05b 845
HannesTschofenig 0:796d0f61a05b 846 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 847 polarssl_printf( "passed\n" );
HannesTschofenig 0:796d0f61a05b 848
HannesTschofenig 0:796d0f61a05b 849 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 850 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
HannesTschofenig 0:796d0f61a05b 851 key_len, i, "dec" );
HannesTschofenig 0:796d0f61a05b 852
HannesTschofenig 0:796d0f61a05b 853 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
HannesTschofenig 0:796d0f61a05b 854
HannesTschofenig 0:796d0f61a05b 855 ret = gcm_starts( &ctx, GCM_DECRYPT,
HannesTschofenig 0:796d0f61a05b 856 iv[iv_index[i]], iv_len[i],
HannesTschofenig 0:796d0f61a05b 857 additional[add_index[i]], add_len[i] );
HannesTschofenig 0:796d0f61a05b 858 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 859 {
HannesTschofenig 0:796d0f61a05b 860 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 861 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 862
HannesTschofenig 0:796d0f61a05b 863 return( 1 );
HannesTschofenig 0:796d0f61a05b 864 }
HannesTschofenig 0:796d0f61a05b 865
HannesTschofenig 0:796d0f61a05b 866 if( pt_len[i] > 32 )
HannesTschofenig 0:796d0f61a05b 867 {
HannesTschofenig 0:796d0f61a05b 868 size_t rest_len = pt_len[i] - 32;
HannesTschofenig 0:796d0f61a05b 869 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
HannesTschofenig 0:796d0f61a05b 870 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 871 {
HannesTschofenig 0:796d0f61a05b 872 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 873 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 874
HannesTschofenig 0:796d0f61a05b 875 return( 1 );
HannesTschofenig 0:796d0f61a05b 876 }
HannesTschofenig 0:796d0f61a05b 877
HannesTschofenig 0:796d0f61a05b 878 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
HannesTschofenig 0:796d0f61a05b 879 buf + 32 );
HannesTschofenig 0:796d0f61a05b 880 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 881 {
HannesTschofenig 0:796d0f61a05b 882 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 883 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 884
HannesTschofenig 0:796d0f61a05b 885 return( 1 );
HannesTschofenig 0:796d0f61a05b 886 }
HannesTschofenig 0:796d0f61a05b 887 }
HannesTschofenig 0:796d0f61a05b 888 else
HannesTschofenig 0:796d0f61a05b 889 {
HannesTschofenig 0:796d0f61a05b 890 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
HannesTschofenig 0:796d0f61a05b 891 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 892 {
HannesTschofenig 0:796d0f61a05b 893 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 894 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 895
HannesTschofenig 0:796d0f61a05b 896 return( 1 );
HannesTschofenig 0:796d0f61a05b 897 }
HannesTschofenig 0:796d0f61a05b 898 }
HannesTschofenig 0:796d0f61a05b 899
HannesTschofenig 0:796d0f61a05b 900 ret = gcm_finish( &ctx, tag_buf, 16 );
HannesTschofenig 0:796d0f61a05b 901 if( ret != 0 ||
HannesTschofenig 0:796d0f61a05b 902 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
HannesTschofenig 0:796d0f61a05b 903 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
HannesTschofenig 0:796d0f61a05b 904 {
HannesTschofenig 0:796d0f61a05b 905 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 906 polarssl_printf( "failed\n" );
HannesTschofenig 0:796d0f61a05b 907
HannesTschofenig 0:796d0f61a05b 908 return( 1 );
HannesTschofenig 0:796d0f61a05b 909 }
HannesTschofenig 0:796d0f61a05b 910
HannesTschofenig 0:796d0f61a05b 911 gcm_free( &ctx );
HannesTschofenig 0:796d0f61a05b 912
HannesTschofenig 0:796d0f61a05b 913 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 914 polarssl_printf( "passed\n" );
HannesTschofenig 0:796d0f61a05b 915
HannesTschofenig 0:796d0f61a05b 916 }
HannesTschofenig 0:796d0f61a05b 917 }
HannesTschofenig 0:796d0f61a05b 918
HannesTschofenig 0:796d0f61a05b 919 if( verbose != 0 )
HannesTschofenig 0:796d0f61a05b 920 polarssl_printf( "\n" );
HannesTschofenig 0:796d0f61a05b 921
HannesTschofenig 0:796d0f61a05b 922 return( 0 );
HannesTschofenig 0:796d0f61a05b 923 }
HannesTschofenig 0:796d0f61a05b 924
HannesTschofenig 0:796d0f61a05b 925
HannesTschofenig 0:796d0f61a05b 926
HannesTschofenig 0:796d0f61a05b 927 #endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
HannesTschofenig 0:796d0f61a05b 928
HannesTschofenig 0:796d0f61a05b 929 #endif /* POLARSSL_GCM_C */
HannesTschofenig 0:796d0f61a05b 930
HannesTschofenig 0:796d0f61a05b 931