Merge changes for leaner memory footprint

This commit is contained in:
Paul Bakker 2014-07-04 15:02:19 +02:00
commit 8fb99abaac
11 changed files with 137 additions and 36 deletions

View File

@ -22,6 +22,8 @@ Features
from the default list (inactive by default). from the default list (inactive by default).
* Add server-side enforcement of sent renegotiation requests * Add server-side enforcement of sent renegotiation requests
(ssl_set_renegotiation_enforced()) (ssl_set_renegotiation_enforced())
* Add SSL_CIPHERSUITES config.h flag to allow specifying a list of
ciphersuites to use and save some memory if the list is small.
Changes Changes
* Add LINK_WITH_PTHREAD option in CMake for explicit linking that is * Add LINK_WITH_PTHREAD option in CMake for explicit linking that is

View File

@ -3,7 +3,7 @@
* Distinguishing features: * Distinguishing features:
* - no bignum, no PK, no X509 * - no bignum, no PK, no X509
* - fully modern and secure (provided the pre-shared keys have high entropy) * - fully modern and secure (provided the pre-shared keys have high entropy)
* - very low record overhead if using the CCM-8 suites * - very low record overhead with CCM-8
* - optimized for low RAM usage * - optimized for low RAM usage
* *
* See README.txt for usage instructions. * See README.txt for usage instructions.
@ -13,7 +13,7 @@
/* System support */ /* System support */
//#define POLARSSL_HAVE_IPV6 /* Optional */ //#define POLARSSL_HAVE_IPV6 /* Optional */
//#define POLARSSL_HAVE_TIME /* Optionnaly used in Hello messages */ //#define POLARSSL_HAVE_TIME /* Optionally used in Hello messages */
/* Other POLARSSL_HAVE_XXX flags irrelevant for this configuration */ /* Other POLARSSL_HAVE_XXX flags irrelevant for this configuration */
/* PolarSSL feature support */ /* PolarSSL feature support */
@ -36,6 +36,9 @@
/* Save RAM at the expense of ROM */ /* Save RAM at the expense of ROM */
#define POLARSSL_AES_ROM_TABLES #define POLARSSL_AES_ROM_TABLES
/* Save some RAM by adjusting to your exact needs */
#define POLARSSL_PSK_MAX_LEN 16 /* 128-bits keys are generally enough */
/* /*
* You should adjust this to the exact number of sources you're using: default * You should adjust this to the exact number of sources you're using: default
* is the "platform_entropy_poll" source, but you may want to add other ones * is the "platform_entropy_poll" source, but you may want to add other ones
@ -43,9 +46,17 @@
*/ */
#define ENTROPY_MAX_SOURCES 2 #define ENTROPY_MAX_SOURCES 2
/*
* Use only CCM_8 ciphersuites, and
* save ROM and a few bytes of RAM by specifying our own ciphersuite list
*/
#define SSL_CIPHERSUITES \
TLS_PSK_WITH_AES_256_CCM_8, \
TLS_PSK_WITH_AES_128_CCM_8
/* /*
* Save RAM at the expense of interoperability: do this only if you control * Save RAM at the expense of interoperability: do this only if you control
* both ends of the connection! (See coments in "polarssl/ssl.h".) * both ends of the connection! (See comments in "polarssl/ssl.h".)
* The optimal size here depends on the typical size of records. * The optimal size here depends on the typical size of records.
*/ */
#define SSL_MAX_CONTENT_LEN 512 #define SSL_MAX_CONTENT_LEN 512

View File

@ -77,6 +77,11 @@
*/ */
#define ENTROPY_MAX_SOURCES 2 #define ENTROPY_MAX_SOURCES 2
/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
#define SSL_CIPHERSUITES \
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, \
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
/* /*
* Save RAM at the expense of interoperability: do this only if you control * Save RAM at the expense of interoperability: do this only if you control
* both ends of the connection! (See coments in "polarssl/ssl.h".) * both ends of the connection! (See coments in "polarssl/ssl.h".)

View File

@ -2154,6 +2154,21 @@
/* SSL options */ /* SSL options */
//#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ //#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */
//#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ //#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
//#define POLARSSL_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
/**
* Complete list of ciphersuites to use, in order of preference.
*
* \warning No dependency checking is done on that field! This option can only
* be used to restrict the set of available ciphersuites. It is your
* responsibility to make sure the needed modules are active.
*
* Use this to save a few hundred bytes of ROM (default ordering of all
* available ciphersuites) and a few to a few hundred bytes of RAM.
*
* The value below is only an example, not the default.
*/
//#define SSL_CIPHERSUITES TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
/* Debug options */ /* Debug options */
//#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ //#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */

