00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "polarssl/config.h"
00029
00030 #if defined(POLARSSL_GCM_C)
00031
00032 #include "polarssl/gcm.h"
00033
00034
00035
00036
00037 #ifndef GET_UINT32_BE
00038 #define GET_UINT32_BE(n,b,i) \
00039 { \
00040 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
00041 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
00042 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
00043 | ( (uint32_t) (b)[(i) + 3] ); \
00044 }
00045 #endif
00046
00047 #ifndef PUT_UINT32_BE
00048 #define PUT_UINT32_BE(n,b,i) \
00049 { \
00050 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
00051 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
00052 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
00053 (b)[(i) + 3] = (unsigned char) ( (n) ); \
00054 }
00055 #endif
00056
00057 static int gcm_gen_table( gcm_context *ctx )
00058 {
00059 int ret, i, j;
00060 uint64_t hi, lo;
00061 uint64_t vl, vh;
00062 unsigned char h[16];
00063 size_t olen = 0;
00064
00065 memset( h, 0, 16 );
00066 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
00067 return( ret );
00068
00069 ctx->HH[0] = 0;
00070 ctx->HL[0] = 0;
00071
00072 GET_UINT32_BE( hi, h, 0 );
00073 GET_UINT32_BE( lo, h, 4 );
00074 vh = (uint64_t) hi << 32 | lo;
00075
00076 GET_UINT32_BE( hi, h, 8 );
00077 GET_UINT32_BE( lo, h, 12 );
00078 vl = (uint64_t) hi << 32 | lo;
00079
00080 ctx->HL[8] = vl;
00081 ctx->HH[8] = vh;
00082
00083 for( i = 4; i > 0; i >>= 1 )
00084 {
00085 uint32_t T = ( vl & 1 ) * 0xe1000000U;
00086 vl = ( vh << 63 ) | ( vl >> 1 );
00087 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
00088
00089 ctx->HL[i] = vl;
00090 ctx->HH[i] = vh;
00091 }
00092
00093 for (i = 2; i < 16; i <<= 1 )
00094 {
00095 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
00096 vh = *HiH;
00097 vl = *HiL;
00098 for( j = 1; j < i; j++ )
00099 {
00100 HiH[j] = vh ^ ctx->HH[j];
00101 HiL[j] = vl ^ ctx->HL[j];
00102 }
00103 }
00104
00105 return( 0 );
00106 }
00107
00108 int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
00109 unsigned int keysize )
00110 {
00111 int ret;
00112 const cipher_info_t *cipher_info;
00113
00114 memset( ctx, 0, sizeof(gcm_context) );
00115
00116 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
00117 if( cipher_info == NULL )
00118 return( POLARSSL_ERR_GCM_BAD_INPUT );
00119
00120 if( cipher_info->block_size != 16 )
00121 return( POLARSSL_ERR_GCM_BAD_INPUT );
00122
00123 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
00124 return( ret );
00125
00126 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
00127 POLARSSL_ENCRYPT ) ) != 0 )
00128 {
00129 return( ret );
00130 }
00131
00132 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
00133 return( ret );
00134
00135 return( 0 );
00136 }
00137
00138 static const uint64_t last4[16] =
00139 {
00140 0x0000, 0x1c20, 0x3840, 0x2460,
00141 0x7080, 0x6ca0, 0x48c0, 0x54e0,
00142 0xe100, 0xfd20, 0xd940, 0xc560,
00143 0x9180, 0x8da0, 0xa9c0, 0xb5e0
00144 };
00145
00146 static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
00147 unsigned char output[16] )
00148 {
00149 int i = 0;
00150 unsigned char z[16];
00151 unsigned char lo, hi, rem;
00152 uint64_t zh, zl;
00153
00154 memset( z, 0x00, 16 );
00155
00156 lo = x[15] & 0xf;
00157 hi = x[15] >> 4;
00158
00159 zh = ctx->HH[lo];
00160 zl = ctx->HL[lo];
00161
00162 for( i = 15; i >= 0; i-- )
00163 {
00164 lo = x[i] & 0xf;
00165 hi = x[i] >> 4;
00166
00167 if( i != 15 )
00168 {
00169 rem = (unsigned char) zl & 0xf;
00170 zl = ( zh << 60 ) | ( zl >> 4 );
00171 zh = ( zh >> 4 );
00172 zh ^= (uint64_t) last4[rem] << 48;
00173 zh ^= ctx->HH[lo];
00174 zl ^= ctx->HL[lo];
00175
00176 }
00177
00178 rem = (unsigned char) zl & 0xf;
00179 zl = ( zh << 60 ) | ( zl >> 4 );
00180 zh = ( zh >> 4 );
00181 zh ^= (uint64_t) last4[rem] << 48;
00182 zh ^= ctx->HH[hi];
00183 zl ^= ctx->HL[hi];
00184 }
00185
00186 PUT_UINT32_BE( zh >> 32, output, 0 );
00187 PUT_UINT32_BE( zh, output, 4 );
00188 PUT_UINT32_BE( zl >> 32, output, 8 );
00189 PUT_UINT32_BE( zl, output, 12 );
00190 }
00191
00192 int gcm_starts( gcm_context *ctx,
00193 int mode,
00194 const unsigned char *iv,
00195 size_t iv_len,
00196 const unsigned char *add,
00197 size_t add_len )
00198 {
00199 int ret;
00200 unsigned char work_buf[16];
00201 size_t i;
00202 const unsigned char *p;
00203 size_t use_len, olen = 0;
00204
00205 memset( ctx->y, 0x00, sizeof(ctx->y) );
00206 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
00207
00208 ctx->mode = mode;
00209 ctx->len = 0;
00210 ctx->add_len = 0;
00211
00212 if( iv_len == 12 )
00213 {
00214 memcpy( ctx->y, iv, iv_len );
00215 ctx->y[15] = 1;
00216 }
00217 else
00218 {
00219 memset( work_buf, 0x00, 16 );
00220 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
00221
00222 p = iv;
00223 while( iv_len > 0 )
00224 {
00225 use_len = ( iv_len < 16 ) ? iv_len : 16;
00226
00227 for( i = 0; i < use_len; i++ )
00228 ctx->y[i] ^= p[i];
00229
00230 gcm_mult( ctx, ctx->y, ctx->y );
00231
00232 iv_len -= use_len;
00233 p += use_len;
00234 }
00235
00236 for( i = 0; i < 16; i++ )
00237 ctx->y[i] ^= work_buf[i];
00238
00239 gcm_mult( ctx, ctx->y, ctx->y );
00240 }
00241
00242 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
00243 &olen ) ) != 0 )
00244 {
00245 return( ret );
00246 }
00247
00248 ctx->add_len = add_len;
00249 p = add;
00250 while( add_len > 0 )
00251 {
00252 use_len = ( add_len < 16 ) ? add_len : 16;
00253
00254 for( i = 0; i < use_len; i++ )
00255 ctx->buf[i] ^= p[i];
00256
00257 gcm_mult( ctx, ctx->buf, ctx->buf );
00258
00259 add_len -= use_len;
00260 p += use_len;
00261 }
00262
00263 return( 0 );
00264 }
00265
00266 int gcm_update( gcm_context *ctx,
00267 size_t length,
00268 const unsigned char *input,
00269 unsigned char *output )
00270 {
00271 int ret;
00272 unsigned char ectr[16];
00273 size_t i;
00274 const unsigned char *p;
00275 unsigned char *out_p = output;
00276 size_t use_len, olen = 0;
00277
00278 if( output > input && (size_t) ( output - input ) < length )
00279 return( POLARSSL_ERR_GCM_BAD_INPUT );
00280
00281 ctx->len += length;
00282
00283 p = input;
00284 while( length > 0 )
00285 {
00286 use_len = ( length < 16 ) ? length : 16;
00287
00288 for( i = 16; i > 12; i-- )
00289 if( ++ctx->y[i - 1] != 0 )
00290 break;
00291
00292 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
00293 &olen ) ) != 0 )
00294 {
00295 return( ret );
00296 }
00297
00298 for( i = 0; i < use_len; i++ )
00299 {
00300 if( ctx->mode == GCM_DECRYPT )
00301 ctx->buf[i] ^= p[i];
00302 out_p[i] = ectr[i] ^ p[i];
00303 if( ctx->mode == GCM_ENCRYPT )
00304 ctx->buf[i] ^= out_p[i];
00305 }
00306
00307 gcm_mult( ctx, ctx->buf, ctx->buf );
00308
00309 length -= use_len;
00310 p += use_len;
00311 out_p += use_len;
00312 }
00313
00314 return( 0 );
00315 }
00316
00317 int gcm_finish( gcm_context *ctx,
00318 unsigned char *tag,
00319 size_t tag_len )
00320 {
00321 unsigned char work_buf[16];
00322 size_t i;
00323 uint64_t orig_len = ctx->len * 8;
00324 uint64_t orig_add_len = ctx->add_len * 8;
00325
00326 if( tag_len > 16 )
00327 return( POLARSSL_ERR_GCM_BAD_INPUT );
00328
00329 if( tag_len != 0 )
00330 memcpy( tag, ctx->base_ectr, tag_len );
00331
00332 if( orig_len || orig_add_len )
00333 {
00334 memset( work_buf, 0x00, 16 );
00335
00336 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
00337 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
00338 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
00339 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
00340
00341 for( i = 0; i < 16; i++ )
00342 ctx->buf[i] ^= work_buf[i];
00343
00344 gcm_mult( ctx, ctx->buf, ctx->buf );
00345
00346 for( i = 0; i < tag_len; i++ )
00347 tag[i] ^= ctx->buf[i];
00348 }
00349
00350 return( 0 );
00351 }
00352
00353 int gcm_crypt_and_tag( gcm_context *ctx,
00354 int mode,
00355 size_t length,
00356 const unsigned char *iv,
00357 size_t iv_len,
00358 const unsigned char *add,
00359 size_t add_len,
00360 const unsigned char *input,
00361 unsigned char *output,
00362 size_t tag_len,
00363 unsigned char *tag )
00364 {
00365 int ret;
00366
00367 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
00368 return( ret );
00369
00370 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
00371 return( ret );
00372
00373 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
00374 return( ret );
00375
00376 return( 0 );
00377 }
00378
00379 int gcm_auth_decrypt( gcm_context *ctx,
00380 size_t length,
00381 const unsigned char *iv,
00382 size_t iv_len,
00383 const unsigned char *add,
00384 size_t add_len,
00385 const unsigned char *tag,
00386 size_t tag_len,
00387 const unsigned char *input,
00388 unsigned char *output )
00389 {
00390 unsigned char check_tag[16];
00391 size_t i;
00392 int diff;
00393
00394 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
00395
00396
00397 for( diff = 0, i = 0; i < tag_len; i++ )
00398 diff |= tag[i] ^ check_tag[i];
00399
00400 if( diff != 0 )
00401 {
00402 memset( output, 0, length );
00403 return( POLARSSL_ERR_GCM_AUTH_FAILED );
00404 }
00405
00406 return( 0 );
00407 }
00408
00409 void gcm_free( gcm_context *ctx )
00410 {
00411 (void) cipher_free_ctx( &ctx->cipher_ctx );
00412 memset( ctx, 0, sizeof( gcm_context ) );
00413 }
00414
00415 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
00416
00417 #include <stdio.h>
00418
00419
00420
00421
00422
00423
00424 #define MAX_TESTS 6
00425
00426 int key_index[MAX_TESTS] =
00427 { 0, 0, 1, 1, 1, 1 };
00428
00429 unsigned char key[MAX_TESTS][32] =
00430 {
00431 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
00435 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
00436 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
00437 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
00438 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
00439 };
00440
00441 size_t iv_len[MAX_TESTS] =
00442 { 12, 12, 12, 12, 8, 60 };
00443
00444 int iv_index[MAX_TESTS] =
00445 { 0, 0, 1, 1, 1, 2 };
00446
00447 unsigned char iv[MAX_TESTS][64] =
00448 {
00449 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00450 0x00, 0x00, 0x00, 0x00 },
00451 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
00452 0xde, 0xca, 0xf8, 0x88 },
00453 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
00454 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
00455 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
00456 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
00457 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
00458 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
00459 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
00460 0xa6, 0x37, 0xb3, 0x9b },
00461 };
00462
00463 size_t add_len[MAX_TESTS] =
00464 { 0, 0, 0, 20, 20, 20 };
00465
00466 int add_index[MAX_TESTS] =
00467 { 0, 0, 0, 1, 1, 1 };
00468
00469 unsigned char additional[MAX_TESTS][64] =
00470 {
00471 { 0x00 },
00472 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
00473 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
00474 0xab, 0xad, 0xda, 0xd2 },
00475 };
00476
00477 size_t pt_len[MAX_TESTS] =
00478 { 0, 16, 64, 60, 60, 60 };
00479
00480 int pt_index[MAX_TESTS] =
00481 { 0, 0, 1, 1, 1, 1 };
00482
00483 unsigned char pt[MAX_TESTS][64] =
00484 {
00485 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
00487 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
00488 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
00489 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
00490 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
00491 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
00492 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
00493 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
00494 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
00495 };
00496
00497 unsigned char ct[MAX_TESTS * 3][64] =
00498 {
00499 { 0x00 },
00500 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
00501 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
00502 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
00503 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
00504 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
00505 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
00506 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
00507 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
00508 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
00509 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
00510 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
00511 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
00512 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
00513 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
00514 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
00515 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
00516 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
00517 0x3d, 0x58, 0xe0, 0x91 },
00518 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
00519 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
00520 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
00521 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
00522 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
00523 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
00524 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
00525 0xc2, 0x3f, 0x45, 0x98 },
00526 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
00527 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
00528 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
00529 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
00530 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
00531 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
00532 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
00533 0x4c, 0x34, 0xae, 0xe5 },
00534 { 0x00 },
00535 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
00536 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
00537 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
00538 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
00539 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
00540 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
00541 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
00542 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
00543 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
00544 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
00545 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
00546 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
00547 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
00548 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
00549 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
00550 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
00551 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
00552 0xcc, 0xda, 0x27, 0x10 },
00553 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
00554 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
00555 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
00556 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
00557 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
00558 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
00559 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
00560 0xa0, 0xf0, 0x62, 0xf7 },
00561 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
00562 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
00563 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
00564 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
00565 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
00566 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
00567 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
00568 0xe9, 0xb7, 0x37, 0x3b },
00569 { 0x00 },
00570 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
00571 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
00572 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
00573 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
00574 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
00575 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
00576 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
00577 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
00578 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
00579 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
00580 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
00581 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
00582 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
00583 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
00584 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
00585 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
00586 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
00587 0xbc, 0xc9, 0xf6, 0x62 },
00588 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
00589 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
00590 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
00591 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
00592 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
00593 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
00594 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
00595 0xf4, 0x7c, 0x9b, 0x1f },
00596 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
00597 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
00598 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
00599 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
00600 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
00601 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
00602 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
00603 0x44, 0xae, 0x7e, 0x3f },
00604 };
00605
00606 unsigned char tag[MAX_TESTS * 3][16] =
00607 {
00608 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
00609 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
00610 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
00611 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
00612 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
00613 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
00614 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
00615 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
00616 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
00617 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
00618 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
00619 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
00620 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
00621 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
00622 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
00623 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
00624 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
00625 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
00626 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
00627 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
00628 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
00629 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
00630 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
00631 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
00632 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
00633 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
00634 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
00635 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
00636 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
00637 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
00638 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
00639 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
00640 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
00641 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
00642 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
00643 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
00644 };
00645
00646 int gcm_self_test( int verbose )
00647 {
00648 gcm_context ctx;
00649 unsigned char buf[64];
00650 unsigned char tag_buf[16];
00651 int i, j, ret;
00652 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
00653
00654 for( j = 0; j < 3; j++ )
00655 {
00656 int key_len = 128 + 64 * j;
00657
00658 for( i = 0; i < MAX_TESTS; i++ )
00659 {
00660 if( verbose != 0 )
00661 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
00662
00663 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
00664
00665 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
00666 pt_len[i],
00667 iv[iv_index[i]], iv_len[i],
00668 additional[add_index[i]], add_len[i],
00669 pt[pt_index[i]], buf, 16, tag_buf );
00670
00671 if( ret != 0 ||
00672 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
00673 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
00674 {
00675 if( verbose != 0 )
00676 printf( "failed\n" );
00677
00678 return( 1 );
00679 }
00680
00681 gcm_free( &ctx );
00682
00683 if( verbose != 0 )
00684 printf( "passed\n" );
00685
00686 if( verbose != 0 )
00687 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
00688
00689 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
00690
00691 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
00692 pt_len[i],
00693 iv[iv_index[i]], iv_len[i],
00694 additional[add_index[i]], add_len[i],
00695 ct[j * 6 + i], buf, 16, tag_buf );
00696
00697 if( ret != 0 ||
00698 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
00699 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
00700 {
00701 if( verbose != 0 )
00702 printf( "failed\n" );
00703
00704 return( 1 );
00705 }
00706
00707 gcm_free( &ctx );
00708
00709 if( verbose != 0 )
00710 printf( "passed\n" );
00711
00712 if( verbose != 0 )
00713 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
00714
00715 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
00716
00717 ret = gcm_starts( &ctx, GCM_ENCRYPT,
00718 iv[iv_index[i]], iv_len[i],
00719 additional[add_index[i]], add_len[i] );
00720 if( ret != 0 )
00721 {
00722 if( verbose != 0 )
00723 printf( "failed\n" );
00724
00725 return( 1 );
00726 }
00727
00728 if( pt_len[i] > 32 )
00729 {
00730 size_t rest_len = pt_len[i] - 32;
00731 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
00732 if( ret != 0 )
00733 {
00734 if( verbose != 0 )
00735 printf( "failed\n" );
00736
00737 return( 1 );
00738 }
00739
00740 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
00741 if( ret != 0 )
00742 {
00743 if( verbose != 0 )
00744 printf( "failed\n" );
00745
00746 return( 1 );
00747 }
00748 }
00749 else
00750 {
00751 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
00752 if( ret != 0 )
00753 {
00754 if( verbose != 0 )
00755 printf( "failed\n" );
00756
00757 return( 1 );
00758 }
00759 }
00760
00761 ret = gcm_finish( &ctx, tag_buf, 16 );
00762 if( ret != 0 ||
00763 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
00764 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
00765 {
00766 if( verbose != 0 )
00767 printf( "failed\n" );
00768
00769 return( 1 );
00770 }
00771
00772 gcm_free( &ctx );
00773
00774 if( verbose != 0 )
00775 printf( "passed\n" );
00776
00777 if( verbose != 0 )
00778 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
00779
00780 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
00781
00782 ret = gcm_starts( &ctx, GCM_DECRYPT,
00783 iv[iv_index[i]], iv_len[i],
00784 additional[add_index[i]], add_len[i] );
00785 if( ret != 0 )
00786 {
00787 if( verbose != 0 )
00788 printf( "failed\n" );
00789
00790 return( 1 );
00791 }
00792
00793 if( pt_len[i] > 32 )
00794 {
00795 size_t rest_len = pt_len[i] - 32;
00796 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
00797 if( ret != 0 )
00798 {
00799 if( verbose != 0 )
00800 printf( "failed\n" );
00801
00802 return( 1 );
00803 }
00804
00805 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
00806 if( ret != 0 )
00807 {
00808 if( verbose != 0 )
00809 printf( "failed\n" );
00810
00811 return( 1 );
00812 }
00813 }
00814 else
00815 {
00816 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
00817 if( ret != 0 )
00818 {
00819 if( verbose != 0 )
00820 printf( "failed\n" );
00821
00822 return( 1 );
00823 }
00824 }
00825
00826 ret = gcm_finish( &ctx, tag_buf, 16 );
00827 if( ret != 0 ||
00828 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
00829 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
00830 {
00831 if( verbose != 0 )
00832 printf( "failed\n" );
00833
00834 return( 1 );
00835 }
00836
00837 gcm_free( &ctx );
00838
00839 if( verbose != 0 )
00840 printf( "passed\n" );
00841
00842 }
00843 }
00844
00845 if( verbose != 0 )
00846 printf( "\n" );
00847
00848 return( 0 );
00849 }
00850
00851
00852
00853 #endif
00854
00855 #endif