diff options
Diffstat (limited to 'thirdparty/mbedtls/library/gcm.c')
-rw-r--r-- | thirdparty/mbedtls/library/gcm.c | 244 |
1 files changed, 114 insertions, 130 deletions
diff --git a/thirdparty/mbedtls/library/gcm.c b/thirdparty/mbedtls/library/gcm.c index 2afe5025a0..43a5e1bec6 100644 --- a/thirdparty/mbedtls/library/gcm.c +++ b/thirdparty/mbedtls/library/gcm.c @@ -2,13 +2,7 @@ * NIST SP800-38D compliant GCM implementation * * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. @@ -21,27 +15,6 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** */ /* @@ -54,16 +27,13 @@ * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif +#include "common.h" #if defined(MBEDTLS_GCM_C) #include "mbedtls/gcm.h" #include "mbedtls/platform_util.h" +#include "mbedtls/error.h" #include <string.h> @@ -89,29 +59,6 @@ MBEDTLS_INTERNAL_VALIDATE( cond ) /* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* * Initialize a context */ void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) @@ -141,12 +88,12 @@ static int gcm_gen_table( mbedtls_gcm_context *ctx ) return( ret ); /* pack h as two 64-bits ints, big-endian */ - GET_UINT32_BE( hi, h, 0 ); - GET_UINT32_BE( lo, h, 4 ); + hi = MBEDTLS_GET_UINT32_BE( h, 0 ); + lo = MBEDTLS_GET_UINT32_BE( h, 4 ); vh = (uint64_t) hi << 32 | lo; - GET_UINT32_BE( hi, h, 8 ); - GET_UINT32_BE( lo, h, 12 ); + hi = MBEDTLS_GET_UINT32_BE( h, 8 ); + lo = MBEDTLS_GET_UINT32_BE( h, 12 ); vl = (uint64_t) hi << 32 | lo; /* 8 = 1000 corresponds to 1 in GF(2^128) */ @@ -193,14 +140,15 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, const unsigned char *key, unsigned int keybits ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const mbedtls_cipher_info_t *cipher_info; GCM_VALIDATE_RET( ctx != NULL ); GCM_VALIDATE_RET( key != NULL ); GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 ); - cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, + MBEDTLS_MODE_ECB ); if( cipher_info == NULL ) return( MBEDTLS_ERR_GCM_BAD_INPUT ); @@ -252,10 +200,10 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) { unsigned char h[16]; - PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); - PUT_UINT32_BE( ctx->HH[8], h, 4 ); - PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); - PUT_UINT32_BE( ctx->HL[8], h, 12 ); + MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); + MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 ); + MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); + MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 ); mbedtls_aesni_gcm_mult( output, x, h ); return; @@ -270,7 +218,7 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], for( i = 15; i >= 0; i-- ) { lo = x[i] & 0xf; - hi = x[i] >> 4; + hi = ( x[i] >> 4 ) & 0xf; if( i != 15 ) { @@ -291,10 +239,10 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], zl ^= ctx->HL[hi]; } - PUT_UINT32_BE( zh >> 32, output, 0 ); - PUT_UINT32_BE( zh, output, 4 ); - PUT_UINT32_BE( zl >> 32, output, 8 ); - PUT_UINT32_BE( zl, output, 12 ); + MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 ); + MBEDTLS_PUT_UINT32_BE( zh, output, 4 ); + MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 ); + MBEDTLS_PUT_UINT32_BE( zl, output, 12 ); } int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, @@ -304,11 +252,12 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, const unsigned char *add, size_t add_len ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char work_buf[16]; size_t i; const unsigned char *p; size_t use_len, olen = 0; + uint64_t iv_bits; GCM_VALIDATE_RET( ctx != NULL ); GCM_VALIDATE_RET( iv != NULL ); @@ -338,7 +287,8 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, else { memset( work_buf, 0x00, 16 ); - PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); + iv_bits = (uint64_t)iv_len * 8; + MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 ); p = iv; while( iv_len > 0 ) @@ -360,8 +310,8 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, gcm_mult( ctx, ctx->y, ctx->y ); } - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, - &olen ) ) != 0 ) + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, + ctx->base_ectr, &olen ) ) != 0 ) { return( ret ); } @@ -389,7 +339,7 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx, const unsigned char *input, unsigned char *output ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char ectr[16]; size_t i; const unsigned char *p; @@ -471,10 +421,10 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, { memset( work_buf, 0x00, 16 ); - PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); - PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); - PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); - PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); + MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); + MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); + MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); + MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); for( i = 0; i < 16; i++ ) ctx->buf[i] ^= work_buf[i]; @@ -500,7 +450,7 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, size_t tag_len, unsigned char *tag ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; GCM_VALIDATE_RET( ctx != NULL ); GCM_VALIDATE_RET( iv != NULL ); @@ -532,7 +482,7 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, const unsigned char *input, unsigned char *output ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char check_tag[16]; size_t i; int diff; @@ -582,10 +532,10 @@ void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) */ #define MAX_TESTS 6 -static const int key_index[MAX_TESTS] = +static const int key_index_test_data[MAX_TESTS] = { 0, 0, 1, 1, 1, 1 }; -static const unsigned char key[MAX_TESTS][32] = +static const unsigned char key_test_data[MAX_TESTS][32] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -597,13 +547,13 @@ static const unsigned char key[MAX_TESTS][32] = 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, }; -static const size_t iv_len[MAX_TESTS] = +static const size_t iv_len_test_data[MAX_TESTS] = { 12, 12, 12, 12, 8, 60 }; -static const int iv_index[MAX_TESTS] = +static const int iv_index_test_data[MAX_TESTS] = { 0, 0, 1, 1, 1, 2 }; -static const unsigned char iv[MAX_TESTS][64] = +static const unsigned char iv_test_data[MAX_TESTS][64] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -619,13 +569,13 @@ static const unsigned char iv[MAX_TESTS][64] = 0xa6, 0x37, 0xb3, 0x9b }, }; -static const size_t add_len[MAX_TESTS] = +static const size_t add_len_test_data[MAX_TESTS] = { 0, 0, 0, 20, 20, 20 }; -static const int add_index[MAX_TESTS] = +static const int add_index_test_data[MAX_TESTS] = { 0, 0, 0, 1, 1, 1 }; -static const unsigned char additional[MAX_TESTS][64] = +static const unsigned char additional_test_data[MAX_TESTS][64] = { { 0x00 }, { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, @@ -633,13 +583,13 @@ static const unsigned char additional[MAX_TESTS][64] = 0xab, 0xad, 0xda, 0xd2 }, }; -static const size_t pt_len[MAX_TESTS] = +static const size_t pt_len_test_data[MAX_TESTS] = { 0, 16, 64, 60, 60, 60 }; -static const int pt_index[MAX_TESTS] = +static const int pt_index_test_data[MAX_TESTS] = { 0, 0, 1, 1, 1, 1 }; -static const unsigned char pt[MAX_TESTS][64] = +static const unsigned char pt_test_data[MAX_TESTS][64] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -653,7 +603,7 @@ static const unsigned char pt[MAX_TESTS][64] = 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, }; -static const unsigned char ct[MAX_TESTS * 3][64] = +static const unsigned char ct_test_data[MAX_TESTS * 3][64] = { { 0x00 }, { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, @@ -762,7 +712,7 @@ static const unsigned char ct[MAX_TESTS * 3][64] = 0x44, 0xae, 0x7e, 0x3f }, }; -static const unsigned char tag[MAX_TESTS * 3][16] = +static const unsigned char tag_test_data[MAX_TESTS * 3][16] = { { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, @@ -822,7 +772,8 @@ int mbedtls_gcm_self_test( int verbose ) mbedtls_printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" ); - ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], + ret = mbedtls_gcm_setkey( &ctx, cipher, + key_test_data[key_index_test_data[i]], key_len ); /* * AES-192 is an optional feature that may be unavailable when @@ -840,15 +791,28 @@ int mbedtls_gcm_self_test( int verbose ) } ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, - pt_len[i], - iv[iv_index[i]], iv_len[i], - additional[add_index[i]], add_len[i], - pt[pt_index[i]], buf, 16, tag_buf ); + pt_len_test_data[i], + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i], + pt_test_data[pt_index_test_data[i]], + buf, 16, tag_buf ); +#if defined(MBEDTLS_GCM_ALT) + /* Allow alternative implementations to only support 12-byte nonces. */ + if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && + iv_len_test_data[i] != 12 ) + { + mbedtls_printf( "skipped\n" ); + break; + } +#endif /* defined(MBEDTLS_GCM_ALT) */ if( ret != 0 ) goto exit; - if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || - memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + if ( memcmp( buf, ct_test_data[j * 6 + i], + pt_len_test_data[i] ) != 0 || + memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) { ret = 1; goto exit; @@ -865,22 +829,26 @@ int mbedtls_gcm_self_test( int verbose ) mbedtls_printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" ); - ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], + ret = mbedtls_gcm_setkey( &ctx, cipher, + key_test_data[key_index_test_data[i]], key_len ); if( ret != 0 ) goto exit; ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, - pt_len[i], - iv[iv_index[i]], iv_len[i], - additional[add_index[i]], add_len[i], - ct[j * 6 + i], buf, 16, tag_buf ); + pt_len_test_data[i], + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i], + ct_test_data[j * 6 + i], buf, 16, tag_buf ); if( ret != 0 ) goto exit; - if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || - memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + if( memcmp( buf, pt_test_data[pt_index_test_data[i]], + pt_len_test_data[i] ) != 0 || + memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) { ret = 1; goto exit; @@ -897,32 +865,40 @@ int mbedtls_gcm_self_test( int verbose ) mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" ); - ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], + ret = mbedtls_gcm_setkey( &ctx, cipher, + key_test_data[key_index_test_data[i]], key_len ); if( ret != 0 ) goto exit; ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, - iv[iv_index[i]], iv_len[i], - additional[add_index[i]], add_len[i] ); + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i] ); if( ret != 0 ) goto exit; - if( pt_len[i] > 32 ) + if( pt_len_test_data[i] > 32 ) { - size_t rest_len = pt_len[i] - 32; - ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); + size_t rest_len = pt_len_test_data[i] - 32; + ret = mbedtls_gcm_update( &ctx, 32, + pt_test_data[pt_index_test_data[i]], + buf ); if( ret != 0 ) goto exit; - ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, - buf + 32 ); + ret = mbedtls_gcm_update( &ctx, rest_len, + pt_test_data[pt_index_test_data[i]] + 32, + buf + 32 ); if( ret != 0 ) goto exit; } else { - ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); + ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i], + pt_test_data[pt_index_test_data[i]], + buf ); if( ret != 0 ) goto exit; } @@ -931,8 +907,9 @@ int mbedtls_gcm_self_test( int verbose ) if( ret != 0 ) goto exit; - if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || - memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + if( memcmp( buf, ct_test_data[j * 6 + i], + pt_len_test_data[i] ) != 0 || + memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) { ret = 1; goto exit; @@ -949,32 +926,38 @@ int mbedtls_gcm_self_test( int verbose ) mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" ); - ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], + ret = mbedtls_gcm_setkey( &ctx, cipher, + key_test_data[key_index_test_data[i]], key_len ); if( ret != 0 ) goto exit; ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, - iv[iv_index[i]], iv_len[i], - additional[add_index[i]], add_len[i] ); + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i] ); if( ret != 0 ) goto exit; - if( pt_len[i] > 32 ) + if( pt_len_test_data[i] > 32 ) { - size_t rest_len = pt_len[i] - 32; - ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); + size_t rest_len = pt_len_test_data[i] - 32; + ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i], + buf ); if( ret != 0 ) goto exit; - ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, + ret = mbedtls_gcm_update( &ctx, rest_len, + ct_test_data[j * 6 + i] + 32, buf + 32 ); if( ret != 0 ) goto exit; } else { - ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], + ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i], + ct_test_data[j * 6 + i], buf ); if( ret != 0 ) goto exit; @@ -984,8 +967,9 @@ int mbedtls_gcm_self_test( int verbose ) if( ret != 0 ) goto exit; - if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || - memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + if( memcmp( buf, pt_test_data[pt_index_test_data[i]], + pt_len_test_data[i] ) != 0 || + memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) { ret = 1; goto exit; |