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