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