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