Merge branch 'development-psa-proposed' into development
Resolve conflicts by performing the following.
- Take the upstream Mbed TLS ChangeLog verbatim.
- Reject changes to Makefiles and CMake that are related to using Mbed
Crypto as a submodule. It doesn't make sense to use Mbed Crypto as a
submodule of itself.
- Reject README changes, as Mbed Crypto has its own, different README.
- Reject PSA-related changes to config.h. We don't want to disable the
availability of the PSA Crypto API by default in the Mbed Crypto
config.h.
- Don't inadvertently revert dead code removal in
mbedtls_cipher_write_tag() which was added in f2a752940307 ("Fix
double return statement in cipher.c")
- Where Mbed Crypto already had some MBEDTLS_USE_PSA_CRYPTO code (from
past companion PRs) take the latest version from Mbed TLS which
includes integration with MBEDTLS_CHECK_PARAMS.
- Update the version of the shared library files to match what's
currently present in Mbed TLS.
- Reject removal of testing with PSA from config full tests.
- Resolve conflicts in test tests/suites/helpers.function, where both
Mbed Crypto and Mbed TLS both added documentation for TEST_ASSERT.
Combine text from both documentation efforts.
- Reject adding a submodule of ourselves.
- Reject addition of submodule tests in all.sh.
- Reject addition of submodule to library path in
tests/scripts/run-test-suites.pl.
- Avoid using USE_CRYPTO_SUBMODULE=1 in
component_test_use_psa_crypto_full_cmake_asan() in all.sh.
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 3b56c44..e9372be 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -179,7 +179,7 @@
if(USE_SHARED_MBEDTLS_LIBRARY)
add_library(mbedcrypto SHARED ${src_crypto})
- set_target_properties(mbedcrypto PROPERTIES VERSION 2.14.0 SOVERSION 3)
+ set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.0 SOVERSION 3)
target_link_libraries(mbedcrypto ${libs})
target_include_directories(mbedcrypto
PUBLIC ${CMAKE_SOURCE_DIR}/include/
@@ -191,11 +191,11 @@
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
else()
add_library(mbedx509 SHARED ${src_x509})
- set_target_properties(mbedx509 PROPERTIES VERSION 2.14.0 SOVERSION 0)
+ set_target_properties(mbedx509 PROPERTIES VERSION 2.16.0 SOVERSION 0)
target_link_libraries(mbedx509 ${libs} mbedcrypto)
add_library(mbedtls SHARED ${src_tls})
- set_target_properties(mbedtls PROPERTIES VERSION 2.14.0 SOVERSION 12)
+ set_target_properties(mbedtls PROPERTIES VERSION 2.16.0 SOVERSION 12)
target_link_libraries(mbedtls ${libs} mbedx509)
install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/Makefile b/library/Makefile
index 1822a24..8533eaa 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -40,7 +40,7 @@
SOEXT_X509=so.0
SOEXT_CRYPTO=so.3
-# Set AR_DASH= (empty string) to use an ar implentation that does not accept
+# Set AR_DASH= (empty string) to use an ar implementation that does not accept
# the - prefix for command line options (e.g. llvm-ar)
AR_DASH ?= -
diff --git a/library/aes.c b/library/aes.c
index 3de571e..0543cd7 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -56,6 +56,12 @@
#if !defined(MBEDTLS_AES_ALT)
+/* Parameter validation macros based on platform_util.h */
+#define AES_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
+#define AES_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
/*
* 32-bit integer manipulation macros (little endian)
*/
@@ -511,6 +517,8 @@
void mbedtls_aes_init( mbedtls_aes_context *ctx )
{
+ AES_VALIDATE( ctx != NULL );
+
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
}
@@ -525,12 +533,17 @@
#if defined(MBEDTLS_CIPHER_MODE_XTS)
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
{
+ AES_VALIDATE( ctx != NULL );
+
mbedtls_aes_init( &ctx->crypt );
mbedtls_aes_init( &ctx->tweak );
}
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
{
+ if( ctx == NULL )
+ return;
+
mbedtls_aes_free( &ctx->crypt );
mbedtls_aes_free( &ctx->tweak );
}
@@ -546,14 +559,8 @@
unsigned int i;
uint32_t *RK;
-#if !defined(MBEDTLS_AES_ROM_TABLES)
- if( aes_init_done == 0 )
- {
- aes_gen_tables();
- aes_init_done = 1;
-
- }
-#endif
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( key != NULL );
switch( keybits )
{
@@ -563,6 +570,14 @@
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
}
+#if !defined(MBEDTLS_AES_ROM_TABLES)
+ if( aes_init_done == 0 )
+ {
+ aes_gen_tables();
+ aes_init_done = 1;
+ }
+#endif
+
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
if( aes_padlock_ace == -1 )
aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
@@ -662,6 +677,9 @@
uint32_t *RK;
uint32_t *SK;
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( key != NULL );
+
mbedtls_aes_init( &cty );
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
@@ -752,6 +770,9 @@
const unsigned char *key1, *key2;
unsigned int key1bits, key2bits;
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( key != NULL );
+
ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
&key2, &key2bits );
if( ret != 0 )
@@ -774,6 +795,9 @@
const unsigned char *key1, *key2;
unsigned int key1bits, key2bits;
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( key != NULL );
+
ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
&key2, &key2bits );
if( ret != 0 )
@@ -977,10 +1001,16 @@
* AES-ECB block encryption/decryption
*/
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
- int mode,
- const unsigned char input[16],
- unsigned char output[16] )
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] )
{
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
@@ -1018,6 +1048,13 @@
int i;
unsigned char temp[16];
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+ AES_VALIDATE_RET( iv != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
if( length % 16 )
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
@@ -1143,6 +1180,13 @@
unsigned char prev_tweak[16];
unsigned char tmp[16];
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+ AES_VALIDATE_RET( data_unit != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
/* Data units must be at least 16 bytes long. */
if( length < 16 )
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
@@ -1242,7 +1286,20 @@
unsigned char *output )
{
int c;
- size_t n = *iv_off;
+ size_t n;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+ AES_VALIDATE_RET( iv_off != NULL );
+ AES_VALIDATE_RET( iv != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
+ n = *iv_off;
+
+ if( n > 15 )
+ return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
if( mode == MBEDTLS_AES_DECRYPT )
{
@@ -1280,15 +1337,21 @@
* AES-CFB8 buffer encryption/decryption
*/
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
{
unsigned char c;
unsigned char ov[17];
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+ AES_VALIDATE_RET( iv != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
while( length-- )
{
memcpy( ov, iv, 16 );
@@ -1321,7 +1384,18 @@
unsigned char *output )
{
int ret = 0;
- size_t n = *iv_off;
+ size_t n;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( iv_off != NULL );
+ AES_VALIDATE_RET( iv != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
+ n = *iv_off;
+
+ if( n > 15 )
+ return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
while( length-- )
{
@@ -1356,7 +1430,16 @@
unsigned char *output )
{
int c, i;
- size_t n = *nc_off;
+ size_t n;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( nc_off != NULL );
+ AES_VALIDATE_RET( nonce_counter != NULL );
+ AES_VALIDATE_RET( stream_block != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
+ n = *nc_off;
if ( n > 0x0F )
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
diff --git a/library/aria.c b/library/aria.c
index ca9e147..aff66d6 100644
--- a/library/aria.c
+++ b/library/aria.c
@@ -55,6 +55,12 @@
#define inline __inline
#endif
+/* Parameter validation macros */
+#define ARIA_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA )
+#define ARIA_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
/*
* 32-bit integer manipulation macros (little endian)
*/
@@ -449,9 +455,11 @@
int i;
uint32_t w[4][4], *w2;
+ ARIA_VALIDATE_RET( ctx != NULL );
+ ARIA_VALIDATE_RET( key != NULL );
if( keybits != 128 && keybits != 192 && keybits != 256 )
- return( MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH );
+ return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
/* Copy key to W0 (and potential remainder to W1) */
GET_UINT32_LE( w[0][0], key, 0 );
@@ -503,6 +511,8 @@
const unsigned char *key, unsigned int keybits )
{
int i, j, k, ret;
+ ARIA_VALIDATE_RET( ctx != NULL );
+ ARIA_VALIDATE_RET( key != NULL );
ret = mbedtls_aria_setkey_enc( ctx, key, keybits );
if( ret != 0 )
@@ -539,6 +549,9 @@
int i;
uint32_t a, b, c, d;
+ ARIA_VALIDATE_RET( ctx != NULL );
+ ARIA_VALIDATE_RET( input != NULL );
+ ARIA_VALIDATE_RET( output != NULL );
GET_UINT32_LE( a, input, 0 );
GET_UINT32_LE( b, input, 4 );
@@ -586,6 +599,7 @@
/* Initialize context */
void mbedtls_aria_init( mbedtls_aria_context *ctx )
{
+ ARIA_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_aria_context ) );
}
@@ -612,6 +626,13 @@
int i;
unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
+ ARIA_VALIDATE_RET( ctx != NULL );
+ ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT ||
+ mode == MBEDTLS_ARIA_DECRYPT );
+ ARIA_VALIDATE_RET( length == 0 || input != NULL );
+ ARIA_VALIDATE_RET( length == 0 || output != NULL );
+ ARIA_VALIDATE_RET( iv != NULL );
+
if( length % MBEDTLS_ARIA_BLOCKSIZE )
return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
@@ -665,7 +686,23 @@
unsigned char *output )
{
unsigned char c;
- size_t n = *iv_off;
+ size_t n;
+
+ ARIA_VALIDATE_RET( ctx != NULL );
+ ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT ||
+ mode == MBEDTLS_ARIA_DECRYPT );
+ ARIA_VALIDATE_RET( length == 0 || input != NULL );
+ ARIA_VALIDATE_RET( length == 0 || output != NULL );
+ ARIA_VALIDATE_RET( iv != NULL );
+ ARIA_VALIDATE_RET( iv_off != NULL );
+
+ n = *iv_off;
+
+ /* An overly large value of n can lead to an unlimited
+ * buffer overflow. Therefore, guard against this
+ * outside of parameter validation. */
+ if( n >= MBEDTLS_ARIA_BLOCKSIZE )
+ return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
if( mode == MBEDTLS_ARIA_DECRYPT )
{
@@ -713,7 +750,21 @@
unsigned char *output )
{
int c, i;
- size_t n = *nc_off;
+ size_t n;
+
+ ARIA_VALIDATE_RET( ctx != NULL );
+ ARIA_VALIDATE_RET( length == 0 || input != NULL );
+ ARIA_VALIDATE_RET( length == 0 || output != NULL );
+ ARIA_VALIDATE_RET( nonce_counter != NULL );
+ ARIA_VALIDATE_RET( stream_block != NULL );
+ ARIA_VALIDATE_RET( nc_off != NULL );
+
+ n = *nc_off;
+ /* An overly large value of n can lead to an unlimited
+ * buffer overflow. Therefore, guard against this
+ * outside of parameter validation. */
+ if( n >= MBEDTLS_ARIA_BLOCKSIZE )
+ return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
while( length-- )
{
diff --git a/library/bignum.c b/library/bignum.c
index be4df2f..87015af 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -59,6 +59,11 @@
#define mbedtls_free free
#endif
+#define MPI_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+#define MPI_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
#define biL (ciL << 3) /* bits in limb */
#define biH (ciL << 2) /* half limb size */
@@ -83,8 +88,7 @@
*/
void mbedtls_mpi_init( mbedtls_mpi *X )
{
- if( X == NULL )
- return;
+ MPI_VALIDATE( X != NULL );
X->s = 1;
X->n = 0;
@@ -116,6 +120,7 @@
int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
{
mbedtls_mpi_uint *p;
+ MPI_VALIDATE_RET( X != NULL );
if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
@@ -147,6 +152,10 @@
{
mbedtls_mpi_uint *p;
size_t i;
+ MPI_VALIDATE_RET( X != NULL );
+
+ if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
+ return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
/* Actually resize up in this case */
if( X->n <= nblimbs )
@@ -183,6 +192,8 @@
{
int ret = 0;
size_t i;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
if( X == Y )
return( 0 );
@@ -222,6 +233,8 @@
void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
{
mbedtls_mpi T;
+ MPI_VALIDATE( X != NULL );
+ MPI_VALIDATE( Y != NULL );
memcpy( &T, X, sizeof( mbedtls_mpi ) );
memcpy( X, Y, sizeof( mbedtls_mpi ) );
@@ -237,6 +250,8 @@
{
int ret = 0;
size_t i;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
/* make sure assign is 0 or 1 in a time-constant manner */
assign = (assign | (unsigned char)-assign) >> 7;
@@ -266,6 +281,8 @@
int ret, s;
size_t i;
mbedtls_mpi_uint tmp;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
if( X == Y )
return( 0 );
@@ -298,6 +315,7 @@
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
{
int ret;
+ MPI_VALIDATE_RET( X != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
memset( X->p, 0, X->n * ciL );
@@ -315,6 +333,8 @@
*/
int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
{
+ MPI_VALIDATE_RET( X != NULL );
+
if( X->n * biL <= pos )
return( 0 );
@@ -333,6 +353,7 @@
int ret = 0;
size_t off = pos / biL;
size_t idx = pos % biL;
+ MPI_VALIDATE_RET( X != NULL );
if( val != 0 && val != 1 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -359,6 +380,7 @@
size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
{
size_t i, j, count = 0;
+ MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
for( i = 0; i < X->n; i++ )
for( j = 0; j < biL; j++, count++ )
@@ -439,6 +461,8 @@
size_t i, j, slen, n;
mbedtls_mpi_uint d;
mbedtls_mpi T;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( s != NULL );
if( radix < 2 || radix > 16 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -503,26 +527,38 @@
}
/*
- * Helper to write the digits high-order first
+ * Helper to write the digits high-order first.
*/
-static int mpi_write_hlp( mbedtls_mpi *X, int radix, char **p )
+static int mpi_write_hlp( mbedtls_mpi *X, int radix,
+ char **p, const size_t buflen )
{
int ret;
mbedtls_mpi_uint r;
+ size_t length = 0;
+ char *p_end = *p + buflen;
- if( radix < 2 || radix > 16 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ do
+ {
+ if( length >= buflen )
+ {
+ return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+ }
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
+ /*
+ * Write the residue in the current position, as an ASCII character.
+ */
+ if( r < 0xA )
+ *(--p_end) = (char)( '0' + r );
+ else
+ *(--p_end) = (char)( 'A' + ( r - 0xA ) );
- if( mbedtls_mpi_cmp_int( X, 0 ) != 0 )
- MBEDTLS_MPI_CHK( mpi_write_hlp( X, radix, p ) );
+ length++;
+ } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 );
- if( r < 10 )
- *(*p)++ = (char)( r + 0x30 );
- else
- *(*p)++ = (char)( r + 0x37 );
+ memmove( *p, p_end, length );
+ *p += length;
cleanup:
@@ -539,6 +575,9 @@
size_t n;
char *p;
mbedtls_mpi T;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( olen != NULL );
+ MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
if( radix < 2 || radix > 16 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -592,7 +631,7 @@
if( T.s == -1 )
T.s = 1;
- MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
+ MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) );
}
*p++ = '\0';
@@ -620,6 +659,12 @@
*/
char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( fin != NULL );
+
+ if( radix < 2 || radix > 16 )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
memset( s, 0, sizeof( s ) );
if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
@@ -651,6 +696,10 @@
* newline characters and '\0'
*/
char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
+ MPI_VALIDATE_RET( X != NULL );
+
+ if( radix < 2 || radix > 16 )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
memset( s, 0, sizeof( s ) );
@@ -678,14 +727,104 @@
}
#endif /* MBEDTLS_FS_IO */
+
+/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
+ * into the storage form used by mbedtls_mpi. */
+
+static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
+{
+ uint8_t i;
+ mbedtls_mpi_uint tmp = 0;
+ /* This works regardless of the endianness. */
+ for( i = 0; i < ciL; i++, x >>= 8 )
+ tmp |= ( x & 0xFF ) << ( ( ciL - 1 - i ) << 3 );
+ return( tmp );
+}
+
+static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
+{
+#if defined(__BYTE_ORDER__)
+
+/* Nothing to do on bigendian systems. */
+#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
+ return( x );
+#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
+
+#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
+
+/* For GCC and Clang, have builtins for byte swapping. */
+#if defined(__GNUC__) && defined(__GNUC_PREREQ)
+#if __GNUC_PREREQ(4,3)
+#define have_bswap
+#endif
+#endif
+
+#if defined(__clang__) && defined(__has_builtin)
+#if __has_builtin(__builtin_bswap32) && \
+ __has_builtin(__builtin_bswap64)
+#define have_bswap
+#endif
+#endif
+
+#if defined(have_bswap)
+ /* The compiler is hopefully able to statically evaluate this! */
+ switch( sizeof(mbedtls_mpi_uint) )
+ {
+ case 4:
+ return( __builtin_bswap32(x) );
+ case 8:
+ return( __builtin_bswap64(x) );
+ }
+#endif
+#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
+#endif /* __BYTE_ORDER__ */
+
+ /* Fall back to C-based reordering if we don't know the byte order
+ * or we couldn't use a compiler-specific builtin. */
+ return( mpi_uint_bigendian_to_host_c( x ) );
+}
+
+static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
+{
+ mbedtls_mpi_uint *cur_limb_left;
+ mbedtls_mpi_uint *cur_limb_right;
+ if( limbs == 0 )
+ return;
+
+ /*
+ * Traverse limbs and
+ * - adapt byte-order in each limb
+ * - swap the limbs themselves.
+ * For that, simultaneously traverse the limbs from left to right
+ * and from right to left, as long as the left index is not bigger
+ * than the right index (it's not a problem if limbs is odd and the
+ * indices coincide in the last iteration).
+ */
+ for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
+ cur_limb_left <= cur_limb_right;
+ cur_limb_left++, cur_limb_right-- )
+ {
+ mbedtls_mpi_uint tmp;
+ /* Note that if cur_limb_left == cur_limb_right,
+ * this code effectively swaps the bytes only once. */
+ tmp = mpi_uint_bigendian_to_host( *cur_limb_left );
+ *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right );
+ *cur_limb_right = tmp;
+ }
+}
+
/*
* Import X from unsigned binary data, big endian
*/
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
{
int ret;
- size_t i, j;
- size_t const limbs = CHARS_TO_LIMBS( buflen );
+ size_t const limbs = CHARS_TO_LIMBS( buflen );
+ size_t const overhead = ( limbs * ciL ) - buflen;
+ unsigned char *Xp;
+
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
/* Ensure that target MPI has exactly the necessary number of limbs */
if( X->n != limbs )
@@ -694,11 +833,17 @@
mbedtls_mpi_init( X );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
}
-
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
- for( i = buflen, j = 0; i > 0; i--, j++ )
- X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
+ /* Avoid calling `memcpy` with NULL source argument,
+ * even if buflen is 0. */
+ if( buf != NULL )
+ {
+ Xp = (unsigned char*) X->p;
+ memcpy( Xp + overhead, buf, buflen );
+
+ mpi_bigendian_to_host( X->p, limbs );
+ }
cleanup:
@@ -711,11 +856,16 @@
int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
unsigned char *buf, size_t buflen )
{
- size_t stored_bytes = X->n * ciL;
+ size_t stored_bytes;
size_t bytes_to_copy;
unsigned char *p;
size_t i;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
+
+ stored_bytes = X->n * ciL;
+
if( stored_bytes < buflen )
{
/* There is enough space in the output buffer. Write initial
@@ -754,6 +904,7 @@
int ret;
size_t i, v0, t1;
mbedtls_mpi_uint r0 = 0, r1;
+ MPI_VALIDATE_RET( X != NULL );
v0 = count / (biL );
t1 = count & (biL - 1);
@@ -803,6 +954,7 @@
{
size_t i, v0, v1;
mbedtls_mpi_uint r0 = 0, r1;
+ MPI_VALIDATE_RET( X != NULL );
v0 = count / biL;
v1 = count & (biL - 1);
@@ -845,6 +997,8 @@
int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
{
size_t i, j;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
for( i = X->n; i > 0; i-- )
if( X->p[i - 1] != 0 )
@@ -875,6 +1029,8 @@
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
{
size_t i, j;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
for( i = X->n; i > 0; i-- )
if( X->p[i - 1] != 0 )
@@ -909,6 +1065,7 @@
{
mbedtls_mpi Y;
mbedtls_mpi_uint p[1];
+ MPI_VALIDATE_RET( X != NULL );
*p = ( z < 0 ) ? -z : z;
Y.s = ( z < 0 ) ? -1 : 1;
@@ -926,6 +1083,9 @@
int ret;
size_t i, j;
mbedtls_mpi_uint *o, *p, c, tmp;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( B != NULL );
if( X == B )
{
@@ -1003,6 +1163,9 @@
mbedtls_mpi TB;
int ret;
size_t n;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( B != NULL );
if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
@@ -1043,8 +1206,12 @@
*/
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret, s = A->s;
+ int ret, s;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( B != NULL );
+ s = A->s;
if( A->s * B->s < 0 )
{
if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
@@ -1074,8 +1241,12 @@
*/
int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret, s = A->s;
+ int ret, s;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( B != NULL );
+ s = A->s;
if( A->s * B->s > 0 )
{
if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
@@ -1107,6 +1278,8 @@
{
mbedtls_mpi _B;
mbedtls_mpi_uint p[1];
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
_B.s = ( b < 0 ) ? -1 : 1;
@@ -1123,6 +1296,8 @@
{
mbedtls_mpi _B;
mbedtls_mpi_uint p[1];
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
_B.s = ( b < 0 ) ? -1 : 1;
@@ -1212,6 +1387,9 @@
int ret;
size_t i, j;
mbedtls_mpi TA, TB;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( B != NULL );
mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
@@ -1248,6 +1426,8 @@
{
mbedtls_mpi _B;
mbedtls_mpi_uint p[1];
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
_B.s = 1;
_B.n = 1;
@@ -1356,11 +1536,14 @@
/*
* Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
*/
-int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
+int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+ const mbedtls_mpi *B )
{
int ret;
size_t i, n, t, k;
mbedtls_mpi X, Y, Z, T1, T2;
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( B != NULL );
if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
@@ -1471,10 +1654,13 @@
/*
* Division by int: A = Q * b + R
*/
-int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b )
+int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
+ const mbedtls_mpi *A,
+ mbedtls_mpi_sint b )
{
mbedtls_mpi _B;
mbedtls_mpi_uint p[1];
+ MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
_B.s = ( b < 0 ) ? -1 : 1;
@@ -1490,6 +1676,9 @@
int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
int ret;
+ MPI_VALIDATE_RET( R != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( B != NULL );
if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
@@ -1514,6 +1703,8 @@
{
size_t i;
mbedtls_mpi_uint x, y, z;
+ MPI_VALIDATE_RET( r != NULL );
+ MPI_VALIDATE_RET( A != NULL );
if( b == 0 )
return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
@@ -1627,7 +1818,8 @@
/*
* Montgomery reduction: A = A * R^-1 mod N
*/
-static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
+static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
+ mbedtls_mpi_uint mm, const mbedtls_mpi *T )
{
mbedtls_mpi_uint z = 1;
mbedtls_mpi U;
@@ -1641,7 +1833,9 @@
/*
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
*/
-int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR )
+int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *E, const mbedtls_mpi *N,
+ mbedtls_mpi *_RR )
{
int ret;
size_t wbits, wsize, one = 1;
@@ -1651,6 +1845,11 @@
mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
int neg;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( E != NULL );
+ MPI_VALIDATE_RET( N != NULL );
+
if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -1855,6 +2054,10 @@
size_t lz, lzt;
mbedtls_mpi TG, TA, TB;
+ MPI_VALIDATE_RET( G != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( B != NULL );
+
mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
@@ -1910,16 +2113,28 @@
void *p_rng )
{
int ret;
- unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+ size_t const limbs = CHARS_TO_LIMBS( size );
+ size_t const overhead = ( limbs * ciL ) - size;
+ unsigned char *Xp;
- if( size > MBEDTLS_MPI_MAX_SIZE )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( f_rng != NULL );
- MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
+ /* Ensure that target MPI has exactly the necessary number of limbs */
+ if( X->n != limbs )
+ {
+ mbedtls_mpi_free( X );
+ mbedtls_mpi_init( X );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
+ }
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+ Xp = (unsigned char*) X->p;
+ f_rng( p_rng, Xp + overhead, size );
+
+ mpi_bigendian_to_host( X->p, limbs );
cleanup:
- mbedtls_platform_zeroize( buf, sizeof( buf ) );
return( ret );
}
@@ -1930,6 +2145,9 @@
{
int ret;
mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( A != NULL );
+ MPI_VALIDATE_RET( N != NULL );
if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -2089,7 +2307,11 @@
size_t i, j, k, s;
mbedtls_mpi W, R, T, A, RR;
- mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( f_rng != NULL );
+
+ mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R );
+ mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
mbedtls_mpi_init( &RR );
/*
@@ -2161,7 +2383,8 @@
}
cleanup:
- mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
+ mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
+ mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
mbedtls_mpi_free( &RR );
return( ret );
@@ -2176,6 +2399,8 @@
{
int ret;
mbedtls_mpi XX;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( f_rng != NULL );
XX.s = 1;
XX.n = X->n;
@@ -2207,12 +2432,15 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( f_rng != NULL );
+
/*
* In the past our key generation aimed for an error rate of at most
* 2^-80. Since this function is deprecated, aim for the same certainty
* here as well.
*/
- return mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng );
+ return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
}
#endif
@@ -2240,6 +2468,9 @@
mbedtls_mpi_uint r;
mbedtls_mpi Y;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( f_rng != NULL );
+
if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
diff --git a/library/blowfish.c b/library/blowfish.c
index 5b6bb98..cbf9238 100644
--- a/library/blowfish.c
+++ b/library/blowfish.c
@@ -40,6 +40,12 @@
#if !defined(MBEDTLS_BLOWFISH_ALT)
+/* Parameter validation macros */
+#define BLOWFISH_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA )
+#define BLOWFISH_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
/*
* 32-bit integer manipulation macros (big endian)
*/
@@ -153,6 +159,7 @@
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx )
{
+ BLOWFISH_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_blowfish_context ) );
}
@@ -167,16 +174,20 @@
/*
* Blowfish key schedule
*/
-int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
- unsigned int keybits )
+int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx,
+ const unsigned char *key,
+ unsigned int keybits )
{
unsigned int i, j, k;
uint32_t data, datal, datar;
+ BLOWFISH_VALIDATE_RET( ctx != NULL );
+ BLOWFISH_VALIDATE_RET( key != NULL );
- if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS ||
- ( keybits % 8 ) )
+ if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS ||
+ keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS ||
+ keybits % 8 != 0 )
{
- return( MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH );
+ return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
}
keybits >>= 3;
@@ -231,6 +242,11 @@
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] )
{
uint32_t X0, X1;
+ BLOWFISH_VALIDATE_RET( ctx != NULL );
+ BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+ mode == MBEDTLS_BLOWFISH_DECRYPT );
+ BLOWFISH_VALIDATE_RET( input != NULL );
+ BLOWFISH_VALIDATE_RET( output != NULL );
GET_UINT32_BE( X0, input, 0 );
GET_UINT32_BE( X1, input, 4 );
@@ -263,6 +279,12 @@
{
int i;
unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
+ BLOWFISH_VALIDATE_RET( ctx != NULL );
+ BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+ mode == MBEDTLS_BLOWFISH_DECRYPT );
+ BLOWFISH_VALIDATE_RET( iv != NULL );
+ BLOWFISH_VALIDATE_RET( length == 0 || input != NULL );
+ BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
if( length % MBEDTLS_BLOWFISH_BLOCKSIZE )
return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
@@ -317,7 +339,19 @@
unsigned char *output )
{
int c;
- size_t n = *iv_off;
+ size_t n;
+
+ BLOWFISH_VALIDATE_RET( ctx != NULL );
+ BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+ mode == MBEDTLS_BLOWFISH_DECRYPT );
+ BLOWFISH_VALIDATE_RET( iv != NULL );
+ BLOWFISH_VALIDATE_RET( iv_off != NULL );
+ BLOWFISH_VALIDATE_RET( length == 0 || input != NULL );
+ BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+ n = *iv_off;
+ if( n >= 8 )
+ return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
{
@@ -365,7 +399,17 @@
unsigned char *output )
{
int c, i;
- size_t n = *nc_off;
+ size_t n;
+ BLOWFISH_VALIDATE_RET( ctx != NULL );
+ BLOWFISH_VALIDATE_RET( nonce_counter != NULL );
+ BLOWFISH_VALIDATE_RET( stream_block != NULL );
+ BLOWFISH_VALIDATE_RET( nc_off != NULL );
+ BLOWFISH_VALIDATE_RET( length == 0 || input != NULL );
+ BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+ n = *nc_off;
+ if( n >= 8 )
+ return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
while( length-- )
{
diff --git a/library/camellia.c b/library/camellia.c
index 41b7da0..22262b8 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -49,6 +49,12 @@
#if !defined(MBEDTLS_CAMELLIA_ALT)
+/* Parameter validation macros */
+#define CAMELLIA_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA )
+#define CAMELLIA_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
/*
* 32-bit integer manipulation macros (big endian)
*/
@@ -321,6 +327,7 @@
void mbedtls_camellia_init( mbedtls_camellia_context *ctx )
{
+ CAMELLIA_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_camellia_context ) );
}
@@ -335,8 +342,9 @@
/*
* Camellia key schedule (encryption)
*/
-int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
- unsigned int keybits )
+int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
+ const unsigned char *key,
+ unsigned int keybits )
{
int idx;
size_t i;
@@ -346,6 +354,9 @@
uint32_t KC[16];
uint32_t TK[20];
+ CAMELLIA_VALIDATE_RET( ctx != NULL );
+ CAMELLIA_VALIDATE_RET( key != NULL );
+
RK = ctx->rk;
memset( t, 0, 64 );
@@ -356,7 +367,7 @@
case 128: ctx->nr = 3; idx = 0; break;
case 192:
case 256: ctx->nr = 4; idx = 1; break;
- default : return( MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH );
+ default : return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
}
for( i = 0; i < keybits / 8; ++i )
@@ -440,14 +451,17 @@
/*
* Camellia key schedule (decryption)
*/
-int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
- unsigned int keybits )
+int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
+ const unsigned char *key,
+ unsigned int keybits )
{
int idx, ret;
size_t i;
mbedtls_camellia_context cty;
uint32_t *RK;
uint32_t *SK;
+ CAMELLIA_VALIDATE_RET( ctx != NULL );
+ CAMELLIA_VALIDATE_RET( key != NULL );
mbedtls_camellia_init( &cty );
@@ -495,6 +509,11 @@
{
int NR;
uint32_t *RK, X[4];
+ CAMELLIA_VALIDATE_RET( ctx != NULL );
+ CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+ mode == MBEDTLS_CAMELLIA_DECRYPT );
+ CAMELLIA_VALIDATE_RET( input != NULL );
+ CAMELLIA_VALIDATE_RET( output != NULL );
( (void) mode );
@@ -552,14 +571,20 @@
* Camellia-CBC buffer encryption/decryption
*/
int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
{
int i;
unsigned char temp[16];
+ CAMELLIA_VALIDATE_RET( ctx != NULL );
+ CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+ mode == MBEDTLS_CAMELLIA_DECRYPT );
+ CAMELLIA_VALIDATE_RET( iv != NULL );
+ CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
+ CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
if( length % 16 )
return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
@@ -614,7 +639,18 @@
unsigned char *output )
{
int c;
- size_t n = *iv_off;
+ size_t n;
+ CAMELLIA_VALIDATE_RET( ctx != NULL );
+ CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+ mode == MBEDTLS_CAMELLIA_DECRYPT );
+ CAMELLIA_VALIDATE_RET( iv != NULL );
+ CAMELLIA_VALIDATE_RET( iv_off != NULL );
+ CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
+ CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+ n = *iv_off;
+ if( n >= 16 )
+ return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
if( mode == MBEDTLS_CAMELLIA_DECRYPT )
{
@@ -662,7 +698,17 @@
unsigned char *output )
{
int c, i;
- size_t n = *nc_off;
+ size_t n;
+ CAMELLIA_VALIDATE_RET( ctx != NULL );
+ CAMELLIA_VALIDATE_RET( nonce_counter != NULL );
+ CAMELLIA_VALIDATE_RET( stream_block != NULL );
+ CAMELLIA_VALIDATE_RET( nc_off != NULL );
+ CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
+ CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+ n = *nc_off;
+ if( n >= 16 )
+ return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
while( length-- )
{
diff --git a/library/ccm.c b/library/ccm.c
index 90cab8e..01e58b0 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -52,6 +52,11 @@
#if !defined(MBEDTLS_CCM_ALT)
+#define CCM_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT )
+#define CCM_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#define CCM_ENCRYPT 0
#define CCM_DECRYPT 1
@@ -60,6 +65,7 @@
*/
void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
{
+ CCM_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
}
@@ -71,6 +77,9 @@
int ret;
const mbedtls_cipher_info_t *cipher_info;
+ CCM_VALIDATE_RET( ctx != NULL );
+ CCM_VALIDATE_RET( key != NULL );
+
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -97,6 +106,8 @@
*/
void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
{
+ if( ctx == NULL )
+ return;
mbedtls_cipher_free( &ctx->cipher_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
}
@@ -310,6 +321,12 @@
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len )
{
+ CCM_VALIDATE_RET( ctx != NULL );
+ CCM_VALIDATE_RET( iv != NULL );
+ CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+ CCM_VALIDATE_RET( length == 0 || input != NULL );
+ CCM_VALIDATE_RET( length == 0 || output != NULL );
+ CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
add, add_len, input, output, tag, tag_len ) );
}
@@ -320,6 +337,12 @@
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len )
{
+ CCM_VALIDATE_RET( ctx != NULL );
+ CCM_VALIDATE_RET( iv != NULL );
+ CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+ CCM_VALIDATE_RET( length == 0 || input != NULL );
+ CCM_VALIDATE_RET( length == 0 || output != NULL );
+ CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
if( tag_len == 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -341,6 +364,13 @@
unsigned char i;
int diff;
+ CCM_VALIDATE_RET( ctx != NULL );
+ CCM_VALIDATE_RET( iv != NULL );
+ CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+ CCM_VALIDATE_RET( length == 0 || input != NULL );
+ CCM_VALIDATE_RET( length == 0 || output != NULL );
+ CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
iv, iv_len, add, add_len,
input, output, check_tag, tag_len ) ) != 0 )
@@ -367,6 +397,13 @@
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len )
{
+ CCM_VALIDATE_RET( ctx != NULL );
+ CCM_VALIDATE_RET( iv != NULL );
+ CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+ CCM_VALIDATE_RET( length == 0 || input != NULL );
+ CCM_VALIDATE_RET( length == 0 || output != NULL );
+ CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
if( tag_len == 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
diff --git a/library/chacha20.c b/library/chacha20.c
index d14a51e..0757163 100644
--- a/library/chacha20.c
+++ b/library/chacha20.c
@@ -53,6 +53,12 @@
#define inline __inline
#endif
+/* Parameter validation macros */
+#define CHACHA20_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
+#define CHACHA20_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#define BYTES_TO_U32_LE( data, offset ) \
( (uint32_t) data[offset] \
| (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \
@@ -181,14 +187,13 @@
void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
{
- if( ctx != NULL )
- {
- mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
- mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
+ CHACHA20_VALIDATE( ctx != NULL );
- /* Initially, there's no keystream bytes available */
- ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
- }
+ mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
+ mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
+
+ /* Initially, there's no keystream bytes available */
+ ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
}
void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
@@ -202,10 +207,8 @@
int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
const unsigned char key[32] )
{
- if( ( ctx == NULL ) || ( key == NULL ) )
- {
- return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
- }
+ CHACHA20_VALIDATE_RET( ctx != NULL );
+ CHACHA20_VALIDATE_RET( key != NULL );
/* ChaCha20 constants - the string "expand 32-byte k" */
ctx->state[0] = 0x61707865;
@@ -230,10 +233,8 @@
const unsigned char nonce[12],
uint32_t counter )
{
- if( ( ctx == NULL ) || ( nonce == NULL ) )
- {
- return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
- }
+ CHACHA20_VALIDATE_RET( ctx != NULL );
+ CHACHA20_VALIDATE_RET( nonce != NULL );
/* Counter */
ctx->state[12] = counter;
@@ -259,15 +260,9 @@
size_t offset = 0U;
size_t i;
- if( ctx == NULL )
- {
- return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
- }
- else if( ( size > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) )
- {
- /* input and output pointers are allowed to be NULL only if size == 0 */
- return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
- }
+ CHACHA20_VALIDATE_RET( ctx != NULL );
+ CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
+ CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
/* Use leftover keystream bytes, if available */
while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
@@ -332,6 +327,11 @@
mbedtls_chacha20_context ctx;
int ret;
+ CHACHA20_VALIDATE_RET( key != NULL );
+ CHACHA20_VALIDATE_RET( nonce != NULL );
+ CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
+ CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
+
mbedtls_chacha20_init( &ctx );
ret = mbedtls_chacha20_setkey( &ctx, key );
diff --git a/library/chachapoly.c b/library/chachapoly.c
index 860f877..dc643dd 100644
--- a/library/chachapoly.c
+++ b/library/chachapoly.c
@@ -44,6 +44,12 @@
#if !defined(MBEDTLS_CHACHAPOLY_ALT)
+/* Parameter validation macros */
+#define CHACHAPOLY_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
+#define CHACHAPOLY_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#define CHACHAPOLY_STATE_INIT ( 0 )
#define CHACHAPOLY_STATE_AAD ( 1 )
#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
@@ -90,39 +96,35 @@
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
{
- if( ctx != NULL )
- {
- mbedtls_chacha20_init( &ctx->chacha20_ctx );
- mbedtls_poly1305_init( &ctx->poly1305_ctx );
- ctx->aad_len = 0U;
- ctx->ciphertext_len = 0U;
- ctx->state = CHACHAPOLY_STATE_INIT;
- ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
- }
+ CHACHAPOLY_VALIDATE( ctx != NULL );
+
+ mbedtls_chacha20_init( &ctx->chacha20_ctx );
+ mbedtls_poly1305_init( &ctx->poly1305_ctx );
+ ctx->aad_len = 0U;
+ ctx->ciphertext_len = 0U;
+ ctx->state = CHACHAPOLY_STATE_INIT;
+ ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
}
void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
{
- if( ctx != NULL )
- {
- mbedtls_chacha20_free( &ctx->chacha20_ctx );
- mbedtls_poly1305_free( &ctx->poly1305_ctx );
- ctx->aad_len = 0U;
- ctx->ciphertext_len = 0U;
- ctx->state = CHACHAPOLY_STATE_INIT;
- ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
- }
+ if( ctx == NULL )
+ return;
+
+ mbedtls_chacha20_free( &ctx->chacha20_ctx );
+ mbedtls_poly1305_free( &ctx->poly1305_ctx );
+ ctx->aad_len = 0U;
+ ctx->ciphertext_len = 0U;
+ ctx->state = CHACHAPOLY_STATE_INIT;
+ ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
}
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
const unsigned char key[32] )
{
int ret;
-
- if( ( ctx == NULL ) || ( key == NULL ) )
- {
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
+ CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+ CHACHAPOLY_VALIDATE_RET( key != NULL );
ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
@@ -135,11 +137,8 @@
{
int ret;
unsigned char poly1305_key[64];
-
- if( ( ctx == NULL ) || ( nonce == NULL ) )
- {
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
+ CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+ CHACHAPOLY_VALIDATE_RET( nonce != NULL );
/* Set counter = 0, will be update to 1 when generating Poly1305 key */
ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
@@ -176,19 +175,11 @@
const unsigned char *aad,
size_t aad_len )
{
- if( ctx == NULL )
- {
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
- else if( ( aad_len > 0U ) && ( aad == NULL ) )
- {
- /* aad pointer is allowed to be NULL if aad_len == 0 */
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
- else if( ctx->state != CHACHAPOLY_STATE_AAD )
- {
+ CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+ CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
+
+ if( ctx->state != CHACHAPOLY_STATE_AAD )
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
- }
ctx->aad_len += aad_len;
@@ -201,18 +192,12 @@
unsigned char *output )
{
int ret;
+ CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+ CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );
+ CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );
- if( ctx == NULL )
- {
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
- else if( ( len > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) )
- {
- /* input and output pointers are allowed to be NULL if len == 0 */
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
- else if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
- ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
+ if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
+ ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
{
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
}
@@ -257,12 +242,10 @@
{
int ret;
unsigned char len_block[16];
+ CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+ CHACHAPOLY_VALIDATE_RET( mac != NULL );
- if( ( ctx == NULL ) || ( mac == NULL ) )
- {
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
- else if( ctx->state == CHACHAPOLY_STATE_INIT )
+ if( ctx->state == CHACHAPOLY_STATE_INIT )
{
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
}
@@ -350,6 +333,13 @@
unsigned char *output,
unsigned char tag[16] )
{
+ CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+ CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+ CHACHAPOLY_VALIDATE_RET( tag != NULL );
+ CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
+ CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL );
+ CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL );
+
return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
length, nonce, aad, aad_len,
input, output, tag ) );
@@ -368,9 +358,12 @@
unsigned char check_tag[16];
size_t i;
int diff;
-
- if( tag == NULL )
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
+ CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+ CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+ CHACHAPOLY_VALIDATE_RET( tag != NULL );
+ CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
+ CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL );
+ CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL );
if( ( ret = chachapoly_crypt_and_tag( ctx,
MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
diff --git a/library/cipher.c b/library/cipher.c
index 5d7e53f..63f1f41 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -70,6 +70,11 @@
#define mbedtls_free free
#endif
+#define CIPHER_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
+#define CIPHER_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/* Compare the contents of two buffers in constant time.
* Returns 0 if the contents are bitwise identical, otherwise returns
@@ -87,7 +92,7 @@
for( diff = 0, i = 0; i < len; i++ )
diff |= p1[i] ^ p2[i];
- return (int)diff;
+ return( (int)diff );
}
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
@@ -159,6 +164,7 @@
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
{
+ CIPHER_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
}
@@ -208,7 +214,8 @@
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
const mbedtls_cipher_info_t *cipher_info )
{
- if( NULL == cipher_info || NULL == ctx )
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ if( cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
@@ -269,17 +276,12 @@
int key_bitlen,
const mbedtls_operation_t operation )
{
- if( NULL == ctx || NULL == ctx->cipher_info ||
- NULL == ctx->cipher_ctx )
- {
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( key != NULL );
+ CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
+ operation == MBEDTLS_DECRYPT );
+ if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
- if( operation != MBEDTLS_DECRYPT &&
- operation != MBEDTLS_ENCRYPT )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ctx->psa_enabled == 1 )
@@ -364,27 +366,27 @@
MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
{
- return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
- ctx->key_bitlen );
+ return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
+ ctx->key_bitlen ) );
}
if( MBEDTLS_DECRYPT == operation )
- return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
- ctx->key_bitlen );
-
+ return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
+ ctx->key_bitlen ) );
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len )
+ const unsigned char *iv,
+ size_t iv_len )
{
size_t actual_iv_size;
- if( NULL == ctx || NULL == ctx->cipher_info )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- else if( NULL == iv && iv_len != 0 )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ctx->psa_enabled == 1 )
{
@@ -395,9 +397,6 @@
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
- if( NULL == iv && iv_len == 0 )
- ctx->iv_size = 0;
-
/* avoid buffer overflow in ctx->iv */
if( iv_len > MBEDTLS_MAX_IV_LENGTH )
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
@@ -436,7 +435,8 @@
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
{
- if( NULL == ctx || NULL == ctx->cipher_info )
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -457,7 +457,9 @@
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len )
{
- if( NULL == ctx || NULL == ctx->cipher_info )
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -473,8 +475,8 @@
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
- return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
- ctx->iv, ctx->iv_size, ad, ad_len );
+ return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
+ ctx->iv, ctx->iv_size, ad, ad_len ) );
}
#endif
@@ -494,8 +496,8 @@
if ( result != 0 )
return( result );
- return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- ad, ad_len );
+ return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+ ad, ad_len ) );
}
#endif
@@ -507,12 +509,14 @@
size_t ilen, unsigned char *output, size_t *olen )
{
int ret;
- size_t block_size = 0;
+ size_t block_size;
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
- {
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ctx->psa_enabled == 1 )
@@ -547,8 +551,8 @@
if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
{
*olen = ilen;
- return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
- output );
+ return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
+ output ) );
}
#endif
@@ -556,14 +560,14 @@
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
{
*olen = ilen;
- return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- ilen, input, output );
+ return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+ ilen, input, output ) );
}
#endif
if ( 0 == block_size )
{
- return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+ return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
}
if( input == output &&
@@ -626,7 +630,7 @@
{
if( 0 == block_size )
{
- return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+ return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
}
/* Encryption: only cache partial blocks
@@ -927,7 +931,10 @@
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen )
{
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -1007,8 +1014,8 @@
/* Set output size for decryption */
if( MBEDTLS_DECRYPT == ctx->operation )
- return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
- olen );
+ return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
+ olen ) );
/* Set output size for encryption */
*olen = mbedtls_cipher_get_block_size( ctx );
@@ -1025,8 +1032,9 @@
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
mbedtls_cipher_padding_t mode )
{
- if( NULL == ctx ||
- MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
+ CIPHER_VALIDATE_RET( ctx != NULL );
+
+ if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
@@ -1087,7 +1095,9 @@
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len )
{
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+ if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( MBEDTLS_ENCRYPT != ctx->operation )
@@ -1130,8 +1140,12 @@
unsigned char check_tag[16];
int ret;
- if( NULL == ctx || NULL == ctx->cipher_info ||
- MBEDTLS_DECRYPT != ctx->operation )
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ if( MBEDTLS_DECRYPT != ctx->operation )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
@@ -1204,6 +1218,12 @@
int ret;
size_t finish_olen;
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ctx->psa_enabled == 1 )
{
@@ -1292,6 +1312,14 @@
unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len )
{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ctx->psa_enabled == 1 )
{
@@ -1371,6 +1399,14 @@
unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len )
{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ctx->psa_enabled == 1 )
{
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index fb12157..0db7beb 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -102,7 +102,8 @@
/*
* Initialize with an empty key
*/
- if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
@@ -120,8 +121,9 @@
const unsigned char *custom,
size_t len )
{
- return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
- MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
+ return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy,
+ custom, len,
+ MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
}
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
@@ -136,17 +138,20 @@
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
}
-void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
+void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
+ int resistance )
{
ctx->prediction_resistance = resistance;
}
-void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
+void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
+ size_t len )
{
ctx->entropy_len = len;
}
-void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
+void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
+ int interval )
{
ctx->reseed_interval = interval;
}
@@ -154,7 +159,8 @@
static int block_cipher_df( unsigned char *output,
const unsigned char *data, size_t data_len )
{
- unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
+ unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
+ MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
@@ -168,7 +174,8 @@
if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
- memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
+ memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
+ MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
mbedtls_aes_init( &aes_ctx );
/*
@@ -193,7 +200,8 @@
for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
key[i] = i;
- if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
@@ -215,7 +223,8 @@
use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
- if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
+ chain, chain ) ) != 0 )
{
goto exit;
}
@@ -232,7 +241,8 @@
/*
* Do final encryption with reduced data
*/
- if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
@@ -241,7 +251,8 @@
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
{
- if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
+ iv, iv ) ) != 0 )
{
goto exit;
}
@@ -277,7 +288,7 @@
* ctx->counter = V
*/
static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
- const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
+ const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
{
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = tmp;
@@ -298,8 +309,11 @@
/*
* Crypt counter block
*/
- if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
+ ctx->counter, p ) ) != 0 )
+ {
goto exit;
+ }
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
}
@@ -310,9 +324,13 @@
/*
* Update key and counter
*/
- if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ {
goto exit;
- memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
+ }
+ memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
+ MBEDTLS_CTR_DRBG_BLOCKSIZE );
exit:
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
@@ -496,11 +514,14 @@
/*
* Crypt counter block
*/
- if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
+ ctx->counter, tmp ) ) != 0 )
+ {
goto exit;
+ }
- use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
- output_len;
+ use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE )
+ ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
/*
* Copy random block to destination
*/
@@ -520,7 +541,8 @@
return( 0 );
}
-int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
+int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
+ size_t output_len )
{
int ret;
mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
@@ -541,7 +563,8 @@
}
#if defined(MBEDTLS_FS_IO)
-int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
+int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx,
+ const char *path )
{
int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
FILE *f;
@@ -550,13 +573,19 @@
if( ( f = fopen( path, "wb" ) ) == NULL )
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
- if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
+ if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
+ MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
goto exit;
- if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
+ if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) !=
+ MBEDTLS_CTR_DRBG_MAX_INPUT )
+ {
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
+ }
else
+ {
ret = 0;
+ }
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -565,7 +594,8 @@
return( ret );
}
-int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
+int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
+ const char *path )
{
int ret = 0;
FILE *f = NULL;
@@ -679,7 +709,7 @@
test_offset = 0;
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
- (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
+ (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
@@ -700,7 +730,7 @@
test_offset = 0;
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
- (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
+ (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
diff --git a/library/debug.c b/library/debug.c
index 824cd02..6e1efbf 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -35,6 +35,7 @@
#define mbedtls_free free
#define mbedtls_time_t time_t
#define mbedtls_snprintf snprintf
+#define mbedtls_vsnprintf vsnprintf
#endif
#include "mbedtls/debug.h"
@@ -90,20 +91,7 @@
return;
va_start( argp, format );
-#if defined(_WIN32)
-#if defined(_TRUNCATE) && !defined(__MINGW32__)
- ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
-#else
- ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
- if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE )
- {
- str[DEBUG_BUF_SIZE-1] = '\0';
- ret = -1;
- }
-#endif
-#else
- ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
-#endif
+ ret = mbedtls_vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
va_end( argp );
if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 )
diff --git a/library/dhm.c b/library/dhm.c
index 82cbb0c..fb6937e 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -60,6 +60,11 @@
#if !defined(MBEDTLS_DHM_ALT)
+#define DHM_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
+#define DHM_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
/*
* helper to validate the mbedtls_mpi size and import it
*/
@@ -121,6 +126,7 @@
void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
{
+ DHM_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
}
@@ -132,6 +138,9 @@
const unsigned char *end )
{
int ret;
+ DHM_VALIDATE_RET( ctx != NULL );
+ DHM_VALIDATE_RET( p != NULL && *p != NULL );
+ DHM_VALIDATE_RET( end != NULL );
if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
@@ -157,6 +166,10 @@
int ret, count = 0;
size_t n1, n2, n3;
unsigned char *p;
+ DHM_VALIDATE_RET( ctx != NULL );
+ DHM_VALIDATE_RET( output != NULL );
+ DHM_VALIDATE_RET( olen != NULL );
+ DHM_VALIDATE_RET( f_rng != NULL );
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
@@ -227,9 +240,9 @@
const mbedtls_mpi *G )
{
int ret;
-
- if( ctx == NULL || P == NULL || G == NULL )
- return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+ DHM_VALIDATE_RET( ctx != NULL );
+ DHM_VALIDATE_RET( P != NULL );
+ DHM_VALIDATE_RET( G != NULL );
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
@@ -248,8 +261,10 @@
const unsigned char *input, size_t ilen )
{
int ret;
+ DHM_VALIDATE_RET( ctx != NULL );
+ DHM_VALIDATE_RET( input != NULL );
- if( ctx == NULL || ilen < 1 || ilen > ctx->len )
+ if( ilen < 1 || ilen > ctx->len )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
@@ -267,8 +282,11 @@
void *p_rng )
{
int ret, count = 0;
+ DHM_VALIDATE_RET( ctx != NULL );
+ DHM_VALIDATE_RET( output != NULL );
+ DHM_VALIDATE_RET( f_rng != NULL );
- if( ctx == NULL || olen < 1 || olen > ctx->len )
+ if( olen < 1 || olen > ctx->len )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
@@ -380,8 +398,11 @@
{
int ret;
mbedtls_mpi GYb;
+ DHM_VALIDATE_RET( ctx != NULL );
+ DHM_VALIDATE_RET( output != NULL );
+ DHM_VALIDATE_RET( olen != NULL );
- if( ctx == NULL || output_size < ctx->len )
+ if( output_size < ctx->len )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
@@ -428,11 +449,19 @@
*/
void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
{
- mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf );
- mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP );
- mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
- mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X );
- mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->P );
+ if( ctx == NULL )
+ return;
+
+ mbedtls_mpi_free( &ctx->pX );
+ mbedtls_mpi_free( &ctx->Vf );
+ mbedtls_mpi_free( &ctx->Vi );
+ mbedtls_mpi_free( &ctx->RP );
+ mbedtls_mpi_free( &ctx->K );
+ mbedtls_mpi_free( &ctx->GY );
+ mbedtls_mpi_free( &ctx->GX );
+ mbedtls_mpi_free( &ctx->X );
+ mbedtls_mpi_free( &ctx->G );
+ mbedtls_mpi_free( &ctx->P );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
}
@@ -449,7 +478,12 @@
unsigned char *p, *end;
#if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_context pem;
+#endif /* MBEDTLS_PEM_PARSE_C */
+ DHM_VALIDATE_RET( dhm != NULL );
+ DHM_VALIDATE_RET( dhmin != NULL );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_init( &pem );
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
@@ -596,6 +630,8 @@
int ret;
size_t n;
unsigned char *buf;
+ DHM_VALIDATE_RET( dhm != NULL );
+ DHM_VALIDATE_RET( path != NULL );
if( ( ret = load_file( path, &buf, &n ) ) != 0 )
return( ret );
diff --git a/library/ecdh.c b/library/ecdh.c
index d68db8a..da95c60 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -35,9 +35,16 @@
#if defined(MBEDTLS_ECDH_C)
#include "mbedtls/ecdh.h"
+#include "mbedtls/platform_util.h"
#include <string.h>
+/* Parameter validation macros based on platform_util.h */
+#define ECDH_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECDH_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
#endif
@@ -78,6 +85,10 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
+ ECDH_VALIDATE_RET( grp != NULL );
+ ECDH_VALIDATE_RET( d != NULL );
+ ECDH_VALIDATE_RET( Q != NULL );
+ ECDH_VALIDATE_RET( f_rng != NULL );
return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) );
}
#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
@@ -123,6 +134,10 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
+ ECDH_VALIDATE_RET( grp != NULL );
+ ECDH_VALIDATE_RET( Q != NULL );
+ ECDH_VALIDATE_RET( d != NULL );
+ ECDH_VALIDATE_RET( z != NULL );
return( ecdh_compute_shared_restartable( grp, z, Q, d,
f_rng, p_rng, NULL ) );
}
@@ -146,6 +161,8 @@
*/
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
{
+ ECDH_VALIDATE( ctx != NULL );
+
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
ecdh_init_internal( ctx );
mbedtls_ecp_point_init( &ctx->Vi );
@@ -181,8 +198,7 @@
*/
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
{
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ ECDH_VALIDATE_RET( ctx != NULL );
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
return( ecdh_setup_internal( ctx, grp_id ) );
@@ -218,8 +234,7 @@
*/
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx )
{
- if( ctx == NULL )
- return;
+ ECDH_VALIDATE( ctx != NULL );
ctx->restart_enabled = 1;
}
@@ -318,9 +333,10 @@
void *p_rng )
{
int restart_enabled = 0;
-
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ ECDH_VALIDATE_RET( ctx != NULL );
+ ECDH_VALIDATE_RET( olen != NULL );
+ ECDH_VALIDATE_RET( buf != NULL );
+ ECDH_VALIDATE_RET( f_rng != NULL );
#if defined(MBEDTLS_ECP_RESTARTABLE)
restart_enabled = ctx->restart_enabled;
@@ -366,9 +382,10 @@
{
int ret;
mbedtls_ecp_group_id grp_id;
-
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ ECDH_VALIDATE_RET( ctx != NULL );
+ ECDH_VALIDATE_RET( buf != NULL );
+ ECDH_VALIDATE_RET( *buf != NULL );
+ ECDH_VALIDATE_RET( end != NULL );
if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) )
!= 0 )
@@ -420,9 +437,10 @@
mbedtls_ecdh_side side )
{
int ret;
-
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ ECDH_VALIDATE_RET( ctx != NULL );
+ ECDH_VALIDATE_RET( key != NULL );
+ ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
+ side == MBEDTLS_ECDH_THEIRS );
if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
return( ret );
@@ -488,9 +506,10 @@
void *p_rng )
{
int restart_enabled = 0;
-
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ ECDH_VALIDATE_RET( ctx != NULL );
+ ECDH_VALIDATE_RET( olen != NULL );
+ ECDH_VALIDATE_RET( buf != NULL );
+ ECDH_VALIDATE_RET( f_rng != NULL );
#if defined(MBEDTLS_ECP_RESTARTABLE)
restart_enabled = ctx->restart_enabled;
@@ -535,8 +554,8 @@
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
const unsigned char *buf, size_t blen )
{
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ ECDH_VALIDATE_RET( ctx != NULL );
+ ECDH_VALIDATE_RET( buf != NULL );
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
return( ecdh_read_public_internal( ctx, buf, blen ) );
@@ -607,9 +626,9 @@
void *p_rng )
{
int restart_enabled = 0;
-
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ ECDH_VALIDATE_RET( ctx != NULL );
+ ECDH_VALIDATE_RET( olen != NULL );
+ ECDH_VALIDATE_RET( buf != NULL );
#if defined(MBEDTLS_ECP_RESTARTABLE)
restart_enabled = ctx->restart_enabled;
diff --git a/library/ecdsa.c b/library/ecdsa.c
index a62c14c..dc19384 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -50,6 +50,14 @@
#define mbedtls_free free
#endif
+#include "mbedtls/platform_util.h"
+
+/* Parameter validation macros based on platform_util.h */
+#define ECDSA_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECDSA_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if defined(MBEDTLS_ECP_RESTARTABLE)
/*
@@ -377,6 +385,13 @@
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
+ ECDSA_VALIDATE_RET( grp != NULL );
+ ECDSA_VALIDATE_RET( r != NULL );
+ ECDSA_VALIDATE_RET( s != NULL );
+ ECDSA_VALIDATE_RET( d != NULL );
+ ECDSA_VALIDATE_RET( f_rng != NULL );
+ ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+
return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
f_rng, p_rng, NULL ) );
}
@@ -456,6 +471,12 @@
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg )
{
+ ECDSA_VALIDATE_RET( grp != NULL );
+ ECDSA_VALIDATE_RET( r != NULL );
+ ECDSA_VALIDATE_RET( s != NULL );
+ ECDSA_VALIDATE_RET( d != NULL );
+ ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+
return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) );
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@@ -574,9 +595,17 @@
* Verify ECDSA signature of hashed message
*/
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
- const unsigned char *buf, size_t blen,
- const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
+ const unsigned char *buf, size_t blen,
+ const mbedtls_ecp_point *Q,
+ const mbedtls_mpi *r,
+ const mbedtls_mpi *s)
{
+ ECDSA_VALIDATE_RET( grp != NULL );
+ ECDSA_VALIDATE_RET( Q != NULL );
+ ECDSA_VALIDATE_RET( r != NULL );
+ ECDSA_VALIDATE_RET( s != NULL );
+ ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+
return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
}
#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
@@ -618,6 +647,10 @@
{
int ret;
mbedtls_mpi r, s;
+ ECDSA_VALIDATE_RET( ctx != NULL );
+ ECDSA_VALIDATE_RET( hash != NULL );
+ ECDSA_VALIDATE_RET( sig != NULL );
+ ECDSA_VALIDATE_RET( slen != NULL );
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s );
@@ -652,12 +685,17 @@
/*
* Compute and write signature
*/
-int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hlen,
- unsigned char *sig, size_t *slen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
+int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
+ mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hlen,
+ unsigned char *sig, size_t *slen,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
{
+ ECDSA_VALIDATE_RET( ctx != NULL );
+ ECDSA_VALIDATE_RET( hash != NULL );
+ ECDSA_VALIDATE_RET( sig != NULL );
+ ECDSA_VALIDATE_RET( slen != NULL );
return( mbedtls_ecdsa_write_signature_restartable(
ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
}
@@ -669,6 +707,10 @@
unsigned char *sig, size_t *slen,
mbedtls_md_type_t md_alg )
{
+ ECDSA_VALIDATE_RET( ctx != NULL );
+ ECDSA_VALIDATE_RET( hash != NULL );
+ ECDSA_VALIDATE_RET( sig != NULL );
+ ECDSA_VALIDATE_RET( slen != NULL );
return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen,
NULL, NULL ) );
}
@@ -681,6 +723,9 @@
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen )
{
+ ECDSA_VALIDATE_RET( ctx != NULL );
+ ECDSA_VALIDATE_RET( hash != NULL );
+ ECDSA_VALIDATE_RET( sig != NULL );
return( mbedtls_ecdsa_read_signature_restartable(
ctx, hash, hlen, sig, slen, NULL ) );
}
@@ -698,6 +743,9 @@
const unsigned char *end = sig + slen;
size_t len;
mbedtls_mpi r, s;
+ ECDSA_VALIDATE_RET( ctx != NULL );
+ ECDSA_VALIDATE_RET( hash != NULL );
+ ECDSA_VALIDATE_RET( sig != NULL );
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s );
@@ -752,8 +800,16 @@
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
- mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
+ int ret = 0;
+ ECDSA_VALIDATE_RET( ctx != NULL );
+ ECDSA_VALIDATE_RET( f_rng != NULL );
+
+ ret = mbedtls_ecp_group_load( &ctx->grp, gid );
+ if( ret != 0 )
+ return( ret );
+
+ return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d,
+ &ctx->Q, f_rng, p_rng ) );
}
#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */
@@ -763,6 +819,8 @@
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
{
int ret;
+ ECDSA_VALIDATE_RET( ctx != NULL );
+ ECDSA_VALIDATE_RET( key != NULL );
if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ||
@@ -779,6 +837,8 @@
*/
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
{
+ ECDSA_VALIDATE( ctx != NULL );
+
mbedtls_ecp_keypair_init( ctx );
}
@@ -787,6 +847,9 @@
*/
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
{
+ if( ctx == NULL )
+ return;
+
mbedtls_ecp_keypair_free( ctx );
}
@@ -796,6 +859,8 @@
*/
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
{
+ ECDSA_VALIDATE( ctx != NULL );
+
mbedtls_ecp_restart_init( &ctx->ecp );
ctx->ver = NULL;
@@ -810,6 +875,9 @@
*/
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx )
{
+ if( ctx == NULL )
+ return;
+
mbedtls_ecp_restart_free( &ctx->ecp );
ecdsa_restart_ver_free( ctx->ver );
diff --git a/library/ecjpake.c b/library/ecjpake.c
index ec5a400..b276514 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -33,11 +33,18 @@
#if defined(MBEDTLS_ECJPAKE_C)
#include "mbedtls/ecjpake.h"
+#include "mbedtls/platform_util.h"
#include <string.h>
#if !defined(MBEDTLS_ECJPAKE_ALT)
+/* Parameter validation macros based on platform_util.h */
+#define ECJPAKE_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECJPAKE_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
/*
* Convert a mbedtls_ecjpake_role to identifier string
*/
@@ -54,8 +61,7 @@
*/
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
{
- if( ctx == NULL )
- return;
+ ECJPAKE_VALIDATE( ctx != NULL );
ctx->md_info = NULL;
mbedtls_ecp_group_init( &ctx->grp );
@@ -106,6 +112,11 @@
{
int ret;
+ ECJPAKE_VALIDATE_RET( ctx != NULL );
+ ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT ||
+ role == MBEDTLS_ECJPAKE_SERVER );
+ ECJPAKE_VALIDATE_RET( secret != NULL || len == 0 );
+
ctx->role = role;
if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
@@ -127,6 +138,8 @@
*/
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
{
+ ECJPAKE_VALIDATE_RET( ctx != NULL );
+
if( ctx->md_info == NULL ||
ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
ctx->s.p == NULL )
@@ -504,6 +517,9 @@
const unsigned char *buf,
size_t len )
{
+ ECJPAKE_VALIDATE_RET( ctx != NULL );
+ ECJPAKE_VALIDATE_RET( buf != NULL );
+
return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
&ctx->grp.G,
&ctx->Xp1, &ctx->Xp2, ID_PEER,
@@ -518,6 +534,11 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
+ ECJPAKE_VALIDATE_RET( ctx != NULL );
+ ECJPAKE_VALIDATE_RET( buf != NULL );
+ ECJPAKE_VALIDATE_RET( olen != NULL );
+ ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
&ctx->grp.G,
&ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
@@ -560,6 +581,9 @@
mbedtls_ecp_group grp;
mbedtls_ecp_point G; /* C: GB, S: GA */
+ ECJPAKE_VALIDATE_RET( ctx != NULL );
+ ECJPAKE_VALIDATE_RET( buf != NULL );
+
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &G );
@@ -652,6 +676,11 @@
const unsigned char *end = buf + len;
size_t ec_len;
+ ECJPAKE_VALIDATE_RET( ctx != NULL );
+ ECJPAKE_VALIDATE_RET( buf != NULL );
+ ECJPAKE_VALIDATE_RET( olen != NULL );
+ ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
mbedtls_ecp_point_init( &G );
mbedtls_ecp_point_init( &Xm );
mbedtls_mpi_init( &xm );
@@ -727,6 +756,11 @@
unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
size_t x_bytes;
+ ECJPAKE_VALIDATE_RET( ctx != NULL );
+ ECJPAKE_VALIDATE_RET( buf != NULL );
+ ECJPAKE_VALIDATE_RET( olen != NULL );
+ ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
*olen = mbedtls_md_get_size( ctx->md_info );
if( len < *olen )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
@@ -917,7 +951,7 @@
0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
};
-/* Load my private keys and generate the correponding public keys */
+/* Load my private keys and generate the corresponding public keys */
static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
const unsigned char *xm1, size_t len1,
const unsigned char *xm2, size_t len2 )
diff --git a/library/ecp.c b/library/ecp.c
index 7fefb4c..ecea591 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -86,6 +86,12 @@
#if !defined(MBEDTLS_ECP_ALT)
+/* Parameter validation macros based on platform_util.h */
+#define ECP_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECP_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -238,6 +244,7 @@
*/
void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx )
{
+ ECP_VALIDATE( ctx != NULL );
ctx->ops_done = 0;
ctx->depth = 0;
ctx->rsm = NULL;
@@ -268,6 +275,8 @@
mbedtls_ecp_restart_ctx *rs_ctx,
unsigned ops )
{
+ ECP_VALIDATE_RET( grp != NULL );
+
if( rs_ctx != NULL && ecp_max_ops != 0 )
{
/* scale depending on curve size: the chosen reference is 256-bit,
@@ -496,6 +505,9 @@
{
const mbedtls_ecp_curve_info *curve_info;
+ if( name == NULL )
+ return( NULL );
+
for( curve_info = mbedtls_ecp_curve_list();
curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
curve_info++ )
@@ -526,8 +538,7 @@
*/
void mbedtls_ecp_point_init( mbedtls_ecp_point *pt )
{
- if( pt == NULL )
- return;
+ ECP_VALIDATE( pt != NULL );
mbedtls_mpi_init( &pt->X );
mbedtls_mpi_init( &pt->Y );
@@ -539,8 +550,7 @@
*/
void mbedtls_ecp_group_init( mbedtls_ecp_group *grp )
{
- if( grp == NULL )
- return;
+ ECP_VALIDATE( grp != NULL );
grp->id = MBEDTLS_ECP_DP_NONE;
mbedtls_mpi_init( &grp->P );
@@ -564,8 +574,7 @@
*/
void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key )
{
- if( key == NULL )
- return;
+ ECP_VALIDATE( key != NULL );
mbedtls_ecp_group_init( &key->grp );
mbedtls_mpi_init( &key->d );
@@ -633,6 +642,8 @@
int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
{
int ret;
+ ECP_VALIDATE_RET( P != NULL );
+ ECP_VALIDATE_RET( Q != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) );
@@ -647,7 +658,10 @@
*/
int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src )
{
- return mbedtls_ecp_group_load( dst, src->id );
+ ECP_VALIDATE_RET( dst != NULL );
+ ECP_VALIDATE_RET( src != NULL );
+
+ return( mbedtls_ecp_group_load( dst, src->id ) );
}
/*
@@ -656,6 +670,7 @@
int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt )
{
int ret;
+ ECP_VALIDATE_RET( pt != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) );
@@ -670,6 +685,8 @@
*/
int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
{
+ ECP_VALIDATE_RET( pt != NULL );
+
return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 );
}
@@ -679,6 +696,9 @@
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q )
{
+ ECP_VALIDATE_RET( P != NULL );
+ ECP_VALIDATE_RET( Q != NULL );
+
if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 &&
mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 &&
mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 )
@@ -696,6 +716,9 @@
const char *x, const char *y )
{
int ret;
+ ECP_VALIDATE_RET( P != NULL );
+ ECP_VALIDATE_RET( x != NULL );
+ ECP_VALIDATE_RET( y != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) );
@@ -708,16 +731,19 @@
/*
* Export a point into unsigned binary data (SEC1 2.3.3)
*/
-int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
- int format, size_t *olen,
- unsigned char *buf, size_t buflen )
+int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
+ const mbedtls_ecp_point *P,
+ int format, size_t *olen,
+ unsigned char *buf, size_t buflen )
{
int ret = 0;
size_t plen;
-
- if( format != MBEDTLS_ECP_PF_UNCOMPRESSED &&
- format != MBEDTLS_ECP_PF_COMPRESSED )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( P != NULL );
+ ECP_VALIDATE_RET( olen != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+ ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
+ format == MBEDTLS_ECP_PF_COMPRESSED );
/*
* Common case: P == 0
@@ -764,11 +790,15 @@
/*
* Import a point from unsigned binary data (SEC1 2.3.4)
*/
-int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
- const unsigned char *buf, size_t ilen )
+int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
+ mbedtls_ecp_point *pt,
+ const unsigned char *buf, size_t ilen )
{
int ret;
size_t plen;
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( pt != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
if( ilen < 1 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -803,11 +833,16 @@
* opaque point <1..2^8-1>;
* } ECPoint;
*/
-int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
- const unsigned char **buf, size_t buf_len )
+int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp,
+ mbedtls_ecp_point *pt,
+ const unsigned char **buf, size_t buf_len )
{
unsigned char data_len;
const unsigned char *buf_start;
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( pt != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+ ECP_VALIDATE_RET( *buf != NULL );
/*
* We must have at least two bytes (1 for length, at least one for data)
@@ -825,7 +860,7 @@
buf_start = *buf;
*buf += data_len;
- return mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len );
+ return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) );
}
/*
@@ -839,6 +874,12 @@
unsigned char *buf, size_t blen )
{
int ret;
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( pt != NULL );
+ ECP_VALIDATE_RET( olen != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+ ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
+ format == MBEDTLS_ECP_PF_COMPRESSED );
/*
* buffer length must be at least one, for our length byte
@@ -867,11 +908,14 @@
{
int ret;
mbedtls_ecp_group_id grp_id;
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+ ECP_VALIDATE_RET( *buf != NULL );
if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, len ) ) != 0 )
return( ret );
- return mbedtls_ecp_group_load( grp, grp_id );
+ return( mbedtls_ecp_group_load( grp, grp_id ) );
}
/*
@@ -883,6 +927,9 @@
{
uint16_t tls_id;
const mbedtls_ecp_curve_info *curve_info;
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+ ECP_VALIDATE_RET( *buf != NULL );
/*
* We expect at least three bytes (see below)
@@ -918,6 +965,9 @@
unsigned char *buf, size_t blen )
{
const mbedtls_ecp_curve_info *curve_info;
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+ ECP_VALIDATE_RET( olen != NULL );
if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -2276,6 +2326,10 @@
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
char is_grp_capable = 0;
#endif
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( R != NULL );
+ ECP_VALIDATE_RET( m != NULL );
+ ECP_VALIDATE_RET( P != NULL );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/* reset ops count for this call if top-level */
@@ -2333,6 +2387,10 @@
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( R != NULL );
+ ECP_VALIDATE_RET( m != NULL );
+ ECP_VALIDATE_RET( P != NULL );
return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) );
}
@@ -2435,6 +2493,12 @@
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
char is_grp_capable = 0;
#endif
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( R != NULL );
+ ECP_VALIDATE_RET( m != NULL );
+ ECP_VALIDATE_RET( P != NULL );
+ ECP_VALIDATE_RET( n != NULL );
+ ECP_VALIDATE_RET( Q != NULL );
if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
@@ -2517,6 +2581,12 @@
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
{
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( R != NULL );
+ ECP_VALIDATE_RET( m != NULL );
+ ECP_VALIDATE_RET( P != NULL );
+ ECP_VALIDATE_RET( n != NULL );
+ ECP_VALIDATE_RET( Q != NULL );
return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) );
}
@@ -2539,8 +2609,12 @@
/*
* Check that a point is valid as a public key
*/
-int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
+int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
+ const mbedtls_ecp_point *pt )
{
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( pt != NULL );
+
/* Must use affine coordinates */
if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
return( MBEDTLS_ERR_ECP_INVALID_KEY );
@@ -2559,8 +2633,12 @@
/*
* Check that an mbedtls_mpi is valid as a private key
*/
-int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d )
+int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
+ const mbedtls_mpi *d )
{
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( d != NULL );
+
#if defined(ECP_MONTGOMERY)
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
{
@@ -2601,7 +2679,13 @@
void *p_rng )
{
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- size_t n_size = ( grp->nbits + 7 ) / 8;
+ size_t n_size;
+
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( d != NULL );
+ ECP_VALIDATE_RET( f_rng != NULL );
+
+ n_size = ( grp->nbits + 7 ) / 8;
#if defined(ECP_MONTGOMERY)
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
@@ -2680,6 +2764,11 @@
void *p_rng )
{
int ret;
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( d != NULL );
+ ECP_VALIDATE_RET( G != NULL );
+ ECP_VALIDATE_RET( Q != NULL );
+ ECP_VALIDATE_RET( f_rng != NULL );
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
@@ -2696,6 +2785,11 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
+ ECP_VALIDATE_RET( grp != NULL );
+ ECP_VALIDATE_RET( d != NULL );
+ ECP_VALIDATE_RET( Q != NULL );
+ ECP_VALIDATE_RET( f_rng != NULL );
+
return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
}
@@ -2706,6 +2800,8 @@
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
int ret;
+ ECP_VALIDATE_RET( key != NULL );
+ ECP_VALIDATE_RET( f_rng != NULL );
if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
return( ret );
@@ -2721,6 +2817,8 @@
int ret;
mbedtls_ecp_point Q;
mbedtls_ecp_group grp;
+ ECP_VALIDATE_RET( pub != NULL );
+ ECP_VALIDATE_RET( prv != NULL );
if( pub->grp.id == MBEDTLS_ECP_DP_NONE ||
pub->grp.id != prv->grp.id ||
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 68e2441..731621d 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -28,11 +28,18 @@
#if defined(MBEDTLS_ECP_C)
#include "mbedtls/ecp.h"
+#include "mbedtls/platform_util.h"
#include <string.h>
#if !defined(MBEDTLS_ECP_ALT)
+/* Parameter validation macros based on platform_util.h */
+#define ECP_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECP_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
@@ -746,6 +753,7 @@
*/
int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
{
+ ECP_VALIDATE_RET( grp != NULL );
mbedtls_ecp_group_free( grp );
grp->id = id;
diff --git a/library/error.c b/library/error.c
index eabee9e..c596f0b 100644
--- a/library/error.c
+++ b/library/error.c
@@ -567,7 +567,7 @@
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" );
+ mbedtls_snprintf( buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" );
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
// END generated code
@@ -618,8 +618,8 @@
#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_BAD_INPUT_DATA) )
+ mbedtls_snprintf( buf, buflen, "ARIA - Bad input data" );
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) )
@@ -672,17 +672,17 @@
#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_BAD_INPUT_DATA) )
+ mbedtls_snprintf( buf, buflen, "BLOWFISH - Bad input data" );
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
+ if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
+ mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
#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_BAD_INPUT_DATA) )
+ mbedtls_snprintf( buf, buflen, "CAMELLIA - Bad input data" );
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) )
@@ -855,16 +855,22 @@
#if defined(MBEDTLS_SHA1_C)
if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
+ if( use_ret == -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA) )
+ mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 input data was malformed" );
#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" );
+ if( use_ret == -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA) )
+ mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 input data was malformed" );
#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" );
+ if( use_ret == -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA) )
+ mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 input data was malformed" );
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_THREADING_C)
diff --git a/library/gcm.c b/library/gcm.c
index c486ef7..675926a 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -57,6 +57,12 @@
#if !defined(MBEDTLS_GCM_ALT)
+/* Parameter validation macros */
+#define GCM_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
+#define GCM_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
/*
* 32-bit integer manipulation macros (big endian)
*/
@@ -85,6 +91,7 @@
*/
void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
{
+ GCM_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
}
@@ -164,6 +171,10 @@
int ret;
const mbedtls_cipher_info_t *cipher_info;
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( key != NULL );
+ GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
+
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -274,6 +285,10 @@
const unsigned char *p;
size_t use_len, olen = 0;
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( iv != NULL );
+ GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+
/* IV and AD are limited to 2^64 bits, so 2^61 bytes */
/* IV is not allowed to be zero length */
if( iv_len == 0 ||
@@ -356,6 +371,10 @@
unsigned char *out_p = output;
size_t use_len, olen = 0;
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( length == 0 || input != NULL );
+ GCM_VALIDATE_RET( length == 0 || output != NULL );
+
if( output > input && (size_t) ( output - input ) < length )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -409,8 +428,14 @@
{
unsigned char work_buf[16];
size_t i;
- uint64_t orig_len = ctx->len * 8;
- uint64_t orig_add_len = ctx->add_len * 8;
+ uint64_t orig_len;
+ uint64_t orig_add_len;
+
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( tag != NULL );
+
+ orig_len = ctx->len * 8;
+ orig_add_len = ctx->add_len * 8;
if( tag_len > 16 || tag_len < 4 )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -452,6 +477,13 @@
{
int ret;
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( iv != NULL );
+ GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+ GCM_VALIDATE_RET( length == 0 || input != NULL );
+ GCM_VALIDATE_RET( length == 0 || output != NULL );
+ GCM_VALIDATE_RET( tag != NULL );
+
if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
return( ret );
@@ -480,6 +512,13 @@
size_t i;
int diff;
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( iv != NULL );
+ GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+ GCM_VALIDATE_RET( tag != NULL );
+ GCM_VALIDATE_RET( length == 0 || input != NULL );
+ GCM_VALIDATE_RET( length == 0 || output != NULL );
+
if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
iv, iv_len, add, add_len,
input, output, tag_len, check_tag ) ) != 0 )
@@ -502,6 +541,8 @@
void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
{
+ if( ctx == NULL )
+ return;
mbedtls_cipher_free( &ctx->cipher_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
}
diff --git a/library/nist_kw.c b/library/nist_kw.c
index 176af9f..317a242 100644
--- a/library/nist_kw.c
+++ b/library/nist_kw.c
@@ -311,7 +311,7 @@
}
mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 );
mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 );
- mbedtls_cipher_finish( &ctx->cipher_ctx, NULL, &olen );
+
return( ret );
}
@@ -528,7 +528,7 @@
mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) );
mbedtls_platform_zeroize( &diff, sizeof( diff ) );
mbedtls_platform_zeroize( A, sizeof( A ) );
- mbedtls_cipher_finish( &ctx->cipher_ctx, NULL, &olen );
+
return( ret );
}
diff --git a/library/pem.c b/library/pem.c
index 6069a23..897c8a0 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -423,9 +423,11 @@
void mbedtls_pem_free( mbedtls_pem_context *ctx )
{
- if( ctx->buf != NULL )
+ if ( ctx->buf != NULL )
+ {
mbedtls_platform_zeroize( ctx->buf, ctx->buflen );
- mbedtls_free( ctx->buf );
+ mbedtls_free( ctx->buf );
+ }
mbedtls_free( ctx->info );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) );
diff --git a/library/pk.c b/library/pk.c
index 72f09ac..a1e278e 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -48,13 +48,18 @@
#include <limits.h>
#include <stdint.h>
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
/*
* Initialise a mbedtls_pk_context
*/
void mbedtls_pk_init( mbedtls_pk_context *ctx )
{
- if( ctx == NULL )
- return;
+ PK_VALIDATE( ctx != NULL );
ctx->pk_info = NULL;
ctx->pk_ctx = NULL;
@@ -65,10 +70,11 @@
*/
void mbedtls_pk_free( mbedtls_pk_context *ctx )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ if( ctx == NULL )
return;
- ctx->pk_info->ctx_free_func( ctx->pk_ctx );
+ if ( ctx->pk_info != NULL )
+ ctx->pk_info->ctx_free_func( ctx->pk_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
}
@@ -79,6 +85,7 @@
*/
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
{
+ PK_VALIDATE( ctx != NULL );
ctx->pk_info = NULL;
ctx->rs_ctx = NULL;
}
@@ -132,7 +139,8 @@
*/
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
{
- if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ if( info == NULL || ctx->pk_info != NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
@@ -187,7 +195,8 @@
mbedtls_rsa_alt_context *rsa_alt;
const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
- if( ctx == NULL || ctx->pk_info != NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ if( ctx->pk_info != NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
@@ -211,7 +220,9 @@
*/
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
{
- /* null or NONE context can't do anything */
+ /* A context with null pk_info is not set up yet and can't do anything.
+ * For backward compatibility, also accept NULL instead of a context
+ * pointer. */
if( ctx == NULL || ctx->pk_info == NULL )
return( 0 );
@@ -268,7 +279,12 @@
const unsigned char *sig, size_t sig_len,
mbedtls_pk_restart_ctx *rs_ctx )
{
- if( ctx == NULL || ctx->pk_info == NULL ||
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+ hash != NULL );
+ PK_VALIDATE_RET( sig != NULL );
+
+ if( ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
@@ -321,7 +337,12 @@
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+ hash != NULL );
+ PK_VALIDATE_RET( sig != NULL );
+
+ if( ctx->pk_info == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ! mbedtls_pk_can_do( ctx, type ) )
@@ -381,7 +402,12 @@
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_pk_restart_ctx *rs_ctx )
{
- if( ctx == NULL || ctx->pk_info == NULL ||
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+ hash != NULL );
+ PK_VALIDATE_RET( sig != NULL );
+
+ if( ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
@@ -435,7 +461,12 @@
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( input != NULL || ilen == 0 );
+ PK_VALIDATE_RET( output != NULL || osize == 0 );
+ PK_VALIDATE_RET( olen != NULL );
+
+ if( ctx->pk_info == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->decrypt_func == NULL )
@@ -453,7 +484,12 @@
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( input != NULL || ilen == 0 );
+ PK_VALIDATE_RET( output != NULL || osize == 0 );
+ PK_VALIDATE_RET( olen != NULL );
+
+ if( ctx->pk_info == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->encrypt_func == NULL )
@@ -468,8 +504,11 @@
*/
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
{
- if( pub == NULL || pub->pk_info == NULL ||
- prv == NULL || prv->pk_info == NULL )
+ PK_VALIDATE_RET( pub != NULL );
+ PK_VALIDATE_RET( prv != NULL );
+
+ if( pub->pk_info == NULL ||
+ prv->pk_info == NULL )
{
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
}
@@ -496,6 +535,8 @@
*/
size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
{
+ /* For backward compatibility, accept NULL or a context that
+ * isn't set up yet, and return a fake value that should be safe. */
if( ctx == NULL || ctx->pk_info == NULL )
return( 0 );
@@ -507,7 +548,8 @@
*/
int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ if( ctx->pk_info == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->debug_func == NULL )
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 57a3925..c7f879a 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -564,7 +564,7 @@
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
/* mbedtls_pk_write_pubkey() expects a full PK context;
- * re-construct one to make it happy. */
+ * re-construct one to make it happy */
key.pk_info = &pk_info;
key.pk_ctx = ctx;
p = buf + sizeof( buf );
diff --git a/library/pkparse.c b/library/pkparse.c
index 86d9fb0..ae210bc 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -61,6 +61,12 @@
#define mbedtls_free free
#endif
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if defined(MBEDTLS_FS_IO)
/*
* Load all data from a file into a given buffer.
@@ -74,6 +80,10 @@
FILE *f;
long size;
+ PK_VALIDATE_RET( path != NULL );
+ PK_VALIDATE_RET( buf != NULL );
+ PK_VALIDATE_RET( n != NULL );
+
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
@@ -124,6 +134,9 @@
size_t n;
unsigned char *buf;
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( path != NULL );
+
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
return( ret );
@@ -148,6 +161,9 @@
size_t n;
unsigned char *buf;
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( path != NULL );
+
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
return( ret );
@@ -605,6 +621,11 @@
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
const mbedtls_pk_info_t *pk_info;
+ PK_VALIDATE_RET( p != NULL );
+ PK_VALIDATE_RET( *p != NULL );
+ PK_VALIDATE_RET( end != NULL );
+ PK_VALIDATE_RET( pk != NULL );
+
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
@@ -1145,16 +1166,22 @@
{
int ret;
const mbedtls_pk_info_t *pk_info;
-
#if defined(MBEDTLS_PEM_PARSE_C)
size_t len;
mbedtls_pem_context pem;
+#endif
- mbedtls_pem_init( &pem );
+ PK_VALIDATE_RET( pk != NULL );
+ if( keylen == 0 )
+ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+ PK_VALIDATE_RET( key != NULL );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+ mbedtls_pem_init( &pem );
#if defined(MBEDTLS_RSA_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
+ if( key[keylen - 1] != '\0' )
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else
ret = mbedtls_pem_read_buffer( &pem,
@@ -1185,7 +1212,7 @@
#if defined(MBEDTLS_ECP_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
+ if( key[keylen - 1] != '\0' )
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else
ret = mbedtls_pem_read_buffer( &pem,
@@ -1215,7 +1242,7 @@
#endif /* MBEDTLS_ECP_C */
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
+ if( key[keylen - 1] != '\0' )
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else
ret = mbedtls_pem_read_buffer( &pem,
@@ -1238,7 +1265,7 @@
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
+ if( key[keylen - 1] != '\0' )
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else
ret = mbedtls_pem_read_buffer( &pem,
@@ -1276,9 +1303,6 @@
{
unsigned char *key_copy;
- if( keylen == 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
-
if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
@@ -1360,11 +1384,18 @@
#if defined(MBEDTLS_PEM_PARSE_C)
size_t len;
mbedtls_pem_context pem;
+#endif
+ PK_VALIDATE_RET( ctx != NULL );
+ if( keylen == 0 )
+ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+ PK_VALIDATE_RET( key != NULL || keylen == 0 );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_init( &pem );
#if defined(MBEDTLS_RSA_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
+ if( key[keylen - 1] != '\0' )
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else
ret = mbedtls_pem_read_buffer( &pem,
@@ -1395,7 +1426,7 @@
#endif /* MBEDTLS_RSA_C */
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
+ if( key[keylen - 1] != '\0' )
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else
ret = mbedtls_pem_read_buffer( &pem,
diff --git a/library/pkwrite.c b/library/pkwrite.c
index ab4f7f5..b87f81b 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -30,6 +30,7 @@
#include "mbedtls/pk.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
#include <string.h>
@@ -58,6 +59,12 @@
#define mbedtls_free free
#endif
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if defined(MBEDTLS_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
@@ -155,6 +162,11 @@
int ret;
size_t len = 0;
+ PK_VALIDATE_RET( p != NULL );
+ PK_VALIDATE_RET( *p != NULL );
+ PK_VALIDATE_RET( start != NULL );
+ PK_VALIDATE_RET( key != NULL );
+
#if defined(MBEDTLS_RSA_C)
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
@@ -201,6 +213,11 @@
mbedtls_pk_type_t pk_type;
const char *oid;
+ PK_VALIDATE_RET( key != NULL );
+ if( size == 0 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+ PK_VALIDATE_RET( buf != NULL );
+
c = buf + size;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
@@ -278,9 +295,16 @@
int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
int ret;
- unsigned char *c = buf + size;
+ unsigned char *c;
size_t len = 0;
+ PK_VALIDATE_RET( key != NULL );
+ if( size == 0 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+ PK_VALIDATE_RET( buf != NULL );
+
+ c = buf + size;
+
#if defined(MBEDTLS_RSA_C)
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
{
@@ -518,6 +542,9 @@
unsigned char output_buf[PUB_DER_MAX_BYTES];
size_t olen = 0;
+ PK_VALIDATE_RET( key != NULL );
+ PK_VALIDATE_RET( buf != NULL || size == 0 );
+
if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
sizeof(output_buf) ) ) < 0 )
{
@@ -541,6 +568,9 @@
const char *begin, *end;
size_t olen = 0;
+ PK_VALIDATE_RET( key != NULL );
+ PK_VALIDATE_RET( buf != NULL || size == 0 );
+
if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
return( ret );
diff --git a/library/platform.c b/library/platform.c
index 73a6db9..5756159 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -82,28 +82,15 @@
!( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&
defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */
-#if defined(_WIN32)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
#include <stdarg.h>
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
{
int ret;
va_list argp;
- /* Avoid calling the invalid parameter handler by checking ourselves */
- if( s == NULL || n == 0 || fmt == NULL )
- return( -1 );
-
va_start( argp, fmt );
-#if defined(_TRUNCATE) && !defined(__MINGW32__)
- ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
-#else
- ret = _vsnprintf( s, n, fmt, argp );
- if( ret < 0 || (size_t) ret == n )
- {
- s[n-1] = '\0';
- ret = -1;
- }
-#endif
+ ret = mbedtls_vsnprintf( s, n, fmt, argp );
va_end( argp );
return( ret );
@@ -140,6 +127,62 @@
}
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#include <stdarg.h>
+int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg )
+{
+ int ret;
+
+ /* Avoid calling the invalid parameter handler by checking ourselves */
+ if( s == NULL || n == 0 || fmt == NULL )
+ return( -1 );
+
+#if defined(_TRUNCATE)
+ ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg );
+#else
+ ret = vsnprintf( s, n, fmt, arg );
+ if( ret < 0 || (size_t) ret == n )
+ {
+ s[n-1] = '\0';
+ ret = -1;
+ }
+#endif
+
+ return( ret );
+}
+#endif
+
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_vsnprintf_uninit( char * s, size_t n,
+ const char * format, va_list arg )
+{
+ ((void) s);
+ ((void) n);
+ ((void) format);
+ ((void) arg);
+ return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */
+
+int (*mbedtls_vsnprintf)( char * s, size_t n,
+ const char * format,
+ va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF;
+
+int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
+ const char * format,
+ va_list arg ) )
+{
+ mbedtls_vsnprintf = vsnprintf_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
/*
diff --git a/library/platform_util.c b/library/platform_util.c
index ca5fe4f..756e226 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -35,6 +35,7 @@
#endif
#include "mbedtls/platform_util.h"
+#include "mbedtls/platform.h"
#include "mbedtls/threading.h"
#include <stddef.h>
diff --git a/library/poly1305.c b/library/poly1305.c
index e22d3af..b274119 100644
--- a/library/poly1305.c
+++ b/library/poly1305.c
@@ -49,6 +49,12 @@
#define inline __inline
#endif
+/* Parameter validation macros */
+#define POLY1305_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
+#define POLY1305_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
#define BYTES_TO_U32_LE( data, offset ) \
@@ -276,27 +282,24 @@
void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
{
- if( ctx != NULL )
- {
- mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
- }
+ POLY1305_VALIDATE( ctx != NULL );
+
+ mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
}
void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
{
- if( ctx != NULL )
- {
- mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
- }
+ if( ctx == NULL )
+ return;
+
+ mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
}
int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
const unsigned char key[32] )
{
- if( ctx == NULL || key == NULL )
- {
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
+ POLY1305_VALIDATE_RET( ctx != NULL );
+ POLY1305_VALIDATE_RET( key != NULL );
/* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
@@ -331,16 +334,8 @@
size_t remaining = ilen;
size_t queue_free_len;
size_t nblocks;
-
- if( ctx == NULL )
- {
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
- else if( ( ilen > 0U ) && ( input == NULL ) )
- {
- /* input pointer is allowed to be NULL only if ilen == 0 */
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
+ POLY1305_VALIDATE_RET( ctx != NULL );
+ POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
{
@@ -398,10 +393,8 @@
int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
unsigned char mac[16] )
{
- if( ( ctx == NULL ) || ( mac == NULL ) )
- {
- return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
- }
+ POLY1305_VALIDATE_RET( ctx != NULL );
+ POLY1305_VALIDATE_RET( mac != NULL );
/* Process any leftover data */
if( ctx->queue_len > 0U )
@@ -431,6 +424,9 @@
{
mbedtls_poly1305_context ctx;
int ret;
+ POLY1305_VALIDATE_RET( key != NULL );
+ POLY1305_VALIDATE_RET( mac != NULL );
+ POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
mbedtls_poly1305_init( &ctx );
diff --git a/library/rsa.c b/library/rsa.c
index 25544aa..a35af44 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -71,6 +71,12 @@
#if !defined(MBEDTLS_RSA_ALT)
+/* Parameter validation macros */
+#define RSA_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
+#define RSA_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if defined(MBEDTLS_PKCS1_V15)
/* constant-time buffer comparison */
static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
@@ -93,6 +99,7 @@
const mbedtls_mpi *D, const mbedtls_mpi *E )
{
int ret;
+ RSA_VALIDATE_RET( ctx != NULL );
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
@@ -117,6 +124,7 @@
unsigned char const *E, size_t E_len )
{
int ret = 0;
+ RSA_VALIDATE_RET( ctx != NULL );
if( N != NULL )
{
@@ -240,12 +248,16 @@
int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
{
int ret = 0;
+ int have_N, have_P, have_Q, have_D, have_E;
+ int n_missing, pq_missing, d_missing, is_pub, is_priv;
- const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
- const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
- const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
- const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
- const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
+ RSA_VALIDATE_RET( ctx != NULL );
+
+ have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
+ have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
+ have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
+ have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
+ have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
/*
* Check whether provided parameters are enough
@@ -257,13 +269,13 @@
*
*/
- const int n_missing = have_P && have_Q && have_D && have_E;
- const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
- const int d_missing = have_P && have_Q && !have_D && have_E;
- const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
+ n_missing = have_P && have_Q && have_D && have_E;
+ pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
+ d_missing = have_P && have_Q && !have_D && have_E;
+ is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
/* These three alternatives are mutually exclusive */
- const int is_priv = n_missing || pq_missing || d_missing;
+ is_priv = n_missing || pq_missing || d_missing;
if( !is_priv && !is_pub )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -336,9 +348,11 @@
unsigned char *E, size_t E_len )
{
int ret = 0;
+ int is_priv;
+ RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */
- const int is_priv =
+ is_priv =
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@@ -379,9 +393,11 @@
mbedtls_mpi *D, mbedtls_mpi *E )
{
int ret;
+ int is_priv;
+ RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */
- int is_priv =
+ is_priv =
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@@ -421,9 +437,11 @@
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
{
int ret;
+ int is_priv;
+ RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */
- int is_priv =
+ is_priv =
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@@ -459,6 +477,10 @@
int padding,
int hash_id )
{
+ RSA_VALIDATE( ctx != NULL );
+ RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
+ padding == MBEDTLS_RSA_PKCS_V21 );
+
memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
mbedtls_rsa_set_padding( ctx, padding, hash_id );
@@ -471,8 +493,13 @@
/*
* Set padding for an existing RSA context
*/
-void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
+void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
+ int hash_id )
{
+ RSA_VALIDATE( ctx != NULL );
+ RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
+ padding == MBEDTLS_RSA_PKCS_V21 );
+
ctx->padding = padding;
ctx->hash_id = hash_id;
}
@@ -503,11 +530,10 @@
int ret;
mbedtls_mpi H, G, L;
int prime_quality = 0;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( f_rng != NULL );
- if( f_rng == NULL || nbits < 128 || exponent < 3 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
-
- if( nbits % 2 )
+ if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
/*
@@ -612,6 +638,8 @@
*/
int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
{
+ RSA_VALIDATE_RET( ctx != NULL );
+
if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
@@ -635,6 +663,8 @@
*/
int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
{
+ RSA_VALIDATE_RET( ctx != NULL );
+
if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
{
@@ -664,6 +694,9 @@
int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
const mbedtls_rsa_context *prv )
{
+ RSA_VALIDATE_RET( pub != NULL );
+ RSA_VALIDATE_RET( prv != NULL );
+
if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
mbedtls_rsa_check_privkey( prv ) != 0 )
{
@@ -689,6 +722,9 @@
int ret;
size_t olen;
mbedtls_mpi T;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( output != NULL );
if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -831,6 +867,10 @@
* checked result; should be the same in the end. */
mbedtls_mpi I, C;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( output != NULL );
+
if( rsa_check_context( ctx, 1 /* private key checks */,
f_rng != NULL /* blinding y/n */ ) != 0 )
{
@@ -1091,6 +1131,13 @@
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( output != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
+ RSA_VALIDATE_RET( label_len == 0 || label != NULL );
+
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1168,13 +1215,13 @@
int ret;
unsigned char *p = output;
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( output != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
- // We don't check p_rng because it won't be dereferenced here
- if( f_rng == NULL || output == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( ilen != 0 && input == NULL )
+ if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
olen = ctx->len;
@@ -1188,6 +1235,9 @@
*p++ = 0;
if( mode == MBEDTLS_RSA_PUBLIC )
{
+ if( f_rng == NULL )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
*p++ = MBEDTLS_RSA_CRYPT;
while( nb_pad-- > 0 )
@@ -1233,6 +1283,12 @@
const unsigned char *input,
unsigned char *output )
{
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( output != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
+
switch( ctx->padding )
{
#if defined(MBEDTLS_PKCS1_V15)
@@ -1275,6 +1331,14 @@
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+ RSA_VALIDATE_RET( label_len == 0 || label != NULL );
+ RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( olen != NULL );
+
/*
* Parameters sanity checks
*/
@@ -1495,11 +1559,7 @@
size_t output_max_len )
{
int ret;
- size_t ilen = ctx->len;
- size_t i;
- size_t plaintext_max_size = ( output_max_len > ilen - 11 ?
- ilen - 11 :
- output_max_len );
+ size_t ilen, i, plaintext_max_size;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
/* The following variables take sensitive values: their value must
* not leak into the observable behavior of the function other than
@@ -1517,6 +1577,18 @@
size_t plaintext_size = 0;
unsigned output_too_large;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+ RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( olen != NULL );
+
+ ilen = ctx->len;
+ plaintext_max_size = ( output_max_len > ilen - 11 ?
+ ilen - 11 :
+ output_max_len );
+
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1658,6 +1730,13 @@
unsigned char *output,
size_t output_max_len)
{
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+ RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( olen != NULL );
+
switch( ctx->padding )
{
#if defined(MBEDTLS_PKCS1_V15)
@@ -1699,6 +1778,13 @@
size_t msb;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
+ hashlen == 0 ) ||
+ hash != NULL );
+ RSA_VALIDATE_RET( sig != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1946,6 +2032,14 @@
int ret;
unsigned char *sig_try = NULL, *verif = NULL;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
+ hashlen == 0 ) ||
+ hash != NULL );
+ RSA_VALIDATE_RET( sig != NULL );
+
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -2015,6 +2109,14 @@
const unsigned char *hash,
unsigned char *sig )
{
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
+ hashlen == 0 ) ||
+ hash != NULL );
+ RSA_VALIDATE_RET( sig != NULL );
+
switch( ctx->padding )
{
#if defined(MBEDTLS_PKCS1_V15)
@@ -2061,6 +2163,14 @@
mbedtls_md_context_t md_ctx;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( sig != NULL );
+ RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
+ hashlen == 0 ) ||
+ hash != NULL );
+
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -2189,7 +2299,16 @@
const unsigned char *hash,
const unsigned char *sig )
{
- mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
+ mbedtls_md_type_t mgf1_hash_id;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( sig != NULL );
+ RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
+ hashlen == 0 ) ||
+ hash != NULL );
+
+ mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
? (mbedtls_md_type_t) ctx->hash_id
: md_alg;
@@ -2215,9 +2334,19 @@
const unsigned char *sig )
{
int ret = 0;
- const size_t sig_len = ctx->len;
+ size_t sig_len;
unsigned char *encoded = NULL, *encoded_expected = NULL;
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( sig != NULL );
+ RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
+ hashlen == 0 ) ||
+ hash != NULL );
+
+ sig_len = ctx->len;
+
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -2287,6 +2416,14 @@
const unsigned char *hash,
const unsigned char *sig )
{
+ RSA_VALIDATE_RET( ctx != NULL );
+ RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+ mode == MBEDTLS_RSA_PUBLIC );
+ RSA_VALIDATE_RET( sig != NULL );
+ RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
+ hashlen == 0 ) ||
+ hash != NULL );
+
switch( ctx->padding )
{
#if defined(MBEDTLS_PKCS1_V15)
@@ -2312,6 +2449,8 @@
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
{
int ret;
+ RSA_VALIDATE_RET( dst != NULL );
+ RSA_VALIDATE_RET( src != NULL );
dst->ver = src->ver;
dst->len = src->len;
@@ -2351,14 +2490,23 @@
*/
void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
{
- mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
- mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
- mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
- mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
+ if( ctx == NULL )
+ return;
+
+ mbedtls_mpi_free( &ctx->Vi );
+ mbedtls_mpi_free( &ctx->Vf );
+ mbedtls_mpi_free( &ctx->RN );
+ mbedtls_mpi_free( &ctx->D );
+ mbedtls_mpi_free( &ctx->Q );
+ mbedtls_mpi_free( &ctx->P );
+ mbedtls_mpi_free( &ctx->E );
+ mbedtls_mpi_free( &ctx->N );
#if !defined(MBEDTLS_RSA_NO_CRT)
- mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
- mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
+ mbedtls_mpi_free( &ctx->RQ );
+ mbedtls_mpi_free( &ctx->RP );
+ mbedtls_mpi_free( &ctx->QP );
+ mbedtls_mpi_free( &ctx->DQ );
mbedtls_mpi_free( &ctx->DP );
#endif /* MBEDTLS_RSA_NO_CRT */
diff --git a/library/sha1.c b/library/sha1.c
index bab6087..e8d4096 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -46,6 +46,11 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
+#define SHA1_VALIDATE_RET(cond) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA )
+
+#define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if !defined(MBEDTLS_SHA1_ALT)
/*
@@ -73,6 +78,8 @@
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
{
+ SHA1_VALIDATE( ctx != NULL );
+
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
}
@@ -87,6 +94,9 @@
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src )
{
+ SHA1_VALIDATE( dst != NULL );
+ SHA1_VALIDATE( src != NULL );
+
*dst = *src;
}
@@ -95,6 +105,8 @@
*/
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
{
+ SHA1_VALIDATE_RET( ctx != NULL );
+
ctx->total[0] = 0;
ctx->total[1] = 0;
@@ -120,6 +132,9 @@
{
uint32_t temp, W[16], A, B, C, D, E;
+ SHA1_VALIDATE_RET( ctx != NULL );
+ SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
+
GET_UINT32_BE( W[ 0], data, 0 );
GET_UINT32_BE( W[ 1], data, 4 );
GET_UINT32_BE( W[ 2], data, 8 );
@@ -294,6 +309,9 @@
size_t fill;
uint32_t left;
+ SHA1_VALIDATE_RET( ctx != NULL );
+ SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
+
if( ilen == 0 )
return( 0 );
@@ -352,6 +370,9 @@
uint32_t used;
uint32_t high, low;
+ SHA1_VALIDATE_RET( ctx != NULL );
+ SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
+
/*
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
*/
@@ -420,6 +441,9 @@
int ret;
mbedtls_sha1_context ctx;
+ SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
+ SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
+
mbedtls_sha1_init( &ctx );
if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
diff --git a/library/sha256.c b/library/sha256.c
index dbb4a89..8a540ad 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -49,6 +49,10 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
+#define SHA256_VALIDATE_RET(cond) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
+#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if !defined(MBEDTLS_SHA256_ALT)
/*
@@ -76,6 +80,8 @@
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
{
+ SHA256_VALIDATE( ctx != NULL );
+
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
}
@@ -90,6 +96,9 @@
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src )
{
+ SHA256_VALIDATE( dst != NULL );
+ SHA256_VALIDATE( src != NULL );
+
*dst = *src;
}
@@ -98,6 +107,9 @@
*/
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
{
+ SHA256_VALIDATE_RET( ctx != NULL );
+ SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
+
ctx->total[0] = 0;
ctx->total[1] = 0;
@@ -192,6 +204,9 @@
uint32_t A[8];
unsigned int i;
+ SHA256_VALIDATE_RET( ctx != NULL );
+ SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
+
for( i = 0; i < 8; i++ )
A[i] = ctx->state[i];
@@ -263,6 +278,9 @@
size_t fill;
uint32_t left;
+ SHA256_VALIDATE_RET( ctx != NULL );
+ SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
+
if( ilen == 0 )
return( 0 );
@@ -321,6 +339,9 @@
uint32_t used;
uint32_t high, low;
+ SHA256_VALIDATE_RET( ctx != NULL );
+ SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
+
/*
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
*/
@@ -395,6 +416,10 @@
int ret;
mbedtls_sha256_context ctx;
+ SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
+ SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
+ SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
+
mbedtls_sha256_init( &ctx );
if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
diff --git a/library/sha512.c b/library/sha512.c
index a9440e8..941ecda 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -55,6 +55,10 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
+#define SHA512_VALIDATE_RET(cond) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
+#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
+
#if !defined(MBEDTLS_SHA512_ALT)
/*
@@ -90,6 +94,8 @@
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
{
+ SHA512_VALIDATE( ctx != NULL );
+
memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
}
@@ -104,6 +110,9 @@
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
const mbedtls_sha512_context *src )
{
+ SHA512_VALIDATE( dst != NULL );
+ SHA512_VALIDATE( src != NULL );
+
*dst = *src;
}
@@ -112,6 +121,9 @@
*/
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
{
+ SHA512_VALIDATE_RET( ctx != NULL );
+ SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+
ctx->total[0] = 0;
ctx->total[1] = 0;
@@ -209,6 +221,9 @@
uint64_t temp1, temp2, W[80];
uint64_t A, B, C, D, E, F, G, H;
+ SHA512_VALIDATE_RET( ctx != NULL );
+ SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
+
#define SHR(x,n) (x >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
@@ -294,6 +309,9 @@
size_t fill;
unsigned int left;
+ SHA512_VALIDATE_RET( ctx != NULL );
+ SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
+
if( ilen == 0 )
return( 0 );
@@ -351,6 +369,9 @@
unsigned used;
uint64_t high, low;
+ SHA512_VALIDATE_RET( ctx != NULL );
+ SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
+
/*
* Add padding: 0x80 then 0x00 until 16 bytes remain for the length
*/
@@ -427,6 +448,10 @@
int ret;
mbedtls_sha512_context ctx;
+ SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+ SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
+ SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
+
mbedtls_sha512_init( &ctx );
if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 8a90288..46e24e4 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1489,7 +1489,7 @@
*/
/*
- * Minimal length (with everything empty and extensions ommitted) is
+ * Minimal length (with everything empty and extensions omitted) is
* 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
* read at least up to session id length without worrying.
*/
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index cf44ed5..f224d5e 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -50,10 +50,19 @@
#include <string.h>
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#include "psa/crypto.h"
+#endif
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/oid.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#endif
+
static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
@@ -490,6 +499,76 @@
#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static int tls_prf_generic( mbedtls_md_type_t md_type,
+ const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen )
+{
+ psa_status_t status;
+ psa_algorithm_t alg;
+ psa_key_policy_t policy;
+ psa_key_handle_t master_slot;
+ psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+
+ if( ( status = psa_allocate_key( &master_slot ) ) != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ if( md_type == MBEDTLS_MD_SHA384 )
+ alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
+ else
+ alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
+
+ policy = psa_key_policy_init();
+ psa_key_policy_set_usage( &policy,
+ PSA_KEY_USAGE_DERIVE,
+ alg );
+ status = psa_set_key_policy( master_slot, &policy );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ status = psa_import_key( master_slot, PSA_KEY_TYPE_DERIVE, secret, slen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ status = psa_key_derivation( &generator,
+ master_slot, alg,
+ random, rlen,
+ (unsigned char const *) label,
+ (size_t) strlen( label ),
+ dlen );
+ if( status != PSA_SUCCESS )
+ {
+ psa_generator_abort( &generator );
+ psa_destroy_key( master_slot );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_generator_read( &generator, dstbuf, dlen );
+ if( status != PSA_SUCCESS )
+ {
+ psa_generator_abort( &generator );
+ psa_destroy_key( master_slot );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_generator_abort( &generator );
+ if( status != PSA_SUCCESS )
+ {
+ psa_destroy_key( master_slot );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_destroy_key( master_slot );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ return( 0 );
+}
+
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+
static int tls_prf_generic( mbedtls_md_type_t md_type,
const unsigned char *secret, size_t slen,
const char *label,
@@ -552,7 +631,7 @@
return( 0 );
}
-
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SHA256_C)
static int tls_prf_sha256( const unsigned char *secret, size_t slen,
const char *label,
@@ -1347,7 +1426,7 @@
mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
- mbedtls_md5_finish_ret( &md5, hash );
+ mbedtls_md5_finish_ret( &md5, hash );
mbedtls_sha1_finish_ret( &sha1, hash + 16 );
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
@@ -1364,6 +1443,28 @@
#if defined(MBEDTLS_SHA256_C)
void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_status_t status;
+ psa_hash_operation_t sha256_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha256" ) );
+ status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha256_psa, hash, 32, &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, 32 );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
+#else
mbedtls_sha256_context sha256;
mbedtls_sha256_init( &sha256 );
@@ -1377,7 +1478,7 @@
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_sha256_free( &sha256 );
-
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return;
}
#endif /* MBEDTLS_SHA256_C */
@@ -1385,6 +1486,28 @@
#if defined(MBEDTLS_SHA512_C)
void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_status_t status;
+ psa_hash_operation_t sha384_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha384" ) );
+ status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha384_psa, hash, 48, &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, 48 );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
+#else
mbedtls_sha512_context sha512;
mbedtls_sha512_init( &sha512 );
@@ -1398,7 +1521,7 @@
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_sha512_free( &sha512 );
-
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return;
}
#endif /* MBEDTLS_SHA512_C */
@@ -2772,7 +2895,7 @@
}
/*
- * A record can't be split accross datagrams. If we need to read but
+ * A record can't be split across datagrams. If we need to read but
* are not at the beginning of a new record, the caller did something
* wrong.
*/
@@ -6172,11 +6295,21 @@
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &ssl->handshake->fin_sha256_psa );
+ psa_hash_setup( &ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
+#else
mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 );
#endif
+#endif
#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &ssl->handshake->fin_sha384_psa );
+ psa_hash_setup( &ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
+#else
mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
}
@@ -6190,11 +6323,19 @@
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
+#else
mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
#endif
+#endif
#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
+#else
mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
}
@@ -6213,7 +6354,11 @@
static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
+#else
mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
+#endif
}
#endif
@@ -6221,7 +6366,11 @@
static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
+#else
mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
+#endif
}
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@@ -6377,13 +6526,44 @@
{
int len = 12;
const char *sender;
- mbedtls_sha256_context sha256;
unsigned char padbuf[32];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_hash_operation_t sha256_psa;
+ psa_status_t status;
+#else
+ mbedtls_sha256_context sha256;
+#endif
mbedtls_ssl_session *session = ssl->session_negotiate;
if( !session )
session = ssl->session;
+ sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+ ? "client finished"
+ : "server finished";
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ sha256_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha256" ) );
+
+ status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha256_psa, padbuf, sizeof( padbuf ), &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 32 );
+#else
+
mbedtls_sha256_init( &sha256 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) );
@@ -6401,19 +6581,15 @@
sha256.state, sizeof( sha256.state ) );
#endif
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
-
mbedtls_sha256_finish_ret( &sha256, padbuf );
+ mbedtls_sha256_free( &sha256 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 32, buf, len );
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_sha256_free( &sha256 );
-
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
@@ -6426,13 +6602,43 @@
{
int len = 12;
const char *sender;
- mbedtls_sha512_context sha512;
unsigned char padbuf[48];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_hash_operation_t sha384_psa;
+ psa_status_t status;
+#else
+ mbedtls_sha512_context sha512;
+#endif
mbedtls_ssl_session *session = ssl->session_negotiate;
if( !session )
session = ssl->session;
+ sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+ ? "client finished"
+ : "server finished";
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ sha384_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha384" ) );
+
+ status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha384_psa, padbuf, sizeof( padbuf ), &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 48 );
+#else
mbedtls_sha512_init( &sha512 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) );
@@ -6450,19 +6656,15 @@
sha512.state, sizeof( sha512.state ) );
#endif
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
-
mbedtls_sha512_finish_ret( &sha512, padbuf );
+ mbedtls_sha512_free( &sha512 );
+#endif
ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 48, buf, len );
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_sha512_free( &sha512 );
-
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
@@ -6773,13 +6975,23 @@
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ handshake->fin_sha256_psa = psa_hash_operation_init();
+ psa_hash_setup( &handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
+#else
mbedtls_sha256_init( &handshake->fin_sha256 );
mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 );
#endif
+#endif
#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ handshake->fin_sha384_psa = psa_hash_operation_init();
+ psa_hash_setup( &handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
+#else
mbedtls_sha512_init( &handshake->fin_sha512 );
mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
handshake->update_checksum = ssl_update_checksum_start;
@@ -9082,11 +9294,19 @@
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &handshake->fin_sha256_psa );
+#else
mbedtls_sha256_free( &handshake->fin_sha256 );
#endif
+#endif
#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &handshake->fin_sha384_psa );
+#else
mbedtls_sha512_free( &handshake->fin_sha512 );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_DHM_C)
@@ -9975,6 +10195,70 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+ unsigned char *hash, size_t *hashlen,
+ unsigned char *data, size_t data_len,
+ mbedtls_md_type_t md_alg )
+{
+ psa_status_t status;
+ psa_hash_operation_t hash_operation;
+ psa_algorithm_t hash_alg = mbedtls_psa_translate_md( md_alg );
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) );
+
+ if( ( status = psa_hash_setup( &hash_operation,
+ hash_alg ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_setup", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_update( &hash_operation, ssl->handshake->randbytes,
+ 64 ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_update( &hash_operation,
+ data, data_len ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_finish( &hash_operation, hash, MBEDTLS_MD_MAX_SIZE,
+ hashlen ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_finish", status );
+ goto exit;
+ }
+
+exit:
+ if( status != PSA_SUCCESS )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+ switch( status )
+ {
+ case PSA_ERROR_NOT_SUPPORTED:
+ return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
+ case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
+ case PSA_ERROR_BUFFER_TOO_SMALL:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ case PSA_ERROR_INSUFFICIENT_MEMORY:
+ return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+ default:
+ return( MBEDTLS_ERR_MD_HW_ACCEL_FAILED );
+ }
+ }
+ return( 0 );
+}
+
+#else
+
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
unsigned char *hash, size_t *hashlen,
unsigned char *data, size_t data_len,
@@ -9985,6 +10269,8 @@
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
*hashlen = mbedtls_md_get_size( md_info );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) );
+
mbedtls_md_init( &ctx );
/*
@@ -10029,6 +10315,8 @@
return( ret );
}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */
diff --git a/library/version_features.c b/library/version_features.c
index 2bfcfc0..ad3f937 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -72,6 +72,9 @@
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
"MBEDTLS_PLATFORM_SNPRINTF_ALT",
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+ "MBEDTLS_PLATFORM_VSNPRINTF_ALT",
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
"MBEDTLS_PLATFORM_NV_SEED_ALT",
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
@@ -84,6 +87,9 @@
#if defined(MBEDTLS_DEPRECATED_REMOVED)
"MBEDTLS_DEPRECATED_REMOVED",
#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#if defined(MBEDTLS_CHECK_PARAMS)
+ "MBEDTLS_CHECK_PARAMS",
+#endif /* MBEDTLS_CHECK_PARAMS */
#if defined(MBEDTLS_TIMING_ALT)
"MBEDTLS_TIMING_ALT",
#endif /* MBEDTLS_TIMING_ALT */
diff --git a/library/x509.c b/library/x509.c
index 52b5b64..6b7899f 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -116,7 +116,7 @@
}
/*
- * Parse an algorithm identifier with (optional) paramaters
+ * Parse an algorithm identifier with (optional) parameters
*/
int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 3a3c0a0..1b1f0a7 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -373,7 +373,7 @@
for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ )
{
ver_chain->items[i].crt = NULL;
- ver_chain->items[i].flags = -1;
+ ver_chain->items[i].flags = (uint32_t) -1;
}
ver_chain->len = 0;
@@ -2261,7 +2261,7 @@
* Tests for (aspects of) this function should include at least:
* - trusted EE
* - EE -> trusted root
- * - EE -> intermedate CA -> trusted root
+ * - EE -> intermediate CA -> trusted root
* - if relevant: EE untrusted
* - if relevant: EE -> intermediate, untrusted
* with the aspect under test checked at each relevant level (EE, int, root).
diff --git a/library/x509_csr.c b/library/x509_csr.c
index f844257..c8c08c8 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -279,15 +279,24 @@
{
mbedtls_pem_init( &pem );
ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN CERTIFICATE REQUEST-----",
- "-----END CERTIFICATE REQUEST-----",
- buf, NULL, 0, &use_len );
+ "-----BEGIN CERTIFICATE REQUEST-----",
+ "-----END CERTIFICATE REQUEST-----",
+ buf, NULL, 0, &use_len );
+ if( ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+ {
+ ret = mbedtls_pem_read_buffer( &pem,
+ "-----BEGIN NEW CERTIFICATE REQUEST-----",
+ "-----END NEW CERTIFICATE REQUEST-----",
+ buf, NULL, 0, &use_len );
+ }
if( ret == 0 )
+ {
/*
* Was PEM encoded, parse the result
*/
ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen );
+ }
mbedtls_pem_free( &pem );
if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )