ecdsa works. added error handling

This commit is contained in:
merlokk 2018-11-07 16:55:23 +02:00
commit 7d60dcab7d
13 changed files with 3292 additions and 24 deletions

View file

@ -23,6 +23,8 @@
#include "mbedtls/x509.h"
#include "mbedtls/base64.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
#include "mbedtls/timing.h"
#include "crypto_test.h"
#include "sda_test.h"
@ -56,6 +58,12 @@ return 0;
res = mbedtls_rsa_self_test(verbose);
if (res) TestFail = true;
res = mbedtls_entropy_self_test(verbose);
if (res) TestFail = true;
res = mbedtls_timing_self_test(verbose);
if (res) TestFail = true;
res = mbedtls_ctr_drbg_self_test(verbose);
if (res) TestFail = true;

View file

@ -7,6 +7,10 @@ mbedtls_SOURCES = \
base64.c \
bignum.c \
ctr_drbg.c \
entropy_poll.c \
entropy.c \
error.c \
timing.c \
ecp.c \
ecp_curves.c \
certs.c \

View file

@ -735,7 +735,7 @@
* See dhm.h for more details.
*
*/
#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
/**
* \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
@ -841,7 +841,7 @@
* See dhm.h for more details.
*
*/
#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
/**
* \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
@ -1414,7 +1414,7 @@
*
* Comment this to disable anti-replay in DTLS.
*/
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
/**
* \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
@ -1459,7 +1459,7 @@
*
* Requires: MBEDTLS_SSL_PROTO_DTLS
*/
#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
//#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
/**
* \def MBEDTLS_SSL_SESSION_TICKETS
@ -2093,7 +2093,7 @@
* See dhm.h for more details.
*
*/
#define MBEDTLS_DHM_C
//#define MBEDTLS_DHM_C
/**
* \def MBEDTLS_ECDH_C
@ -2235,7 +2235,7 @@
* This module adds support for the Hashed Message Authentication Code
* (HMAC)-based key derivation function (HKDF).
*/
#define MBEDTLS_HKDF_C
//#define MBEDTLS_HKDF_C
/**
* \def MBEDTLS_HMAC_DRBG_C
@ -2249,7 +2249,7 @@
*
* Uncomment to enable the HMAC_DRBG random number geerator.
*/
#define MBEDTLS_HMAC_DRBG_C
//#define MBEDTLS_HMAC_DRBG_C
/**
* \def MBEDTLS_NIST_KW_C
@ -2365,7 +2365,7 @@
*
* This module provides networking routines.
*/
#define MBEDTLS_NET_C
//#define MBEDTLS_NET_C
/**
* \def MBEDTLS_OID_C
@ -2555,7 +2555,7 @@
* Module: library/poly1305.c
* Caller: library/chachapoly.c
*/
#define MBEDTLS_POLY1305_C
//#define MBEDTLS_POLY1305_C
/**
* \def MBEDTLS_RIPEMD160_C
@ -2687,7 +2687,7 @@
*
* This module is required for SSL/TLS client support.
*/
#define MBEDTLS_SSL_CLI_C
//#define MBEDTLS_SSL_CLI_C
/**
* \def MBEDTLS_SSL_SRV_C
@ -2701,7 +2701,7 @@
*
* This module is required for SSL/TLS server support.
*/
#define MBEDTLS_SSL_SRV_C
//#define MBEDTLS_SSL_SRV_C
/**
* \def MBEDTLS_SSL_TLS_C
@ -2717,7 +2717,7 @@
*
* This module is required for SSL/TLS.
*/
#define MBEDTLS_SSL_TLS_C
//#define MBEDTLS_SSL_TLS_C
/**
* \def MBEDTLS_THREADING_C
@ -2883,7 +2883,7 @@
* Module: library/xtea.c
* Caller:
*/
#define MBEDTLS_XTEA_C
//#define MBEDTLS_XTEA_C
/* \} name SECTION: mbed TLS modules */

723
common/mbedtls/entropy.c Normal file
View file

@ -0,0 +1,723 @@
/*
* Entropy accumulator implementation
*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* 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.
*
* 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_ENTROPY_C)
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
#warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! "
#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES "
#warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE "
#endif
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
#include "mbedtls/platform_util.h"
#include <string.h>
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
#include "mbedtls/platform.h"
#endif
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if defined(MBEDTLS_HAVEGE_C)
#include "mbedtls/havege.h"
#endif
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
{
ctx->source_count = 0;
memset( ctx->source, 0, sizeof( ctx->source ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
ctx->accumulator_started = 0;
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_init( &ctx->accumulator );
#else
mbedtls_sha256_init( &ctx->accumulator );
#endif
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_init( &ctx->havege_data );
#endif
/* Reminder: Update ENTROPY_HAVE_STRONG in the test files
* when adding more strong entropy sources here. */
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
1, MBEDTLS_ENTROPY_SOURCE_STRONG );
#endif
#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
MBEDTLS_ENTROPY_MIN_PLATFORM,
MBEDTLS_ENTROPY_SOURCE_STRONG );
#endif
#if defined(MBEDTLS_TIMING_C)
mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
MBEDTLS_ENTROPY_MIN_HARDCLOCK,
MBEDTLS_ENTROPY_SOURCE_WEAK );
#endif
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data,
MBEDTLS_ENTROPY_MIN_HAVEGE,
MBEDTLS_ENTROPY_SOURCE_STRONG );
#endif
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
MBEDTLS_ENTROPY_MIN_HARDWARE,
MBEDTLS_ENTROPY_SOURCE_STRONG );
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
MBEDTLS_ENTROPY_BLOCK_SIZE,
MBEDTLS_ENTROPY_SOURCE_STRONG );
ctx->initial_entropy_run = 0;
#endif
#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
}
void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
{
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_free( &ctx->havege_data );
#endif
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &ctx->mutex );
#endif
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_free( &ctx->accumulator );
#else
mbedtls_sha256_free( &ctx->accumulator );
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
ctx->initial_entropy_run = 0;
#endif
ctx->source_count = 0;
mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
ctx->accumulator_started = 0;
}
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
mbedtls_entropy_f_source_ptr f_source, void *p_source,
size_t threshold, int strong )
{
int idx, ret = 0;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif
idx = ctx->source_count;
if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES )
{
ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
goto exit;
}
ctx->source[idx].f_source = f_source;
ctx->source[idx].p_source = p_source;
ctx->source[idx].threshold = threshold;
ctx->source[idx].strong = strong;
ctx->source_count++;
exit:
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
}
/*
* Entropy accumulator update
*/
static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id,
const unsigned char *data, size_t len )
{
unsigned char header[2];
unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
size_t use_len = len;
const unsigned char *p = data;
int ret = 0;
if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
{
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 )
goto cleanup;
#else
if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 )
goto cleanup;
#endif
p = tmp;
use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
}
header[0] = source_id;
header[1] = use_len & 0xFF;
/*
* Start the accumulator if this has not already happened. Note that
* it is sufficient to start the accumulator here only because all calls to
* gather entropy eventually execute this code.
*/
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
if( ctx->accumulator_started == 0 &&
( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
goto cleanup;
else
ctx->accumulator_started = 1;
if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
goto cleanup;
ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len );
#else
if( ctx->accumulator_started == 0 &&
( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
goto cleanup;
else
ctx->accumulator_started = 1;
if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
goto cleanup;
ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len );
#endif
cleanup:
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
return( ret );
}
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len )
{
int ret;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif
ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len );
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
}
/*
* Run through the different sources to add entropy to our accumulator
*/
static int entropy_gather_internal( mbedtls_entropy_context *ctx )
{
int ret, i, have_one_strong = 0;
unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
size_t olen;
if( ctx->source_count == 0 )
return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
/*
* Run through our entropy sources
*/
for( i = 0; i < ctx->source_count; i++ )
{
if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
have_one_strong = 1;
olen = 0;
if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 )
{
goto cleanup;
}
/*
* Add if we actually gathered something
*/
if( olen > 0 )
{
if( ( ret = entropy_update( ctx, (unsigned char) i,
buf, olen ) ) != 0 )
return( ret );
ctx->source[i].size += olen;
}
}
if( have_one_strong == 0 )
ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
return( ret );
}
/*
* Thread-safe wrapper for entropy_gather_internal()
*/
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
{
int ret;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif
ret = entropy_gather_internal( ctx );
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
}
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
{
int ret, count = 0, i, done;
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
#if defined(MBEDTLS_ENTROPY_NV_SEED)
/* Update the NV entropy seed before generating any entropy for outside
* use.
*/
if( ctx->initial_entropy_run == 0 )
{
ctx->initial_entropy_run = 1;
if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 )
return( ret );
}
#endif
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif
/*
* Always gather extra entropy before a call
*/
do
{
if( count++ > ENTROPY_MAX_LOOP )
{
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
goto exit;
}
if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
goto exit;
done = 1;
for( i = 0; i < ctx->source_count; i++ )
if( ctx->source[i].size < ctx->source[i].threshold )
done = 0;
}
while( ! done );
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
/*
* Note that at this stage it is assumed that the accumulator was started
* in a previous call to entropy_update(). If this is not guaranteed, the
* code below will fail.
*/
if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 )
goto exit;
/*
* Reset accumulator and counters and recycle existing entropy
*/
mbedtls_sha512_free( &ctx->accumulator );
mbedtls_sha512_init( &ctx->accumulator );
if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
goto exit;
if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf,
MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
goto exit;
/*
* Perform second SHA-512 on entropy
*/
if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
buf, 0 ) ) != 0 )
goto exit;
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 )
goto exit;
/*
* Reset accumulator and counters and recycle existing entropy
*/
mbedtls_sha256_free( &ctx->accumulator );
mbedtls_sha256_init( &ctx->accumulator );
if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
goto exit;
if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf,
MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
goto exit;
/*
* Perform second SHA-256 on entropy
*/
if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
buf, 0 ) ) != 0 )
goto exit;
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
for( i = 0; i < ctx->source_count; i++ )
ctx->source[i].size = 0;
memcpy( output, buf, len );
ret = 0;
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
}
#if defined(MBEDTLS_ENTROPY_NV_SEED)
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
{
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
/* Read new seed and write it to NV */
if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
return( ret );
if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
/* Manually update the remaining stream with a separator value to diverge */
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
return( ret );
}
#endif /* MBEDTLS_ENTROPY_NV_SEED */
#if defined(MBEDTLS_FS_IO)
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
{
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
FILE *f;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
if( ( f = fopen( path, "wb" ) ) == NULL )
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
goto exit;
if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
{
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
goto exit;
}
ret = 0;
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
fclose( f );
return( ret );
}
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path )
{
int ret = 0;
FILE *f;
size_t n;
unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
fseek( f, 0, SEEK_END );
n = (size_t) ftell( f );
fseek( f, 0, SEEK_SET );
if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE )
n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
if( fread( buf, 1, n, f ) != n )
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
else
ret = mbedtls_entropy_update_manual( ctx, buf, n );
fclose( f );
mbedtls_platform_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( mbedtls_entropy_write_seed_file( ctx, path ) );
}
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
/*
* Dummy source function
*/
static int entropy_dummy_source( void *data, unsigned char *output,
size_t len, size_t *olen )
{
((void) data);
memset( output, 0x2a, len );
*olen = len;
return( 0 );
}
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len )
{
int ret = 0;
size_t entropy_len = 0;
size_t olen = 0;
size_t attempts = buf_len;
while( attempts > 0 && entropy_len < buf_len )
{
if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len,
buf_len - entropy_len, &olen ) ) != 0 )
return( ret );
entropy_len += olen;
attempts--;
}
if( entropy_len < buf_len )
{
ret = 1;
}
return( ret );
}
static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf,
size_t buf_len )
{
unsigned char set= 0xFF;
unsigned char unset = 0x00;
size_t i;
for( i = 0; i < buf_len; i++ )
{
set &= buf[i];
unset |= buf[i];
}
return( set == 0xFF || unset == 0x00 );
}
/*
* A test to ensure hat the entropy sources are functioning correctly
* and there is no obvious failure. The test performs the following checks:
* - The entropy source is not providing only 0s (all bits unset) or 1s (all
* bits set).
* - The entropy source is not providing values in a pattern. Because the
* hardware could be providing data in an arbitrary length, this check polls
* the hardware entropy source twice and compares the result to ensure they
* are not equal.
* - The error code returned by the entropy source is not an error.
*/
int mbedtls_entropy_source_self_test( int verbose )
{
int ret = 0;
unsigned char buf0[2 * sizeof( unsigned long long int )];
unsigned char buf1[2 * sizeof( unsigned long long int )];
if( verbose != 0 )
mbedtls_printf( " ENTROPY_BIAS test: " );
memset( buf0, 0x00, sizeof( buf0 ) );
memset( buf1, 0x00, sizeof( buf1 ) );
if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 )
goto cleanup;
/* Make sure that the returned values are not all 0 or 1 */
if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 )
goto cleanup;
/* Make sure that the entropy source is not returning values in a
* pattern */
ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0;
cleanup:
if( verbose != 0 )
{
if( ret != 0 )
mbedtls_printf( "failed\n" );
else
mbedtls_printf( "passed\n" );
mbedtls_printf( "\n" );
}
return( ret != 0 );
}
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
/*
* The actual entropy quality is hard to test, but we can at least
* test that the functions don't cause errors and write the correct
* amount of data to buffers.
*/
int mbedtls_entropy_self_test( int verbose )
{
int ret = 1;
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
mbedtls_entropy_context ctx;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
size_t i, j;
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
if( verbose != 0 )
mbedtls_printf( " ENTROPY test: " );
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
mbedtls_entropy_init( &ctx );
/* First do a gather to make sure we have default sources */
if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 )
goto cleanup;
ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16,
MBEDTLS_ENTROPY_SOURCE_WEAK );
if( ret != 0 )
goto cleanup;
if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 )
goto cleanup;
/*
* To test that mbedtls_entropy_func writes correct number of bytes:
* - use the whole buffer and rely on ASan to detect overruns
* - collect entropy 8 times and OR the result in an accumulator:
* any byte should then be 0 with probably 2^(-64), so requiring
* each of the 32 or 64 bytes to be non-zero has a false failure rate
* of at most 2^(-58) which is acceptable.
*/
for( i = 0; i < 8; i++ )
{
if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 )
goto cleanup;
for( j = 0; j < sizeof( buf ); j++ )
acc[j] |= buf[j];
}
for( j = 0; j < sizeof( buf ); j++ )
{
if( acc[j] == 0 )
{
ret = 1;
goto cleanup;
}
}
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 )
goto cleanup;
#endif
cleanup:
mbedtls_entropy_free( &ctx );
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
if( verbose != 0 )
{
if( ret != 0 )
mbedtls_printf( "failed\n" );
else
mbedtls_printf( "passed\n" );
mbedtls_printf( "\n" );
}
return( ret != 0 );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_ENTROPY_C */

291
common/mbedtls/entropy.h Normal file
View file

@ -0,0 +1,291 @@
/**
* \file entropy.h
*
* \brief Entropy accumulator implementation
*/
/*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* 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.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ENTROPY_H
#define MBEDTLS_ENTROPY_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#include "sha512.h"
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#else
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
#include "sha256.h"
#endif
#endif
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
#include "havege.h"
#endif
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */
#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */
#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D /**< No strong sources have been added to poll. */
#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F /**< Read/write error in file. */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES)
#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
#endif
#if !defined(MBEDTLS_ENTROPY_MAX_GATHER)
#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
#endif
/* \} name SECTION: Module settings */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
#else
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */
#endif
#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */
#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES
#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */
#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Entropy poll callback pointer
*
* \param data Callback-specific data pointer
* \param output Data to fill
* \param len Maximum size to provide
* \param olen The actual amount of bytes put into the buffer (Can be 0)
*
* \return 0 if no critical failures occurred,
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise
*/
typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
size_t *olen);
/**
* \brief Entropy source state
*/
typedef struct mbedtls_entropy_source_state
{
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */
void * p_source; /**< The callback data pointer */
size_t size; /**< Amount received in bytes */
size_t threshold; /**< Minimum bytes required before release */
int strong; /**< Is the source strong? */
}
mbedtls_entropy_source_state;
/**
* \brief Entropy context structure
*/
typedef struct mbedtls_entropy_context
{
int accumulator_started;
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_context accumulator;
#else
mbedtls_sha256_context accumulator;
#endif
int source_count;
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES];
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_state havege_data;
#endif
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex; /*!< mutex */
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
int initial_entropy_run;
#endif
}
mbedtls_entropy_context;
/**
* \brief Initialize the context
*
* \param ctx Entropy context to initialize
*/
void mbedtls_entropy_init( mbedtls_entropy_context *ctx );
/**
* \brief Free the data in the context
*
* \param ctx Entropy context to free
*/
void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
/**
* \brief Adds an entropy source to poll
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
* \param f_source Entropy function
* \param p_source Function data
* \param threshold Minimum required from source before entropy is released
* ( with mbedtls_entropy_func() ) (in bytes)
* \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or
* MBEDTLS_ENTROPY_SOURCE_WEAK.
* At least one strong source needs to be added.
* Weaker sources (such as the cycle counter) can be used as
* a complement.
*
* \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES
*/
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
mbedtls_entropy_f_source_ptr f_source, void *p_source,
size_t threshold, int strong );
/**
* \brief Trigger an extra gather poll for the accumulator
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
*
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx );
/**
* \brief Retrieve entropy from the accumulator
* (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE)
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param data Entropy context
* \param output Buffer to fill
* \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE
*
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len );
/**
* \brief Add data to the accumulator manually
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
* \param data Data to add
* \param len Length of data
*
* \return 0 if successful
*/
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len );
#if defined(MBEDTLS_ENTROPY_NV_SEED)
/**
* \brief Trigger an update of the seed file in NV by using the
* current entropy pool.
*
* \param ctx Entropy context
*
* \return 0 if successful
*/
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx );
#endif /* MBEDTLS_ENTROPY_NV_SEED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief Write a seed file
*
* \param ctx Entropy context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path );
/**
* \brief Read and update a seed file. Seed is added to this
* instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are
* read from the seed file. The rest is ignored.
*
* \param ctx Entropy context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error,
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* This module self-test also calls the entropy self-test,
* mbedtls_entropy_source_self_test();
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_entropy_self_test( int verbose );
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
/**
* \brief Checkup routine
*
* Verifies the integrity of the hardware entropy source
* provided by the function 'mbedtls_hardware_poll()'.
*
* Note this is the only hardware entropy source that is known
* at link time, and other entropy sources configured
* dynamically at runtime by the function
* mbedtls_entropy_add_source() will not be tested.
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_entropy_source_self_test( int verbose );
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* entropy.h */

View file

@ -0,0 +1,277 @@
/*
* Platform-specific and custom entropy polling functions
*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* 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.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if defined(__linux__)
/* Ensure that syscall() is available even when compiling with -std=c99 */
#define _GNU_SOURCE
#endif
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <string.h>
#if defined(MBEDTLS_ENTROPY_C)
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
#if defined(MBEDTLS_TIMING_C)
#include "mbedtls/timing.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
#include "mbedtls/havege.h"
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
#include "mbedtls/platform.h"
#endif
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
!defined(__HAIKU__)
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
#endif
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
#if !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0400
#endif
#include <windows.h>
#include <wincrypt.h>
int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
size_t *olen )
{
HCRYPTPROV provider;
((void) data);
*olen = 0;
if( CryptAcquireContext( &provider, NULL, NULL,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
{
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
}
if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
{
CryptReleaseContext( provider, 0 );
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
}
CryptReleaseContext( provider, 0 );
*olen = len;
return( 0 );
}
#else /* _WIN32 && !EFIX64 && !EFI32 */
/*
* Test for Linux getrandom() support.
* Since there is no wrapper in the libc yet, use the generic syscall wrapper
* available in GNU libc and compatible libc's (eg uClibc).
*/
#if defined(__linux__) && defined(__GLIBC__)
#include <unistd.h>
#include <sys/syscall.h>
#if defined(SYS_getrandom)
#define HAVE_GETRANDOM
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
{
/* MemSan cannot understand that the syscall writes to the buffer */
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
memset( buf, 0, buflen );
#endif
#endif
return( syscall( SYS_getrandom, buf, buflen, flags ) );
}
#include <sys/utsname.h>
/* Check if version is at least 3.17.0 */
static int check_version_3_17_plus( void )
{
int minor;
struct utsname un;
const char *ver;
/* Get version information */
uname(&un);
ver = un.release;
/* Check major version; assume a single digit */
if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
return( -1 );
if( ver[0] - '0' > 3 )
return( 0 );
/* Ok, so now we know major == 3, check minor.
* Assume 1 or 2 digits. */
if( ver[2] < '0' || ver[2] > '9' )
return( -1 );
minor = ver[2] - '0';
if( ver[3] >= '0' && ver[3] <= '9' )
minor = 10 * minor + ver[3] - '0';
else if( ver [3] != '.' )
return( -1 );
if( minor < 17 )
return( -1 );
return( 0 );
}
static int has_getrandom = -1;
#endif /* SYS_getrandom */
#endif /* __linux__ */
#include <stdio.h>
int mbedtls_platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
FILE *file;
size_t read_len;
((void) data);
#if defined(HAVE_GETRANDOM)
if( has_getrandom == -1 )
has_getrandom = ( check_version_3_17_plus() == 0 );
if( has_getrandom )
{
int ret;
if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
*olen = ret;
return( 0 );
}
#endif /* HAVE_GETRANDOM */
*olen = 0;
file = fopen( "/dev/urandom", "rb" );
if( file == NULL )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
read_len = fread( output, 1, len, file );
if( read_len != len )
{
fclose( file );
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
}
fclose( file );
*olen = len;
return( 0 );
}
#endif /* _WIN32 && !EFIX64 && !EFI32 */
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
int mbedtls_null_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
((void) data);
((void) output);
*olen = 0;
if( len < sizeof(unsigned char) )
return( 0 );
*olen = sizeof(unsigned char);
return( 0 );
}
#endif
#if defined(MBEDTLS_TIMING_C)
int mbedtls_hardclock_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
unsigned long timer = mbedtls_timing_hardclock();
((void) data);
*olen = 0;
if( len < sizeof(unsigned long) )
return( 0 );
memcpy( output, &timer, sizeof(unsigned long) );
*olen = sizeof(unsigned long);
return( 0 );
}
#endif /* MBEDTLS_TIMING_C */
#if defined(MBEDTLS_HAVEGE_C)
int mbedtls_havege_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
*olen = 0;
if( mbedtls_havege_random( hs, output, len ) != 0 )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
*olen = len;
return( 0 );
}
#endif /* MBEDTLS_HAVEGE_C */
#if defined(MBEDTLS_ENTROPY_NV_SEED)
int mbedtls_nv_seed_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
((void) data);
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
if( len < use_len )
use_len = len;
memcpy( output, buf, use_len );
*olen = use_len;
return( 0 );
}
#endif /* MBEDTLS_ENTROPY_NV_SEED */
#endif /* MBEDTLS_ENTROPY_C */

