Commit 863dfb59 authored by Nathaniel Wesley Filardo's avatar Nathaniel Wesley Filardo Committed by Marcel Stör
Browse files

SSL rampage (#2938)

* Remove stale putative MD2 support

This hasn't worked in a while, presumably since one of our upstream
merges.  Don't bother making it work, since MD2 is generally considered
insecure.

* Land mbedtls 2.16.3-77-gf02988e57

* TLS: remove some dead code from espconn_mbedtls

There was some... frankly kind of scary buffer and data shuffling if
ESP8266_PLATFORM was defined.  Since we don't, in fact, define that
preprocessor symbol, just drop the code lest anyone (possibly future-me)
be scared.

* TLS: espconn_mbedtls: run through astyle

No functional changes

* TLS: espconn_mbedtls: put the file_params on the stack

There's no need to malloc a structure that's used only locally.

* TLS: Further minor tidying of mbedtls glue

What an absolute shitshow this is.  mbedtls should absolutely not
be mentioned inside sys/socket.h and app/mbedtls/app/lwIPSocket.c is not
so much glue as it as a complete copy of a random subset of lwIP; it
should go, but we aren't there yet.

Get rid of the mysterious "mbedlts_record" struct, which housed merely a
length of bytes sent solely for gating the "record sent" callback.

Remove spurious __attribute__((weak)) from symbols not otherwise
defined and rename them to emphasize that they are not actually part of
mbedtls proper.

* TLS: Rampage esp mbedtls glue and delete unused code

This at least makes the shitshow smaller

* TLS: lwip: fix some memp definitions

I presume these also need the new arguments

* TLS: Remove more non-NodeMCU code from our mbedtls

* TLS: drop support for 1.1

Depending on who you ask it's either EOL already or EOL soon, so
we may as well get rid of it now.
parent f5672207
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "mbedtls/aes.h" #include "mbedtls/aes.h"
#include "mbedtls/md5.h" #include "mbedtls/md5.h"
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -45,11 +46,6 @@ ...@@ -45,11 +46,6 @@
#endif #endif
#if defined(MBEDTLS_PEM_PARSE_C) #if defined(MBEDTLS_PEM_PARSE_C)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
void mbedtls_pem_init( mbedtls_pem_context *ctx ) void mbedtls_pem_init( mbedtls_pem_context *ctx )
{ {
memset( ctx, 0, sizeof( mbedtls_pem_context ) ); memset( ctx, 0, sizeof( mbedtls_pem_context ) );
...@@ -135,7 +131,7 @@ static int pem_pbkdf1( unsigned char *key, size_t keylen, ...@@ -135,7 +131,7 @@ static int pem_pbkdf1( unsigned char *key, size_t keylen,
exit: exit:
mbedtls_md5_free( &md5_ctx ); mbedtls_md5_free( &md5_ctx );
mbedtls_zeroize( md5sum, 16 ); mbedtls_platform_zeroize( md5sum, 16 );
return( ret ); return( ret );
} }
...@@ -164,7 +160,7 @@ static int pem_des_decrypt( unsigned char des_iv[8], ...@@ -164,7 +160,7 @@ static int pem_des_decrypt( unsigned char des_iv[8],
exit: exit:
mbedtls_des_free( &des_ctx ); mbedtls_des_free( &des_ctx );
mbedtls_zeroize( des_key, 8 ); mbedtls_platform_zeroize( des_key, 8 );
return( ret ); return( ret );
} }
...@@ -192,7 +188,7 @@ static int pem_des3_decrypt( unsigned char des3_iv[8], ...@@ -192,7 +188,7 @@ static int pem_des3_decrypt( unsigned char des3_iv[8],
exit: exit:
mbedtls_des3_free( &des3_ctx ); mbedtls_des3_free( &des3_ctx );
mbedtls_zeroize( des3_key, 24 ); mbedtls_platform_zeroize( des3_key, 24 );
return( ret ); return( ret );
} }
...@@ -222,7 +218,7 @@ static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, ...@@ -222,7 +218,7 @@ static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
exit: exit:
mbedtls_aes_free( &aes_ctx ); mbedtls_aes_free( &aes_ctx );
mbedtls_zeroize( aes_key, keylen ); mbedtls_platform_zeroize( aes_key, keylen );
return( ret ); return( ret );
} }
...@@ -359,7 +355,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const ...@@ -359,7 +355,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 ) if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
{ {
mbedtls_zeroize( buf, len ); mbedtls_platform_zeroize( buf, len );
mbedtls_free( buf ); mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
} }
...@@ -370,7 +366,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const ...@@ -370,7 +366,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
if( pwd == NULL ) if( pwd == NULL )
{ {
mbedtls_zeroize( buf, len ); mbedtls_platform_zeroize( buf, len );
mbedtls_free( buf ); mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ); return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED );
} }
...@@ -403,16 +399,16 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const ...@@ -403,16 +399,16 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
* The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
* length bytes (allow 4 to be sure) in all known use cases. * length bytes (allow 4 to be sure) in all known use cases.
* *
* Use that as heurisitic to try detecting password mismatchs. * Use that as a heuristic to try to detect password mismatches.
*/ */
if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
{ {
mbedtls_zeroize( buf, len ); mbedtls_platform_zeroize( buf, len );
mbedtls_free( buf ); mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ); return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH );
} }
#else #else
mbedtls_zeroize( buf, len ); mbedtls_platform_zeroize( buf, len );
mbedtls_free( buf ); mbedtls_free( buf );
return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
...@@ -427,12 +423,14 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const ...@@ -427,12 +423,14 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
void mbedtls_pem_free( mbedtls_pem_context *ctx ) void mbedtls_pem_free( mbedtls_pem_context *ctx )
{ {
if( ctx->buf != NULL ) if ( ctx->buf != NULL )
mbedtls_zeroize( ctx->buf, ctx->buflen ); {
mbedtls_free( ctx->buf ); mbedtls_platform_zeroize( ctx->buf, ctx->buflen );
mbedtls_free( ctx->buf );
}
mbedtls_free( ctx->info ); mbedtls_free( ctx->info );
mbedtls_zeroize( ctx, sizeof( mbedtls_pem_context ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) );
} }
#endif /* MBEDTLS_PEM_PARSE_C */ #endif /* MBEDTLS_PEM_PARSE_C */
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include "mbedtls/pk.h" #include "mbedtls/pk.h"
#include "mbedtls/pk_internal.h" #include "mbedtls/pk_internal.h"
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
#endif #endif
...@@ -42,18 +44,18 @@ ...@@ -42,18 +44,18 @@
#include <limits.h> #include <limits.h>
#include <stdint.h> #include <stdint.h>
/* Implementation that should never be optimized out by the compiler */ /* Parameter validation macros based on platform_util.h */
static void mbedtls_zeroize( void *v, size_t n ) { #define PK_VALIDATE_RET( cond ) \
volatile unsigned char *p = v; while( n-- ) *p++ = 0; MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
} #define PK_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
/* /*
* Initialise a mbedtls_pk_context * Initialise a mbedtls_pk_context
*/ */
void mbedtls_pk_init( mbedtls_pk_context *ctx ) void mbedtls_pk_init( mbedtls_pk_context *ctx )
{ {
if( ctx == NULL ) PK_VALIDATE( ctx != NULL );
return;
ctx->pk_info = NULL; ctx->pk_info = NULL;
ctx->pk_ctx = NULL; ctx->pk_ctx = NULL;
...@@ -64,13 +66,43 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx ) ...@@ -64,13 +66,43 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx )
*/ */
void mbedtls_pk_free( mbedtls_pk_context *ctx ) void mbedtls_pk_free( mbedtls_pk_context *ctx )
{ {
if( ctx == NULL || ctx->pk_info == NULL ) if( ctx == NULL )
return;
if ( ctx->pk_info != NULL )
ctx->pk_info->ctx_free_func( ctx->pk_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
}
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/*
* Initialize a restart context
*/
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
{
PK_VALIDATE( ctx != NULL );
ctx->pk_info = NULL;
ctx->rs_ctx = NULL;
}
/*
* Free the components of a restart context
*/
void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL ||
ctx->pk_info->rs_free_func == NULL )
{
return; return;
}
ctx->pk_info->ctx_free_func( ctx->pk_ctx ); ctx->pk_info->rs_free_func( ctx->rs_ctx );
mbedtls_zeroize( ctx, sizeof( mbedtls_pk_context ) ); ctx->pk_info = NULL;
ctx->rs_ctx = NULL;
} }
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/* /*
* Get pk_info structure from type * Get pk_info structure from type
...@@ -103,7 +135,8 @@ const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ) ...@@ -103,7 +135,8 @@ const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
*/ */
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ) 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 ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
...@@ -126,7 +159,8 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, ...@@ -126,7 +159,8 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
mbedtls_rsa_alt_context *rsa_alt; mbedtls_rsa_alt_context *rsa_alt;
const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; 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 ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
...@@ -150,7 +184,9 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, ...@@ -150,7 +184,9 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
*/ */
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ) 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 ) if( ctx == NULL || ctx->pk_info == NULL )
return( 0 ); return( 0 );
...@@ -174,17 +210,71 @@ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len ...@@ -174,17 +210,71 @@ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len
return( 0 ); return( 0 );
} }
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* /*
* Verify a signature * Helper to set up a restart context if needed
*/ */
int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
const mbedtls_pk_info_t *info )
{
/* Don't do anything if already set up or invalid */
if( ctx == NULL || ctx->pk_info != NULL )
return( 0 );
/* Should never happen when we're called */
if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
ctx->pk_info = info;
return( 0 );
}
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/*
* Verify a signature (restartable)
*/
int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len, const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len ) 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 ) pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* optimization: use non-restartable version if restart disabled */
if( rs_ctx != NULL &&
mbedtls_ecp_restart_is_enabled() &&
ctx->pk_info->verify_rs_func != NULL )
{
int ret;
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
return( ret );
ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
mbedtls_pk_restart_free( rs_ctx );
return( ret );
}
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
(void) rs_ctx;
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
if( ctx->pk_info->verify_func == NULL ) if( ctx->pk_info->verify_func == NULL )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
...@@ -192,6 +282,17 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, ...@@ -192,6 +282,17 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
sig, sig_len ) ); sig, sig_len ) );
} }
/*
* Verify a signature
*/
int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
sig, sig_len, NULL ) );
}
/* /*
* Verify a signature with options * Verify a signature with options
*/ */
...@@ -200,7 +301,12 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, ...@@ -200,7 +301,12 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
const unsigned char *hash, size_t hash_len, const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_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 ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ! mbedtls_pk_can_do( ctx, type ) ) if( ! mbedtls_pk_can_do( ctx, type ) )
...@@ -251,17 +357,47 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, ...@@ -251,17 +357,47 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
} }
/* /*
* Make a signature * Make a signature (restartable)
*/ */
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len, const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len, unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 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 ) pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* optimization: use non-restartable version if restart disabled */
if( rs_ctx != NULL &&
mbedtls_ecp_restart_is_enabled() &&
ctx->pk_info->sign_rs_func != NULL )
{
int ret;
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
return( ret );
ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
mbedtls_pk_restart_free( rs_ctx );
return( ret );
}
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
(void) rs_ctx;
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
if( ctx->pk_info->sign_func == NULL ) if( ctx->pk_info->sign_func == NULL )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
...@@ -269,6 +405,18 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, ...@@ -269,6 +405,18 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
sig, sig_len, f_rng, p_rng ) ); sig, sig_len, f_rng, p_rng ) );
} }
/*
* Make a signature
*/
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
sig, sig_len, f_rng, p_rng, NULL ) );
}
/* /*
* Decrypt message * Decrypt message
*/ */
...@@ -277,7 +425,12 @@ int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, ...@@ -277,7 +425,12 @@ int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
unsigned char *output, size_t *olen, size_t osize, unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 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 ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->decrypt_func == NULL ) if( ctx->pk_info->decrypt_func == NULL )
...@@ -295,7 +448,12 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, ...@@ -295,7 +448,12 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
unsigned char *output, size_t *olen, size_t osize, unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 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 ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->encrypt_func == NULL ) if( ctx->pk_info->encrypt_func == NULL )
...@@ -310,8 +468,11 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, ...@@ -310,8 +468,11 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
*/ */
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ) int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
{ {
if( pub == NULL || pub->pk_info == NULL || PK_VALIDATE_RET( pub != NULL );
prv == NULL || prv->pk_info == NULL || PK_VALIDATE_RET( prv != NULL );
if( pub->pk_info == NULL ||
prv->pk_info == NULL ||
prv->pk_info->check_pair_func == NULL ) prv->pk_info->check_pair_func == NULL )
{ {
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
...@@ -336,6 +497,8 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte ...@@ -336,6 +497,8 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte
*/ */
size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) 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 ) if( ctx == NULL || ctx->pk_info == NULL )
return( 0 ); return( 0 );
...@@ -347,7 +510,8 @@ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) ...@@ -347,7 +510,8 @@ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
*/ */
int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ) 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 ); return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->debug_func == NULL ) if( ctx->pk_info->debug_func == NULL )
......
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
#include "mbedtls/ecdsa.h" #include "mbedtls/ecdsa.h"
#endif #endif
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
#include "mbedtls/platform_util.h"
#endif
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
...@@ -52,13 +56,6 @@ ...@@ -52,13 +56,6 @@
#include <limits.h> #include <limits.h>
#include <stdint.h> #include <stdint.h>
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#endif
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)
static int rsa_can_do( mbedtls_pk_type_t type ) static int rsa_can_do( mbedtls_pk_type_t type )
{ {
...@@ -193,11 +190,19 @@ const mbedtls_pk_info_t mbedtls_rsa_info = { ...@@ -193,11 +190,19 @@ const mbedtls_pk_info_t mbedtls_rsa_info = {
rsa_can_do, rsa_can_do,
rsa_verify_wrap, rsa_verify_wrap,
rsa_sign_wrap, rsa_sign_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
rsa_decrypt_wrap, rsa_decrypt_wrap,
rsa_encrypt_wrap, rsa_encrypt_wrap,
rsa_check_pair_wrap, rsa_check_pair_wrap,
rsa_alloc_wrap, rsa_alloc_wrap,
rsa_free_wrap, rsa_free_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
rsa_debug, rsa_debug,
}; };
#endif /* MBEDTLS_RSA_C */ #endif /* MBEDTLS_RSA_C */
...@@ -265,6 +270,110 @@ static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, ...@@ -265,6 +270,110 @@ static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
return( ret ); return( ret );
} }
#if defined(MBEDTLS_ECP_RESTARTABLE)
/* Forward declarations */
static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
void *rs_ctx );
static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
void *rs_ctx );
/*
* Restart context for ECDSA operations with ECKEY context
*
* We need to store an actual ECDSA context, as we need to pass the same to
* the underlying ecdsa function, so we can't create it on the fly every time.
*/
typedef struct
{
mbedtls_ecdsa_restart_ctx ecdsa_rs;
mbedtls_ecdsa_context ecdsa_ctx;
} eckey_restart_ctx;
static void *eckey_rs_alloc( void )
{
eckey_restart_ctx *rs_ctx;
void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) );
if( ctx != NULL )
{
rs_ctx = ctx;
mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs );
mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx );
}
return( ctx );
}
static void eckey_rs_free( void *ctx )
{
eckey_restart_ctx *rs_ctx;
if( ctx == NULL)
return;
rs_ctx = ctx;
mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs );
mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx );
mbedtls_free( ctx );
}
static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
void *rs_ctx )
{
int ret;
eckey_restart_ctx *rs = rs_ctx;
/* Should never happen */
if( rs == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
/* set up our own sub-context if needed (that is, on first run) */
if( rs->ecdsa_ctx.grp.pbits == 0 )
MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx,
md_alg, hash, hash_len,
sig, sig_len, &rs->ecdsa_rs ) );
cleanup:
return( ret );
}
static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
void *rs_ctx )
{
int ret;
eckey_restart_ctx *rs = rs_ctx;
/* Should never happen */
if( rs == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
/* set up our own sub-context if needed (that is, on first run) */
if( rs->ecdsa_ctx.grp.pbits == 0 )
MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,
hash, hash_len, sig, sig_len,
f_rng, p_rng, &rs->ecdsa_rs ) );
cleanup:
return( ret );
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDSA_C */
static int eckey_check_pair( const void *pub, const void *prv ) static int eckey_check_pair( const void *pub, const void *prv )
...@@ -304,15 +413,23 @@ const mbedtls_pk_info_t mbedtls_eckey_info = { ...@@ -304,15 +413,23 @@ const mbedtls_pk_info_t mbedtls_eckey_info = {
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDSA_C)
eckey_verify_wrap, eckey_verify_wrap,
eckey_sign_wrap, eckey_sign_wrap,
#else #if defined(MBEDTLS_ECP_RESTARTABLE)
eckey_verify_rs_wrap,
eckey_sign_rs_wrap,
#endif
#else /* MBEDTLS_ECDSA_C */
NULL, NULL,
NULL, NULL,
#endif #endif /* MBEDTLS_ECDSA_C */
NULL, NULL,
NULL, NULL,
eckey_check_pair, eckey_check_pair,
eckey_alloc_wrap, eckey_alloc_wrap,
eckey_free_wrap, eckey_free_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
eckey_rs_alloc,
eckey_rs_free,
#endif
eckey_debug, eckey_debug,
}; };
...@@ -332,11 +449,19 @@ const mbedtls_pk_info_t mbedtls_eckeydh_info = { ...@@ -332,11 +449,19 @@ const mbedtls_pk_info_t mbedtls_eckeydh_info = {
eckeydh_can_do, eckeydh_can_do,
NULL, NULL,
NULL, NULL,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
NULL, NULL,
NULL, NULL,
eckey_check_pair, eckey_check_pair,
eckey_alloc_wrap, /* Same underlying key structure */ eckey_alloc_wrap, /* Same underlying key structure */
eckey_free_wrap, /* Same underlying key structure */ eckey_free_wrap, /* Same underlying key structure */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
eckey_debug, /* Same underlying key structure */ eckey_debug, /* Same underlying key structure */
}; };
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
...@@ -372,6 +497,40 @@ static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, ...@@ -372,6 +497,40 @@ static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
} }
#if defined(MBEDTLS_ECP_RESTARTABLE)
static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
void *rs_ctx )
{
int ret;
((void) md_alg);
ret = mbedtls_ecdsa_read_signature_restartable(
(mbedtls_ecdsa_context *) ctx,
hash, hash_len, sig, sig_len,
(mbedtls_ecdsa_restart_ctx *) rs_ctx );
if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
return( ret );
}
static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
void *rs_ctx )
{
return( mbedtls_ecdsa_write_signature_restartable(
(mbedtls_ecdsa_context *) ctx,
md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
(mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
static void *ecdsa_alloc_wrap( void ) static void *ecdsa_alloc_wrap( void )
{ {
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
...@@ -388,6 +547,24 @@ static void ecdsa_free_wrap( void *ctx ) ...@@ -388,6 +547,24 @@ static void ecdsa_free_wrap( void *ctx )
mbedtls_free( ctx ); mbedtls_free( ctx );
} }
#if defined(MBEDTLS_ECP_RESTARTABLE)
static void *ecdsa_rs_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
if( ctx != NULL )
mbedtls_ecdsa_restart_init( ctx );
return( ctx );
}
static void ecdsa_rs_free( void *ctx )
{
mbedtls_ecdsa_restart_free( ctx );
mbedtls_free( ctx );
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
const mbedtls_pk_info_t mbedtls_ecdsa_info = { const mbedtls_pk_info_t mbedtls_ecdsa_info = {
MBEDTLS_PK_ECDSA, MBEDTLS_PK_ECDSA,
"ECDSA", "ECDSA",
...@@ -395,11 +572,19 @@ const mbedtls_pk_info_t mbedtls_ecdsa_info = { ...@@ -395,11 +572,19 @@ const mbedtls_pk_info_t mbedtls_ecdsa_info = {
ecdsa_can_do, ecdsa_can_do,
ecdsa_verify_wrap, ecdsa_verify_wrap,
ecdsa_sign_wrap, ecdsa_sign_wrap,
#if defined(MBEDTLS_ECP_RESTARTABLE)
ecdsa_verify_rs_wrap,
ecdsa_sign_rs_wrap,
#endif
NULL, NULL,
NULL, NULL,
eckey_check_pair, /* Compatible key structures */ eckey_check_pair, /* Compatible key structures */
ecdsa_alloc_wrap, ecdsa_alloc_wrap,
ecdsa_free_wrap, ecdsa_free_wrap,
#if defined(MBEDTLS_ECP_RESTARTABLE)
ecdsa_rs_alloc,
ecdsa_rs_free,
#endif
eckey_debug, /* Compatible key structures */ eckey_debug, /* Compatible key structures */
}; };
#endif /* MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDSA_C */
...@@ -498,7 +683,7 @@ static void *rsa_alt_alloc_wrap( void ) ...@@ -498,7 +683,7 @@ static void *rsa_alt_alloc_wrap( void )
static void rsa_alt_free_wrap( void *ctx ) static void rsa_alt_free_wrap( void *ctx )
{ {
mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
mbedtls_free( ctx ); mbedtls_free( ctx );
} }
...@@ -509,6 +694,10 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = { ...@@ -509,6 +694,10 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
rsa_alt_can_do, rsa_alt_can_do,
NULL, NULL,
rsa_alt_sign_wrap, rsa_alt_sign_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
rsa_alt_decrypt_wrap, rsa_alt_decrypt_wrap,
NULL, NULL,
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)
...@@ -518,6 +707,10 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = { ...@@ -518,6 +707,10 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
#endif #endif
rsa_alt_alloc_wrap, rsa_alt_alloc_wrap,
rsa_alt_free_wrap, rsa_alt_free_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
NULL, NULL,
}; };
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "mbedtls/pkcs12.h" #include "mbedtls/pkcs12.h"
#include "mbedtls/asn1.h" #include "mbedtls/asn1.h"
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -47,11 +48,6 @@ ...@@ -47,11 +48,6 @@
#include "mbedtls/des.h" #include "mbedtls/des.h"
#endif #endif
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#if defined(MBEDTLS_ASN1_PARSE_C) #if defined(MBEDTLS_ASN1_PARSE_C)
static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
...@@ -168,7 +164,7 @@ int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, ...@@ -168,7 +164,7 @@ int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
goto exit; goto exit;
exit: exit:
mbedtls_zeroize( key, sizeof( key ) ); mbedtls_platform_zeroize( key, sizeof( key ) );
mbedtls_arc4_free( &ctx ); mbedtls_arc4_free( &ctx );
return( ret ); return( ret );
...@@ -225,8 +221,8 @@ int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, ...@@ -225,8 +221,8 @@ int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
exit: exit:
mbedtls_zeroize( key, sizeof( key ) ); mbedtls_platform_zeroize( key, sizeof( key ) );
mbedtls_zeroize( iv, sizeof( iv ) ); mbedtls_platform_zeroize( iv, sizeof( iv ) );
mbedtls_cipher_free( &cipher_ctx ); mbedtls_cipher_free( &cipher_ctx );
return( ret ); return( ret );
...@@ -356,10 +352,10 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, ...@@ -356,10 +352,10 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
ret = 0; ret = 0;
exit: exit:
mbedtls_zeroize( salt_block, sizeof( salt_block ) ); mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) );
mbedtls_zeroize( pwd_block, sizeof( pwd_block ) ); mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) );
mbedtls_zeroize( hash_block, sizeof( hash_block ) ); mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) );
mbedtls_zeroize( hash_output, sizeof( hash_output ) ); mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) );
mbedtls_md_free( &md_ctx ); mbedtls_md_free( &md_ctx );
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "mbedtls/pk.h" #include "mbedtls/pk.h"
#include "mbedtls/asn1.h" #include "mbedtls/asn1.h"
#include "mbedtls/oid.h" #include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -60,13 +61,11 @@ ...@@ -60,13 +61,11 @@
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#if defined(MBEDTLS_FS_IO) || \ /* Parameter validation macros based on platform_util.h */
defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) #define PK_VALIDATE_RET( cond ) \
/* Implementation that should never be optimized out by the compiler */ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
static void mbedtls_zeroize( void *v, size_t n ) { #define PK_VALIDATE( cond ) \
volatile unsigned char *p = v; while( n-- ) *p++ = 0; MBEDTLS_INTERNAL_VALIDATE( cond )
}
#endif
#if defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_FS_IO)
/* /*
...@@ -81,6 +80,10 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) ...@@ -81,6 +80,10 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
FILE *f; FILE *f;
long size; long size;
PK_VALIDATE_RET( path != NULL );
PK_VALIDATE_RET( buf != NULL );
PK_VALIDATE_RET( n != NULL );
if( ( f = fopen( path, "rb" ) ) == NULL ) if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
...@@ -105,7 +108,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) ...@@ -105,7 +108,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
{ {
fclose( f ); fclose( f );
mbedtls_zeroize( *buf, *n ); mbedtls_platform_zeroize( *buf, *n );
mbedtls_free( *buf ); mbedtls_free( *buf );
return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
...@@ -131,6 +134,9 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, ...@@ -131,6 +134,9 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
size_t n; size_t n;
unsigned char *buf; unsigned char *buf;
PK_VALIDATE_RET( ctx != NULL );
PK_VALIDATE_RET( path != NULL );
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
return( ret ); return( ret );
...@@ -140,7 +146,7 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, ...@@ -140,7 +146,7 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
ret = mbedtls_pk_parse_key( ctx, buf, n, ret = mbedtls_pk_parse_key( ctx, buf, n,
(const unsigned char *) pwd, strlen( pwd ) ); (const unsigned char *) pwd, strlen( pwd ) );
mbedtls_zeroize( buf, n ); mbedtls_platform_zeroize( buf, n );
mbedtls_free( buf ); mbedtls_free( buf );
return( ret ); return( ret );
...@@ -155,12 +161,15 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) ...@@ -155,12 +161,15 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
size_t n; size_t n;
unsigned char *buf; unsigned char *buf;
PK_VALIDATE_RET( ctx != NULL );
PK_VALIDATE_RET( path != NULL );
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
return( ret ); return( ret );
ret = mbedtls_pk_parse_public_key( ctx, buf, n ); ret = mbedtls_pk_parse_public_key( ctx, buf, n );
mbedtls_zeroize( buf, n ); mbedtls_platform_zeroize( buf, n );
mbedtls_free( buf ); mbedtls_free( buf );
return( ret ); return( ret );
...@@ -612,6 +621,11 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, ...@@ -612,6 +621,11 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
const mbedtls_pk_info_t *pk_info; 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, if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{ {
...@@ -1152,16 +1166,22 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, ...@@ -1152,16 +1166,22 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
{ {
int ret; int ret;
const mbedtls_pk_info_t *pk_info; const mbedtls_pk_info_t *pk_info;
#if defined(MBEDTLS_PEM_PARSE_C) #if defined(MBEDTLS_PEM_PARSE_C)
size_t len; size_t len;
mbedtls_pem_context pem; 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) #if defined(MBEDTLS_RSA_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ /* 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; ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else else
ret = mbedtls_pem_read_buffer( &pem, ret = mbedtls_pem_read_buffer( &pem,
...@@ -1192,7 +1212,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, ...@@ -1192,7 +1212,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ /* 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; ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else else
ret = mbedtls_pem_read_buffer( &pem, ret = mbedtls_pem_read_buffer( &pem,
...@@ -1222,7 +1242,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, ...@@ -1222,7 +1242,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ /* 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; ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else else
ret = mbedtls_pem_read_buffer( &pem, ret = mbedtls_pem_read_buffer( &pem,
...@@ -1245,7 +1265,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, ...@@ -1245,7 +1265,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ /* 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; ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else else
ret = mbedtls_pem_read_buffer( &pem, ret = mbedtls_pem_read_buffer( &pem,
...@@ -1283,9 +1303,6 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, ...@@ -1283,9 +1303,6 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
{ {
unsigned char *key_copy; unsigned char *key_copy;
if( keylen == 0 )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL ) if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
return( MBEDTLS_ERR_PK_ALLOC_FAILED ); return( MBEDTLS_ERR_PK_ALLOC_FAILED );
...@@ -1294,7 +1311,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, ...@@ -1294,7 +1311,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen, ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
pwd, pwdlen ); pwd, pwdlen );
mbedtls_zeroize( key_copy, keylen ); mbedtls_platform_zeroize( key_copy, keylen );
mbedtls_free( key_copy ); mbedtls_free( key_copy );
} }
...@@ -1361,14 +1378,55 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, ...@@ -1361,14 +1378,55 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
{ {
int ret; int ret;
unsigned char *p; unsigned char *p;
#if defined(MBEDTLS_RSA_C)
const mbedtls_pk_info_t *pk_info;
#endif
#if defined(MBEDTLS_PEM_PARSE_C) #if defined(MBEDTLS_PEM_PARSE_C)
size_t len; size_t len;
mbedtls_pem_context pem; 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 ); mbedtls_pem_init( &pem );
#if defined(MBEDTLS_RSA_C)
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
if( key[keylen - 1] != '\0' )
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else
ret = mbedtls_pem_read_buffer( &pem,
"-----BEGIN RSA PUBLIC KEY-----",
"-----END RSA PUBLIC KEY-----",
key, NULL, 0, &len );
if( ret == 0 )
{
p = pem.buf;
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
return( ret );
if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 )
mbedtls_pk_free( ctx );
mbedtls_pem_free( &pem );
return( ret );
}
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{
mbedtls_pem_free( &pem );
return( ret );
}
#endif /* MBEDTLS_RSA_C */
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ /* 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; ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else else
ret = mbedtls_pem_read_buffer( &pem, ret = mbedtls_pem_read_buffer( &pem,
...@@ -1381,23 +1439,43 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, ...@@ -1381,23 +1439,43 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
/* /*
* Was PEM encoded * Was PEM encoded
*/ */
key = pem.buf; p = pem.buf;
keylen = pem.buflen;
ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx );
mbedtls_pem_free( &pem );
return( ret );
} }
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
{ {
mbedtls_pem_free( &pem ); mbedtls_pem_free( &pem );
return( ret ); return( ret );
} }
mbedtls_pem_free( &pem );
#endif /* MBEDTLS_PEM_PARSE_C */ #endif /* MBEDTLS_PEM_PARSE_C */
#if defined(MBEDTLS_RSA_C)
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
return( ret );
p = (unsigned char *)key;
ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) );
if( ret == 0 )
{
return( ret );
}
mbedtls_pk_free( ctx );
if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
{
return( ret );
}
#endif /* MBEDTLS_RSA_C */
p = (unsigned char *) key; p = (unsigned char *) key;
ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx );
#if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_free( &pem );
#endif
return( ret ); return( ret );
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "mbedtls/pk.h" #include "mbedtls/pk.h"
#include "mbedtls/asn1write.h" #include "mbedtls/asn1write.h"
#include "mbedtls/oid.h" #include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -37,7 +38,9 @@ ...@@ -37,7 +38,9 @@
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
#endif #endif
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
#include "mbedtls/bignum.h"
#include "mbedtls/ecp.h" #include "mbedtls/ecp.h"
#include "mbedtls/platform_util.h"
#endif #endif
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDSA_C)
#include "mbedtls/ecdsa.h" #include "mbedtls/ecdsa.h"
...@@ -54,6 +57,12 @@ ...@@ -54,6 +57,12 @@
#define mbedtls_free free #define mbedtls_free free
#endif #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) #if defined(MBEDTLS_RSA_C)
/* /*
* RSAPublicKey ::= SEQUENCE { * RSAPublicKey ::= SEQUENCE {
...@@ -143,6 +152,26 @@ static int pk_write_ec_param( unsigned char **p, unsigned char *start, ...@@ -143,6 +152,26 @@ static int pk_write_ec_param( unsigned char **p, unsigned char *start,
return( (int) len ); return( (int) len );
} }
/*
* privateKey OCTET STRING -- always of length ceil(log2(n)/8)
*/
static int pk_write_ec_private( unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec )
{
int ret;
size_t byte_length = ( ec->grp.pbits + 7 ) / 8;
unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
ret = mbedtls_mpi_write_binary( &ec->d, tmp, byte_length );
if( ret != 0 )
goto exit;
ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length );
exit:
mbedtls_platform_zeroize( tmp, byte_length );
return( ret );
}
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
...@@ -151,6 +180,11 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, ...@@ -151,6 +180,11 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
int ret; int ret;
size_t len = 0; 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 defined(MBEDTLS_RSA_C)
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
...@@ -173,6 +207,11 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si ...@@ -173,6 +207,11 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si
size_t len = 0, par_len = 0, oid_len; size_t len = 0, par_len = 0, oid_len;
const char *oid; 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; c = buf + size;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
...@@ -217,9 +256,16 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si ...@@ -217,9 +256,16 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si
int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{ {
int ret; int ret;
unsigned char *c = buf + size; unsigned char *c;
size_t len = 0; 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 defined(MBEDTLS_RSA_C)
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
{ {
...@@ -340,9 +386,8 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_ ...@@ -340,9 +386,8 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
len += par_len; len += par_len;
/* privateKey: write as MPI then fix tag */ /* privateKey */
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) ); MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_private( &c, buf, ec ) );
*c = MBEDTLS_ASN1_OCTET_STRING;
/* version */ /* version */
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) );
...@@ -457,6 +502,9 @@ int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, si ...@@ -457,6 +502,9 @@ int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, si
unsigned char output_buf[PUB_DER_MAX_BYTES]; unsigned char output_buf[PUB_DER_MAX_BYTES];
size_t olen = 0; 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, if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
sizeof(output_buf) ) ) < 0 ) sizeof(output_buf) ) ) < 0 )
{ {
...@@ -480,6 +528,9 @@ int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_ ...@@ -480,6 +528,9 @@ int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_
const char *begin, *end; const char *begin, *end;
size_t olen = 0; 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 ) if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
return( ret ); return( ret );
......
...@@ -28,14 +28,7 @@ ...@@ -28,14 +28,7 @@
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_ENTROPY_NV_SEED) && \
!defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
#endif
/* The compile time configuration of memory allocation via the macros /* The compile time configuration of memory allocation via the macros
* MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime
...@@ -65,14 +58,24 @@ static void platform_free_uninit( void *ptr ) ...@@ -65,14 +58,24 @@ static void platform_free_uninit( void *ptr )
#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit #define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit
#endif /* !MBEDTLS_PLATFORM_STD_FREE */ #endif /* !MBEDTLS_PLATFORM_STD_FREE */
void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
void (*mbedtls_free)( void * ) = MBEDTLS_PLATFORM_STD_FREE; static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE;
void * mbedtls_calloc( size_t nmemb, size_t size )
{
return (*mbedtls_calloc_func)( nmemb, size );
}
void mbedtls_free( void * ptr )
{
(*mbedtls_free_func)( ptr );
}
int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
void (*free_func)( void * ) ) void (*free_func)( void * ) )
{ {
mbedtls_calloc = calloc_func; mbedtls_calloc_func = calloc_func;
mbedtls_free = free_func; mbedtls_free_func = free_func;
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_PLATFORM_MEMORY && #endif /* MBEDTLS_PLATFORM_MEMORY &&
...@@ -250,7 +253,7 @@ int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) ...@@ -250,7 +253,7 @@ int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len )
if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
{ {
fclose( file ); fclose( file );
mbedtls_zeroize( buf, buf_len ); mbedtls_platform_zeroize( buf, buf_len );
return( -1 ); return( -1 );
} }
......
/*
* Common and shared functions used by multiple modules in the Mbed TLS
* library.
*
* Copyright (C) 2018, Arm Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of Mbed TLS (https://tls.mbed.org)
*/
/*
* Ensure gmtime_r is available even with -std=c99; must be defined before
* config.h, which pulls in glibc's features.h. Harmless on other platforms.
*/
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 200112L
#endif
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/platform_util.h"
#include "mbedtls/platform.h"
#include "mbedtls/threading.h"
#include <stddef.h>
#include <string.h>
#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
/*
* This implementation should never be optimized out by the compiler
*
* This implementation for mbedtls_platform_zeroize() was inspired from Colin
* Percival's blog article at:
*
* http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
*
* It uses a volatile function pointer to the standard memset(). Because the
* pointer is volatile the compiler expects it to change at
* any time and will not optimize out the call that could potentially perform
* other operations on the input buffer instead of just setting it to 0.
* Nevertheless, as pointed out by davidtgoldblatt on Hacker News
* (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for
* details), optimizations of the following form are still possible:
*
* if( memset_func != memset )
* memset_func( buf, 0, len );
*
* Note that it is extremely difficult to guarantee that
* mbedtls_platform_zeroize() will not be optimized out by aggressive compilers
* in a portable way. For this reason, Mbed TLS also provides the configuration
* option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
* mbedtls_platform_zeroize() to use a suitable implementation for their
* platform and needs.
*/
static void * (* const volatile memset_func)( void *, int, size_t ) = memset;
void mbedtls_platform_zeroize( void *buf, size_t len )
{
MBEDTLS_INTERNAL_VALIDATE( len == 0 || buf != NULL );
if( len > 0 )
memset_func( buf, 0, len );
}
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
#include <time.h>
#if !defined(_WIN32) && (defined(unix) || \
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
defined(__MACH__)))
#include <unistd.h>
#endif /* !_WIN32 && (unix || __unix || __unix__ ||
* (__APPLE__ && __MACH__)) */
#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
/*
* This is a convenience shorthand macro to avoid checking the long
* preprocessor conditions above. Ideally, we could expose this macro in
* platform_util.h and simply use it in platform_util.c, threading.c and
* threading.h. However, this macro is not part of the Mbed TLS public API, so
* we keep it private by only defining it in this file
*/
#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
#define PLATFORM_UTIL_USE_GMTIME
#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */
#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
struct tm *tm_buf )
{
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL );
#elif !defined(PLATFORM_UTIL_USE_GMTIME)
return( gmtime_r( tt, tm_buf ) );
#else
struct tm *lt;
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
return( NULL );
#endif /* MBEDTLS_THREADING_C */
lt = gmtime( tt );
if( lt != NULL )
{
memcpy( tm_buf, lt, sizeof( struct tm ) );
}
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 )
return( NULL );
#endif /* MBEDTLS_THREADING_C */
return( ( lt == NULL ) ? NULL : tm_buf );
#endif /* _WIN32 && !EFIX64 && !EFI32 */
}
#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */
/**
* \file poly1305.c
*
* \brief Poly1305 authentication algorithm.
*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_POLY1305_C)
#include "mbedtls/poly1305.h"
#include "mbedtls/platform_util.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_POLY1305_ALT)
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#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 ) \
( (uint32_t) (data)[offset] \
| (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
| (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
| (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
)
/*
* Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
* However we provided an alternative for platforms without such a multiplier.
*/
#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
static uint64_t mul64( uint32_t a, uint32_t b )
{
/* a = al + 2**16 ah, b = bl + 2**16 bh */
const uint16_t al = (uint16_t) a;
const uint16_t bl = (uint16_t) b;
const uint16_t ah = a >> 16;
const uint16_t bh = b >> 16;
/* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
const uint32_t lo = (uint32_t) al * bl;
const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
const uint32_t hi = (uint32_t) ah * bh;
return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
}
#else
static inline uint64_t mul64( uint32_t a, uint32_t b )
{
return( (uint64_t) a * b );
}
#endif
/**
* \brief Process blocks with Poly1305.
*
* \param ctx The Poly1305 context.
* \param nblocks Number of blocks to process. Note that this
* function only processes full blocks.
* \param input Buffer containing the input block(s).
* \param needs_padding Set to 0 if the padding bit has already been
* applied to the input data before calling this
* function. Otherwise, set this parameter to 1.
*/
static void poly1305_process( mbedtls_poly1305_context *ctx,
size_t nblocks,
const unsigned char *input,
uint32_t needs_padding )
{
uint64_t d0, d1, d2, d3;
uint32_t acc0, acc1, acc2, acc3, acc4;
uint32_t r0, r1, r2, r3;
uint32_t rs1, rs2, rs3;
size_t offset = 0U;
size_t i;
r0 = ctx->r[0];
r1 = ctx->r[1];
r2 = ctx->r[2];
r3 = ctx->r[3];
rs1 = r1 + ( r1 >> 2U );
rs2 = r2 + ( r2 >> 2U );
rs3 = r3 + ( r3 >> 2U );
acc0 = ctx->acc[0];
acc1 = ctx->acc[1];
acc2 = ctx->acc[2];
acc3 = ctx->acc[3];
acc4 = ctx->acc[4];
/* Process full blocks */
for( i = 0U; i < nblocks; i++ )
{
/* The input block is treated as a 128-bit little-endian integer */
d0 = BYTES_TO_U32_LE( input, offset + 0 );
d1 = BYTES_TO_U32_LE( input, offset + 4 );
d2 = BYTES_TO_U32_LE( input, offset + 8 );
d3 = BYTES_TO_U32_LE( input, offset + 12 );
/* Compute: acc += (padded) block as a 130-bit integer */
d0 += (uint64_t) acc0;
d1 += (uint64_t) acc1 + ( d0 >> 32U );
d2 += (uint64_t) acc2 + ( d1 >> 32U );
d3 += (uint64_t) acc3 + ( d2 >> 32U );
acc0 = (uint32_t) d0;
acc1 = (uint32_t) d1;
acc2 = (uint32_t) d2;
acc3 = (uint32_t) d3;
acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
/* Compute: acc *= r */
d0 = mul64( acc0, r0 ) +
mul64( acc1, rs3 ) +
mul64( acc2, rs2 ) +
mul64( acc3, rs1 );
d1 = mul64( acc0, r1 ) +
mul64( acc1, r0 ) +
mul64( acc2, rs3 ) +
mul64( acc3, rs2 ) +
mul64( acc4, rs1 );
d2 = mul64( acc0, r2 ) +
mul64( acc1, r1 ) +
mul64( acc2, r0 ) +
mul64( acc3, rs3 ) +
mul64( acc4, rs2 );
d3 = mul64( acc0, r3 ) +
mul64( acc1, r2 ) +
mul64( acc2, r1 ) +
mul64( acc3, r0 ) +
mul64( acc4, rs3 );
acc4 *= r0;
/* Compute: acc %= (2^130 - 5) (partial remainder) */
d1 += ( d0 >> 32 );
d2 += ( d1 >> 32 );
d3 += ( d2 >> 32 );
acc0 = (uint32_t) d0;
acc1 = (uint32_t) d1;
acc2 = (uint32_t) d2;
acc3 = (uint32_t) d3;
acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
acc4 &= 3U;
acc0 = (uint32_t) d0;
d0 = (uint64_t) acc1 + ( d0 >> 32U );
acc1 = (uint32_t) d0;
d0 = (uint64_t) acc2 + ( d0 >> 32U );
acc2 = (uint32_t) d0;
d0 = (uint64_t) acc3 + ( d0 >> 32U );
acc3 = (uint32_t) d0;
d0 = (uint64_t) acc4 + ( d0 >> 32U );
acc4 = (uint32_t) d0;
offset += POLY1305_BLOCK_SIZE_BYTES;
}
ctx->acc[0] = acc0;
ctx->acc[1] = acc1;
ctx->acc[2] = acc2;
ctx->acc[3] = acc3;
ctx->acc[4] = acc4;
}
/**
* \brief Compute the Poly1305 MAC
*
* \param ctx The Poly1305 context.
* \param mac The buffer to where the MAC is written. Must be
* big enough to contain the 16-byte MAC.
*/
static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
unsigned char mac[16] )
{
uint64_t d;
uint32_t g0, g1, g2, g3, g4;
uint32_t acc0, acc1, acc2, acc3, acc4;
uint32_t mask;
uint32_t mask_inv;
acc0 = ctx->acc[0];
acc1 = ctx->acc[1];
acc2 = ctx->acc[2];
acc3 = ctx->acc[3];
acc4 = ctx->acc[4];
/* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
* We do this by calculating acc - (2^130 - 5), then checking if
* the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
*/
/* Calculate acc + -(2^130 - 5) */
d = ( (uint64_t) acc0 + 5U );
g0 = (uint32_t) d;
d = ( (uint64_t) acc1 + ( d >> 32 ) );
g1 = (uint32_t) d;
d = ( (uint64_t) acc2 + ( d >> 32 ) );
g2 = (uint32_t) d;
d = ( (uint64_t) acc3 + ( d >> 32 ) );
g3 = (uint32_t) d;
g4 = acc4 + (uint32_t) ( d >> 32U );
/* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
mask = (uint32_t) 0U - ( g4 >> 2U );
mask_inv = ~mask;
/* If 131st bit is set then acc=g, otherwise, acc is unmodified */
acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
/* Add 's' */
d = (uint64_t) acc0 + ctx->s[0];
acc0 = (uint32_t) d;
d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
acc1 = (uint32_t) d;
d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
acc2 = (uint32_t) d;
acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
/* Compute MAC (128 least significant bits of the accumulator) */
mac[ 0] = (unsigned char)( acc0 );
mac[ 1] = (unsigned char)( acc0 >> 8 );
mac[ 2] = (unsigned char)( acc0 >> 16 );
mac[ 3] = (unsigned char)( acc0 >> 24 );
mac[ 4] = (unsigned char)( acc1 );
mac[ 5] = (unsigned char)( acc1 >> 8 );
mac[ 6] = (unsigned char)( acc1 >> 16 );
mac[ 7] = (unsigned char)( acc1 >> 24 );
mac[ 8] = (unsigned char)( acc2 );
mac[ 9] = (unsigned char)( acc2 >> 8 );
mac[10] = (unsigned char)( acc2 >> 16 );
mac[11] = (unsigned char)( acc2 >> 24 );
mac[12] = (unsigned char)( acc3 );
mac[13] = (unsigned char)( acc3 >> 8 );
mac[14] = (unsigned char)( acc3 >> 16 );
mac[15] = (unsigned char)( acc3 >> 24 );
}
void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
{
POLY1305_VALIDATE( ctx != NULL );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
}
void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
{
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] )
{
POLY1305_VALIDATE_RET( ctx != NULL );
POLY1305_VALIDATE_RET( key != NULL );
/* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
/* Initial accumulator state */
ctx->acc[0] = 0U;
ctx->acc[1] = 0U;
ctx->acc[2] = 0U;
ctx->acc[3] = 0U;
ctx->acc[4] = 0U;
/* Queue initially empty */
mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
ctx->queue_len = 0U;
return( 0 );
}
int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
const unsigned char *input,
size_t ilen )
{
size_t offset = 0U;
size_t remaining = ilen;
size_t queue_free_len;
size_t nblocks;
POLY1305_VALIDATE_RET( ctx != NULL );
POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
{
queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
if( ilen < queue_free_len )
{
/* Not enough data to complete the block.
* Store this data with the other leftovers.
*/
memcpy( &ctx->queue[ctx->queue_len],
input,
ilen );
ctx->queue_len += ilen;
remaining = 0U;
}
else
{
/* Enough data to produce a complete block */
memcpy( &ctx->queue[ctx->queue_len],
input,
queue_free_len );
ctx->queue_len = 0U;
poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
offset += queue_free_len;
remaining -= queue_free_len;
}
}
if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
{
nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
poly1305_process( ctx, nblocks, &input[offset], 1U );
offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
remaining %= POLY1305_BLOCK_SIZE_BYTES;
}
if( remaining > 0U )
{
/* Store partial block */
ctx->queue_len = remaining;
memcpy( ctx->queue, &input[offset], remaining );
}
return( 0 );
}
int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
unsigned char mac[16] )
{
POLY1305_VALIDATE_RET( ctx != NULL );
POLY1305_VALIDATE_RET( mac != NULL );
/* Process any leftover data */
if( ctx->queue_len > 0U )
{
/* Add padding bit */
ctx->queue[ctx->queue_len] = 1U;
ctx->queue_len++;
/* Pad with zeroes */
memset( &ctx->queue[ctx->queue_len],
0,
POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
poly1305_process( ctx, 1U, /* Process 1 block */
ctx->queue, 0U ); /* Already padded above */
}
poly1305_compute_mac( ctx, mac );
return( 0 );
}
int mbedtls_poly1305_mac( const unsigned char key[32],
const unsigned char *input,
size_t ilen,
unsigned char mac[16] )
{
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 );
ret = mbedtls_poly1305_starts( &ctx, key );
if( ret != 0 )
goto cleanup;
ret = mbedtls_poly1305_update( &ctx, input, ilen );
if( ret != 0 )
goto cleanup;
ret = mbedtls_poly1305_finish( &ctx, mac );
cleanup:
mbedtls_poly1305_free( &ctx );
return( ret );
}
#endif /* MBEDTLS_POLY1305_ALT */
#if defined(MBEDTLS_SELF_TEST)
static const unsigned char test_keys[2][32] =
{
{
0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
},
{
0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
}
};
static const unsigned char test_data[2][127] =
{
{
0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
0x75, 0x70
},
{
0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
}
};
static const size_t test_data_len[2] =
{
34U,
127U
};
static const unsigned char test_mac[2][16] =
{
{
0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
},
{
0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
}
};
#define ASSERT( cond, args ) \
do \
{ \
if( ! ( cond ) ) \
{ \
if( verbose != 0 ) \
mbedtls_printf args; \
\
return( -1 ); \
} \
} \
while( 0 )
int mbedtls_poly1305_self_test( int verbose )
{
unsigned char mac[16];
unsigned i;
int ret;
for( i = 0U; i < 2U; i++ )
{
if( verbose != 0 )
mbedtls_printf( " Poly1305 test %u ", i );
ret = mbedtls_poly1305_mac( test_keys[i],
test_data[i],
test_data_len[i],
mac );
ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_POLY1305_C */
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#if defined(MBEDTLS_RIPEMD160_C) #if defined(MBEDTLS_RIPEMD160_C)
#include "mbedtls/ripemd160.h" #include "mbedtls/ripemd160.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -71,11 +72,6 @@ ...@@ -71,11 +72,6 @@
} }
#endif #endif
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ) void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
{ {
memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) ); memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
...@@ -86,7 +82,7 @@ void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ) ...@@ -86,7 +82,7 @@ void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
if( ctx == NULL ) if( ctx == NULL )
return; return;
mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
} }
void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
...@@ -151,22 +147,29 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, ...@@ -151,22 +147,29 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
D = Dp = ctx->state[3]; D = Dp = ctx->state[3];
E = Ep = ctx->state[4]; E = Ep = ctx->state[4];
#define F1( x, y, z ) ( x ^ y ^ z ) #define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) #define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
#define F3( x, y, z ) ( ( x | ~y ) ^ z ) #define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) #define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
#define F5( x, y, z ) ( x ^ ( y | ~z ) ) #define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) #define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
#define P( a, b, c, d, e, r, s, f, k ) \ #define P( a, b, c, d, e, r, s, f, k ) \
a += f( b, c, d ) + X[r] + k; \ do \
a = S( a, s ) + e; \ { \
c = S( c, 10 ); (a) += f( (b), (c), (d) ) + X[r] + (k); \
(a) = S( (a), (s) ) + (e); \
#define P2( a, b, c, d, e, r, s, rp, sp ) \ (c) = S( (c), 10 ); \
P( a, b, c, d, e, r, s, F, K ); \ } while( 0 )
P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
#define P2( a, b, c, d, e, r, s, rp, sp ) \
do \
{ \
P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
P( a ## p, b ## p, c ## p, d ## p, e ## p, \
(rp), (sp), Fp, Kp ); \
} while( 0 )
#define F F1 #define F F1
#define K 0x00000000 #define K 0x00000000
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
#include "mbedtls/rsa_internal.h" #include "mbedtls/rsa_internal.h"
#include "mbedtls/oid.h" #include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -70,10 +71,11 @@ ...@@ -70,10 +71,11 @@
#if !defined(MBEDTLS_RSA_ALT) #if !defined(MBEDTLS_RSA_ALT)
/* Implementation that should never be optimized out by the compiler */ /* Parameter validation macros */
static void mbedtls_zeroize( void *v, size_t n ) { #define RSA_VALIDATE_RET( cond ) \
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
} #define RSA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
#if defined(MBEDTLS_PKCS1_V15) #if defined(MBEDTLS_PKCS1_V15)
/* constant-time buffer comparison */ /* constant-time buffer comparison */
...@@ -97,6 +99,7 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx, ...@@ -97,6 +99,7 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
const mbedtls_mpi *D, const mbedtls_mpi *E ) const mbedtls_mpi *D, const mbedtls_mpi *E )
{ {
int ret; int ret;
RSA_VALIDATE_RET( ctx != NULL );
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) || if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) || ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
...@@ -121,6 +124,7 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, ...@@ -121,6 +124,7 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
unsigned char const *E, size_t E_len ) unsigned char const *E, size_t E_len )
{ {
int ret = 0; int ret = 0;
RSA_VALIDATE_RET( ctx != NULL );
if( N != NULL ) if( N != NULL )
{ {
...@@ -244,12 +248,16 @@ static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv, ...@@ -244,12 +248,16 @@ static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv,
int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
{ {
int ret = 0; 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;
RSA_VALIDATE_RET( ctx != NULL );
const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 ); have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 ); have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 ); have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
/* /*
* Check whether provided parameters are enough * Check whether provided parameters are enough
...@@ -261,13 +269,13 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) ...@@ -261,13 +269,13 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
* *
*/ */
const int n_missing = have_P && have_Q && have_D && have_E; n_missing = have_P && have_Q && have_D && have_E;
const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E; pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
const int d_missing = have_P && have_Q && !have_D && have_E; d_missing = have_P && have_Q && !have_D && have_E;
const int is_pub = have_N && !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 */ /* 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 ) if( !is_priv && !is_pub )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
...@@ -340,9 +348,11 @@ int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, ...@@ -340,9 +348,11 @@ int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
unsigned char *E, size_t E_len ) unsigned char *E, size_t E_len )
{ {
int ret = 0; int ret = 0;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */ /* 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->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
...@@ -383,9 +393,11 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, ...@@ -383,9 +393,11 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
mbedtls_mpi *D, mbedtls_mpi *E ) mbedtls_mpi *D, mbedtls_mpi *E )
{ {
int ret; int ret;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */ /* 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->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
...@@ -425,9 +437,11 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, ...@@ -425,9 +437,11 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ) mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
{ {
int ret; int ret;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */ /* 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->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
...@@ -463,6 +477,10 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx, ...@@ -463,6 +477,10 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
int padding, int padding,
int hash_id ) 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 ) ); memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
mbedtls_rsa_set_padding( ctx, padding, hash_id ); mbedtls_rsa_set_padding( ctx, padding, hash_id );
...@@ -475,8 +493,13 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx, ...@@ -475,8 +493,13 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
/* /*
* Set padding for an existing RSA context * 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->padding = padding;
ctx->hash_id = hash_id; ctx->hash_id = hash_id;
} }
...@@ -495,6 +518,9 @@ size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ) ...@@ -495,6 +518,9 @@ size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
/* /*
* Generate an RSA keypair * Generate an RSA keypair
*
* This generation method follows the RSA key pair generation procedure of
* FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
*/ */
int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),
...@@ -502,65 +528,87 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, ...@@ -502,65 +528,87 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
unsigned int nbits, int exponent ) unsigned int nbits, int exponent )
{ {
int ret; int ret;
mbedtls_mpi H, G; 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 ) if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
if( nbits % 2 ) /*
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); * If the modulus is 1024 bit long or shorter, then the security strength of
* the RSA algorithm is less than or equal to 80 bits and therefore an error
* rate of 2^-80 is sufficient.
*/
if( nbits > 1024 )
prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR;
mbedtls_mpi_init( &H ); mbedtls_mpi_init( &H );
mbedtls_mpi_init( &G ); mbedtls_mpi_init( &G );
mbedtls_mpi_init( &L );
/* /*
* find primes P and Q with Q < P so that: * find primes P and Q with Q < P so that:
* GCD( E, (P-1)*(Q-1) ) == 1 * 1. |P-Q| > 2^( nbits / 2 - 100 )
* 2. GCD( E, (P-1)*(Q-1) ) == 1
* 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
*/ */
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
do do
{ {
MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0, MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1,
f_rng, p_rng ) ); prime_quality, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
f_rng, p_rng ) );
if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1,
continue; prime_quality, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
if( mbedtls_mpi_bitlen( &ctx->N ) != nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) );
if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) )
continue; continue;
if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) /* not required by any standards, but some users rely on the fact that P > Q */
if( H.s < 0 )
mbedtls_mpi_swap( &ctx->P, &ctx->Q ); mbedtls_mpi_swap( &ctx->P, &ctx->Q );
/* Temporarily replace P,Q by P-1, Q-1 */ /* Temporarily replace P,Q by P-1, Q-1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
/* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
continue;
/* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
continue;
break;
} }
while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ); while( 1 );
/* Restore P,Q */ /* Restore P,Q */
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
ctx->len = mbedtls_mpi_size( &ctx->N ); ctx->len = mbedtls_mpi_size( &ctx->N );
#if !defined(MBEDTLS_RSA_NO_CRT)
/* /*
* D = E^-1 mod ((P-1)*(Q-1))
* DP = D mod (P - 1) * DP = D mod (P - 1)
* DQ = D mod (Q - 1) * DQ = D mod (Q - 1)
* QP = Q^-1 mod P * QP = Q^-1 mod P
*/ */
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
#if !defined(MBEDTLS_RSA_NO_CRT)
MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
&ctx->DP, &ctx->DQ, &ctx->QP ) ); &ctx->DP, &ctx->DQ, &ctx->QP ) );
#endif /* MBEDTLS_RSA_NO_CRT */ #endif /* MBEDTLS_RSA_NO_CRT */
...@@ -572,6 +620,7 @@ cleanup: ...@@ -572,6 +620,7 @@ cleanup:
mbedtls_mpi_free( &H ); mbedtls_mpi_free( &H );
mbedtls_mpi_free( &G ); mbedtls_mpi_free( &G );
mbedtls_mpi_free( &L );
if( ret != 0 ) if( ret != 0 )
{ {
...@@ -589,6 +638,8 @@ cleanup: ...@@ -589,6 +638,8 @@ cleanup:
*/ */
int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) 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 ) if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
...@@ -612,6 +663,8 @@ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) ...@@ -612,6 +663,8 @@ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
*/ */
int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
{ {
RSA_VALIDATE_RET( ctx != NULL );
if( mbedtls_rsa_check_pubkey( ctx ) != 0 || if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 ) rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
{ {
...@@ -641,6 +694,9 @@ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) ...@@ -641,6 +694,9 @@ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
const mbedtls_rsa_context *prv ) const mbedtls_rsa_context *prv )
{ {
RSA_VALIDATE_RET( pub != NULL );
RSA_VALIDATE_RET( prv != NULL );
if( mbedtls_rsa_check_pubkey( pub ) != 0 || if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
mbedtls_rsa_check_privkey( prv ) != 0 ) mbedtls_rsa_check_privkey( prv ) != 0 )
{ {
...@@ -666,6 +722,9 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, ...@@ -666,6 +722,9 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
int ret; int ret;
size_t olen; size_t olen;
mbedtls_mpi T; 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 */ ) ) if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
...@@ -808,6 +867,10 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, ...@@ -808,6 +867,10 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
* checked result; should be the same in the end. */ * checked result; should be the same in the end. */
mbedtls_mpi I, C; 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 */, if( rsa_check_context( ctx, 1 /* private key checks */,
f_rng != NULL /* blinding y/n */ ) != 0 ) f_rng != NULL /* blinding y/n */ ) != 0 )
{ {
...@@ -1042,7 +1105,7 @@ static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, ...@@ -1042,7 +1105,7 @@ static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
} }
exit: exit:
mbedtls_zeroize( mask, sizeof( mask ) ); mbedtls_platform_zeroize( mask, sizeof( mask ) );
return( ret ); return( ret );
} }
...@@ -1068,6 +1131,13 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, ...@@ -1068,6 +1131,13 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx; 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( input != NULL );
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
...@@ -1144,11 +1214,13 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, ...@@ -1144,11 +1214,13 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
int ret; int ret;
unsigned char *p = output; unsigned char *p = output;
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) RSA_VALIDATE_RET( ctx != NULL );
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
RSA_VALIDATE_RET( input != NULL );
// We don't check p_rng because it won't be dereferenced here if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
if( f_rng == NULL || input == NULL || output == NULL )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
olen = ctx->len; olen = ctx->len;
...@@ -1162,6 +1234,9 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, ...@@ -1162,6 +1234,9 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
*p++ = 0; *p++ = 0;
if( mode == MBEDTLS_RSA_PUBLIC ) if( mode == MBEDTLS_RSA_PUBLIC )
{ {
if( f_rng == NULL )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
*p++ = MBEDTLS_RSA_CRYPT; *p++ = MBEDTLS_RSA_CRYPT;
while( nb_pad-- > 0 ) while( nb_pad-- > 0 )
...@@ -1206,6 +1281,12 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, ...@@ -1206,6 +1281,12 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
const unsigned char *input, const unsigned char *input,
unsigned char *output ) 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( input != NULL );
switch( ctx->padding ) switch( ctx->padding )
{ {
#if defined(MBEDTLS_PKCS1_V15) #if defined(MBEDTLS_PKCS1_V15)
...@@ -1248,6 +1329,14 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, ...@@ -1248,6 +1329,14 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx; 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 * Parameters sanity checks
*/ */
...@@ -1356,8 +1445,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, ...@@ -1356,8 +1445,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
ret = 0; ret = 0;
cleanup: cleanup:
mbedtls_zeroize( buf, sizeof( buf ) ); mbedtls_platform_zeroize( buf, sizeof( buf ) );
mbedtls_zeroize( lhash, sizeof( lhash ) ); mbedtls_platform_zeroize( lhash, sizeof( lhash ) );
return( ret ); return( ret );
} }
...@@ -1467,11 +1556,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, ...@@ -1467,11 +1556,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
size_t output_max_len ) size_t output_max_len )
{ {
int ret; int ret;
size_t ilen = ctx->len; size_t ilen, i, plaintext_max_size;
size_t i;
size_t plaintext_max_size = ( output_max_len > ilen - 11 ?
ilen - 11 :
output_max_len );
unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
/* The following variables take sensitive values: their value must /* The following variables take sensitive values: their value must
* not leak into the observable behavior of the function other than * not leak into the observable behavior of the function other than
...@@ -1489,6 +1574,18 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, ...@@ -1489,6 +1574,18 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
size_t plaintext_size = 0; size_t plaintext_size = 0;
unsigned output_too_large; 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 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
...@@ -1607,7 +1704,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, ...@@ -1607,7 +1704,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
*olen = plaintext_size; *olen = plaintext_size;
cleanup: cleanup:
mbedtls_zeroize( buf, sizeof( buf ) ); mbedtls_platform_zeroize( buf, sizeof( buf ) );
return( ret ); return( ret );
} }
...@@ -1624,6 +1721,13 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, ...@@ -1624,6 +1721,13 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
unsigned char *output, unsigned char *output,
size_t output_max_len) 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 ) switch( ctx->padding )
{ {
#if defined(MBEDTLS_PKCS1_V15) #if defined(MBEDTLS_PKCS1_V15)
...@@ -1660,11 +1764,18 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, ...@@ -1660,11 +1764,18 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
size_t olen; size_t olen;
unsigned char *p = sig; unsigned char *p = sig;
unsigned char salt[MBEDTLS_MD_MAX_SIZE]; unsigned char salt[MBEDTLS_MD_MAX_SIZE];
unsigned int slen, hlen, offset = 0; size_t slen, min_slen, hlen, offset = 0;
int ret; int ret;
size_t msb; size_t msb;
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx; 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 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
...@@ -1689,10 +1800,20 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, ...@@ -1689,10 +1800,20 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
hlen = mbedtls_md_get_size( md_info ); hlen = mbedtls_md_get_size( md_info );
slen = hlen;
if( olen < hlen + slen + 2 ) /* Calculate the largest possible salt length. Normally this is the hash
* length, which is the maximum length the salt can have. If there is not
* enough room, use the maximum salt length that fits. The constraint is
* that the hash length plus the salt length plus 2 bytes must be at most
* the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
* (PKCS#1 v2.2) §9.1.1 step 3. */
min_slen = hlen - 2;
if( olen < hlen + min_slen + 2 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
else if( olen >= hlen + hlen + 2 )
slen = hlen;
else
slen = olen - hlen - 2;
memset( sig, 0, olen ); memset( sig, 0, olen );
...@@ -1702,7 +1823,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, ...@@ -1702,7 +1823,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
/* Note: EMSA-PSS encoding is over the length of N - 1 bits */ /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
p += olen - hlen * 2 - 2; p += olen - hlen - slen - 2;
*p++ = 0x01; *p++ = 0x01;
memcpy( p, salt, slen ); memcpy( p, salt, slen );
p += slen; p += slen;
...@@ -1738,7 +1859,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, ...@@ -1738,7 +1859,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
p += hlen; p += hlen;
*p++ = 0xBC; *p++ = 0xBC;
mbedtls_zeroize( salt, sizeof( salt ) ); mbedtls_platform_zeroize( salt, sizeof( salt ) );
exit: exit:
mbedtls_md_free( &md_ctx ); mbedtls_md_free( &md_ctx );
...@@ -1880,7 +2001,7 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, ...@@ -1880,7 +2001,7 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
* after the initial bounds check. */ * after the initial bounds check. */
if( p != dst + dst_len ) if( p != dst + dst_len )
{ {
mbedtls_zeroize( dst, dst_len ); mbedtls_platform_zeroize( dst, dst_len );
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
} }
...@@ -1902,6 +2023,14 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, ...@@ -1902,6 +2023,14 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
int ret; int ret;
unsigned char *sig_try = NULL, *verif = NULL; 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 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
...@@ -1971,6 +2100,14 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, ...@@ -1971,6 +2100,14 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
const unsigned char *hash, const unsigned char *hash,
unsigned char *sig ) 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 ) switch( ctx->padding )
{ {
#if defined(MBEDTLS_PKCS1_V15) #if defined(MBEDTLS_PKCS1_V15)
...@@ -2017,6 +2154,14 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, ...@@ -2017,6 +2154,14 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
mbedtls_md_context_t md_ctx; mbedtls_md_context_t md_ctx;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; 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 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
...@@ -2145,7 +2290,16 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, ...@@ -2145,7 +2290,16 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
const unsigned char *hash, const unsigned char *hash,
const unsigned char *sig ) 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 ? (mbedtls_md_type_t) ctx->hash_id
: md_alg; : md_alg;
...@@ -2171,9 +2325,19 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, ...@@ -2171,9 +2325,19 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
const unsigned char *sig ) const unsigned char *sig )
{ {
int ret = 0; int ret = 0;
const size_t sig_len = ctx->len; size_t sig_len;
unsigned char *encoded = NULL, *encoded_expected = NULL; 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 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
...@@ -2217,13 +2381,13 @@ cleanup: ...@@ -2217,13 +2381,13 @@ cleanup:
if( encoded != NULL ) if( encoded != NULL )
{ {
mbedtls_zeroize( encoded, sig_len ); mbedtls_platform_zeroize( encoded, sig_len );
mbedtls_free( encoded ); mbedtls_free( encoded );
} }
if( encoded_expected != NULL ) if( encoded_expected != NULL )
{ {
mbedtls_zeroize( encoded_expected, sig_len ); mbedtls_platform_zeroize( encoded_expected, sig_len );
mbedtls_free( encoded_expected ); mbedtls_free( encoded_expected );
} }
...@@ -2243,6 +2407,14 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, ...@@ -2243,6 +2407,14 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
const unsigned char *hash, const unsigned char *hash,
const unsigned char *sig ) 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 ) switch( ctx->padding )
{ {
#if defined(MBEDTLS_PKCS1_V15) #if defined(MBEDTLS_PKCS1_V15)
...@@ -2268,6 +2440,8 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, ...@@ -2268,6 +2440,8 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
{ {
int ret; int ret;
RSA_VALIDATE_RET( dst != NULL );
RSA_VALIDATE_RET( src != NULL );
dst->ver = src->ver; dst->ver = src->ver;
dst->len = src->len; dst->len = src->len;
...@@ -2307,14 +2481,23 @@ cleanup: ...@@ -2307,14 +2481,23 @@ cleanup:
*/ */
void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
{ {
mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf ); if( ctx == NULL )
mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D ); return;
mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N ); 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) #if !defined(MBEDTLS_RSA_NO_CRT)
mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->RQ );
mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ ); mbedtls_mpi_free( &ctx->RP );
mbedtls_mpi_free( &ctx->QP );
mbedtls_mpi_free( &ctx->DQ );
mbedtls_mpi_free( &ctx->DP ); mbedtls_mpi_free( &ctx->DP );
#endif /* MBEDTLS_RSA_NO_CRT */ #endif /* MBEDTLS_RSA_NO_CRT */
......
...@@ -351,15 +351,20 @@ int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, ...@@ -351,15 +351,20 @@ int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P,
*/ */
#if defined(MBEDTLS_GENPRIME) #if defined(MBEDTLS_GENPRIME)
/*
* When generating keys, the strongest security we support aims for an error
* rate of at most 2^-100 and we are aiming for the same certainty here as
* well.
*/
if( f_rng != NULL && P != NULL && if( f_rng != NULL && P != NULL &&
( ret = mbedtls_mpi_is_prime( P, f_rng, p_rng ) ) != 0 ) ( ret = mbedtls_mpi_is_prime_ext( P, 50, f_rng, p_rng ) ) != 0 )
{ {
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup; goto cleanup;
} }
if( f_rng != NULL && Q != NULL && if( f_rng != NULL && Q != NULL &&
( ret = mbedtls_mpi_is_prime( Q, f_rng, p_rng ) ) != 0 ) ( ret = mbedtls_mpi_is_prime_ext( Q, 50, f_rng, p_rng ) ) != 0 )
{ {
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
goto cleanup; goto cleanup;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#if defined(MBEDTLS_SHA1_C) #if defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h" #include "mbedtls/sha1.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -45,12 +46,12 @@ ...@@ -45,12 +46,12 @@
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_SHA1_ALT) #define SHA1_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA )
/* Implementation that should never be optimized out by the compiler */ #define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; #if !defined(MBEDTLS_SHA1_ALT)
}
/* /*
* 32-bit integer manipulation macros (big endian) * 32-bit integer manipulation macros (big endian)
...@@ -77,6 +78,8 @@ static void mbedtls_zeroize( void *v, size_t n ) { ...@@ -77,6 +78,8 @@ static void mbedtls_zeroize( void *v, size_t n ) {
void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
{ {
SHA1_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
} }
...@@ -85,12 +88,15 @@ void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) ...@@ -85,12 +88,15 @@ void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
if( ctx == NULL ) if( ctx == NULL )
return; return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
} }
void mbedtls_sha1_clone( mbedtls_sha1_context *dst, void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src ) const mbedtls_sha1_context *src )
{ {
SHA1_VALIDATE( dst != NULL );
SHA1_VALIDATE( src != NULL );
*dst = *src; *dst = *src;
} }
...@@ -99,6 +105,8 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst, ...@@ -99,6 +105,8 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
*/ */
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
{ {
SHA1_VALIDATE_RET( ctx != NULL );
ctx->total[0] = 0; ctx->total[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
...@@ -124,6 +132,9 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, ...@@ -124,6 +132,9 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
{ {
uint32_t temp, W[16], A, B, C, D, E; 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[ 0], data, 0 );
GET_UINT32_BE( W[ 1], data, 4 ); GET_UINT32_BE( W[ 1], data, 4 );
GET_UINT32_BE( W[ 2], data, 8 ); GET_UINT32_BE( W[ 2], data, 8 );
...@@ -141,19 +152,21 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, ...@@ -141,19 +152,21 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
GET_UINT32_BE( W[14], data, 56 ); GET_UINT32_BE( W[14], data, 56 );
GET_UINT32_BE( W[15], data, 60 ); GET_UINT32_BE( W[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
#define R(t) \ #define R(t) \
( \ ( \
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ temp = W[( (t) - 3 ) & 0x0F] ^ W[( (t) - 8 ) & 0x0F] ^ \
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ W[( (t) - 14 ) & 0x0F] ^ W[ (t) & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \ ( W[(t) & 0x0F] = S(temp,1) ) \
) )
#define P(a,b,c,d,e,x) \ #define P(a,b,c,d,e,x) \
{ \ do \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ { \
} (e) += S((a),5) + F((b),(c),(d)) + K + (x); \
(b) = S((b),30); \
} while( 0 )
A = ctx->state[0]; A = ctx->state[0];
B = ctx->state[1]; B = ctx->state[1];
...@@ -161,7 +174,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, ...@@ -161,7 +174,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
D = ctx->state[3]; D = ctx->state[3];
E = ctx->state[4]; E = ctx->state[4];
#define F(x,y,z) (z ^ (x & (y ^ z))) #define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define K 0x5A827999 #define K 0x5A827999
P( A, B, C, D, E, W[0] ); P( A, B, C, D, E, W[0] );
...@@ -188,7 +201,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, ...@@ -188,7 +201,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
#undef K #undef K
#undef F #undef F
#define F(x,y,z) (x ^ y ^ z) #define F(x,y,z) ((x) ^ (y) ^ (z))
#define K 0x6ED9EBA1 #define K 0x6ED9EBA1
P( A, B, C, D, E, R(20) ); P( A, B, C, D, E, R(20) );
...@@ -215,7 +228,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, ...@@ -215,7 +228,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
#undef K #undef K
#undef F #undef F
#define F(x,y,z) ((x & y) | (z & (x | y))) #define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define K 0x8F1BBCDC #define K 0x8F1BBCDC
P( A, B, C, D, E, R(40) ); P( A, B, C, D, E, R(40) );
...@@ -242,7 +255,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, ...@@ -242,7 +255,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
#undef K #undef K
#undef F #undef F
#define F(x,y,z) (x ^ y ^ z) #define F(x,y,z) ((x) ^ (y) ^ (z))
#define K 0xCA62C1D6 #define K 0xCA62C1D6
P( A, B, C, D, E, R(60) ); P( A, B, C, D, E, R(60) );
...@@ -298,6 +311,9 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, ...@@ -298,6 +311,9 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
size_t fill; size_t fill;
uint32_t left; uint32_t left;
SHA1_VALIDATE_RET( ctx != NULL );
SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
if( ilen == 0 ) if( ilen == 0 )
return( 0 ); return( 0 );
...@@ -356,6 +372,9 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, ...@@ -356,6 +372,9 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
uint32_t used; uint32_t used;
uint32_t high, low; 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 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
*/ */
...@@ -424,6 +443,9 @@ int mbedtls_sha1_ret( const unsigned char *input, ...@@ -424,6 +443,9 @@ int mbedtls_sha1_ret( const unsigned char *input,
int ret; int ret;
mbedtls_sha1_context ctx; mbedtls_sha1_context ctx;
SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
mbedtls_sha1_init( &ctx ); mbedtls_sha1_init( &ctx );
if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#if defined(MBEDTLS_SHA256_C) #if defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.h" #include "mbedtls/sha256.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -48,12 +49,11 @@ ...@@ -48,12 +49,11 @@
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_SHA256_ALT) #define SHA256_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
/* Implementation that should never be optimized out by the compiler */ #if !defined(MBEDTLS_SHA256_ALT)
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/* /*
* 32-bit integer manipulation macros (big endian) * 32-bit integer manipulation macros (big endian)
...@@ -80,6 +80,8 @@ do { \ ...@@ -80,6 +80,8 @@ do { \
void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
{ {
SHA256_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
} }
...@@ -88,12 +90,15 @@ void mbedtls_sha256_free( mbedtls_sha256_context *ctx ) ...@@ -88,12 +90,15 @@ void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
if( ctx == NULL ) if( ctx == NULL )
return; return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
} }
void mbedtls_sha256_clone( mbedtls_sha256_context *dst, void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src ) const mbedtls_sha256_context *src )
{ {
SHA256_VALIDATE( dst != NULL );
SHA256_VALIDATE( src != NULL );
*dst = *src; *dst = *src;
} }
...@@ -102,6 +107,9 @@ void mbedtls_sha256_clone( mbedtls_sha256_context *dst, ...@@ -102,6 +107,9 @@ void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
*/ */
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ) 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[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
...@@ -164,8 +172,8 @@ static const uint32_t K[] = ...@@ -164,8 +172,8 @@ static const uint32_t K[] =
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
}; };
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) #define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) #define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
...@@ -173,21 +181,22 @@ static const uint32_t K[] = ...@@ -173,21 +181,22 @@ static const uint32_t K[] =
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
#define F0(x,y,z) ((x & y) | (z & (x | y))) #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define F1(x,y,z) (z ^ (x & (y ^ z))) #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define R(t) \ #define R(t) \
( \ ( \
W[t] = S1(W[t - 2]) + W[t - 7] + \ W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
S0(W[t - 15]) + W[t - 16] \ S0(W[(t) - 15]) + W[(t) - 16] \
) )
#define P(a,b,c,d,e,f,g,h,x,K) \ #define P(a,b,c,d,e,f,g,h,x,K) \
{ \ do \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \ { \
temp2 = S2(a) + F0(a,b,c); \ temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
d += temp1; h = temp1 + temp2; \ temp2 = S2(a) + F0((a),(b),(c)); \
} (d) += temp1; (h) = temp1 + temp2; \
} while( 0 )
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
const unsigned char data[64] ) const unsigned char data[64] )
...@@ -196,6 +205,9 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, ...@@ -196,6 +205,9 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
uint32_t A[8]; uint32_t A[8];
unsigned int i; unsigned int i;
SHA256_VALIDATE_RET( ctx != NULL );
SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
for( i = 0; i < 8; i++ ) for( i = 0; i < 8; i++ )
A[i] = ctx->state[i]; A[i] = ctx->state[i];
...@@ -267,6 +279,9 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, ...@@ -267,6 +279,9 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
size_t fill; size_t fill;
uint32_t left; uint32_t left;
SHA256_VALIDATE_RET( ctx != NULL );
SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
if( ilen == 0 ) if( ilen == 0 )
return( 0 ); return( 0 );
...@@ -325,6 +340,9 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, ...@@ -325,6 +340,9 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
uint32_t used; uint32_t used;
uint32_t high, low; 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 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
*/ */
...@@ -399,6 +417,10 @@ int mbedtls_sha256_ret( const unsigned char *input, ...@@ -399,6 +417,10 @@ int mbedtls_sha256_ret( const unsigned char *input,
int ret; int ret;
mbedtls_sha256_context ctx; 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 ); mbedtls_sha256_init( &ctx );
if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 ) if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#if defined(MBEDTLS_SHA512_C) #if defined(MBEDTLS_SHA512_C)
#include "mbedtls/sha512.h" #include "mbedtls/sha512.h"
#include "mbedtls/platform_util.h"
#if defined(_MSC_VER) || defined(__WATCOMC__) #if defined(_MSC_VER) || defined(__WATCOMC__)
#define UL64(x) x##ui64 #define UL64(x) x##ui64
...@@ -54,12 +55,11 @@ ...@@ -54,12 +55,11 @@
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_SHA512_ALT) #define SHA512_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
/* Implementation that should never be optimized out by the compiler */ #if !defined(MBEDTLS_SHA512_ALT)
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/* /*
* 64-bit integer manipulation macros (big endian) * 64-bit integer manipulation macros (big endian)
...@@ -94,6 +94,8 @@ static void mbedtls_zeroize( void *v, size_t n ) { ...@@ -94,6 +94,8 @@ static void mbedtls_zeroize( void *v, size_t n ) {
void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
{ {
SHA512_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
} }
...@@ -102,12 +104,15 @@ void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) ...@@ -102,12 +104,15 @@ void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
if( ctx == NULL ) if( ctx == NULL )
return; return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
} }
void mbedtls_sha512_clone( mbedtls_sha512_context *dst, void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
const mbedtls_sha512_context *src ) const mbedtls_sha512_context *src )
{ {
SHA512_VALIDATE( dst != NULL );
SHA512_VALIDATE( src != NULL );
*dst = *src; *dst = *src;
} }
...@@ -116,6 +121,9 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst, ...@@ -116,6 +121,9 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
*/ */
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ) 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[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
...@@ -213,8 +221,11 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, ...@@ -213,8 +221,11 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
uint64_t temp1, temp2, W[80]; uint64_t temp1, temp2, W[80];
uint64_t A, B, C, D, E, F, G, H; uint64_t A, B, C, D, E, F, G, H;
#define SHR(x,n) (x >> n) SHA512_VALIDATE_RET( ctx != NULL );
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
#define SHR(x,n) ((x) >> (n))
#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
...@@ -222,15 +233,16 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, ...@@ -222,15 +233,16 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
#define F0(x,y,z) ((x & y) | (z & (x | y))) #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define F1(x,y,z) (z ^ (x & (y ^ z))) #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define P(a,b,c,d,e,f,g,h,x,K) \ #define P(a,b,c,d,e,f,g,h,x,K) \
{ \ do \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \ { \
temp2 = S2(a) + F0(a,b,c); \ temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
d += temp1; h = temp1 + temp2; \ temp2 = S2(a) + F0((a),(b),(c)); \
} (d) += temp1; (h) = temp1 + temp2; \
} while( 0 )
for( i = 0; i < 16; i++ ) for( i = 0; i < 16; i++ )
{ {
...@@ -298,6 +310,9 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, ...@@ -298,6 +310,9 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
size_t fill; size_t fill;
unsigned int left; unsigned int left;
SHA512_VALIDATE_RET( ctx != NULL );
SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
if( ilen == 0 ) if( ilen == 0 )
return( 0 ); return( 0 );
...@@ -355,6 +370,9 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, ...@@ -355,6 +370,9 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
unsigned used; unsigned used;
uint64_t high, low; 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 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
*/ */
...@@ -431,6 +449,10 @@ int mbedtls_sha512_ret( const unsigned char *input, ...@@ -431,6 +449,10 @@ int mbedtls_sha512_ret( const unsigned char *input,
int ret; int ret;
mbedtls_sha512_context ctx; 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 ); mbedtls_sha512_init( &ctx );
if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 ) if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
......
...@@ -43,11 +43,11 @@ ...@@ -43,11 +43,11 @@
/* /*
* Ordered from most preferred to least preferred in terms of security. * Ordered from most preferred to least preferred in terms of security.
* *
* Current rule (except rc4, weak and null which come last): * Current rule (except RC4 and 3DES, weak and null which come last):
* 1. By key exchange: * 1. By key exchange:
* Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK
* 2. By key length and cipher: * 2. By key length and cipher:
* AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES * ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128
* 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8
* 4. By hash function used when relevant * 4. By hash function used when relevant
* 5. By key exchange/auth again: EC > non-EC * 5. By key exchange/auth again: EC > non-EC
...@@ -57,6 +57,11 @@ static const int ciphersuite_preference[] = ...@@ -57,6 +57,11 @@ static const int ciphersuite_preference[] =
#if defined(MBEDTLS_SSL_CIPHERSUITES) #if defined(MBEDTLS_SSL_CIPHERSUITES)
MBEDTLS_SSL_CIPHERSUITES, MBEDTLS_SSL_CIPHERSUITES,
#else #else
/* Chacha-Poly ephemeral suites */
MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
/* All AES-256 ephemeral suites */ /* All AES-256 ephemeral suites */
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
...@@ -81,6 +86,14 @@ static const int ciphersuite_preference[] = ...@@ -81,6 +86,14 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
/* All ARIA-256 ephemeral suites */
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
/* All AES-128 ephemeral suites */ /* All AES-128 ephemeral suites */
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
...@@ -105,12 +118,17 @@ static const int ciphersuite_preference[] = ...@@ -105,12 +118,17 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
/* All remaining >= 128-bit ephemeral suites */ /* All ARIA-128 ephemeral suites */
MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
/* The PSK ephemeral suites */ /* The PSK ephemeral suites */
MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
...@@ -121,6 +139,9 @@ static const int ciphersuite_preference[] = ...@@ -121,6 +139,9 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
...@@ -132,9 +153,9 @@ static const int ciphersuite_preference[] = ...@@ -132,9 +153,9 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
/* The ECJPAKE suite */ /* The ECJPAKE suite */
MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
...@@ -161,6 +182,14 @@ static const int ciphersuite_preference[] = ...@@ -161,6 +182,14 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
/* All ARIA-256 suites */
MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
/* All AES-128 suites */ /* All AES-128 suites */
MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_RSA_WITH_AES_128_CCM, MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
...@@ -183,27 +212,34 @@ static const int ciphersuite_preference[] = ...@@ -183,27 +212,34 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
/* All remaining >= 128-bit suites */ /* All ARIA-128 suites */
MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
/* The RSA PSK suites */ /* The RSA PSK suites */
MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
/* The PSK suites */ /* The PSK suites */
MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_PSK_WITH_AES_256_CCM, MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
...@@ -211,6 +247,8 @@ static const int ciphersuite_preference[] = ...@@ -211,6 +247,8 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_PSK_WITH_AES_128_CCM, MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
...@@ -219,7 +257,19 @@ static const int ciphersuite_preference[] = ...@@ -219,7 +257,19 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
/* 3DES suites */
MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
/* RC4 suites */ /* RC4 suites */
...@@ -266,6 +316,75 @@ static const int ciphersuite_preference[] = ...@@ -266,6 +316,75 @@ static const int ciphersuite_preference[] =
static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
{ {
#if defined(MBEDTLS_CHACHAPOLY_C) && \
defined(MBEDTLS_SHA256_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
"TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
"TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
{ MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
"TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
{ MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
"TLS-PSK-WITH-CHACHA20-POLY1305-SHA256",
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
"TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256",
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
{ MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
"TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256",
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
{ MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
"TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256",
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_CHACHAPOLY_C &&
MBEDTLS_SHA256_C &&
MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
#if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_SHA1_C) #if defined(MBEDTLS_SHA1_C)
...@@ -1688,6 +1807,365 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = ...@@ -1688,6 +1807,365 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#endif /* MBEDTLS_DES_C */ #endif /* MBEDTLS_DES_C */
#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ #endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */
#if defined(MBEDTLS_ARIA_C)
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
"TLS-RSA-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
"TLS-RSA-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
"TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
"TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384,MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
"TLS-PSK-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
"TLS-PSK-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
"TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
"TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
"TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
"TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
"TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
"TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
"TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
"TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
"TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
"TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
"TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
"TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256",
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
"TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256",
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
#endif /* MBEDTLS_ARIA_C */
{ 0, "", { 0, "",
MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE, MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE,
0, 0, 0, 0, 0 } 0, 0, 0, 0, 0 }
...@@ -1704,6 +2182,26 @@ const int *mbedtls_ssl_list_ciphersuites( void ) ...@@ -1704,6 +2182,26 @@ const int *mbedtls_ssl_list_ciphersuites( void )
static int supported_ciphersuites[MAX_CIPHERSUITES]; static int supported_ciphersuites[MAX_CIPHERSUITES];
static int supported_init = 0; static int supported_init = 0;
static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info )
{
(void)cs_info;
#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES)
if( cs_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
return( 1 );
#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */
#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES)
if( cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_ECB ||
cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_CBC )
{
return( 1 );
}
#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */
return( 0 );
}
const int *mbedtls_ssl_list_ciphersuites( void ) const int *mbedtls_ssl_list_ciphersuites( void )
{ {
/* /*
...@@ -1719,14 +2217,12 @@ const int *mbedtls_ssl_list_ciphersuites( void ) ...@@ -1719,14 +2217,12 @@ const int *mbedtls_ssl_list_ciphersuites( void )
*p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1;
p++ ) p++ )
{ {
#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES)
const mbedtls_ssl_ciphersuite_t *cs_info; const mbedtls_ssl_ciphersuite_t *cs_info;
if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL && if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL &&
cs_info->cipher != MBEDTLS_CIPHER_ARC4_128 ) !ciphersuite_is_removed( cs_info ) )
#else {
if( mbedtls_ssl_ciphersuite_from_id( *p ) != NULL )
#endif
*(q++) = *p; *(q++) = *p;
}
} }
*q = 0; *q = 0;
......
...@@ -48,10 +48,7 @@ ...@@ -48,10 +48,7 @@
#endif #endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
/* Implementation that should never be optimized out by the compiler */ #include "mbedtls/platform_util.h"
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#endif #endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
...@@ -60,7 +57,7 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, ...@@ -60,7 +57,7 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
size_t hostname_len; size_t hostname_len;
*olen = 0; *olen = 0;
...@@ -130,7 +127,7 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, ...@@ -130,7 +127,7 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
*olen = 0; *olen = 0;
...@@ -174,7 +171,7 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, ...@@ -174,7 +171,7 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
size_t sig_alg_len = 0; size_t sig_alg_len = 0;
const int *md; const int *md;
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
...@@ -259,7 +256,7 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, ...@@ -259,7 +256,7 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
unsigned char *elliptic_curve_list = p + 6; unsigned char *elliptic_curve_list = p + 6;
size_t elliptic_curve_len = 0; size_t elliptic_curve_len = 0;
const mbedtls_ecp_curve_info *info; const mbedtls_ecp_curve_info *info;
...@@ -332,7 +329,7 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, ...@@ -332,7 +329,7 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
*olen = 0; *olen = 0;
...@@ -365,7 +362,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, ...@@ -365,7 +362,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
{ {
int ret; int ret;
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
size_t kkpp_len; size_t kkpp_len;
*olen = 0; *olen = 0;
...@@ -442,7 +439,7 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, ...@@ -442,7 +439,7 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
*olen = 0; *olen = 0;
...@@ -475,7 +472,7 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, ...@@ -475,7 +472,7 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
*olen = 0; *olen = 0;
...@@ -507,7 +504,7 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, ...@@ -507,7 +504,7 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
*olen = 0; *olen = 0;
...@@ -541,7 +538,7 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, ...@@ -541,7 +538,7 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
*olen = 0; *olen = 0;
...@@ -575,7 +572,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, ...@@ -575,7 +572,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
size_t tlen = ssl->session_negotiate->ticket_len; size_t tlen = ssl->session_negotiate->ticket_len;
*olen = 0; *olen = 0;
...@@ -619,7 +616,7 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, ...@@ -619,7 +616,7 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
size_t alpnlen = 0; size_t alpnlen = 0;
const char **cur; const char **cur;
...@@ -1091,12 +1088,21 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ...@@ -1091,12 +1088,21 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
mbedtls_ssl_send_flight_completed( ssl ); mbedtls_ssl_send_flight_completed( ssl );
#endif #endif
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
return( ret ); return( ret );
} }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
return( ret );
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
return( 0 ); return( 0 );
...@@ -1494,7 +1500,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ...@@ -1494,7 +1500,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
buf = ssl->in_msg; buf = ssl->in_msg;
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{ {
/* No alert on a read error. */ /* No alert on a read error. */
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
...@@ -1757,6 +1763,14 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ...@@ -1757,6 +1763,14 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA &&
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
ssl->handshake->ecrs_enabled = 1;
}
#endif
if( comp != MBEDTLS_SSL_COMPRESS_NULL if( comp != MBEDTLS_SSL_COMPRESS_NULL
#if defined(MBEDTLS_ZLIB_SUPPORT) #if defined(MBEDTLS_ZLIB_SUPPORT)
&& comp != MBEDTLS_SSL_COMPRESS_DEFLATE && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
...@@ -2013,8 +2027,14 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char * ...@@ -2013,8 +2027,14 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char *
static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
{ {
const mbedtls_ecp_curve_info *curve_info; const mbedtls_ecp_curve_info *curve_info;
mbedtls_ecp_group_id grp_id;
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
grp_id = ssl->handshake->ecdh_ctx.grp.id;
#else
grp_id = ssl->handshake->ecdh_ctx.grp_id;
#endif
curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id ); curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id );
if( curve_info == NULL ) if( curve_info == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
...@@ -2024,14 +2044,15 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) ...@@ -2024,14 +2044,15 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 ) if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 )
#else #else
if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
ssl->handshake->ecdh_ctx.grp.nbits > 521 ) ssl->handshake->ecdh_ctx.grp.nbits > 521 )
#endif #endif
return( -1 ); return( -1 );
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp ); MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_QP );
return( 0 ); return( 0 );
} }
...@@ -2062,6 +2083,10 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl, ...@@ -2062,6 +2083,10 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
(const unsigned char **) p, end ) ) != 0 ) (const unsigned char **) p, end ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret ); MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret ); return( ret );
} }
...@@ -2132,7 +2157,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, ...@@ -2132,7 +2157,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
unsigned char *p = ssl->handshake->premaster + pms_offset; unsigned char *p = ssl->handshake->premaster + pms_offset;
if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN ) if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) );
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
...@@ -2175,7 +2200,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, ...@@ -2175,7 +2200,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk, if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
p, ssl->handshake->pmslen, p, ssl->handshake->pmslen,
ssl->out_msg + offset + len_bytes, olen, ssl->out_msg + offset + len_bytes, olen,
MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes, MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
...@@ -2343,7 +2368,15 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2343,7 +2368,15 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ssl->handshake->ecrs_enabled &&
ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing )
{
goto start_processing;
}
#endif
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
return( ret ); return( ret );
...@@ -2380,6 +2413,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2380,6 +2413,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ssl->handshake->ecrs_enabled )
ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing;
start_processing:
#endif
p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
end = ssl->in_msg + ssl->in_hslen; end = ssl->in_msg + ssl->in_hslen;
MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p ); MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
...@@ -2472,6 +2511,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2472,6 +2511,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
size_t params_len = p - params; size_t params_len = p - params;
void *rs_ctx = NULL;
/* /*
* Handle the digitally-signed structure * Handle the digitally-signed structure
...@@ -2518,6 +2558,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2518,6 +2558,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
/* /*
* Read signature * Read signature
*/ */
if( p > end - 2 ) if( p > end - 2 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
...@@ -2558,10 +2599,9 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2558,10 +2599,9 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
defined(MBEDTLS_SSL_PROTO_TLS1_2) defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( md_alg != MBEDTLS_MD_NONE ) if( md_alg != MBEDTLS_MD_NONE )
{ {
/* Info from md_alg will be used instead */ ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
hashlen = 0; params, params_len,
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, params, md_alg );
params_len, md_alg );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
} }
...@@ -2573,8 +2613,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2573,8 +2613,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
(unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
if( ssl->session_negotiate->peer_cert == NULL ) if( ssl->session_negotiate->peer_cert == NULL )
{ {
...@@ -2595,12 +2634,25 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2595,12 +2634,25 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
} }
if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
md_alg, hash, hashlen, p, sig_len ) ) != 0 ) if( ssl->handshake->ecrs_enabled )
rs_ctx = &ssl->handshake->ecrs_ctx.pk;
#endif
if( ( ret = mbedtls_pk_verify_restartable(
&ssl->session_negotiate->peer_cert->pk,
md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 )
{ {
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
#endif
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret ); return( ret );
} }
} }
...@@ -2651,7 +2703,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) ...@@ -2651,7 +2703,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
return( 0 ); return( 0 );
} }
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
return( ret ); return( ret );
...@@ -2803,7 +2855,7 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) ...@@ -2803,7 +2855,7 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
return( ret ); return( ret );
...@@ -2898,6 +2950,16 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2898,6 +2950,16 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
*/ */
i = 4; i = 4;
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ssl->handshake->ecrs_enabled )
{
if( ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret )
goto ecdh_calc_secret;
mbedtls_ecdh_enable_restart( &ssl->handshake->ecdh_ctx );
}
#endif
ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
&n, &n,
&ssl->out_msg[i], 1000, &ssl->out_msg[i], 1000,
...@@ -2905,11 +2967,27 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2905,11 +2967,27 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
if( ret != 0 ) if( ret != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret ); return( ret );
} }
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Q );
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ssl->handshake->ecrs_enabled )
{
ssl->handshake->ecrs_n = n;
ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret;
}
ecdh_calc_secret:
if( ssl->handshake->ecrs_enabled )
n = ssl->handshake->ecrs_n;
#endif
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
&ssl->handshake->pmslen, &ssl->handshake->pmslen,
ssl->handshake->premaster, ssl->handshake->premaster,
...@@ -2917,10 +2995,15 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2917,10 +2995,15 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret ); return( ret );
} }
MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Z );
} }
else else
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
...@@ -2942,7 +3025,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2942,7 +3025,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
i = 4; i = 4;
n = ssl->conf->psk_identity_len; n = ssl->conf->psk_identity_len;
if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN ) if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or " MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or "
"SSL buffer too short" ) ); "SSL buffer too short" ) );
...@@ -2978,7 +3061,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2978,7 +3061,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
*/ */
n = ssl->handshake->dhm_ctx.len; n = ssl->handshake->dhm_ctx.len;
if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN ) if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long" MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long"
" or SSL buffer too short" ) ); " or SSL buffer too short" ) );
...@@ -3007,7 +3090,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3007,7 +3090,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
* ClientECDiffieHellmanPublic public; * ClientECDiffieHellmanPublic public;
*/ */
ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
&ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i, &ssl->out_msg[i], MBEDTLS_SSL_OUT_CONTENT_LEN - i,
ssl->conf->f_rng, ssl->conf->p_rng ); ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 ) if( ret != 0 )
{ {
...@@ -3015,7 +3098,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3015,7 +3098,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Q );
} }
else else
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
...@@ -3048,7 +3132,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3048,7 +3132,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
i = 4; i = 4;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n, ssl->out_msg + i, MBEDTLS_SSL_OUT_CONTENT_LEN - i, &n,
ssl->conf->f_rng, ssl->conf->p_rng ); ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 ) if( ret != 0 )
{ {
...@@ -3079,9 +3163,9 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3079,9 +3163,9 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
ssl->state++; ssl->state++;
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
return( ret ); return( ret );
} }
...@@ -3135,9 +3219,18 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) ...@@ -3135,9 +3219,18 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
unsigned char *hash_start = hash; unsigned char *hash_start = hash;
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
unsigned int hashlen; unsigned int hashlen;
void *rs_ctx = NULL;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ssl->handshake->ecrs_enabled &&
ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign )
{
goto sign;
}
#endif
if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
...@@ -3169,8 +3262,15 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) ...@@ -3169,8 +3262,15 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
} }
/* /*
* Make an RSA signature of the handshake digests * Make a signature of the handshake digests
*/ */
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ssl->handshake->ecrs_enabled )
ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign;
sign:
#endif
ssl->handshake->calc_verify( ssl, hash ); ssl->handshake->calc_verify( ssl, hash );
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
...@@ -3247,11 +3347,21 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) ...@@ -3247,11 +3347,21 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen, #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ssl->handshake->ecrs_enabled )
rs_ctx = &ssl->handshake->ecrs_ctx.pk;
#endif
if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ),
md_alg, hash_start, hashlen,
ssl->out_msg + 6 + offset, &n, ssl->out_msg + 6 + offset, &n,
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret ); return( ret );
} }
...@@ -3264,9 +3374,9 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) ...@@ -3264,9 +3374,9 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
ssl->state++; ssl->state++;
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
return( ret ); return( ret );
} }
...@@ -3292,7 +3402,7 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) ...@@ -3292,7 +3402,7 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
return( ret ); return( ret );
...@@ -3353,8 +3463,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) ...@@ -3353,8 +3463,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
if( ticket_len == 0 ) if( ticket_len == 0 )
return( 0 ); return( 0 );
mbedtls_zeroize( ssl->session_negotiate->ticket, mbedtls_platform_zeroize( ssl->session_negotiate->ticket,
ssl->session_negotiate->ticket_len ); ssl->session_negotiate->ticket_len );
mbedtls_free( ssl->session_negotiate->ticket ); mbedtls_free( ssl->session_negotiate->ticket );
ssl->session_negotiate->ticket = NULL; ssl->session_negotiate->ticket = NULL;
ssl->session_negotiate->ticket_len = 0; ssl->session_negotiate->ticket_len = 0;
...@@ -3406,10 +3516,10 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) ...@@ -3406,10 +3516,10 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
{ {
if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
return( ret ); return( ret );
} }
#endif #endif /* MBEDTLS_SSL_PROTO_DTLS */
/* Change state now, so that it is right in mbedtls_ssl_read_record(), used /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
* by DTLS for dropping out-of-sequence ChangeCipherSpec records */ * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
......
...@@ -40,14 +40,10 @@ ...@@ -40,14 +40,10 @@
#include "mbedtls/ssl_cookie.h" #include "mbedtls/ssl_cookie.h"
#include "mbedtls/ssl_internal.h" #include "mbedtls/ssl_internal.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/* /*
* If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is
* available. Try SHA-256 first, 512 wastes resources since we need to stay * available. Try SHA-256 first, 512 wastes resources since we need to stay
...@@ -101,7 +97,7 @@ void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ) ...@@ -101,7 +97,7 @@ void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx )
mbedtls_mutex_free( &ctx->mutex ); mbedtls_mutex_free( &ctx->mutex );
#endif #endif
mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) );
} }
int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
...@@ -122,7 +118,7 @@ int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, ...@@ -122,7 +118,7 @@ int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
mbedtls_zeroize( key, sizeof( key ) ); mbedtls_platform_zeroize( key, sizeof( key ) );
return( 0 ); return( 0 );
} }
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "mbedtls/debug.h" #include "mbedtls/debug.h"
#include "mbedtls/ssl.h" #include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h" #include "mbedtls/ssl_internal.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
...@@ -49,13 +50,6 @@ ...@@ -49,13 +50,6 @@
#include "mbedtls/platform_time.h" #include "mbedtls/platform_time.h"
#endif #endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
#endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl,
const unsigned char *info, const unsigned char *info,
...@@ -572,7 +566,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, ...@@ -572,7 +566,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) ); memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) );
/* Zeroize instead of free as we copied the content */ /* Zeroize instead of free as we copied the content */
mbedtls_zeroize( &session, sizeof( mbedtls_ssl_session ) ); mbedtls_platform_zeroize( &session, sizeof( mbedtls_ssl_session ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) );
...@@ -734,7 +728,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, ...@@ -734,7 +728,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
cur->cert ); cur->cert );
if( ! mbedtls_pk_can_do( cur->key, pk_alg ) ) if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
continue; continue;
...@@ -758,7 +752,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, ...@@ -758,7 +752,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDSA_C)
if( pk_alg == MBEDTLS_PK_ECDSA && if( pk_alg == MBEDTLS_PK_ECDSA &&
ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 ) ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
continue; continue;
...@@ -1300,7 +1294,7 @@ read_record_header: ...@@ -1300,7 +1294,7 @@ read_record_header:
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
memcpy( ssl->out_ctr + 2, ssl->in_ctr + 2, 6 ); memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
...@@ -1328,7 +1322,7 @@ read_record_header: ...@@ -1328,7 +1322,7 @@ read_record_header:
else else
#endif #endif
{ {
if( msg_len > MBEDTLS_SSL_MAX_CONTENT_LEN ) if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
...@@ -1455,7 +1449,7 @@ read_record_header: ...@@ -1455,7 +1449,7 @@ read_record_header:
*/ */
/* /*
* 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 * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
* read at least up to session id length without worrying. * read at least up to session id length without worrying.
*/ */
...@@ -2266,7 +2260,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, ...@@ -2266,7 +2260,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
{ {
int ret; int ret;
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
size_t kkpp_len; size_t kkpp_len;
*olen = 0; *olen = 0;
...@@ -2373,7 +2367,7 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) ...@@ -2373,7 +2367,7 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
cookie_len_byte = p++; cookie_len_byte = p++;
if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie, if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie,
&p, ssl->out_buf + MBEDTLS_SSL_BUFFER_LEN, &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN,
ssl->cli_id, ssl->cli_id_len ) ) != 0 ) ssl->cli_id, ssl->cli_id_len ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret );
...@@ -2390,11 +2384,20 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) ...@@ -2390,11 +2384,20 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT; ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT;
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
return( ret );
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
return( ret ); return( ret );
} }
#endif /* MBEDTLS_SSL_PROTO_DTLS */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) );
...@@ -2630,7 +2633,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ...@@ -2630,7 +2633,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO;
ret = mbedtls_ssl_write_record( ssl ); ret = mbedtls_ssl_write_handshake_msg( ssl );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
...@@ -2673,7 +2676,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) ...@@ -2673,7 +2676,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
size_t dn_size, total_dn_size; /* excluding length bytes */ size_t dn_size, total_dn_size; /* excluding length bytes */
size_t ct_len, sa_len; /* including length bytes */ size_t ct_len, sa_len; /* including length bytes */
unsigned char *buf, *p; unsigned char *buf, *p;
const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
const mbedtls_x509_crt *crt; const mbedtls_x509_crt *crt;
int authmode; int authmode;
...@@ -2825,7 +2828,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) ...@@ -2825,7 +2828,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 ); ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 );
ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size ); ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size );
ret = mbedtls_ssl_write_record( ssl ); ret = mbedtls_ssl_write_handshake_msg( ssl );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) );
...@@ -2863,54 +2866,56 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) ...@@ -2863,54 +2866,56 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
{
/* Append the signature to ssl->out_msg, leaving 2 bytes for the
* signature length which will be added in ssl_write_server_key_exchange
* after the call to ssl_prepare_server_key_exchange.
* ssl_write_server_key_exchange also takes care of incrementing
* ssl->out_msglen. */
unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2;
size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN
- sig_start );
int ret = ssl->conf->f_async_resume( ssl,
sig_start, signature_len, sig_max_len );
if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
{
ssl->handshake->async_in_progress = 0;
mbedtls_ssl_set_async_operation_data( ssl, NULL );
}
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret );
return( ret );
}
#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
/* Prepare the ServerKeyExchange message, up to and including
* calculating the signature if any, but excluding formatting the
* signature and sending the message. */
static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
{ {
int ret;
size_t n = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info; ssl->transform_negotiate->ciphersuite_info;
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
unsigned char *p = ssl->out_msg + 4;
size_t len = 0;
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
unsigned char *dig_signed = p; unsigned char *dig_signed = NULL;
size_t dig_signed_len = 0;
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); (void) ciphersuite_info; /* unused in some configurations */
#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
/* (void) signature_len;
* #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
* Part 1: Extract static ECDH parameters and abort
* if ServerKeyExchange not needed.
*
*/
/* For suites involving ECDH, extract DH parameters
* from certificate at this point. */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
{
ssl_get_ecdh_params_from_cert( ssl );
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
/* Key exchanges not involving ephemeral keys don't use ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
* ServerKeyExchange, so end here. */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++;
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */
/* /*
* *
* Part 2: Provide key exchange parameters for chosen ciphersuite. * Part 1: Provide key exchange parameters for chosen ciphersuite.
* *
*/ */
...@@ -2920,18 +2925,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2920,18 +2925,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; int ret;
size_t len = 0;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, ret = mbedtls_ecjpake_write_round_two(
p, end - p, &len, ssl->conf->f_rng, ssl->conf->p_rng ); &ssl->handshake->ecjpake_ctx,
ssl->out_msg + ssl->out_msglen,
MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 ) if( ret != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret ); return( ret );
} }
p += len; ssl->out_msglen += len;
n += len;
} }
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
...@@ -2945,10 +2953,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2945,10 +2953,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{ {
*(p++) = 0x00; ssl->out_msg[ssl->out_msglen++] = 0x00;
*(p++) = 0x00; ssl->out_msg[ssl->out_msglen++] = 0x00;
n += 2;
} }
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
...@@ -2959,6 +2965,9 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2959,6 +2965,9 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) ) if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) )
{ {
int ret;
size_t len = 0;
if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) );
...@@ -2982,21 +2991,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -2982,21 +2991,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx, if( ( ret = mbedtls_dhm_make_params(
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), &ssl->handshake->dhm_ctx,
p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
ssl->out_msg + ssl->out_msglen, &len,
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret );
return( ret ); return( ret );
} }
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
dig_signed = p; dig_signed = ssl->out_msg + ssl->out_msglen;
dig_signed_len = len;
#endif #endif
p += len; ssl->out_msglen += len;
n += len;
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
...@@ -3021,6 +3030,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3021,6 +3030,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
*/ */
const mbedtls_ecp_curve_info **curve = NULL; const mbedtls_ecp_curve_info **curve = NULL;
const mbedtls_ecp_group_id *gid; const mbedtls_ecp_group_id *gid;
int ret;
size_t len = 0;
/* Match our preference list against the offered curves */ /* Match our preference list against the offered curves */
for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
...@@ -3037,48 +3048,50 @@ curve_matching_done: ...@@ -3037,48 +3048,50 @@ curve_matching_done:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
if( ( ret = mbedtls_ecp_group_load( &ssl->handshake->ecdh_ctx.grp, if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx,
(*curve)->grp_id ) ) != 0 ) (*curve)->grp_id ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret );
return( ret ); return( ret );
} }
if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len, if( ( ret = mbedtls_ecdh_make_params(
p, MBEDTLS_SSL_MAX_CONTENT_LEN - n, &ssl->handshake->ecdh_ctx, &len,
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) ssl->out_msg + ssl->out_msglen,
MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
return( ret ); return( ret );
} }
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
dig_signed = p; dig_signed = ssl->out_msg + ssl->out_msglen;
dig_signed_len = len;
#endif #endif
p += len; ssl->out_msglen += len;
n += len;
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q ); MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Q );
} }
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
/* /*
* *
* Part 3: For key exchanges involving the server signing the * Part 2: For key exchanges involving the server signing the
* exchange parameters, compute and add the signature here. * exchange parameters, compute and add the signature here.
* *
*/ */
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
{ {
size_t signature_len = 0; size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
unsigned int hashlen = 0; size_t hashlen = 0;
unsigned char hash[64]; unsigned char hash[MBEDTLS_MD_MAX_SIZE];
int ret;
/* /*
* 3.1: Choose hash algorithm: * 2.1: Choose hash algorithm:
* A: For TLS 1.2, obey signature-hash-algorithm extension * A: For TLS 1.2, obey signature-hash-algorithm extension
* to choose appropriate hash. * to choose appropriate hash.
* B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1 * B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1
...@@ -3125,7 +3138,7 @@ curve_matching_done: ...@@ -3125,7 +3138,7 @@ curve_matching_done:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) );
/* /*
* 3.2: Compute the hash to be signed * 2.2: Compute the hash to be signed
*/ */
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) defined(MBEDTLS_SSL_PROTO_TLS1_1)
...@@ -3145,9 +3158,7 @@ curve_matching_done: ...@@ -3145,9 +3158,7 @@ curve_matching_done:
defined(MBEDTLS_SSL_PROTO_TLS1_2) defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( md_alg != MBEDTLS_MD_NONE ) if( md_alg != MBEDTLS_MD_NONE )
{ {
/* Info from md_alg will be used instead */ ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
hashlen = 0;
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash,
dig_signed, dig_signed,
dig_signed_len, dig_signed_len,
md_alg ); md_alg );
...@@ -3162,18 +3173,11 @@ curve_matching_done: ...@@ -3162,18 +3173,11 @@ curve_matching_done:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
(unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
/* /*
* 3.3: Compute and add the signature * 2.3: Compute and add the signature
*/ */
if( mbedtls_ssl_own_key( ssl ) == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{ {
...@@ -3193,46 +3197,162 @@ curve_matching_done: ...@@ -3193,46 +3197,162 @@ curve_matching_done:
* *
*/ */
*(p++) = mbedtls_ssl_hash_from_md_alg( md_alg ); ssl->out_msg[ssl->out_msglen++] =
*(p++) = mbedtls_ssl_sig_from_pk_alg( sig_alg ); mbedtls_ssl_hash_from_md_alg( md_alg );
ssl->out_msg[ssl->out_msglen++] =
n += 2; mbedtls_ssl_sig_from_pk_alg( sig_alg );
} }
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen, #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
p + 2 , &signature_len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) if( ssl->conf->f_async_sign_start != NULL )
{
ret = ssl->conf->f_async_sign_start( ssl,
mbedtls_ssl_own_cert( ssl ),
md_alg, hash, hashlen );
switch( ret )
{
case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
/* act as if f_async_sign was null */
break;
case 0:
ssl->handshake->async_in_progress = 1;
return( ssl_resume_server_key_exchange( ssl, signature_len ) );
case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
ssl->handshake->async_in_progress = 1;
return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
default:
MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret );
return( ret );
}
}
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
if( mbedtls_ssl_own_key( ssl ) == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
}
/* Append the signature to ssl->out_msg, leaving 2 bytes for the
* signature length which will be added in ssl_write_server_key_exchange
* after the call to ssl_prepare_server_key_exchange.
* ssl_write_server_key_exchange also takes care of incrementing
* ssl->out_msglen. */
if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ),
md_alg, hash, hashlen,
ssl->out_msg + ssl->out_msglen + 2,
signature_len,
ssl->conf->f_rng,
ssl->conf->p_rng ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
return( ret ); return( ret );
} }
}
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
return( 0 );
}
/* Prepare the ServerKeyExchange message and send it. For ciphersuites
* that do not include a ServerKeyExchange message, do nothing. Either
* way, if successful, move on to the next step in the SSL state
* machine. */
static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
{
int ret;
size_t signature_len = 0;
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
/* Extract static ECDH parameters and abort if ServerKeyExchange
* is not needed. */
if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
{
/* For suites involving ECDH, extract DH parameters
* from certificate at this point. */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
{
ssl_get_ecdh_params_from_cert( ssl );
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
*(p++) = (unsigned char)( signature_len >> 8 ); /* Key exchanges not involving ephemeral keys don't use
*(p++) = (unsigned char)( signature_len ); * ServerKeyExchange, so end here. */
n += 2; MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++;
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", p, signature_len ); #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
/* If we have already prepared the message and there is an ongoing
* signature operation, resume signing. */
if( ssl->handshake->async_in_progress != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) );
ret = ssl_resume_server_key_exchange( ssl, &signature_len );
}
else
#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
{
/* ServerKeyExchange is needed. Prepare the message. */
ret = ssl_prepare_server_key_exchange( ssl, &signature_len );
}
n += signature_len; if( ret != 0 )
{
/* If we're starting to write a new message, set ssl->out_msglen
* to 0. But if we're resuming after an asynchronous message,
* out_msglen is the amount of data written so far and mst be
* preserved. */
if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) );
else
ssl->out_msglen = 0;
return( ret );
} }
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
/* Done with actual work; add header and send. */ /* If there is a signature, write its length.
* ssl_prepare_server_key_exchange already wrote the signature
* itself at its proper place in the output buffer. */
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
if( signature_len != 0 )
{
ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len );
ssl->out_msglen = 4 + n; MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
ssl->out_msg + ssl->out_msglen,
signature_len );
/* Skip over the already-written signature */
ssl->out_msglen += signature_len;
}
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
/* Add header and send. */
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
ssl->state++; ssl->state++;
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
return( ret ); return( ret );
} }
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
return( 0 ); return( 0 );
} }
...@@ -3253,12 +3373,21 @@ static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl ) ...@@ -3253,12 +3373,21 @@ static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
mbedtls_ssl_send_flight_completed( ssl ); mbedtls_ssl_send_flight_completed( ssl );
#endif #endif
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
return( ret ); return( ret );
} }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
return( ret );
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) );
return( 0 ); return( 0 );
...@@ -3307,28 +3436,50 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char * ...@@ -3307,28 +3436,50 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char *
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
const unsigned char *p, #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
const unsigned char *end, static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl,
size_t pms_offset ) unsigned char *peer_pms,
size_t *peer_pmslen,
size_t peer_pmssize )
{
int ret = ssl->conf->f_async_resume( ssl,
peer_pms, peer_pmslen, peer_pmssize );
if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
{
ssl->handshake->async_in_progress = 0;
mbedtls_ssl_set_async_operation_data( ssl, NULL );
}
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret );
return( ret );
}
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
const unsigned char *p,
const unsigned char *end,
unsigned char *peer_pms,
size_t *peer_pmslen,
size_t peer_pmssize )
{ {
int ret; int ret;
size_t len = mbedtls_pk_get_len( mbedtls_ssl_own_key( ssl ) ); mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
unsigned char *pms = ssl->handshake->premaster + pms_offset; mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk;
unsigned char ver[2]; size_t len = mbedtls_pk_get_len( public_key );
unsigned char fake_pms[48], peer_pms[48];
unsigned char mask;
size_t i, peer_pmslen;
unsigned int diff;
if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) ) #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
/* If we have already started decoding the message and there is an ongoing
* decryption operation, resume signing. */
if( ssl->handshake->async_in_progress != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) );
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); return( ssl_resume_decrypt_pms( ssl,
peer_pms, peer_pmslen, peer_pmssize ) );
} }
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
/* /*
* Decrypt the premaster using own private RSA key * Prepare to decrypt the premaster using own private RSA key
*/ */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2) defined(MBEDTLS_SSL_PROTO_TLS1_2)
...@@ -3353,30 +3504,120 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, ...@@ -3353,30 +3504,120 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
} }
/*
* Decrypt the premaster secret
*/
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
if( ssl->conf->f_async_decrypt_start != NULL )
{
ret = ssl->conf->f_async_decrypt_start( ssl,
mbedtls_ssl_own_cert( ssl ),
p, len );
switch( ret )
{
case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
/* act as if f_async_decrypt_start was null */
break;
case 0:
ssl->handshake->async_in_progress = 1;
return( ssl_resume_decrypt_pms( ssl,
peer_pms,
peer_pmslen,
peer_pmssize ) );
case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
ssl->handshake->async_in_progress = 1;
return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
default:
MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret );
return( ret );
}
}
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) );
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
}
ret = mbedtls_pk_decrypt( private_key, p, len,
peer_pms, peer_pmslen, peer_pmssize,
ssl->conf->f_rng, ssl->conf->p_rng );
return( ret );
}
static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
const unsigned char *p,
const unsigned char *end,
size_t pms_offset )
{
int ret;
unsigned char *pms = ssl->handshake->premaster + pms_offset;
unsigned char ver[2];
unsigned char fake_pms[48], peer_pms[48];
unsigned char mask;
size_t i, peer_pmslen;
unsigned int diff;
/* In case of a failure in decryption, the decryption may write less than
* 2 bytes of output, but we always read the first two bytes. It doesn't
* matter in the end because diff will be nonzero in that case due to
* peer_pmslen being less than 48, and we only care whether diff is 0.
* But do initialize peer_pms for robustness anyway. This also makes
* memory analyzers happy (don't access uninitialized memory, even
* if it's an unsigned char). */
peer_pms[0] = peer_pms[1] = ~0;
ret = ssl_decrypt_encrypted_pms( ssl, p, end,
peer_pms,
&peer_pmslen,
sizeof( peer_pms ) );
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
return( ret );
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
mbedtls_ssl_write_version( ssl->handshake->max_major_ver, mbedtls_ssl_write_version( ssl->handshake->max_major_ver,
ssl->handshake->max_minor_ver, ssl->handshake->max_minor_ver,
ssl->conf->transport, ver ); ssl->conf->transport, ver );
/* Avoid data-dependent branches while checking for invalid
* padding, to protect against timing-based Bleichenbacher-type
* attacks. */
diff = (unsigned int) ret;
diff |= peer_pmslen ^ 48;
diff |= peer_pms[0] ^ ver[0];
diff |= peer_pms[1] ^ ver[1];
/* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
/* MSVC has a warning about unary minus on unsigned, but this is
* well-defined and precisely what we want to do here */
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 )
#endif
mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
/* /*
* Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
* must not cause the connection to end immediately; instead, send a * must not cause the connection to end immediately; instead, send a
* bad_record_mac later in the handshake. * bad_record_mac later in the handshake.
* Also, avoid data-dependant branches here to protect against * To protect against timing-based variants of the attack, we must
* timing-based variants. * not have any branch that depends on whether the decryption was
* successful. In particular, always generate the fake premaster secret,
* regardless of whether it will ultimately influence the output or not.
*/ */
ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) ); ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
if( ret != 0 ) if( ret != 0 )
{
/* It's ok to abort on an RNG failure, since this does not reveal
* anything about the RSA decryption. */
return( ret ); return( ret );
}
ret = mbedtls_pk_decrypt( mbedtls_ssl_own_key( ssl ), p, len,
peer_pms, &peer_pmslen,
sizeof( peer_pms ),
ssl->conf->f_rng, ssl->conf->p_rng );
diff = (unsigned int) ret;
diff |= peer_pmslen ^ 48;
diff |= peer_pms[0] ^ ver[0];
diff |= peer_pms[1] ^ ver[1];
#if defined(MBEDTLS_SSL_DEBUG_ALL) #if defined(MBEDTLS_SSL_DEBUG_ALL)
if( diff != 0 ) if( diff != 0 )
...@@ -3391,18 +3632,8 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, ...@@ -3391,18 +3632,8 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
} }
ssl->handshake->pmslen = 48; ssl->handshake->pmslen = 48;
/* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ /* Set pms to either the true or the fake PMS, without
/* MSVC has a warning about unary minus on unsigned, but this is * data-dependent branches. */
* well-defined and precisely what we want to do here */
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 )
#endif
mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
for( i = 0; i < ssl->handshake->pmslen; i++ ) for( i = 0; i < ssl->handshake->pmslen; i++ )
pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] );
...@@ -3484,7 +3715,21 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3484,7 +3715,21 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \
( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) )
if( ( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) &&
( ssl->handshake->async_in_progress != 0 ) )
{
/* We've already read a record and there is an asynchronous
* operation in progress to decrypt it. So skip reading the
* record. */
MBEDTLS_SSL_DEBUG_MSG( 3, ( "will resume decryption of previously-read record" ) );
}
else
#endif
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
return( ret ); return( ret );
...@@ -3550,7 +3795,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3550,7 +3795,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
} }
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_QP );
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
&ssl->handshake->pmslen, &ssl->handshake->pmslen,
...@@ -3562,7 +3808,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3562,7 +3808,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
} }
MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z ", &ssl->handshake->ecdh_ctx.z ); MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Z );
} }
else else
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
...@@ -3596,6 +3843,19 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3596,6 +3843,19 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
{ {
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
if ( ssl->handshake->async_in_progress != 0 )
{
/* There is an asynchronous operation in progress to
* decrypt the encrypted premaster secret, so skip
* directly to resuming this operation. */
MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) );
/* Update p to skip the PSK identity. ssl_parse_encrypted_pms
* won't actually use it, but maintain p anyway for robustness. */
p += ssl->conf->psk_identity_len + 2;
}
else
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
...@@ -3662,7 +3922,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) ...@@ -3662,7 +3922,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
} }
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_QP );
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
ciphersuite_info->key_exchange ) ) != 0 ) ciphersuite_info->key_exchange ) ) != 0 )
...@@ -3781,21 +4042,10 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) ...@@ -3781,21 +4042,10 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
} }
/* Read the message without adding it to the checksum */ /* Read the message without adding it to the checksum */
do { ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ );
if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret );
return( ret );
}
ret = mbedtls_ssl_handle_message_type( ssl );
} while( MBEDTLS_ERR_SSL_NON_FATAL == ret );
if( 0 != ret ) if( 0 != ret )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record" ), ret );
return( ret ); return( ret );
} }
...@@ -3961,7 +4211,7 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) ...@@ -3961,7 +4211,7 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket, if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket,
ssl->session_negotiate, ssl->session_negotiate,
ssl->out_msg + 10, ssl->out_msg + 10,
ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN, ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN,
&tlen, &lifetime ) ) != 0 ) &tlen, &lifetime ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret );
...@@ -3984,9 +4234,9 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) ...@@ -3984,9 +4234,9 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
*/ */
ssl->handshake->new_session_ticket = 0; ssl->handshake->new_session_ticket = 0;
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
return( ret ); return( ret );
} }
...@@ -4015,10 +4265,10 @@ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) ...@@ -4015,10 +4265,10 @@ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl )
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
{ {
if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
return( ret ); return( ret );
} }
#endif #endif /* MBEDTLS_SSL_PROTO_DTLS */
switch( ssl->state ) switch( ssl->state )
{ {
......
...@@ -36,14 +36,10 @@ ...@@ -36,14 +36,10 @@
#endif #endif
#include "mbedtls/ssl_ticket.h" #include "mbedtls/ssl_ticket.h"
#include "mbedtls/platform_util.h"
#include <string.h> #include <string.h>
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/* /*
* Initialze context * Initialze context
*/ */
...@@ -83,7 +79,7 @@ static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx, ...@@ -83,7 +79,7 @@ static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx,
mbedtls_cipher_get_key_bitlen( &key->ctx ), mbedtls_cipher_get_key_bitlen( &key->ctx ),
MBEDTLS_ENCRYPT ); MBEDTLS_ENCRYPT );
mbedtls_zeroize( buf, sizeof( buf ) ); mbedtls_platform_zeroize( buf, sizeof( buf ) );
return( ret ); return( ret );
} }
...@@ -483,7 +479,7 @@ void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx ) ...@@ -483,7 +479,7 @@ void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx )
mbedtls_mutex_free( &ctx->mutex ); mbedtls_mutex_free( &ctx->mutex );
#endif #endif
mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) );
} }
#endif /* MBEDTLS_SSL_TICKET_C */ #endif /* MBEDTLS_SSL_TICKET_C */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment