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