View file

@ -0,0 +1,112 @@
/**
* \file entropy_poll.h
*
* \brief Platform-specific and custom entropy polling functions
*/
/*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* 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.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ENTROPY_POLL_H
#define MBEDTLS_ENTROPY_POLL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Default thresholds for built-in sources, in bytes
*/
#define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */
#define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */
#define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */
#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE)
#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */
#endif
/**
* \brief Entropy poll callback that provides 0 entropy.
*/
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
int mbedtls_null_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
/**
* \brief Platform-specific entropy poll callback
*/
int mbedtls_platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_HAVEGE_C)
/**
* \brief HAVEGE based entropy poll callback
*
* Requires an HAVEGE state as its data pointer.
*/
int mbedtls_havege_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_TIMING_C)
/**
* \brief mbedtls_timing_hardclock-based entropy poll callback
*/
int mbedtls_hardclock_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
/**
* \brief Entropy poll callback for a hardware source
*
* \warning This is not provided by mbed TLS!
* See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h.
*
* \note This must accept NULL as its first argument.
*/
int mbedtls_hardware_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
/**
* \brief Entropy poll callback for a non-volatile seed file
*
* \note This must accept NULL as its first argument.
*/
int mbedtls_nv_seed_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#ifdef __cplusplus
}
#endif
#endif /* entropy_poll.h */

897
common/mbedtls/error.c Normal file
View file

