mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-25 17:35:37 +01:00
3b0c430638
This is done to account for platforms, for which we want custom behavior upon the program termination, hence we call `mbedtls_exit()` instead of returning from `main()`. For the sake of consistency, introduces the modifications have been made to the test and utility examples as well. These, while less likely to be used in the low level environments, won't suffer from such a change.
245 lines
7.1 KiB
C
245 lines
7.1 KiB
C
/*
|
|
* Example ECDHE with Curve25519 program
|
|
*
|
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
|
* 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.
|
|
* 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.
|
|
*
|
|
* This file is part of mbed TLS (https://tls.mbed.org)
|
|
*/
|
|
|
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
|
#include "mbedtls/config.h"
|
|
#else
|
|
#include MBEDTLS_CONFIG_FILE
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_PLATFORM_C)
|
|
#include "mbedtls/platform.h"
|
|
#else
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#define mbedtls_printf printf
|
|
#define mbedtls_exit exit
|
|
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
|
|
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
|
|
#endif /* MBEDTLS_PLATFORM_C */
|
|
|
|
#if !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) || \
|
|
!defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
|
|
!defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
|
|
int main( void )
|
|
{
|
|
mbedtls_printf( "MBEDTLS_ECDH_C and/or MBEDTLS_ECDH_LEGACY_CONTEXT and/or "
|
|
"MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
|
|
"MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
|
|
"not defined\n" );
|
|
mbedtls_exit( 0 );
|
|
}
|
|
#else
|
|
|
|
#include "mbedtls/entropy.h"
|
|
#include "mbedtls/ctr_drbg.h"
|
|
#include "mbedtls/ecdh.h"
|
|
|
|
|
|
int main( int argc, char *argv[] )
|
|
{
|
|
int ret = 1;
|
|
int exit_code = MBEDTLS_EXIT_FAILURE;
|
|
mbedtls_ecdh_context ctx_cli, ctx_srv;
|
|
mbedtls_entropy_context entropy;
|
|
mbedtls_ctr_drbg_context ctr_drbg;
|
|
unsigned char cli_to_srv[32], srv_to_cli[32];
|
|
const char pers[] = "ecdh";
|
|
((void) argc);
|
|
((void) argv);
|
|
|
|
mbedtls_ecdh_init( &ctx_cli );
|
|
mbedtls_ecdh_init( &ctx_srv );
|
|
mbedtls_ctr_drbg_init( &ctr_drbg );
|
|
|
|
/*
|
|
* Initialize random number generation
|
|
*/
|
|
mbedtls_printf( " . Seeding the random number generator..." );
|
|
fflush( stdout );
|
|
|
|
mbedtls_entropy_init( &entropy );
|
|
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
|
|
(const unsigned char *) pers,
|
|
sizeof pers ) ) != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
mbedtls_printf( " ok\n" );
|
|
|
|
/*
|
|
* Client: inialize context and generate keypair
|
|
*/
|
|
mbedtls_printf( " . Setting up client context..." );
|
|
fflush( stdout );
|
|
|
|
ret = mbedtls_ecp_group_load( &ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519 );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
ret = mbedtls_ecdh_gen_public( &ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q,
|
|
mbedtls_ctr_drbg_random, &ctr_drbg );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
ret = mbedtls_mpi_write_binary( &ctx_cli.Q.X, cli_to_srv, 32 );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
mbedtls_printf( " ok\n" );
|
|
|
|
/*
|
|
* Server: initialize context and generate keypair
|
|
*/
|
|
mbedtls_printf( " . Setting up server context..." );
|
|
fflush( stdout );
|
|
|
|
ret = mbedtls_ecp_group_load( &ctx_srv.grp, MBEDTLS_ECP_DP_CURVE25519 );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
ret = mbedtls_ecdh_gen_public( &ctx_srv.grp, &ctx_srv.d, &ctx_srv.Q,
|
|
mbedtls_ctr_drbg_random, &ctr_drbg );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
ret = mbedtls_mpi_write_binary( &ctx_srv.Q.X, srv_to_cli, 32 );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
mbedtls_printf( " ok\n" );
|
|
|
|
/*
|
|
* Server: read peer's key and generate shared secret
|
|
*/
|
|
mbedtls_printf( " . Server reading client key and computing secret..." );
|
|
fflush( stdout );
|
|
|
|
ret = mbedtls_mpi_lset( &ctx_srv.Qp.Z, 1 );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
ret = mbedtls_mpi_read_binary( &ctx_srv.Qp.X, cli_to_srv, 32 );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
ret = mbedtls_ecdh_compute_shared( &ctx_srv.grp, &ctx_srv.z,
|
|
&ctx_srv.Qp, &ctx_srv.d,
|
|
mbedtls_ctr_drbg_random, &ctr_drbg );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
mbedtls_printf( " ok\n" );
|
|
|
|
/*
|
|
* Client: read peer's key and generate shared secret
|
|
*/
|
|
mbedtls_printf( " . Client reading server key and computing secret..." );
|
|
fflush( stdout );
|
|
|
|
ret = mbedtls_mpi_lset( &ctx_cli.Qp.Z, 1 );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
ret = mbedtls_mpi_read_binary( &ctx_cli.Qp.X, srv_to_cli, 32 );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
ret = mbedtls_ecdh_compute_shared( &ctx_cli.grp, &ctx_cli.z,
|
|
&ctx_cli.Qp, &ctx_cli.d,
|
|
mbedtls_ctr_drbg_random, &ctr_drbg );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
mbedtls_printf( " ok\n" );
|
|
|
|
/*
|
|
* Verification: are the computed secrets equal?
|
|
*/
|
|
mbedtls_printf( " . Checking if both computed secrets are equal..." );
|
|
fflush( stdout );
|
|
|
|
ret = mbedtls_mpi_cmp_mpi( &ctx_cli.z, &ctx_srv.z );
|
|
if( ret != 0 )
|
|
{
|
|
mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
mbedtls_printf( " ok\n" );
|
|
|
|
exit_code = MBEDTLS_EXIT_SUCCESS;
|
|
|
|
exit:
|
|
|
|
#if defined(_WIN32)
|
|
mbedtls_printf( " + Press Enter to exit this program.\n" );
|
|
fflush( stdout ); getchar();
|
|
#endif
|
|
|
|
mbedtls_ecdh_free( &ctx_srv );
|
|
mbedtls_ecdh_free( &ctx_cli );
|
|
mbedtls_ctr_drbg_free( &ctr_drbg );
|
|
mbedtls_entropy_free( &entropy );
|
|
|
|
mbedtls_exit( exit_code );
|
|
}
|
|
#endif /* MBEDTLS_ECDH_C && MBEDTLS_ECP_DP_CURVE25519_ENABLED &&
|
|
MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
|