View File

@ -34,6 +34,7 @@
#endif #endif
#include "net.h" #include "net.h"
#include "bignum.h" #include "bignum.h"
#include "ecp.h"
#include "ssl_ciphersuites.h" #include "ssl_ciphersuites.h"
@ -252,7 +253,9 @@
* Note: the RFC defines the default size of SSL / TLS messages. If you * Note: the RFC defines the default size of SSL / TLS messages. If you
* change the value here, other clients / servers may not be able to * change the value here, other clients / servers may not be able to
* communicate with you anymore. Only change this value if you control * communicate with you anymore. Only change this value if you control
* both sides of the connection and have it reduced at both sides! * both sides of the connection and have it reduced at both sides, or
* if you're using the Max Fragment Length extension and you know all your
* peers are using it too!
*/ */
#if !defined(SSL_MAX_CONTENT_LEN) #if !defined(SSL_MAX_CONTENT_LEN)
#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ #define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */
@ -261,8 +264,8 @@
/* \} name SECTION: Module settings */ /* \} name SECTION: Module settings */
/* /*
* Allow an extra 301 bytes for the record header and encryption overhead: * Allow extra bytes for record, authentication and encryption overhead:
* counter (8) + header (5) + IV(16) + MAC (48) + padding (256) * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256)
* and allow for a maximum of 1024 of compression expansion if * and allow for a maximum of 1024 of compression expansion if
* enabled. * enabled.
*/ */
@ -272,8 +275,36 @@
#define SSL_COMPRESSION_ADD 0 #define SSL_COMPRESSION_ADD 0
#endif #endif
#define SSL_BUFFER_LEN (SSL_MAX_CONTENT_LEN + SSL_COMPRESSION_ADD + 333) #if defined(POLARSSL_RC4_C) || defined(POLARSSL_CIPHER_MODE_CBC)
/* Ciphersuites using HMAC */
#if defined(POLARSSL_SHA512_C)
#define SSL_MAC_ADD 48 /* SHA-384 used for HMAC */
#elif defined(POLARSSL_SHA256_C)
#define SSL_MAC_ADD 32 /* SHA-256 used for HMAC */
#else
#define SSL_MAC_ADD 20 /* SHA-1 used for HMAC */
#endif
#else
/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */
#define SSL_MAC_ADD 16
#endif
#if defined(POLARSSL_CIPHER_MODE_CBC)
#define SSL_PADDING_ADD 256
#else
#define SSL_PADDING_ADD 0
#endif
#define SSL_BUFFER_LEN ( SSL_MAX_CONTENT_LEN \
+ SSL_COMPRESSION_ADD \
+ 29 /* counter + header + IV */ \
+ SSL_MAC_ADD \
+ SSL_PADDING_ADD \
)
/*
* Signaling ciphersuite values (SCSV)
*/
#define SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ #define SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */
/* /*
@ -382,12 +413,43 @@
/* /*
* Size defines * Size defines
*/ */
#if !defined(POLARSSL_MPI_MAX_SIZE) #if !defined(POLARSSL_PSK_MAX_LEN)
#define POLARSSL_PREMASTER_SIZE 512 #define POLARSSL_PSK_MAX_LEN 32 /* 256 bits */
#else
#define POLARSSL_PREMASTER_SIZE POLARSSL_MPI_MAX_SIZE
#endif #endif
/* Dummy type used only for its size */
union _ssl_premaster_secret
{
#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)
unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */
#endif
#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED)
unsigned char _pms_dhm[POLARSSL_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */
#endif
#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
unsigned char _pms_ecdh[POLARSSL_ECP_MAX_BYTES]; /* RFC 4492 5.10 */
#endif
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
unsigned char _pms_psk[4 + 2 * POLARSSL_PSK_MAX_LEN]; /* RFC 4279 2 */
#endif
#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
unsigned char _pms_dhe_psk[4 + POLARSSL_MPI_MAX_SIZE
+ POLARSSL_PSK_MAX_LEN]; /* RFC 4279 3 */
#endif
#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
unsigned char _pms_rsa_psk[52 + POLARSSL_PSK_MAX_LEN]; /* RFC 4279 4 */
#endif
#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
unsigned char _pms_ecdhe_psk[4 + POLARSSL_ECP_MAX_BYTES
+ POLARSSL_PSK_MAX_LEN]; /* RFC 5489 2 */
#endif
};
#define POLARSSL_PREMASTER_SIZE sizeof( union _ssl_premaster_secret )
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -233,6 +233,7 @@ extern "C" {
#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ #define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */
#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ #define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */
/* Reminder: update _ssl_premaster_secret when adding a new key exchange */
typedef enum { typedef enum {
POLARSSL_KEY_EXCHANGE_NONE = 0, POLARSSL_KEY_EXCHANGE_NONE = 0,
POLARSSL_KEY_EXCHANGE_RSA, POLARSSL_KEY_EXCHANGE_RSA,

View File

@ -57,6 +57,9 @@
*/ */
static const int ciphersuite_preference[] = static const int ciphersuite_preference[] =
{ {
#if defined(SSL_CIPHERSUITES)
SSL_CIPHERSUITES,
#else
/* All AES-256 ephemeral suites */ /* All AES-256 ephemeral suites */
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
@ -257,13 +260,10 @@ static const int ciphersuite_preference[] =
TLS_PSK_WITH_NULL_SHA256, TLS_PSK_WITH_NULL_SHA256,
TLS_PSK_WITH_NULL_SHA, TLS_PSK_WITH_NULL_SHA,
#endif
0 0
}; };
#define MAX_CIPHERSUITES 176
static int supported_ciphersuites[MAX_CIPHERSUITES];
static int supported_init = 0;
static const ssl_ciphersuite_t ciphersuite_definitions[] = static const ssl_ciphersuite_t ciphersuite_definitions[] =
{ {
#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
@ -1679,6 +1679,17 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
{ 0, "", 0, 0, 0, 0, 0, 0, 0, 0 } { 0, "", 0, 0, 0, 0, 0, 0, 0, 0 }
}; };
#if defined(SSL_CIPHERSUITES)
const int *ssl_list_ciphersuites( void )
{
return( ciphersuite_preference );
}
#else
#define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \
sizeof( ciphersuite_definitions[0] )
static int supported_ciphersuites[MAX_CIPHERSUITES];
static int supported_init = 0;
const int *ssl_list_ciphersuites( void ) const int *ssl_list_ciphersuites( void )
{ {
/* /*
@ -1687,21 +1698,21 @@ const int *ssl_list_ciphersuites( void )
*/ */
if( supported_init == 0 ) if( supported_init == 0 )
{ {
const int *p = ciphersuite_preference; const int *p;
int *q = supported_ciphersuites; int *q;
size_t i;
size_t max = sizeof(supported_ciphersuites) / sizeof(int);
for( i = 0; i < max - 1 && p[i] != 0; i++ ) for( p = ciphersuite_preference, q = supported_ciphersuites;
*p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1;
p++ )
{ {
#if defined(POLARSSL_REMOVE_ARC4_CIPHERSUITES) #if defined(POLARSSL_REMOVE_ARC4_CIPHERSUITES)
const ssl_ciphersuite_t *cs_info; const ssl_ciphersuite_t *cs_info;
if( ( cs_info = ssl_ciphersuite_from_id( p[i] ) ) != NULL && if( ( cs_info = ssl_ciphersuite_from_id( *p ) ) != NULL &&
cs_info->cipher != POLARSSL_CIPHER_ARC4_128 ) cs_info->cipher != POLARSSL_CIPHER_ARC4_128 )
#else #else
if( ssl_ciphersuite_from_id( p[i] ) != NULL ) if( ssl_ciphersuite_from_id( *p ) != NULL )
#endif #endif
*(q++) = p[i]; *(q++) = *p;
} }
*q = 0; *q = 0;
@ -1710,6 +1721,7 @@ const int *ssl_list_ciphersuites( void )
return( supported_ciphersuites ); return( supported_ciphersuites );
}; };
#endif /* SSL_CIPHERSUITES */
const ssl_ciphersuite_t *ssl_ciphersuite_from_string( const ssl_ciphersuite_t *ssl_ciphersuite_from_string(
const char *ciphersuite_name ) const char *ciphersuite_name )

View File

@ -3747,12 +3747,7 @@ int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
if( psk == NULL || psk_identity == NULL ) if( psk == NULL || psk_identity == NULL )
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
/* if( psk_len > POLARSSL_PSK_MAX_LEN )
* The length will be check later anyway, but in case it is obviously
* too large, better abort now. The PMS is as follows:
* other_len (2 bytes) + other + psk_len (2 bytes) + psk
*/
if( psk_len + 4 > POLARSSL_PREMASTER_SIZE )
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
if( ssl->psk != NULL ) if( ssl->psk != NULL )

View File

@ -325,7 +325,7 @@ int main( int argc, char *argv[] )
int ret = 0, len, server_fd, i, written, frags; int ret = 0, len, server_fd, i, written, frags;
unsigned char buf[SSL_MAX_CONTENT_LEN + 1]; unsigned char buf[SSL_MAX_CONTENT_LEN + 1];
#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
unsigned char psk[256]; unsigned char psk[POLARSSL_PSK_MAX_LEN];
size_t psk_len = 0; size_t psk_len = 0;
#endif #endif
#if defined(POLARSSL_SSL_ALPN) #if defined(POLARSSL_SSL_ALPN)

View File

@ -127,8 +127,6 @@ int main( int argc, char *argv[] )
"<h2>PolarSSL Test Server</h2>\r\n" \ "<h2>PolarSSL Test Server</h2>\r\n" \
"<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE "<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE
#define MAX_PSK_LEN 256
/* /*
* Size of the basic I/O buffer. Able to hold our default response. * Size of the basic I/O buffer. Able to hold our default response.
* *
@ -462,7 +460,7 @@ int unhexify( unsigned char *output, const char *input, size_t *olen )
size_t j; size_t j;
*olen = strlen( input ); *olen = strlen( input );
if( *olen % 2 != 0 || *olen / 2 > MAX_PSK_LEN ) if( *olen % 2 != 0 || *olen / 2 > POLARSSL_PSK_MAX_LEN )
return( -1 ); return( -1 );
*olen /= 2; *olen /= 2;
@ -486,7 +484,7 @@ struct _psk_entry
{ {
const char *name; const char *name;
size_t key_len; size_t key_len;
unsigned char key[MAX_PSK_LEN]; unsigned char key[POLARSSL_PSK_MAX_LEN];
psk_entry *next; psk_entry *next;
}; };
@ -575,7 +573,7 @@ int main( int argc, char *argv[] )
int version_suites[4][2]; int version_suites[4][2];
unsigned char buf[IO_BUF_LEN]; unsigned char buf[IO_BUF_LEN];
#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
unsigned char psk[MAX_PSK_LEN]; unsigned char psk[POLARSSL_PSK_MAX_LEN];
size_t psk_len = 0; size_t psk_len = 0;
psk_entry *psk_info = NULL; psk_entry *psk_info = NULL;
#endif #endif

View File

@ -20,7 +20,7 @@ my %configs = (
'config-picocoin.h' 'config-picocoin.h'
=> 0, => 0,
'config-ccm-psk-tls1_2.h' 'config-ccm-psk-tls1_2.h'
=> '-m tls1_2 -f \'TLS-PSK.*AES.*CCM\'', => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
); );
# If no config-name is provided, use all known configs. # If no config-name is provided, use all known configs.