@ -0,0 +1,897 @@
/*
* Error message information
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* 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.
*
* 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_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
#include "mbedtls/error.h"
#include <string.h>
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_snprintf snprintf
#define mbedtls_time_t time_t
#endif
#if defined(MBEDTLS_ERROR_C)
#include <stdio.h>
#if defined(MBEDTLS_AES_C)
#include "mbedtls/aes.h"
#endif
#if defined(MBEDTLS_ARC4_C)
#include "mbedtls/arc4.h"
#endif
#if defined(MBEDTLS_ARIA_C)
#include "mbedtls/aria.h"
#endif
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
#endif
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#endif
#if defined(MBEDTLS_BLOWFISH_C)
#include "mbedtls/blowfish.h"
#endif
#if defined(MBEDTLS_CAMELLIA_C)
#include "mbedtls/camellia.h"
#endif
#if defined(MBEDTLS_CCM_C)
#include "mbedtls/ccm.h"
#endif
#if defined(MBEDTLS_CHACHA20_C)
#include "mbedtls/chacha20.h"
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
#endif
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#endif
#if defined(MBEDTLS_CMAC_C)
#include "mbedtls/cmac.h"
#endif
#if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
#endif
#if defined(MBEDTLS_DES_C)
#include "mbedtls/des.h"
#endif
#if defined(MBEDTLS_DHM_C)
#include "mbedtls/dhm.h"
#endif
#if defined(MBEDTLS_ECP_C)
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_ENTROPY_C)
#include "mbedtls/entropy.h"
#endif
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#endif
#if defined(MBEDTLS_HKDF_C)
#include "mbedtls/hkdf.h"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
#endif
#if defined(MBEDTLS_MD_C)
#include "mbedtls/md.h"
#endif
#if defined(MBEDTLS_MD2_C)
#include "mbedtls/md2.h"
#endif
#if defined(MBEDTLS_MD4_C)
#include "mbedtls/md4.h"
#endif
#if defined(MBEDTLS_MD5_C)
#include "mbedtls/md5.h"
#endif
#if defined(MBEDTLS_NET_C)
#include "mbedtls/net_sockets.h"
#endif
#if defined(MBEDTLS_OID_C)
#include "mbedtls/oid.h"
#endif
#if defined(MBEDTLS_PADLOCK_C)
#include "mbedtls/padlock.h"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
#endif
#if defined(MBEDTLS_PK_C)
#include "mbedtls/pk.h"
#endif
#if defined(MBEDTLS_PKCS12_C)
#include "mbedtls/pkcs12.h"
#endif
#if defined(MBEDTLS_PKCS5_C)
#include "mbedtls/pkcs5.h"
#endif
#if defined(MBEDTLS_POLY1305_C)
#include "mbedtls/poly1305.h"
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#include "mbedtls/ripemd160.h"
#endif
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#endif
#if defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
#include "mbedtls/sha512.h"
#endif
#if defined(MBEDTLS_SSL_TLS_C)
#include "mbedtls/ssl.h"
#endif
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
#include "mbedtls/x509.h"
#endif
#if defined(MBEDTLS_XTEA_C)
#include "mbedtls/xtea.h"
#endif
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
size_t len;
int use_ret;
if( buflen == 0 )
return;
memset( buf, 0x00, buflen );
if( ret < 0 )
ret = -ret;
if( ret & 0xFF80 )
{
use_ret = ret & 0xFF80;
// High level error codes
//
// BEGIN generated code
#if defined(MBEDTLS_CIPHER_C)
if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" );
#endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_DHM_C)
if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" );
if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" );
if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) )
mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" );
#endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_ECP_C)
if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "ECP - The requested feature is not available, for example, the requested curve is not supported" );
if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as ephemeral key, failed" );
if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" );
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C)
if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" );
if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" );
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" );
if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) )
mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" );
if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" );
if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) )
mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) )
mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) )
mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" );
if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" );
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
#if defined(MBEDTLS_PK_C)
if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" );
if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) )
mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" );
if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" );
if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) )
mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) )
mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" );
if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" );
if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) )
mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) )
mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) )
mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" );
#endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_PKCS12_C)
if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS12_C */
#if defined(MBEDTLS_PKCS5_C)
if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) )
mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS5_C */
#if defined(MBEDTLS_RSA_C)
if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) )
mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" );
if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" );
if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) )
mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) )
mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" );
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SSL_TLS_C)
if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) )
mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) )
mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) )
mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) )
mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" );
if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) )
mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) )
mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" );
if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) )
mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) )
mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) )
mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) )
mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" );
if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) )
mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) )
mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) )
{
mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
return;
}
if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) )
mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) )
mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) )
mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) )
mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" );
if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) )
mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) )
mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" );
if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) )
mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) )
mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) )
mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" );
if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
mbedtls_snprintf( buf, buflen, "SSL - No data of requested type currently available on underlying transport" );
if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) )
mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" );
if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) )
mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" );
if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) )
mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" );
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) )
mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) )
mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" );
if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) )
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) )
mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) )
mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) )
mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) )
mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) )
mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) )
mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) )
mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) )
mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) )
mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" );
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) )
mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) )
mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) )
mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) )
mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "X509 - Input invalid" );
if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" );
if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) )
mbedtls_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" );
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
// END generated code
if( strlen( buf ) == 0 )
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}
use_ret = ret & ~0xFF80;
if( use_ret == 0 )
return;
// If high level code is present, make a concatenation between both
// error strings.
//
len = strlen( buf );
if( len > 0 )
{
if( buflen - len < 5 )
return;
mbedtls_snprintf( buf + len, buflen - len, " : " );
buf += len + 3;
buflen -= len + 3;
}
// Low level error codes
//
// BEGIN generated code
#if defined(MBEDTLS_AES_C)
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_AES_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "AES - Invalid input data" );
if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" );
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_ARC4_C)
if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
#endif /* MBEDTLS_ARC4_C */
#if defined(MBEDTLS_ARIA_C)
if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "ARIA - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "ARIA - Feature not available. For example, an unsupported ARIA key size" );
if( use_ret == -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ARIA - ARIA hardware accelerator failed" );
#endif /* MBEDTLS_ARIA_C */
#if defined(MBEDTLS_ASN1_PARSE_C)
if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) )
mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) )
mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
#endif /* MBEDTLS_ASN1_PARSE_C */
#if defined(MBEDTLS_BASE64_C)
if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" );
if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) )
mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" );
#endif /* MBEDTLS_BASE64_C */
#if defined(MBEDTLS_BIGNUM_C)
if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) )
mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) )
mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) )
mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) )
mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_BLOWFISH_C)
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
#endif /* MBEDTLS_BLOWFISH_C */
#if defined(MBEDTLS_CAMELLIA_C)
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" );
#endif /* MBEDTLS_CAMELLIA_C */
#if defined(MBEDTLS_CCM_C)
if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" );
if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" );
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHA20_C)
if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" );
if( use_ret == -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "CHACHA20 - Feature not available. For example, s part of the API is not implemented" );
if( use_ret == -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CHACHA20 - Chacha20 hardware accelerator failed" );
#endif /* MBEDTLS_CHACHA20_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) )
mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" );
if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Authenticated decryption failed: data was not authentic" );
#endif /* MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_CMAC_C)
if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" );
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_CTR_DRBG_C)
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" );
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" );
#endif /* MBEDTLS_CTR_DRBG_C */
#if defined(MBEDTLS_DES_C)
if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" );
#endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_ENTROPY_C)
if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) )
mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) )
mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) )
mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) )
mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" );
if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" );
#endif /* MBEDTLS_ENTROPY_C */
#if defined(MBEDTLS_GCM_C)
if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_HKDF_C)
if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" );
#endif /* MBEDTLS_HKDF_C */
#if defined(MBEDTLS_HMAC_DRBG_C)
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" );
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" );
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
#endif /* MBEDTLS_HMAC_DRBG_C */
#if defined(MBEDTLS_MD2_C)
if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" );
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" );
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" );
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_NET_C)
if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" );
if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" );
if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" );
if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" );
if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) )
mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" );
if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) )
mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) )
mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" );
if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "NET - Input invalid" );
#endif /* MBEDTLS_NET_C */
#if defined(MBEDTLS_OID_C)
if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) )
mbedtls_snprintf( buf, buflen, "OID - OID is not found" );
if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" );
#endif /* MBEDTLS_OID_C */
#if defined(MBEDTLS_PADLOCK_C)
if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) )
mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
#endif /* MBEDTLS_PADLOCK_C */
#if defined(MBEDTLS_POLY1305_C)
if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" );
if( use_ret == -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "POLY1305 - Feature not available. For example, s part of the API is not implemented" );
if( use_ret == -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "POLY1305 - Poly1305 hardware accelerator failed" );
#endif /* MBEDTLS_POLY1305_C */
#if defined(MBEDTLS_RIPEMD160_C)
if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
#endif /* MBEDTLS_RIPEMD160_C */
#if defined(MBEDTLS_SHA1_C)
if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" );
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" );
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_THREADING_C)
if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" );
if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) )
mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" );
#endif /* MBEDTLS_THREADING_C */
#if defined(MBEDTLS_XTEA_C)
if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" );
#endif /* MBEDTLS_XTEA_C */
// END generated code
if( strlen( buf ) != 0 )
return;
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}
#else /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
/*
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
*/
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
((void) ret);
if( buflen > 0 )
buf[0] = '\0';
}
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
#endif /* MBEDTLS_ERROR_C */

124
common/mbedtls/error.h Normal file
View file

@ -0,0 +1,124 @@
/**
* \file error.h
*
* \brief Error to string translation
*/
/*
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* 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.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ERROR_H
#define MBEDTLS_ERROR_H
#include <stddef.h>
/**
* Error code layout.
*
* Currently we try to keep all error codes within the negative space of 16
* bits signed integers to support all platforms (-0x0001 - -0x7FFF). In
* addition we'd like to give two layers of information on the error if
* possible.
*
* For that purpose the error codes are segmented in the following manner:
*
* 16 bit error code bit-segmentation
*
* 1 bit - Unused (sign bit)
* 3 bits - High level module ID
* 5 bits - Module-dependent error code
* 7 bits - Low level module errors
*
* For historical reasons, low-level error codes are divided in even and odd,
* even codes were assigned first, and -1 is reserved for other errors.
*
* Low-level module errors (0x0002-0x007E, 0x0003-0x007F)
*
* Module Nr Codes assigned
* MPI 7 0x0002-0x0010
* GCM 3 0x0012-0x0014 0x0013-0x0013
* BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
* THREADING 3 0x001A-0x001E
* AES 5 0x0020-0x0022 0x0021-0x0025
* CAMELLIA 3 0x0024-0x0026 0x0027-0x0027
* XTEA 2 0x0028-0x0028 0x0029-0x0029
* BASE64 2 0x002A-0x002C
* OID 1 0x002E-0x002E 0x000B-0x000B
* PADLOCK 1 0x0030-0x0030
* DES 2 0x0032-0x0032 0x0033-0x0033
* CTR_DBRG 4 0x0034-0x003A
* ENTROPY 3 0x003C-0x0040 0x003D-0x003F
* NET 13 0x0042-0x0052 0x0043-0x0049
* ARIA 4 0x0058-0x005E
* ASN1 7 0x0060-0x006C
* CMAC 1 0x007A-0x007A
* PBKDF2 1 0x007C-0x007C
* HMAC_DRBG 4 0x0003-0x0009
* CCM 3 0x000D-0x0011
* ARC4 1 0x0019-0x0019
* MD2 1 0x002B-0x002B
* MD4 1 0x002D-0x002D
* MD5 1 0x002F-0x002F
* RIPEMD160 1 0x0031-0x0031
* SHA1 1 0x0035-0x0035
* SHA256 1 0x0037-0x0037
* SHA512 1 0x0039-0x0039
* CHACHA20 3 0x0051-0x0055
* POLY1305 3 0x0057-0x005B
* CHACHAPOLY 2 0x0054-0x0056
*
* High-level module nr (3 bits - 0x0...-0x7...)
* Name ID Nr of Errors
* PEM 1 9
* PKCS#12 1 4 (Started from top)
* X509 2 20
* PKCS5 2 4 (Started from top)
* DHM 3 11
* PK 3 15 (Started from top)
* RSA 4 11
* ECP 4 9 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
* CIPHER 6 8
* SSL 6 22 (Started from top)
* SSL 7 31
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Translate a mbed TLS error code into a string representation,
* Result is truncated if necessary and always includes a terminating
* null byte.
*
* \param errnum error code
* \param buffer buffer to place representation in
* \param buflen length of the buffer
*/
void mbedtls_strerror( int errnum, char *buffer, size_t buflen );
#ifdef __cplusplus
}
#endif
#endif /* error.h */

