early-access version 1503
This commit is contained in:
159
externals/mbedtls/library/dhm.c
vendored
159
externals/mbedtls/library/dhm.c
vendored
@@ -1,8 +1,31 @@
|
||||
/*
|
||||
* Diffie-Hellman-Merkle key exchange
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* 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:
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* 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
|
||||
@@ -18,7 +41,7 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
* **********
|
||||
*/
|
||||
/*
|
||||
* The following sources were referenced in the design of this implementation
|
||||
@@ -62,6 +85,11 @@
|
||||
|
||||
#if !defined(MBEDTLS_DHM_ALT)
|
||||
|
||||
#define DHM_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
|
||||
#define DHM_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/*
|
||||
* helper to validate the mbedtls_mpi size and import it
|
||||
*/
|
||||
@@ -123,6 +151,7 @@ cleanup:
|
||||
|
||||
void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
|
||||
{
|
||||
DHM_VALIDATE( ctx != NULL );
|
||||
memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
|
||||
}
|
||||
|
||||
@@ -134,6 +163,9 @@ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
|
||||
const unsigned char *end )
|
||||
{
|
||||
int ret;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( p != NULL && *p != NULL );
|
||||
DHM_VALIDATE_RET( end != NULL );
|
||||
|
||||
if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
|
||||
( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
|
||||
@@ -159,6 +191,10 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
|
||||
int ret, count = 0;
|
||||
size_t n1, n2, n3;
|
||||
unsigned char *p;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( output != NULL );
|
||||
DHM_VALIDATE_RET( olen != NULL );
|
||||
DHM_VALIDATE_RET( f_rng != NULL );
|
||||
|
||||
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
@@ -229,9 +265,9 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
|
||||
const mbedtls_mpi *G )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ctx == NULL || P == NULL || G == NULL )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( P != NULL );
|
||||
DHM_VALIDATE_RET( G != NULL );
|
||||
|
||||
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
|
||||
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
|
||||
@@ -250,8 +286,10 @@ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
|
||||
const unsigned char *input, size_t ilen )
|
||||
{
|
||||
int ret;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( input != NULL );
|
||||
|
||||
if( ctx == NULL || ilen < 1 || ilen > ctx->len )
|
||||
if( ilen < 1 || ilen > ctx->len )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
|
||||
@@ -269,8 +307,11 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
|
||||
void *p_rng )
|
||||
{
|
||||
int ret, count = 0;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( output != NULL );
|
||||
DHM_VALIDATE_RET( f_rng != NULL );
|
||||
|
||||
if( ctx == NULL || olen < 1 || olen > ctx->len )
|
||||
if( olen < 1 || olen > ctx->len )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
|
||||
@@ -307,6 +348,32 @@ cleanup:
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Pick a random R in the range [2, M) for blinding purposes
|
||||
*/
|
||||
static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret, count;
|
||||
|
||||
count = 0;
|
||||
do
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
|
||||
|
||||
while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
|
||||
|
||||
if( count++ > 10 )
|
||||
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
|
||||
}
|
||||
while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 );
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Use the blinding method and optimisation suggested in section 10 of:
|
||||
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
|
||||
@@ -316,7 +383,10 @@ cleanup:
|
||||
static int dhm_update_blinding( mbedtls_dhm_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret, count;
|
||||
int ret;
|
||||
mbedtls_mpi R;
|
||||
|
||||
mbedtls_mpi_init( &R );
|
||||
|
||||
/*
|
||||
* Don't use any blinding the first time a particular X is used,
|
||||
@@ -351,24 +421,23 @@ static int dhm_update_blinding( mbedtls_dhm_context *ctx,
|
||||
*/
|
||||
|
||||
/* Vi = random( 2, P-1 ) */
|
||||
count = 0;
|
||||
do
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
|
||||
|
||||
while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
|
||||
/* Vf = Vi^-X mod P
|
||||
* First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
|
||||
* then elevate to the Xth power. */
|
||||
MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||
|
||||
if( count++ > 10 )
|
||||
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
|
||||
}
|
||||
while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
|
||||
|
||||
/* Vf = Vi^-X mod P */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free( &R );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
@@ -382,8 +451,11 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
|
||||
{
|
||||
int ret;
|
||||
mbedtls_mpi GYb;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( output != NULL );
|
||||
DHM_VALIDATE_RET( olen != NULL );
|
||||
|
||||
if( ctx == NULL || output_size < ctx->len )
|
||||
if( output_size < ctx->len )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
|
||||
@@ -430,11 +502,19 @@ cleanup:
|
||||
*/
|
||||
void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
|
||||
{
|
||||
mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf );
|
||||
mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP );
|
||||
mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
|
||||
mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X );
|
||||
mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->P );
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
mbedtls_mpi_free( &ctx->pX );
|
||||
mbedtls_mpi_free( &ctx->Vf );
|
||||
mbedtls_mpi_free( &ctx->Vi );
|
||||
mbedtls_mpi_free( &ctx->RP );
|
||||
mbedtls_mpi_free( &ctx->K );
|
||||
mbedtls_mpi_free( &ctx->GY );
|
||||
mbedtls_mpi_free( &ctx->GX );
|
||||
mbedtls_mpi_free( &ctx->X );
|
||||
mbedtls_mpi_free( &ctx->G );
|
||||
mbedtls_mpi_free( &ctx->P );
|
||||
|
||||
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
|
||||
}
|
||||
@@ -451,7 +531,12 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
|
||||
unsigned char *p, *end;
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pem_context pem;
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
|
||||
DHM_VALIDATE_RET( dhm != NULL );
|
||||
DHM_VALIDATE_RET( dhmin != NULL );
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pem_init( &pem );
|
||||
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
@@ -598,6 +683,8 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
|
||||
int ret;
|
||||
size_t n;
|
||||
unsigned char *buf;
|
||||
DHM_VALIDATE_RET( dhm != NULL );
|
||||
DHM_VALIDATE_RET( path != NULL );
|
||||
|
||||
if( ( ret = load_file( path, &buf, &n ) ) != 0 )
|
||||
return( ret );
|
||||
@@ -615,12 +702,28 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
static const char mbedtls_test_dhm_params[] =
|
||||
"-----BEGIN DH PARAMETERS-----\r\n"
|
||||
"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
|
||||
"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
|
||||
"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
|
||||
"-----END DH PARAMETERS-----\r\n";
|
||||
#else /* MBEDTLS_PEM_PARSE_C */
|
||||
static const char mbedtls_test_dhm_params[] = {
|
||||
0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
|
||||
0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
|
||||
0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
|
||||
0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
|
||||
0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
|
||||
0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
|
||||
0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
|
||||
0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
|
||||
0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
|
||||
0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
|
||||
0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
|
||||
0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
|
||||
static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
|
||||
|
||||
|
Reference in New Issue
Block a user