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