allow single threaded mode to share an RNG at WOLFSSL_CTX level

This commit is contained in:
toddouska
2016-09-16 13:35:29 -07:00
parent ef0cd908ea
commit f191cf206e
5 changed files with 91 additions and 24 deletions

View File

@ -1084,6 +1084,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
if (ctx == NULL) if (ctx == NULL)
err_sys("unable to get ctx"); err_sys("unable to get ctx");
#ifdef SINGLE_THREADED
if (wolfSSL_CTX_new_rng(ctx) != SSL_SUCCESS) {
err_sys("Single Threaded new rng at CTX failed");
}
#endif
if (cipherList) { if (cipherList) {
if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
err_sys("client can't set cipher list 1"); err_sys("client can't set cipher list 1");

View File

@ -1449,6 +1449,13 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH); XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
#endif #endif
#ifdef SINGLE_THREADED
if (ctx->rng) {
wc_FreeRng(ctx->rng);
XFREE(ctx->rng, ctx->heap, DYNAMIC_TYPE_RNG);
}
#endif
#ifndef NO_CERTS #ifndef NO_CERTS
FreeDer(&ctx->privateKey); FreeDer(&ctx->privateKey);
FreeDer(&ctx->certificate); FreeDer(&ctx->certificate);
@ -3475,26 +3482,33 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
} }
#endif #endif
/* RNG */ #ifdef SINGLE_THREADED
ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap, DYNAMIC_TYPE_RNG); ssl->rng = ctx->rng; /* CTX may have one, if so use it */
if (ssl->rng == NULL) {
WOLFSSL_MSG("RNG Memory error");
return MEMORY_E;
}
/* FIPS RNG API does not accept a heap hint */
#ifndef HAVE_FIPS
if ( (ret = wc_InitRng_ex(ssl->rng, ssl->heap)) != 0) {
WOLFSSL_MSG("RNG Init error");
return ret;
}
#else
if ( (ret = wc_InitRng(ssl->rng)) != 0) {
WOLFSSL_MSG("RNG Init error");
return ret;
}
#endif #endif
if (ssl->rng == NULL) {
/* RNG */
ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap,DYNAMIC_TYPE_RNG);
if (ssl->rng == NULL) {
WOLFSSL_MSG("RNG Memory error");
return MEMORY_E;
}
ssl->options.weOwnRng = 1;
/* FIPS RNG API does not accept a heap hint */
#ifndef HAVE_FIPS
if ( (ret = wc_InitRng_ex(ssl->rng, ssl->heap)) != 0) {
WOLFSSL_MSG("RNG Init error");
return ret;
}
#else
if ( (ret = wc_InitRng(ssl->rng)) != 0) {
WOLFSSL_MSG("RNG Init error");
return ret;
}
#endif
}
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER) #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) { if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0); ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
@ -3591,8 +3605,10 @@ void SSL_ResourceFree(WOLFSSL* ssl)
FreeCiphers(ssl); FreeCiphers(ssl);
FreeArrays(ssl, 0); FreeArrays(ssl, 0);
FreeKeyExchange(ssl); FreeKeyExchange(ssl);
wc_FreeRng(ssl->rng); if (ssl->options.weOwnRng) {
XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG); wc_FreeRng(ssl->rng);
XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
}
XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES); XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES); XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN); XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
@ -3783,9 +3799,12 @@ void FreeHandshakeResources(WOLFSSL* ssl)
/* RNG */ /* RNG */
if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) { if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
wc_FreeRng(ssl->rng); if (ssl->options.weOwnRng) {
XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG); wc_FreeRng(ssl->rng);
ssl->rng = NULL; XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
ssl->rng = NULL;
ssl->options.weOwnRng = 0;
}
} }
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS

View File

@ -2323,6 +2323,39 @@ int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
} }
#ifdef SINGLE_THREADED
/* no locking in single threaded mode, allow a CTX level rng to be shared with
* WOLFSSL objects, SSL_SUCCESS on ok */
int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
{
WC_RNG* rng;
int ret;
if (ctx == NULL) {
return BAD_FUNC_ARG;
}
rng = XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
if (rng == NULL) {
return MEMORY_E;
}
#ifndef HAVE_FIPS
ret = wc_InitRng_ex(rng, ctx->heap);
#else
ret = wc_InitRng(rng);
#endif
if (ret != 0) {
XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
return ret;
}
ctx->rng = rng;
return SSL_SUCCESS;
}
#endif
#ifdef WOLFSSL_TRUST_PEER_CERT #ifdef WOLFSSL_TRUST_PEER_CERT
int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm) int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
{ {

View File

@ -1902,7 +1902,10 @@ WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name);
/* wolfSSL context type */ /* wolfSSL context type */
struct WOLFSSL_CTX { struct WOLFSSL_CTX {
WOLFSSL_METHOD* method; WOLFSSL_METHOD* method;
wolfSSL_Mutex countMutex; /* reference count mutex */ #ifdef SINGLE_THREADED
WC_RNG* rng; /* to be shared with WOLFSSL w/o locking */
#endif
wolfSSL_Mutex countMutex; /* reference count mutex */
int refCount; /* reference count */ int refCount; /* reference count */
int err; /* error code in case of mutex not created */ int err; /* error code in case of mutex not created */
#ifndef NO_DH #ifndef NO_DH
@ -2396,6 +2399,7 @@ typedef struct Options {
word16 usingNonblock:1; /* are we using nonblocking socket */ word16 usingNonblock:1; /* are we using nonblocking socket */
word16 saveArrays:1; /* save array Memory for user get keys word16 saveArrays:1; /* save array Memory for user get keys
or psk */ or psk */
word16 weOwnRng:1; /* will be true unless CTX owns */
#ifdef HAVE_POLY1305 #ifdef HAVE_POLY1305
word16 oldPoly:1; /* set when to use old rfc way of poly*/ word16 oldPoly:1; /* set when to use old rfc way of poly*/
#endif #endif

View File

@ -1418,6 +1418,11 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX*); WOLFSSL_API int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX*);
#endif /* !NO_CERTS */ #endif /* !NO_CERTS */
#ifdef SINGLE_THREADED
WOLFSSL_API int wolfSSL_CTX_new_rng(WOLFSSL_CTX*);
#endif
/* end of handshake frees temporary arrays, if user needs for get_keys or /* end of handshake frees temporary arrays, if user needs for get_keys or
psk hints, call KeepArrays before handshake and then FreeArrays when done psk hints, call KeepArrays before handshake and then FreeArrays when done
if don't want to wait for object free */ if don't want to wait for object free */