547
common/mbedtls/timing.c Normal file
View file

@ -0,0 +1,547 @@
/*
* Portable interface to the CPU cycle counter
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* 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.
*
* 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_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif
#if defined(MBEDTLS_TIMING_C)
#include "mbedtls/timing.h"
#if !defined(MBEDTLS_TIMING_ALT)
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
!defined(__HAIKU__)
#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h"
#endif
#ifndef asm
#define asm __asm
#endif
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
#include <windows.h>
#include <winbase.h>
struct _hr_time
{
LARGE_INTEGER start;
};
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <time.h>
struct _hr_time
{
struct timeval start;
};
#endif /* _WIN32 && !EFIX64 && !EFI32 */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__)
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
unsigned long tsc;
__asm rdtsc
__asm mov [tsc], eax
return( tsc );
}
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
( _MSC_VER && _M_IX86 ) || __WATCOMC__ */
/* some versions of mingw-64 have 32-bit longs even on x84_64 */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && ( defined(__i386__) || ( \
( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) )
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
unsigned long lo, hi;
asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
return( lo );
}
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
__GNUC__ && __i386__ */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) )
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
unsigned long lo, hi;
asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
return( lo | ( hi << 32 ) );
}
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
__GNUC__ && ( __amd64__ || __x86_64__ ) */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) )
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
unsigned long tbl, tbu0, tbu1;
do
{
asm volatile( "mftbu %0" : "=r" (tbu0) );
asm volatile( "mftb %0" : "=r" (tbl ) );
asm volatile( "mftbu %0" : "=r" (tbu1) );
}
while( tbu0 != tbu1 );
return( tbl );
}
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
__GNUC__ && ( __powerpc__ || __ppc__ ) */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && defined(__sparc64__)
#if defined(__OpenBSD__)
#warning OpenBSD does not allow access to tick register using software version instead
#else
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
unsigned long tick;
asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) );
return( tick );
}
#endif /* __OpenBSD__ */
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
__GNUC__ && __sparc64__ */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
unsigned long tick;
asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" );
asm volatile( "mov %%g1, %0" : "=r" (tick) );
return( tick );
}
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
__GNUC__ && __sparc__ && !__sparc64__ */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && defined(__alpha__)
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
unsigned long cc;
asm volatile( "rpcc %0" : "=r" (cc) );
return( cc & 0xFFFFFFFF );
}
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
__GNUC__ && __alpha__ */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && defined(__ia64__)
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
unsigned long itc;
asm volatile( "mov %0 = ar.itc" : "=r" (itc) );
return( itc );
}
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
__GNUC__ && __ia64__ */
#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \
!defined(EFIX64) && !defined(EFI32)
#define HAVE_HARDCLOCK
unsigned long mbedtls_timing_hardclock( void )
{
LARGE_INTEGER offset;
QueryPerformanceCounter( &offset );
return( (unsigned long)( offset.QuadPart ) );
}
#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */
#if !defined(HAVE_HARDCLOCK)
#define HAVE_HARDCLOCK
static int hardclock_init = 0;
static struct timeval tv_init;
unsigned long mbedtls_timing_hardclock( void )
{
struct timeval tv_cur;
if( hardclock_init == 0 )
{
#ifdef __MINGW32__
mingw_gettimeofday( &tv_init, NULL );
#else
gettimeofday( &tv_init, NULL );
#endif
hardclock_init = 1;
}
#ifdef __MINGW32__
mingw_gettimeofday( &tv_cur, NULL );
#else
gettimeofday( &tv_cur, NULL );
#endif
return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000
+ ( tv_cur.tv_usec - tv_init.tv_usec ) );
}
#endif /* !HAVE_HARDCLOCK */
volatile int mbedtls_timing_alarmed = 0;
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
{
struct _hr_time *t = (struct _hr_time *) val;
if( reset )
{
QueryPerformanceCounter( &t->start );
return( 0 );
}
else
{
unsigned long delta;
LARGE_INTEGER now, hfreq;
QueryPerformanceCounter( &now );
QueryPerformanceFrequency( &hfreq );
delta = (unsigned long)( ( now.QuadPart - t->start.QuadPart ) * 1000ul
/ hfreq.QuadPart );
return( delta );
}
}
/* It's OK to use a global because alarm() is supposed to be global anyway */
static DWORD alarmMs;
static DWORD WINAPI TimerProc( LPVOID TimerContext )
{
((void) TimerContext);
Sleep( alarmMs );
mbedtls_timing_alarmed = 1;
return( TRUE );
}
void mbedtls_set_alarm( int seconds )
{
DWORD ThreadId;
if( seconds == 0 )
{
/* No need to create a thread for this simple case.
* Also, this shorcut is more reliable at least on MinGW32 */
mbedtls_timing_alarmed = 1;
return;
}
mbedtls_timing_alarmed = 0;
alarmMs = seconds * 1000;
CloseHandle( CreateThread( NULL, 0, TimerProc, NULL, 0, &ThreadId ) );
}
#else /* _WIN32 && !EFIX64 && !EFI32 */
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
{
struct _hr_time *t = (struct _hr_time *) val;
if( reset )
{
gettimeofday( &t->start, NULL );
return( 0 );
}
else
{
unsigned long delta;
struct timeval now;
gettimeofday( &now, NULL );
delta = ( now.tv_sec - t->start.tv_sec ) * 1000ul
+ ( now.tv_usec - t->start.tv_usec ) / 1000;
return( delta );
}
}
static void sighandler( int signum )
{
mbedtls_timing_alarmed = 1;
signal( signum, sighandler );
}
void mbedtls_set_alarm( int seconds )
{
mbedtls_timing_alarmed = 0;
signal( SIGALRM, sighandler );
alarm( seconds );
if( seconds == 0 )
{
/* alarm(0) cancelled any previous pending alarm, but the
handler won't fire, so raise the flag straight away. */
mbedtls_timing_alarmed = 1;
}
}
#endif /* _WIN32 && !EFIX64 && !EFI32 */
/*
* Set delays to watch
*/
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms )
{
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
ctx->int_ms = int_ms;
ctx->fin_ms = fin_ms;
if( fin_ms != 0 )
(void) mbedtls_timing_get_timer( &ctx->timer, 1 );
}
/*
* Get number of delays expired
*/
int mbedtls_timing_get_delay( void *data )
{
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
unsigned long elapsed_ms;
if( ctx->fin_ms == 0 )
return( -1 );
elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 );
if( elapsed_ms >= ctx->fin_ms )
return( 2 );
if( elapsed_ms >= ctx->int_ms )
return( 1 );
return( 0 );
}
#endif /* !MBEDTLS_TIMING_ALT */
#if defined(MBEDTLS_SELF_TEST)
/*
* Busy-waits for the given number of milliseconds.
* Used for testing mbedtls_timing_hardclock.
*/
static void busy_msleep( unsigned long msec )
{
struct mbedtls_timing_hr_time hires;
unsigned long i = 0; /* for busy-waiting */
volatile unsigned long j; /* to prevent optimisation */
(void) mbedtls_timing_get_timer( &hires, 1 );
while( mbedtls_timing_get_timer( &hires, 0 ) < msec )
i++;
j = i;
(void) j;
}
#define FAIL do \
{ \
if( verbose != 0 ) \
{ \
mbedtls_printf( "failed at line %d\n", __LINE__ ); \
mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \
cycles, ratio, millisecs, secs, hardfail, \
(unsigned long) a, (unsigned long) b ); \
mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n", \
mbedtls_timing_get_timer( &hires, 0 ), \
mbedtls_timing_get_timer( &ctx.timer, 0 ), \
mbedtls_timing_get_delay( &ctx ) ); \
} \
return( 1 ); \
} while( 0 )
/*
* Checkup routine
*
* Warning: this is work in progress, some tests may not be reliable enough
* yet! False positives may happen.
*/
int mbedtls_timing_self_test( int verbose )
{
unsigned long cycles = 0, ratio = 0;
unsigned long millisecs = 0, secs = 0;
int hardfail = 0;
struct mbedtls_timing_hr_time hires;
uint32_t a = 0, b = 0;
mbedtls_timing_delay_context ctx;
if( verbose != 0 )
mbedtls_printf( " TIMING tests note: will take some time!\n" );
if( verbose != 0 )
mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " );
{
secs = 1;
(void) mbedtls_timing_get_timer( &hires, 1 );
mbedtls_set_alarm( (int) secs );
while( !mbedtls_timing_alarmed )
;
millisecs = mbedtls_timing_get_timer( &hires, 0 );
/* For some reason on Windows it looks like alarm has an extra delay
* (maybe related to creating a new thread). Allow some room here. */
if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
FAIL;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
if( verbose != 0 )
mbedtls_printf( " TIMING test #2 (set/get_delay ): " );
{
a = 800;
b = 400;
mbedtls_timing_set_delay( &ctx, a, a + b ); /* T = 0 */
busy_msleep( a - a / 4 ); /* T = a - a/4 */
if( mbedtls_timing_get_delay( &ctx ) != 0 )
FAIL;
busy_msleep( a / 4 + b / 4 ); /* T = a + b/4 */
if( mbedtls_timing_get_delay( &ctx ) != 1 )
FAIL;
busy_msleep( b ); /* T = a + b + b/4 */
if( mbedtls_timing_get_delay( &ctx ) != 2 )
FAIL;
}
mbedtls_timing_set_delay( &ctx, 0, 0 );
busy_msleep( 200 );
if( mbedtls_timing_get_delay( &ctx ) != -1 )
FAIL;
if( verbose != 0 )
mbedtls_printf( "passed\n" );
if( verbose != 0 )
mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " );
/*
* Allow one failure for possible counter wrapping.
* On a 4Ghz 32-bit machine the cycle counter wraps about once per second;
* since the whole test is about 10ms, it shouldn't happen twice in a row.
*/
hard_test:
if( hardfail > 1 )
{
if( verbose != 0 )
mbedtls_printf( "failed (ignored)\n" );
goto hard_test_done;
}
/* Get a reference ratio cycles/ms */
millisecs = 1;
cycles = mbedtls_timing_hardclock();
busy_msleep( millisecs );
cycles = mbedtls_timing_hardclock() - cycles;
ratio = cycles / millisecs;
/* Check that the ratio is mostly constant */
for( millisecs = 2; millisecs <= 4; millisecs++ )
{
cycles = mbedtls_timing_hardclock();
busy_msleep( millisecs );
cycles = mbedtls_timing_hardclock() - cycles;
/* Allow variation up to 20% */
if( cycles / millisecs < ratio - ratio / 5 ||
cycles / millisecs > ratio + ratio / 5 )
{
hardfail++;
goto hard_test;
}
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
hard_test_done:
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_TIMING_C */

155
common/mbedtls/timing.h Normal file
View file

@ -0,0 +1,155 @@
/**
* \file timing.h
*
* \brief Portable interface to timeouts and to the CPU cycle counter
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* 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.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_TIMING_H
#define MBEDTLS_TIMING_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_TIMING_ALT)
// Regular implementation
//
/**
* \brief timer structure
*/
struct mbedtls_timing_hr_time
{
unsigned char opaque[32];
};
/**
* \brief Context for mbedtls_timing_set/get_delay()
*/
typedef struct mbedtls_timing_delay_context
{
struct mbedtls_timing_hr_time timer;
uint32_t int_ms;
uint32_t fin_ms;
} mbedtls_timing_delay_context;
#else /* MBEDTLS_TIMING_ALT */
#include "timing_alt.h"
#endif /* MBEDTLS_TIMING_ALT */
extern volatile int mbedtls_timing_alarmed;
/**
* \brief Return the CPU cycle counter value
*
* \warning This is only a best effort! Do not rely on this!
* In particular, it is known to be unreliable on virtual
* machines.
*
* \note This value starts at an unspecified origin and
* may wrap around.
*/
unsigned long mbedtls_timing_hardclock( void );
/**
* \brief Return the elapsed time in milliseconds
*
* \param val points to a timer structure
* \param reset If 0, query the elapsed time. Otherwise (re)start the timer.
*
* \return Elapsed time since the previous reset in ms. When
* restarting, this is always 0.
*
* \note To initialize a timer, call this function with reset=1.
*
* Determining the elapsed time and resetting the timer is not
* atomic on all platforms, so after the sequence
* `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
* get_timer(0) }` the value time1+time2 is only approximately
* the delay since the first reset.
*/
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset );
/**
* \brief Setup an alarm clock
*
* \param seconds delay before the "mbedtls_timing_alarmed" flag is set
* (must be >=0)
*
* \warning Only one alarm at a time is supported. In a threaded
* context, this means one for the whole process, not one per
* thread.
*/
void mbedtls_set_alarm( int seconds );
/**
* \brief Set a pair of delays to watch
* (See \c mbedtls_timing_get_delay().)
*
* \param data Pointer to timing data.
* Must point to a valid \c mbedtls_timing_delay_context struct.
* \param int_ms First (intermediate) delay in milliseconds.
* The effect if int_ms > fin_ms is unspecified.
* \param fin_ms Second (final) delay in milliseconds.
* Pass 0 to cancel the current delay.
*
* \note To set a single delay, either use \c mbedtls_timing_set_timer
* directly or use this function with int_ms == fin_ms.
*/
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
/**
* \brief Get the status of delays
* (Memory helper: number of delays passed.)
*
* \param data Pointer to timing data
* Must point to a valid \c mbedtls_timing_delay_context struct.
*
* \return -1 if cancelled (fin_ms = 0),
* 0 if none of the delays are passed,
* 1 if only the intermediate delay is passed,
* 2 if the final delay is passed.
*/
int mbedtls_timing_get_delay( void *data );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_timing_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* timing.h */

View file

@ -18,7 +18,9 @@
#include <mbedtls/cmac.h>
#include <mbedtls/ecdsa.h>
#include <mbedtls/sha256.h>
#include "mbedtls/ctr_drbg.h"
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/error.h>
//test!!!
#include <util.h>
@ -129,7 +131,84 @@ int ecdsa_init_str(mbedtls_ecdsa_context *ctx, char * key_d, char *key_x, char *
return 0;
}
int ecdsa_signature_create(char * key_d, char *key_x, char *key_y, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen) {
int ecdsa_init(mbedtls_ecdsa_context *ctx, uint8_t * key_d, uint8_t *key_xy) {
if (!ctx)
return 1;
int res;
mbedtls_ecdsa_init(ctx);
res = mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1); // secp256r1
if (res)
return res;
if (key_d) {
res = mbedtls_mpi_read_binary(&ctx->d, key_d, 32);
if (res)
return res;
}
if (key_xy) {
res = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, key_xy, 32 * 2 + 1);
if (res)
return res;
}
return 0;
}
int ecdsa_key_create(uint8_t * key_d, uint8_t *key_xy) {
int res;
mbedtls_ecdsa_context ctx;
ecdsa_init(&ctx, NULL, NULL);
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "ecdsaproxmark";
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
res = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)pers, strlen(pers));
if (res)
goto exit;
res = mbedtls_ecdsa_genkey(&ctx, MBEDTLS_ECP_DP_SECP256R1, mbedtls_ctr_drbg_random, &ctr_drbg);
if (res)
goto exit;
res = mbedtls_mpi_write_binary(&ctx.d, key_d, 32);
if (res)
goto exit;
size_t keylen = 0;
uint8_t public_key[200] = {0};
res = mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &keylen, public_key, sizeof(public_key));
if (res)
goto exit;
if (keylen != 65) { // 0x04 <key x 32b><key y 32b>
res = 1;
goto exit;
}
memcpy(key_xy, public_key, 65);
exit:
mbedtls_entropy_free(&entropy);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_ecdsa_free(&ctx);
return res;
}
char *ecdsa_get_error(int ret) {
static char retstr[300];
memset(retstr, 0x00, sizeof(retstr));
mbedtls_strerror(ret, retstr, sizeof(retstr));
return retstr;
}
int ecdsa_signature_create(uint8_t *key_d, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen) {
int res;
*signaturelen = 0;
@ -138,10 +217,23 @@ int ecdsa_signature_create(char * key_d, char *key_x, char *key_y, uint8_t *inpu
if (res)
return res;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "ecdsaproxmark";
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
res = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)pers, strlen(pers));
if (res)
goto exit;
mbedtls_ecdsa_context ctx;
ecdsa_init_str(&ctx, key_d, key_x, key_y);
res = mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256, shahash, sizeof(shahash), signature, signaturelen, fixed_rand, NULL);
ecdsa_init(&ctx, key_d, key_xy);
res = mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256, shahash, sizeof(shahash), signature, signaturelen, mbedtls_ctr_drbg_random, &ctr_drbg);
exit:
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_ecdsa_free(&ctx);
return res;
}
@ -188,9 +280,12 @@ int ecdsa_signature_verify(uint8_t *key_xy, uint8_t *input, int length, uint8_t
if (res)
return res;
// mbedtls_ecdsa_context ctx;
//...
return 0;
mbedtls_ecdsa_context ctx;
ecdsa_init(&ctx, NULL, key_xy);
res = mbedtls_ecdsa_read_signature(&ctx, shahash, sizeof(shahash), signature, signaturelen);
mbedtls_ecdsa_free(&ctx);
return res;
}
int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *rval, uint8_t *sval) {
@ -251,9 +346,12 @@ int ecdsa_nist_test(bool verbose) {
uint8_t signature[300] = {0};
size_t siglen = 0;
// NIST ecdsa test
if (verbose)
printf("ECDSA NIST test: ");
// make signature
res = ecdsa_signature_create_test(T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen);
printf("res: %x signature[%x]: %s\n", (res<0)?-res:res, siglen, sprint_hex(signature, siglen));
// printf("res: %x signature[%x]: %s\n", (res<0)?-res:res, siglen, sprint_hex(signature, siglen));
if (res)
goto exit;
@ -277,20 +375,51 @@ int ecdsa_nist_test(bool verbose) {
// verify signature
res = ecdsa_signature_verify_keystr(T_Q_X, T_Q_Y, input, length, signature, siglen);
printf("signature check res: %x\n", (res<0)?-res:res);
if (res)
goto exit;
// verify wrong signature
input[0] ^= 0xFF;
res = ecdsa_signature_verify_keystr(T_Q_X, T_Q_Y, input, length, signature, siglen);
printf("wrong signature check res: %x\n", (res<0)?-res:res);
if (!res) {
res = 1;
goto exit;
}
if (verbose)
printf("passed\n");
// random ecdsa test
if (verbose)
printf("ECDSA binary signature create/check test: ");
uint8_t key_d[32] = {0};
uint8_t key_xy[32 * 2 + 2] = {0};
memset(signature, 0x00, sizeof(signature));
siglen = 0;
res = ecdsa_key_create(key_d, key_xy);
if (res)
goto exit;
res = ecdsa_signature_create(key_d, key_xy, input, length, signature, &siglen);
if (res)
goto exit;
res = ecdsa_signature_verify(key_xy, input, length, signature, siglen);
if (res)
goto exit;
input[0] ^= 0xFF;
res = ecdsa_signature_verify(key_xy, input, length, signature, siglen);
if (!res)
goto exit;
if (verbose)
printf("passed\n");
return 0;
exit:
if (verbose)
printf("failed\n");
return res;
}

View file

@ -22,7 +22,8 @@ extern int aes_cmac8(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *mac, in
extern int sha256hash(uint8_t *input, int length, uint8_t *hash);
extern int ecdsa_signature_create(char * key_d, char *key_x, char *key_y, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen);
extern int ecdsa_key_create(uint8_t * key_d, uint8_t *key_xy);
extern int ecdsa_signature_create(uint8_t *key_d, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen);
extern int ecdsa_signature_verify(uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t signaturelen);
extern int ecdsa_nist_test(bool verbose);