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