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: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
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 > 0xFFFFFFFE0ull ) 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 memcpy( tag, ctx->base_ectr , tag_len ); 00419 00420 if( orig_len || orig_add_len ) 00421 { 00422 memset( work_buf, 0x00, 16 ); 00423 00424 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); 00425 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); 00426 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); 00427 PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); 00428 00429 for( i = 0; i < 16; i++ ) 00430 ctx->buf [i] ^= work_buf[i]; 00431 00432 gcm_mult( ctx, ctx->buf , ctx->buf ); 00433 00434 for( i = 0; i < tag_len; i++ ) 00435 tag[i] ^= ctx->buf [i]; 00436 } 00437 00438 return( 0 ); 00439 } 00440 00441 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, 00442 int mode, 00443 size_t length, 00444 const unsigned char *iv, 00445 size_t iv_len, 00446 const unsigned char *add, 00447 size_t add_len, 00448 const unsigned char *input, 00449 unsigned char *output, 00450 size_t tag_len, 00451 unsigned char *tag ) 00452 { 00453 int ret; 00454 00455 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) 00456 return( ret ); 00457 00458 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 ) 00459 return( ret ); 00460 00461 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 ) 00462 return( ret ); 00463 00464 return( 0 ); 00465 } 00466 00467 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, 00468 size_t length, 00469 const unsigned char *iv, 00470 size_t iv_len, 00471 const unsigned char *add, 00472 size_t add_len, 00473 const unsigned char *tag, 00474 size_t tag_len, 00475 const unsigned char *input, 00476 unsigned char *output ) 00477 { 00478 int ret; 00479 unsigned char check_tag[16]; 00480 size_t i; 00481 int diff; 00482 00483 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, 00484 iv, iv_len, add, add_len, 00485 input, output, tag_len, check_tag ) ) != 0 ) 00486 { 00487 return( ret ); 00488 } 00489 00490 /* Check tag in "constant-time" */ 00491 for( diff = 0, i = 0; i < tag_len; i++ ) 00492 diff |= tag[i] ^ check_tag[i]; 00493 00494 if( diff != 0 ) 00495 { 00496 mbedtls_zeroize( output, length ); 00497 return( MBEDTLS_ERR_GCM_AUTH_FAILED ); 00498 } 00499 00500 return( 0 ); 00501 } 00502 00503 void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) 00504 { 00505 mbedtls_cipher_free( &ctx->cipher_ctx ); 00506 mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); 00507 } 00508 00509 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) 00510 /* 00511 * AES-GCM test vectors from: 00512 * 00513 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip 00514 */ 00515 #define MAX_TESTS 6 00516 00517 static const int key_index[MAX_TESTS] = 00518 { 0, 0, 1, 1, 1, 1 }; 00519 00520 static const unsigned char key[MAX_TESTS][32] = 00521 { 00522 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 00527 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 00528 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 00529 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, 00530 }; 00531 00532 static const size_t iv_len[MAX_TESTS] = 00533 { 12, 12, 12, 12, 8, 60 }; 00534 00535 static const int iv_index[MAX_TESTS] = 00536 { 0, 0, 1, 1, 1, 2 }; 00537 00538 static const unsigned char iv[MAX_TESTS][64] = 00539 { 00540 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00541 0x00, 0x00, 0x00, 0x00 }, 00542 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 00543 0xde, 0xca, 0xf8, 0x88 }, 00544 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 00545 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 00546 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 00547 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, 00548 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 00549 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 00550 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, 00551 0xa6, 0x37, 0xb3, 0x9b }, 00552 }; 00553 00554 static const size_t add_len[MAX_TESTS] = 00555 { 0, 0, 0, 20, 20, 20 }; 00556 00557 static const int add_index[MAX_TESTS] = 00558 { 0, 0, 0, 1, 1, 1 }; 00559 00560 static const unsigned char additional[MAX_TESTS][64] = 00561 { 00562 { 0x00 }, 00563 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 00564 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 00565 0xab, 0xad, 0xda, 0xd2 }, 00566 }; 00567 00568 static const size_t pt_len[MAX_TESTS] = 00569 { 0, 16, 64, 60, 60, 60 }; 00570 00571 static const int pt_index[MAX_TESTS] = 00572 { 0, 0, 1, 1, 1, 1 }; 00573 00574 static const unsigned char pt[MAX_TESTS][64] = 00575 { 00576 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 00578 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 00579 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 00580 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 00581 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 00582 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 00583 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 00584 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 00585 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, 00586 }; 00587 00588 static const unsigned char ct[MAX_TESTS * 3][64] = 00589 { 00590 { 0x00 }, 00591 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 00592 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, 00593 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 00594 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 00595 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 00596 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 00597 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 00598 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 00599 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 00600 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, 00601 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 00602 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 00603 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 00604 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 00605 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 00606 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 00607 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 00608 0x3d, 0x58, 0xe0, 0x91 }, 00609 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 00610 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, 00611 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 00612 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, 00613 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 00614 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 00615 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, 00616 0xc2, 0x3f, 0x45, 0x98 }, 00617 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 00618 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, 00619 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 00620 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, 00621 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 00622 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 00623 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, 00624 0x4c, 0x34, 0xae, 0xe5 }, 00625 { 0x00 }, 00626 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, 00627 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, 00628 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 00629 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 00630 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 00631 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 00632 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 00633 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 00634 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 00635 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, 00636 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 00637 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 00638 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 00639 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 00640 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 00641 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 00642 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 00643 0xcc, 0xda, 0x27, 0x10 }, 00644 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, 00645 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, 00646 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, 00647 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, 00648 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, 00649 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, 00650 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, 00651 0xa0, 0xf0, 0x62, 0xf7 }, 00652 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, 00653 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, 00654 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, 00655 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, 00656 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, 00657 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, 00658 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, 00659 0xe9, 0xb7, 0x37, 0x3b }, 00660 { 0x00 }, 00661 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 00662 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, 00663 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 00664 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 00665 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 00666 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 00667 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 00668 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 00669 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 00670 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, 00671 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 00672 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 00673 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 00674 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 00675 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 00676 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 00677 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 00678 0xbc, 0xc9, 0xf6, 0x62 }, 00679 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 00680 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, 00681 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 00682 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, 00683 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, 00684 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, 00685 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, 00686 0xf4, 0x7c, 0x9b, 0x1f }, 00687 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 00688 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, 00689 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 00690 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, 00691 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, 00692 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, 00693 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, 00694 0x44, 0xae, 0x7e, 0x3f }, 00695 }; 00696 00697 static const unsigned char tag[MAX_TESTS * 3][16] = 00698 { 00699 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 00700 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, 00701 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 00702 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, 00703 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 00704 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, 00705 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 00706 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, 00707 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 00708 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, 00709 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 00710 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, 00711 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, 00712 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, 00713 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 00714 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, 00715 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, 00716 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, 00717 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, 00718 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, 00719 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, 00720 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, 00721 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, 00722 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, 00723 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 00724 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, 00725 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, 00726 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, 00727 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, 00728 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, 00729 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, 00730 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, 00731 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, 00732 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, 00733 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 00734 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, 00735 }; 00736 00737 int mbedtls_gcm_self_test( int verbose ) 00738 { 00739 mbedtls_gcm_context ctx; 00740 unsigned char buf[64]; 00741 unsigned char tag_buf[16]; 00742 int i, j, ret; 00743 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; 00744 00745 mbedtls_gcm_init( &ctx ); 00746 00747 for( j = 0; j < 3; j++ ) 00748 { 00749 int key_len = 128 + 64 * j; 00750 00751 for( i = 0; i < MAX_TESTS; i++ ) 00752 { 00753 if( verbose != 0 ) 00754 mbedtls_printf( " AES-GCM-%3d #%d (%s): ", 00755 key_len, i, "enc" ); 00756 00757 mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); 00758 00759 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, 00760 pt_len[i], 00761 iv[iv_index[i]], iv_len[i], 00762 additional[add_index[i]], add_len[i], 00763 pt[pt_index[i]], buf, 16, tag_buf ); 00764 00765 if( ret != 0 || 00766 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || 00767 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) 00768 { 00769 if( verbose != 0 ) 00770 mbedtls_printf( "failed\n" ); 00771 00772 return( 1 ); 00773 } 00774 00775 mbedtls_gcm_free( &ctx ); 00776 00777 if( verbose != 0 ) 00778 mbedtls_printf( "passed\n" ); 00779 00780 if( verbose != 0 ) 00781 mbedtls_printf( " AES-GCM-%3d #%d (%s): ", 00782 key_len, i, "dec" ); 00783 00784 mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); 00785 00786 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, 00787 pt_len[i], 00788 iv[iv_index[i]], iv_len[i], 00789 additional[add_index[i]], add_len[i], 00790 ct[j * 6 + i], buf, 16, tag_buf ); 00791 00792 if( ret != 0 || 00793 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || 00794 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) 00795 { 00796 if( verbose != 0 ) 00797 mbedtls_printf( "failed\n" ); 00798 00799 return( 1 ); 00800 } 00801 00802 mbedtls_gcm_free( &ctx ); 00803 00804 if( verbose != 0 ) 00805 mbedtls_printf( "passed\n" ); 00806 00807 if( verbose != 0 ) 00808 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", 00809 key_len, i, "enc" ); 00810 00811 mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); 00812 00813 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, 00814 iv[iv_index[i]], iv_len[i], 00815 additional[add_index[i]], add_len[i] ); 00816 if( ret != 0 ) 00817 { 00818 if( verbose != 0 ) 00819 mbedtls_printf( "failed\n" ); 00820 00821 return( 1 ); 00822 } 00823 00824 if( pt_len[i] > 32 ) 00825 { 00826 size_t rest_len = pt_len[i] - 32; 00827 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); 00828 if( ret != 0 ) 00829 { 00830 if( verbose != 0 ) 00831 mbedtls_printf( "failed\n" ); 00832 00833 return( 1 ); 00834 } 00835 00836 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, 00837 buf + 32 ); 00838 if( ret != 0 ) 00839 { 00840 if( verbose != 0 ) 00841 mbedtls_printf( "failed\n" ); 00842 00843 return( 1 ); 00844 } 00845 } 00846 else 00847 { 00848 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); 00849 if( ret != 0 ) 00850 { 00851 if( verbose != 0 ) 00852 mbedtls_printf( "failed\n" ); 00853 00854 return( 1 ); 00855 } 00856 } 00857 00858 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); 00859 if( ret != 0 || 00860 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || 00861 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) 00862 { 00863 if( verbose != 0 ) 00864 mbedtls_printf( "failed\n" ); 00865 00866 return( 1 ); 00867 } 00868 00869 mbedtls_gcm_free( &ctx ); 00870 00871 if( verbose != 0 ) 00872 mbedtls_printf( "passed\n" ); 00873 00874 if( verbose != 0 ) 00875 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", 00876 key_len, i, "dec" ); 00877 00878 mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); 00879 00880 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, 00881 iv[iv_index[i]], iv_len[i], 00882 additional[add_index[i]], add_len[i] ); 00883 if( ret != 0 ) 00884 { 00885 if( verbose != 0 ) 00886 mbedtls_printf( "failed\n" ); 00887 00888 return( 1 ); 00889 } 00890 00891 if( pt_len[i] > 32 ) 00892 { 00893 size_t rest_len = pt_len[i] - 32; 00894 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); 00895 if( ret != 0 ) 00896 { 00897 if( verbose != 0 ) 00898 mbedtls_printf( "failed\n" ); 00899 00900 return( 1 ); 00901 } 00902 00903 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, 00904 buf + 32 ); 00905 if( ret != 0 ) 00906 { 00907 if( verbose != 0 ) 00908 mbedtls_printf( "failed\n" ); 00909 00910 return( 1 ); 00911 } 00912 } 00913 else 00914 { 00915 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf ); 00916 if( ret != 0 ) 00917 { 00918 if( verbose != 0 ) 00919 mbedtls_printf( "failed\n" ); 00920 00921 return( 1 ); 00922 } 00923 } 00924 00925 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); 00926 if( ret != 0 || 00927 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || 00928 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) 00929 { 00930 if( verbose != 0 ) 00931 mbedtls_printf( "failed\n" ); 00932 00933 return( 1 ); 00934 } 00935 00936 mbedtls_gcm_free( &ctx ); 00937 00938 if( verbose != 0 ) 00939 mbedtls_printf( "passed\n" ); 00940 00941 } 00942 } 00943 00944 if( verbose != 0 ) 00945 mbedtls_printf( "\n" ); 00946 00947 return( 0 ); 00948 } 00949 00950 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ 00951 00952 #endif /* MBEDTLS_GCM_C */
Generated on Tue Jul 12 2022 11:02:38 by
