From 2466d93546d0b547481fe9a3c10534542d6c2dd7 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Sat, 28 Sep 2013 14:40:38 +0200 Subject: [PATCH 1/7] Threading abstraction layer added --- ChangeLog | 1 + include/polarssl/config.h | 80 +++++++++++++++++++++ include/polarssl/error.h | 1 + include/polarssl/threading.h | 84 ++++++++++++++++++++++ library/CMakeLists.txt | 1 + library/Makefile | 3 +- library/error.c | 13 ++++ library/threading.c | 134 +++++++++++++++++++++++++++++++++++ scripts/generate_errors.pl | 3 +- 9 files changed, 318 insertions(+), 2 deletions(-) create mode 100644 include/polarssl/threading.h create mode 100644 library/threading.c diff --git a/ChangeLog b/ChangeLog index 249434478..0531a8431 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ Features * PSK and DHE-PSK based ciphersuites added * Memory allocation abstraction layer added * Buffer-based memory allocator added (no malloc() / free() / HEAP usage) + * Threading abstraction layer added (dummy / pthread / alternate) * Public Key abstraction layer added * Parsing Elliptic Curve keys * Parsing Elliptic Curve certificates diff --git a/include/polarssl/config.h b/include/polarssl/config.h index f2ac41c67..4a9d0efd5 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -659,6 +659,39 @@ */ #define POLARSSL_SSL_TRUNCATED_HMAC +/** + * \def POLARSSL_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. +#define POLARSSL_THREADING_ALT + */ + +/** + * \def POLARSSL_THREADING_DUMMY + * + * Provide a dummy threading implementation. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to enable code to compile like with threading enabled +#define POLARSSL_THREADING_DUMMY + */ + +/** + * \def POLARSSL_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to enable pthread mutexes. +#define POLARSSL_THREADING_PTHREAD + */ + /** * \def POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 * @@ -1435,6 +1468,27 @@ */ #define POLARSSL_SSL_TLS_C +/** + * \def POLARSSL_THREADING_C + * + * Enable the threading abstraction layer. + * By default PolarSSL assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either POLARSSL_THREADING_ALT, + * POLARSSL_THREADING_PTHREAD or POLARSSL_THREADING_DUMMY. + * + * Enable this layer to allow use of mutexes within PolarSSL +#define POLARSSL_THREADING_C + */ + /** * \def POLARSSL_TIMING_C * @@ -1784,6 +1838,32 @@ #error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites" #endif +#if defined(POLARSSL_THREADING_DUMMY) +#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_DUMMY defined, but not all prerequisites" +#endif +#define POLARSSL_THREADING_IMPL +#endif + +#if defined(POLARSSL_THREADING_PTHREAD) +#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_PTHREAD defined, but not all prerequisites" +#endif +#define POLARSSL_THREADING_IMPL +#endif + +#if defined(POLARSSL_THREADING_ALT) +#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_ALT defined, but not all prerequisites" +#endif +#define POLARSSL_THREADING_IMPL +#endif + +#if defined(POLARSSL_THREADING_C) && !defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_C defined, single threading implementation required" +#endif +#undef POLARSSL_THREADING_IMPL + #if defined(POLARSSL_X509_USE_C) && ( !defined(POLARSSL_BIGNUM_C) || \ !defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_PARSE_C) || \ !defined(POLARSSL_PK_PARSE_C) ) diff --git a/include/polarssl/error.h b/include/polarssl/error.h index ab3d63211..a64960c06 100644 --- a/include/polarssl/error.h +++ b/include/polarssl/error.h @@ -53,6 +53,7 @@ * MPI 7 0x0002-0x0010 * GCM 2 0x0012-0x0014 * BLOWFISH 2 0x0016-0x0018 + * THREADING 3 0x001A-0x001E * AES 2 0x0020-0x0022 * CAMELLIA 2 0x0024-0x0026 * XTEA 1 0x0028-0x0028 diff --git a/include/polarssl/threading.h b/include/polarssl/threading.h new file mode 100644 index 000000000..4afaeea39 --- /dev/null +++ b/include/polarssl/threading.h @@ -0,0 +1,84 @@ +/** + * \file threading.h + * + * \brief Threading abstraction layer + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_THREADING_H +#define POLARSSL_THREADING_H + +#include "config.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define POLARSSL_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */ +#define POLARSSL_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */ +#define POLARSSL_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */ + +#if defined(POLARSSL_THREADING_DUMMY) +typedef void threading_mutex_t; +#endif + +#if defined(POLARSSL_THREADING_PTHREAD) +#include +typedef pthread_mutex_t threading_mutex_t; +#endif + +#if defined(POLARSSL_THREADING_ALT) +/* You should define the threading_mutex_t type in your header */ +#include "threading_alt.h" + +/** + * \brief Set your alternate threading implementation function + * pointers + * + * \param mutex_init the malloc function implementation + * \param mutex_free the free function implementation + * \param mutex_lock the lock function implementation + * \param mutex_unlock the unlock function implementation + * + * \return 0 if successful + */ +int threading_set_alt( int (*mutex_init)( threading_mutex_t * ), + int (*mutex_free)( threading_mutex_t * ), + int (*mutex_lock)( threading_mutex_t * ), + int (*mutex_unlock)( threading_mutex_t * ) ); +#endif /* POLARSSL_THREADING_ALT_C */ + +/* + * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock + */ +extern int (*polarssl_mutex_init)( threading_mutex_t *mutex ); +extern int (*polarssl_mutex_free)( threading_mutex_t *mutex ); +extern int (*polarssl_mutex_lock)( threading_mutex_t *mutex ); +extern int (*polarssl_mutex_unlock)( threading_mutex_t *mutex ); + +#ifdef __cplusplus +} +#endif + +#endif /* threading.h */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index dda7ff1bd..bc22f2682 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -52,6 +52,7 @@ set(src ssl_cli.c ssl_srv.c ssl_tls.c + threading.c timing.c version.c x509.c diff --git a/library/Makefile b/library/Makefile index 003b93304..4c37adf9c 100644 --- a/library/Makefile +++ b/library/Makefile @@ -54,7 +54,8 @@ OBJS= aes.o arc4.o asn1parse.o \ rsa.o sha1.o sha256.o \ sha512.o ssl_cache.o ssl_cli.o \ ssl_srv.o ssl_ciphersuites.o \ - ssl_tls.o timing.o version.o \ + ssl_tls.o threading.o timing.o \ + version.o \ x509.o x509_create.o \ x509_crl.o x509_crt.o x509_csr.o \ x509write_crt.o x509write_csr.o \ diff --git a/library/error.c b/library/error.c index 85068971a..a7e146782 100644 --- a/library/error.c +++ b/library/error.c @@ -145,6 +145,10 @@ #include "polarssl/ssl.h" #endif +#if defined(POLARSSL_THREADING_C) +#include "polarssl/threading.h" +#endif + #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) #include "polarssl/x509.h" #endif @@ -647,6 +651,15 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "SHA512 - Read/write error in file" ); #endif /* POLARSSL_SHA512_C */ +#if defined(POLARSSL_THREADING_C) + if( use_ret == -(POLARSSL_ERR_THREADING_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "THREADING - The selected feature is not available" ); + if( use_ret == -(POLARSSL_ERR_THREADING_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "THREADING - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_THREADING_MUTEX_ERROR) ) + snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" ); +#endif /* POLARSSL_THREADING_C */ + #if defined(POLARSSL_XTEA_C) if( use_ret == -(POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH) ) snprintf( buf, buflen, "XTEA - The data input has an invalid length" ); diff --git a/library/threading.c b/library/threading.c new file mode 100644 index 000000000..e79348aa3 --- /dev/null +++ b/library/threading.c @@ -0,0 +1,134 @@ +/* + * Threading abstraction layer + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_THREADING_C) + +#include "polarssl/threading.h" + +#if defined(POLARSSL_THREADING_DUMMY) +static int threading_mutex_init_dummy( threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( 0 ); +} + +static int threading_mutex_free_dummy( threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( 0 ); +} + +static int threading_mutex_lock_dummy( threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( 0 ); +} + +static int threading_mutex_unlock_dummy( threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( 0 ); +} + +int (*polarssl_mutex_init)( threading_mutex_t * ) = threading_mutex_init_dummy; +int (*polarssl_mutex_free)( threading_mutex_t * ) = threading_mutex_free_dummy; +int (*polarssl_mutex_lock)( threading_mutex_t * ) = threading_mutex_lock_dummy; +int (*polarssl_mutex_unlock)( threading_mutex_t * ) = threading_mutex_unlock_dummy; +#endif /* POLARSSL_THREADING_DUMMY */ + +#if defined(POLARSSL_THREADING_PTHREAD) +static int threading_mutex_init_pthread( threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_init( mutex, NULL ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_free_pthread( threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_destroy( mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_lock_pthread( threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_lock( mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_unlock_pthread( threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_unlock( mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +int (*polarssl_mutex_init)( threading_mutex_t * ) = threading_mutex_init_pthread; +int (*polarssl_mutex_free)( threading_mutex_t * ) = threading_mutex_free_pthread; +int (*polarssl_mutex_lock)( threading_mutex_t * ) = threading_mutex_lock_pthread; +int (*polarssl_mutex_unlock)( threading_mutex_t * ) = threading_mutex_unlock_pthread; +#endif /* POLARSSL_THREADING_PTHREAD */ + +#if defined(POLARSSL_THREADING_ALT) +int (*polarssl_mutex_init)( threading_mutex_t * ) = NULL; +int (*polarssl_mutex_free)( threading_mutex_t * ) = NULL; +int (*polarssl_mutex_lock)( threading_mutex_t * ) = NULL; +int (*polarssl_mutex_unlock)( threading_mutex_t * ) = NULL; + +int threading_set_own( int (*mutex_init)( threading_mutex_t * ), + int (*mutex_free)( threading_mutex_t * ), + int (*mutex_lock)( threading_mutex_t * ), + int (*mutex_unlock)( threading_mutex_t * ) ) +{ + polarssl_mutex_init = mutex_init; + polarssl_mutex_free = mutex_free; + polarssl_mutex_lock = mutex_lock; + polarssl_mutex_unlock = mutex_unlock; + + return( 0 ); +} +#endif /* POLARSSL_THREADING_ALT_C */ + +#endif /* POLARSSL_THREADING_C */ diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl index 85dde353c..0dff537d4 100755 --- a/scripts/generate_errors.pl +++ b/scripts/generate_errors.pl @@ -11,7 +11,8 @@ my $error_format_file = $data_dir.'/error.fmt'; my @low_level_modules = ( "AES", "ASN1", "BLOWFISH", "CAMELLIA", "BIGNUM", "BASE64", "XTEA", "PBKDF2", "OID", "PADLOCK", "DES", "NET", "CTR_DRBG", "ENTROPY", - "MD2", "MD4", "MD5", "SHA1", "SHA256", "SHA512", "GCM" ); + "MD2", "MD4", "MD5", "SHA1", "SHA256", "SHA512", + "GCM", "THREADING" ); my @high_level_modules = ( "PEM", "X509", "DHM", "RSA", "ECP", "MD", "CIPHER", "SSL", "PK", "PKCS12", "PKCS5" ); From c55988406f9ef0d79539ed9764c0bc2a1168ffa7 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Sat, 28 Sep 2013 15:01:27 +0200 Subject: [PATCH 2/7] SSL Cache threading support --- include/polarssl/ssl_cache.h | 9 +++++ library/ssl_cache.c | 64 +++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/include/polarssl/ssl_cache.h b/include/polarssl/ssl_cache.h index 3c5ef8b1c..daa07acb6 100644 --- a/include/polarssl/ssl_cache.h +++ b/include/polarssl/ssl_cache.h @@ -29,6 +29,10 @@ #include "ssl.h" +#if defined(POLARSSL_THREADING_C) +#include "threading.h" +#endif + #if !defined(POLARSSL_CONFIG_OPTIONS) #define SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */ #define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */ @@ -64,6 +68,9 @@ struct _ssl_cache_context ssl_cache_entry *chain; /*!< start of the chain */ int timeout; /*!< cache entry timeout */ int max_entries; /*!< maximum entries */ +#if defined(POLARSSL_THREADING_C) + threading_mutex_t mutex; /*!< mutex */ +#endif }; /** @@ -75,6 +82,7 @@ void ssl_cache_init( ssl_cache_context *cache ); /** * \brief Cache get callback implementation + * (Thread-safe if POLARSSL_THREADING_C is enabled) * * \param data SSL cache context * \param session session to retrieve entry for @@ -83,6 +91,7 @@ int ssl_cache_get( void *data, ssl_session *session ); /** * \brief Cache set callback implementation + * (Thread-safe if POLARSSL_THREADING_C is enabled) * * \param data SSL cache context * \param session session to store entry for diff --git a/library/ssl_cache.c b/library/ssl_cache.c index 113f72440..e0847b6dc 100644 --- a/library/ssl_cache.c +++ b/library/ssl_cache.c @@ -48,16 +48,26 @@ void ssl_cache_init( ssl_cache_context *cache ) cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT; cache->max_entries = SSL_CACHE_DEFAULT_MAX_ENTRIES; + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &cache->mutex ); +#endif } int ssl_cache_get( void *data, ssl_session *session ) { + int ret = 1; #if defined(POLARSSL_HAVE_TIME) time_t t = time( NULL ); #endif ssl_cache_context *cache = (ssl_cache_context *) data; ssl_cache_entry *cur, *entry; +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_lock( &cache->mutex ) != 0 ) + return( 1 ); +#endif + cur = cache->chain; entry = NULL; @@ -93,7 +103,10 @@ int ssl_cache_get( void *data, ssl_session *session ) { session->peer_cert = (x509_crt *) polarssl_malloc( sizeof(x509_crt) ); if( session->peer_cert == NULL ) - return( 1 ); + { + ret = 1; + goto exit; + } x509_crt_init( session->peer_cert ); if( x509_crt_parse( session->peer_cert, entry->peer_cert.p, @@ -101,19 +114,28 @@ int ssl_cache_get( void *data, ssl_session *session ) { polarssl_free( session->peer_cert ); session->peer_cert = NULL; - return( 1 ); + ret = 1; + goto exit; } } #endif /* POLARSSL_X509_CRT_PARSE_C */ - return( 0 ); + ret = 0; + goto exit; } - return( 1 ); +exit: +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &cache->mutex ) != 0 ) + ret = 1; +#endif + + return( ret ); } int ssl_cache_set( void *data, const ssl_session *session ) { + int ret = 1; #if defined(POLARSSL_HAVE_TIME) time_t t = time( NULL ), oldest = 0; ssl_cache_entry *old = NULL; @@ -122,6 +144,11 @@ int ssl_cache_set( void *data, const ssl_session *session ) ssl_cache_entry *cur, *prv; int count = 0; +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &cache->mutex ) ) != 0 ) + return( ret ); +#endif + cur = cache->chain; prv = NULL; @@ -179,7 +206,10 @@ int ssl_cache_set( void *data, const ssl_session *session ) if( count >= cache->max_entries ) { if( cache->chain == NULL ) - return( 1 ); + { + ret = 1; + goto exit; + } cur = cache->chain; cache->chain = cur->next; @@ -200,7 +230,10 @@ int ssl_cache_set( void *data, const ssl_session *session ) { cur = (ssl_cache_entry *) polarssl_malloc( sizeof(ssl_cache_entry) ); if( cur == NULL ) - return( 1 ); + { + ret = 1; + goto exit; + } memset( cur, 0, sizeof(ssl_cache_entry) ); @@ -225,7 +258,10 @@ int ssl_cache_set( void *data, const ssl_session *session ) { cur->peer_cert.p = (unsigned char *) polarssl_malloc( session->peer_cert->raw.len ); if( cur->peer_cert.p == NULL ) - return( 1 ); + { + ret = 1; + goto exit; + } memcpy( cur->peer_cert.p, session->peer_cert->raw.p, session->peer_cert->raw.len ); @@ -235,7 +271,15 @@ int ssl_cache_set( void *data, const ssl_session *session ) } #endif /* POLARSSL_X509_CRT_PARSE_C */ - return( 0 ); + ret = 0; + +exit: +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &cache->mutex ) != 0 ) + ret = 1; +#endif + + return( ret ); } #if defined(POLARSSL_HAVE_TIME) @@ -274,6 +318,10 @@ void ssl_cache_free( ssl_cache_context *cache ) polarssl_free( prv ); } + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &cache->mutex ); +#endif } #endif /* POLARSSL_SSL_CACHE_C */ From 1ffefaca1e13203ca03a439e2513c51d0f755a29 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Sat, 28 Sep 2013 15:23:03 +0200 Subject: [PATCH 3/7] Introduced entropy_free() --- include/polarssl/entropy.h | 7 +++++++ library/entropy.c | 5 +++++ programs/pkey/dh_client.c | 1 + programs/pkey/dh_genprime.c | 1 + programs/pkey/dh_server.c | 1 + programs/pkey/ecdsa.c | 1 + programs/pkey/gen_key.c | 1 + programs/pkey/pk_decrypt.c | 1 + programs/pkey/pk_encrypt.c | 1 + programs/pkey/pk_sign.c | 1 + programs/pkey/rsa_decrypt.c | 1 + programs/pkey/rsa_encrypt.c | 1 + programs/pkey/rsa_genkey.c | 1 + programs/pkey/rsa_sign_pss.c | 1 + programs/random/gen_entropy.c | 1 + programs/random/gen_random_ctr_drbg.c | 1 + programs/ssl/ssl_client1.c | 1 + programs/ssl/ssl_client2.c | 1 + programs/ssl/ssl_fork_server.c | 1 + programs/ssl/ssl_mail_client.c | 1 + programs/ssl/ssl_server.c | 1 + programs/ssl/ssl_server2.c | 1 + programs/test/o_p_test.c | 1 + programs/test/ssl_test.c | 1 + programs/x509/cert_app.c | 1 + programs/x509/cert_req.c | 1 + programs/x509/cert_write.c | 1 + tests/suites/test_suite_rsa.function | 1 + 28 files changed, 38 insertions(+) diff --git a/include/polarssl/entropy.h b/include/polarssl/entropy.h index ea27848db..e334c2247 100644 --- a/include/polarssl/entropy.h +++ b/include/polarssl/entropy.h @@ -116,6 +116,13 @@ entropy_context; */ void entropy_init( entropy_context *ctx ); +/** + * \brief Free the data in the context + * + * \param ctx Entropy context to free + */ +void entropy_free( entropy_context *ctx ); + /** * \brief Adds an entropy source to poll * diff --git a/library/entropy.c b/library/entropy.c index 2352bcff4..d43f9833c 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -64,6 +64,11 @@ void entropy_init( entropy_context *ctx ) #endif /* POLARSSL_NO_DEFAULT_ENTROPY_SOURCES */ } +void entropy_free( entropy_context *ctx ) +{ + ((void) ctx); +} + int entropy_add_source( entropy_context *ctx, f_source_ptr f_source, void *p_source, size_t threshold ) diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c index 4410eb6fe..18027fa65 100644 --- a/programs/pkey/dh_client.c +++ b/programs/pkey/dh_client.c @@ -275,6 +275,7 @@ exit: net_close( server_fd ); rsa_free( &rsa ); dhm_free( &dhm ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c index f773f1e42..2089fb632 100644 --- a/programs/pkey/dh_genprime.c +++ b/programs/pkey/dh_genprime.c @@ -143,6 +143,7 @@ int main( int argc, char *argv[] ) exit: mpi_free( &G ); mpi_free( &P ); mpi_free( &Q ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " Press Enter to exit this program.\n" ); diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index 584ff08da..d2b6cc48d 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -276,6 +276,7 @@ exit: net_close( client_fd ); rsa_free( &rsa ); dhm_free( &dhm ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c index efe671616..add74c6d6 100644 --- a/programs/pkey/ecdsa.c +++ b/programs/pkey/ecdsa.c @@ -179,6 +179,7 @@ exit: ecdsa_free( &ctx_verify ); ecdsa_free( &ctx_sign ); + entropy_free( &entropy ); return( ret ); } diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index 3cf682b8a..19f46a400 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -269,6 +269,7 @@ exit: } pk_free( &key ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c index a6ae28108..bf3455dfc 100644 --- a/programs/pkey/pk_decrypt.c +++ b/programs/pkey/pk_decrypt.c @@ -136,6 +136,7 @@ int main( int argc, char *argv[] ) ret = 0; exit: + entropy_free( &entropy ); #if defined(POLARSSL_ERROR_C) polarssl_strerror( ret, (char *) buf, sizeof(buf) ); diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c index aa202b00e..149e7ddfe 100644 --- a/programs/pkey/pk_encrypt.c +++ b/programs/pkey/pk_encrypt.c @@ -136,6 +136,7 @@ int main( int argc, char *argv[] ) printf( "\n . Done (created \"%s\")\n\n", "result-enc.txt" ); exit: + entropy_free( &entropy ); #if defined(POLARSSL_ERROR_C) polarssl_strerror( ret, (char *) buf, sizeof(buf) ); diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c index 5a874b336..67ac0b414 100644 --- a/programs/pkey/pk_sign.c +++ b/programs/pkey/pk_sign.c @@ -149,6 +149,7 @@ int main( int argc, char *argv[] ) exit: pk_free( &pk ); + entropy_free( &entropy ); #if defined(POLARSSL_ERROR_C) polarssl_strerror( ret, (char *) buf, sizeof(buf) ); diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c index 36ac80953..02d30c8ed 100644 --- a/programs/pkey/rsa_decrypt.c +++ b/programs/pkey/rsa_decrypt.c @@ -160,6 +160,7 @@ int main( int argc, char *argv[] ) ret = 0; exit: + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c index c444c1afa..2ed27e23e 100644 --- a/programs/pkey/rsa_encrypt.c +++ b/programs/pkey/rsa_encrypt.c @@ -148,6 +148,7 @@ int main( int argc, char *argv[] ) printf( "\n . Done (created \"%s\")\n\n", "result-enc.txt" ); exit: + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c index f92c50b6e..7711776ef 100644 --- a/programs/pkey/rsa_genkey.c +++ b/programs/pkey/rsa_genkey.c @@ -150,6 +150,7 @@ exit: fclose( fpriv ); rsa_free( &rsa ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " Press Enter to exit this program.\n" ); diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c index 06fc2e07b..fecfcc26e 100644 --- a/programs/pkey/rsa_sign_pss.c +++ b/programs/pkey/rsa_sign_pss.c @@ -156,6 +156,7 @@ int main( int argc, char *argv[] ) exit: pk_free( &pk ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/random/gen_entropy.c b/programs/random/gen_entropy.c index 38c104c92..e0cbe528a 100644 --- a/programs/random/gen_entropy.c +++ b/programs/random/gen_entropy.c @@ -81,6 +81,7 @@ int main( int argc, char *argv[] ) cleanup: fclose( f ); + entropy_free( &entropy ); return( ret ); } diff --git a/programs/random/gen_random_ctr_drbg.c b/programs/random/gen_random_ctr_drbg.c index fcdc2eec1..32b8521d3 100644 --- a/programs/random/gen_random_ctr_drbg.c +++ b/programs/random/gen_random_ctr_drbg.c @@ -111,6 +111,7 @@ cleanup: printf("\n"); fclose( f ); + entropy_free( &entropy ); return( ret ); } diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c index 2c6e7c868..efb210e46 100644 --- a/programs/ssl/ssl_client1.c +++ b/programs/ssl/ssl_client1.c @@ -277,6 +277,7 @@ exit: x509_crt_free( &cacert ); net_close( server_fd ); ssl_free( &ssl ); + entropy_free( &entropy ); memset( &ssl, 0, sizeof( ssl ) ); diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index f518d39f7..2093d1a6a 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -913,6 +913,7 @@ exit: #endif ssl_session_free( &saved_session ); ssl_free( &ssl ); + entropy_free( &entropy ); memset( &ssl, 0, sizeof( ssl ) ); diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c index 3d4c7d3b3..02de364ba 100644 --- a/programs/ssl/ssl_fork_server.c +++ b/programs/ssl/ssl_fork_server.c @@ -361,6 +361,7 @@ exit: x509_crt_free( &srvcert ); pk_free( &pkey ); ssl_free( &ssl ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " Press Enter to exit this program.\n" ); diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c index edee85db7..70ba6221e 100644 --- a/programs/ssl/ssl_mail_client.c +++ b/programs/ssl/ssl_mail_client.c @@ -791,6 +791,7 @@ exit: x509_crt_free( &cacert ); pk_free( &pkey ); ssl_free( &ssl ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c index 2a528cb07..b4883aae7 100644 --- a/programs/ssl/ssl_server.c +++ b/programs/ssl/ssl_server.c @@ -367,6 +367,7 @@ exit: #if defined(POLARSSL_SSL_CACHE_C) ssl_cache_free( &cache ); #endif + entropy_free( &entropy ); #if defined(_WIN32) printf( " Press Enter to exit this program.\n" ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 2d81e755e..a6ff57fea 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -963,6 +963,7 @@ exit: #endif ssl_free( &ssl ); + entropy_free( &entropy ); #if defined(POLARSSL_SSL_CACHE_C) ssl_cache_free( &cache ); diff --git a/programs/test/o_p_test.c b/programs/test/o_p_test.c index bf54752c9..0665098f6 100644 --- a/programs/test/o_p_test.c +++ b/programs/test/o_p_test.c @@ -252,6 +252,7 @@ int main( int argc, char *argv[] ) printf( "String value (PolarSSL Private Encrypt, OpenSSL Public Decrypt): '%s'\n", o_priv_decrypted ); exit: + entropy_free( &entropy ); #ifdef WIN32 printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/test/ssl_test.c b/programs/test/ssl_test.c index 20907d8db..debdb073e 100644 --- a/programs/test/ssl_test.c +++ b/programs/test/ssl_test.c @@ -401,6 +401,7 @@ exit: x509_crt_free( &srvcert ); pk_free( &pkey ); ssl_free( &ssl ); + entropy_free( &entropy ); net_close( client_fd ); return( ret ); diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c index dedac9420..c43e662af 100644 --- a/programs/x509/cert_app.c +++ b/programs/x509/cert_app.c @@ -449,6 +449,7 @@ exit: x509_crt_free( &cacert ); x509_crt_free( &clicert ); pk_free( &pkey ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c index c6d7dff72..dc45f9496 100644 --- a/programs/x509/cert_req.c +++ b/programs/x509/cert_req.c @@ -329,6 +329,7 @@ exit: x509write_csr_free( &req ); pk_free( &key ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c index ba00dc3de..94dfa1ddc 100644 --- a/programs/x509/cert_write.c +++ b/programs/x509/cert_write.c @@ -650,6 +650,7 @@ exit: pk_free( &loaded_subject_key ); pk_free( &loaded_issuer_key ); mpi_free( &serial ); + entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function index dfd2c96af..9bc8a24bf 100644 --- a/tests/suites/test_suite_rsa.function +++ b/tests/suites/test_suite_rsa.function @@ -528,6 +528,7 @@ void rsa_gen_key( int nrbits, int exponent, int result) } rsa_free( &ctx ); + entropy_free( &entropy ); } /* END_CASE */ From f4e7dc50ea87686f1bf8ccb442e0a5d846a96be3 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Sat, 28 Sep 2013 15:23:57 +0200 Subject: [PATCH 4/7] entropy_func() threading support --- include/polarssl/entropy.h | 8 ++++++++ library/entropy.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/polarssl/entropy.h b/include/polarssl/entropy.h index e334c2247..235b7733c 100644 --- a/include/polarssl/entropy.h +++ b/include/polarssl/entropy.h @@ -41,6 +41,10 @@ #endif #endif +#if defined(POLARSSL_THREADING_C) +#include "threading.h" +#endif + #if defined(POLARSSL_HAVEGE_C) #include "havege.h" #endif @@ -106,6 +110,9 @@ typedef struct #if defined(POLARSSL_HAVEGE_C) havege_state havege_data; #endif +#if defined(POLARSSL_THREADING_C) + threading_mutex_t mutex; /*!< mutex */ +#endif } entropy_context; @@ -149,6 +156,7 @@ int entropy_gather( entropy_context *ctx ); /** * \brief Retrieve entropy from the accumulator (Max ENTROPY_BLOCK_SIZE) + * (Thread-safe if POLARSSL_THREADING_C is enabled) * * \param data Entropy context * \param output Buffer to fill diff --git a/library/entropy.c b/library/entropy.c index d43f9833c..c5fac26e9 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -40,6 +40,10 @@ void entropy_init( entropy_context *ctx ) { memset( ctx, 0, sizeof(entropy_context) ); +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &ctx->mutex ); +#endif + #if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) sha512_starts( &ctx->accumulator, 0 ); #else @@ -67,6 +71,9 @@ void entropy_init( entropy_context *ctx ) void entropy_free( entropy_context *ctx ) { ((void) ctx); +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &ctx->mutex ); +#endif } int entropy_add_source( entropy_context *ctx, @@ -175,16 +182,24 @@ int entropy_func( void *data, unsigned char *output, size_t len ) if( len > ENTROPY_BLOCK_SIZE ) return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + /* * Always gather extra entropy before a call */ do { if( count++ > ENTROPY_MAX_LOOP ) - return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + { + ret = POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + goto exit; + } if( ( ret = entropy_gather( ctx ) ) != 0 ) - return( ret ); + goto exit; reached = 0; @@ -231,7 +246,15 @@ int entropy_func( void *data, unsigned char *output, size_t len ) memcpy( output, buf, len ); - return( 0 ); + ret = 0; + +exit: +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); } #endif From 1337affc914d87e305fbec144643bcf73c7a48cc Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Sun, 29 Sep 2013 14:45:34 +0200 Subject: [PATCH 5/7] Buffer allocator threading support --- include/polarssl/memory.h | 7 +++++ library/memory_buffer_alloc.c | 46 ++++++++++++++++++++++++++++++--- programs/ssl/ssl_server2.c | 5 +++- programs/test/selftest.c | 3 +++ tests/suites/main_test.function | 9 ++++--- 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/include/polarssl/memory.h b/include/polarssl/memory.h index 567a64a16..6a3dab94b 100644 --- a/include/polarssl/memory.h +++ b/include/polarssl/memory.h @@ -71,6 +71,8 @@ int memory_set_own( void * (*malloc_func)( size_t ), * presented buffer and does not call malloc() and free(). * It sets the global polarssl_malloc() and polarssl_free() pointers * to its own functions. + * (Provided polarssl_malloc() and polarssl_free() are thread-safe if + * POLARSSL_THREADING_C is defined) * * \note This code is not optimized and provides a straight-forward * implementation of a stack-based memory allocator. @@ -82,6 +84,11 @@ int memory_set_own( void * (*malloc_func)( size_t ), */ int memory_buffer_alloc_init( unsigned char *buf, size_t len ); +/** + * \brief Free the mutex for thread-safety and clear remaining memory + */ +void memory_buffer_alloc_free(); + /** * \brief Determine when the allocator should automatically verify the state * of the entire chain of headers / meta-data. diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c index de2811fb2..7ec6498de 100644 --- a/library/memory_buffer_alloc.c +++ b/library/memory_buffer_alloc.c @@ -38,6 +38,10 @@ #endif #endif +#if defined(POLARSSL_THREADING_C) +#include "polarssl/threading.h" +#endif + #define MAGIC1 0xFF00AA55 #define MAGIC2 0xEE119966 #define MAX_BT 20 @@ -74,6 +78,9 @@ typedef struct size_t maximum_used; size_t header_count; #endif +#if defined(POLARSSL_THREADING_C) + threading_mutex_t mutex; +#endif } buffer_alloc_ctx; @@ -349,7 +356,6 @@ static void buffer_alloc_free( void *ptr ) memory_header *hdr, *old = NULL; unsigned char *p = (unsigned char *) ptr; - if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) return; @@ -492,14 +498,38 @@ void memory_buffer_alloc_status() } #endif /* POLARSSL_MEMORY_BUFFER_ALLOC_DEBUG */ +#if defined(POLARSSL_THREADING_C) +static void *buffer_alloc_malloc_mutexed( size_t len ) +{ + void *buf; + polarssl_mutex_lock( &heap.mutex ); + buf = buffer_alloc_malloc( len ); + polarssl_mutex_unlock( &heap.mutex ); + return( buf ); +} + +static void buffer_alloc_free_mutexed( void *ptr ) +{ + polarssl_mutex_lock( &heap.mutex ); + buffer_alloc_free( ptr ); + polarssl_mutex_unlock( &heap.mutex ); +} +#endif + int memory_buffer_alloc_init( unsigned char *buf, size_t len ) { - polarssl_malloc = buffer_alloc_malloc; - polarssl_free = buffer_alloc_free; - memset( &heap, 0, sizeof(buffer_alloc_ctx) ); memset( buf, 0, len ); +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &heap.mutex ); + polarssl_malloc = buffer_alloc_malloc_mutexed; + polarssl_free = buffer_alloc_free_mutexed; +#else + polarssl_malloc = buffer_alloc_malloc; + polarssl_free = buffer_alloc_free; +#endif + heap.buf = buf; heap.len = len; @@ -511,4 +541,12 @@ int memory_buffer_alloc_init( unsigned char *buf, size_t len ) return( 0 ); } +void memory_buffer_alloc_free() +{ +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &heap.mutex ); +#endif + memset( &heap, 0, sizeof(buffer_alloc_ctx) ); +} + #endif /* POLARSSL_MEMORY_C && POLARSSL_MEMORY_BUFFER_ALLOC_C */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index a6ff57fea..43d7d79b7 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -969,9 +969,12 @@ exit: ssl_cache_free( &cache ); #endif -#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) && defined(POLARSSL_MEMORY_DEBUG) +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) +#if defined(POLARSSL_MEMORY_DEBUG) memory_buffer_alloc_status(); #endif + memory_buffer_alloc_free(); +#endif #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 246276500..fb9a7cc72 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -190,6 +190,9 @@ int main( int argc, char *argv[] ) fflush( stdout ); getchar(); #endif } +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) + memory_buffer_alloc_free(); +#endif return( ret ); } diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function index d5aa3862c..c64d9be8a 100644 --- a/tests/suites/main_test.function +++ b/tests/suites/main_test.function @@ -202,8 +202,8 @@ int main() char *params[50]; #if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) - unsigned char buf[1000000]; - memory_buffer_alloc_init( buf, sizeof(buf) ); + unsigned char alloc_buf[1000000]; + memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); #endif file = fopen( filename, "r" ); @@ -288,9 +288,12 @@ int main() fprintf( stdout, " (%d / %d tests (%d skipped))\n", total_tests - total_errors, total_tests, total_skipped ); -#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) && defined(POLARSSL_MEMORY_DEBUG) +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) +#if defined(POLARSSL_MEMORY_DEBUG) memory_buffer_alloc_status(); #endif + memory_buffer_alloc_free(); +#endif return( total_errors != 0 ); } From c9965dca278becce5bac9a1d9996c8ecc7154d1d Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Sun, 29 Sep 2013 14:58:17 +0200 Subject: [PATCH 6/7] RSA blinding threading support --- include/polarssl/rsa.h | 7 +++++++ library/rsa.c | 20 +++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/polarssl/rsa.h b/include/polarssl/rsa.h index 71fbff2d8..e7b619159 100644 --- a/include/polarssl/rsa.h +++ b/include/polarssl/rsa.h @@ -32,6 +32,10 @@ #include "bignum.h" #include "md.h" +#if defined(POLARSSL_THREADING_C) +#include "threading.h" +#endif + /* * RSA Error codes */ @@ -100,6 +104,9 @@ typedef struct specified in the md.h header file for the EME-OAEP and EMSA-PSS encoding */ +#if defined(POLARSSL_THREADING_C) + threading_mutex_t mutex; /*!< Thread-safety mutex */ +#endif } rsa_context; diff --git a/library/rsa.c b/library/rsa.c index 42fea4182..1784379f3 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -54,6 +54,10 @@ void rsa_init( rsa_context *ctx, ctx->padding = padding; ctx->hash_id = hash_id; + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &ctx->mutex ); +#endif } #if defined(POLARSSL_GENPRIME) @@ -298,6 +302,9 @@ int rsa_private( rsa_context *ctx, unsigned char *output ) { int ret; +#if defined(POLARSSL_THREADING_C) + int locked = 0; +#endif size_t olen; mpi T, T1, T2; @@ -315,6 +322,10 @@ int rsa_private( rsa_context *ctx, #else if( f_rng != NULL ) { +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_lock( &ctx->mutex ); + locked = 1; +#endif /* * Blinding * T = T * Vi mod N @@ -361,7 +372,10 @@ int rsa_private( rsa_context *ctx, MPI_CHK( mpi_write_binary( &T, output, olen ) ); cleanup: - +#if defined(POLARSSL_THREADING_C) + if( locked ) + polarssl_mutex_unlock( &ctx->mutex ); +#endif mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 ); if( ret != 0 ) @@ -1330,6 +1344,10 @@ void rsa_free( rsa_context *ctx ) mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP ); mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D ); mpi_free( &ctx->E ); mpi_free( &ctx->N ); + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &ctx->mutex ); +#endif } #if defined(POLARSSL_SELF_TEST) From 6838bd1d737b6c3c4518e63543bf1e6a38113f55 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Mon, 30 Sep 2013 13:56:38 +0200 Subject: [PATCH 7/7] Clarified threading issues --- include/polarssl/config.h | 2 ++ include/polarssl/ecdsa.h | 1 + include/polarssl/ecp.h | 1 + include/polarssl/ssl.h | 1 + include/polarssl/threading.h | 4 +++- 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/polarssl/config.h b/include/polarssl/config.h index 4a9d0efd5..bd1234396 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -674,6 +674,8 @@ * \def POLARSSL_THREADING_DUMMY * * Provide a dummy threading implementation. + * Warning: If you use this, all claims of thread-safety in the documentation + * are void! * * Requires: POLARSSL_THREADING_C * diff --git a/include/polarssl/ecdsa.h b/include/polarssl/ecdsa.h index 2de3b68d7..4a29ac634 100644 --- a/include/polarssl/ecdsa.h +++ b/include/polarssl/ecdsa.h @@ -88,6 +88,7 @@ int ecdsa_verify( ecp_group *grp, /** * \brief Compute ECDSA signature and write it to buffer, * serialized as defined in RFC 4492 page 20. + * (Not thread-safe to use same context in multiple threads) * * \param ctx ECDSA context * \param hash Message hash diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h index 94618e769..dec4e0a68 100644 --- a/include/polarssl/ecp.h +++ b/include/polarssl/ecp.h @@ -450,6 +450,7 @@ int ecp_sub( const ecp_group *grp, ecp_point *R, /** * \brief Multiplication by an integer: R = m * P + * (Not thread-safe to use same group in multiple threads) * * \param grp ECP group * \param R Destination point diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index fb9a40c8b..cf18ea751 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -789,6 +789,7 @@ int ssl_get_ciphersuite_id( const char *ciphersuite_name ); /** * \brief Initialize an SSL context + * (An individual SSL context is not thread-safe) * * \param ssl SSL context * diff --git a/include/polarssl/threading.h b/include/polarssl/threading.h index 4afaeea39..ceb127798 100644 --- a/include/polarssl/threading.h +++ b/include/polarssl/threading.h @@ -56,7 +56,7 @@ typedef pthread_mutex_t threading_mutex_t; * \brief Set your alternate threading implementation function * pointers * - * \param mutex_init the malloc function implementation + * \param mutex_init the init function implementation * \param mutex_free the free function implementation * \param mutex_lock the lock function implementation * \param mutex_unlock the unlock function implementation @@ -71,6 +71,8 @@ int threading_set_alt( int (*mutex_init)( threading_mutex_t * ), /* * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock + * + * All these functions are expected to work or the result will be undefined. */ extern int (*polarssl_mutex_init)( threading_mutex_t *mutex ); extern int (*polarssl_mutex_free)( threading_mutex_t *mutex );