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