Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions wolfssl-gnutls-wrapper/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ endif
UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Linux)
CFLAGS += -DENABLE_WOLFSSL -fPIC -Wall -Wextra
CFLAGS += -DENABLE_WOLFSSL -fPIC -Wall -Wextra -pthread
CFLAGS_DEBUG += -g
# Use rpath to wherever we actually link from
LDFLAGS += -Wl,--no-as-needed -Wl,-z,now \
-Wl,-rpath,$(GNUTLS_LIBDIR) -Wl,-rpath,$(WOLFSSL_LIBDIR)
SOFLAG := -shared
DL_LIBS := -ldl
DL_LIBS := -ldl -pthread
endif

ifeq ($(UNAME_S),Darwin)
Expand Down
47 changes: 32 additions & 15 deletions wolfssl-gnutls-wrapper/src/pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,10 @@ static int wolfssl_pk_encrypt_rsa(gnutls_datum_t *ciphertext,
}

/* Encrypt using RSA PKCS#1 v1.5 padding */
wolfssl_rng_lock();
ret = wc_RsaPublicEncrypt(plaintext->data, plaintext->size,
ciphertext->data, ciphertext->size, &rsa, &priv_rng);
wolfssl_rng_unlock();
/* No longer need RSA key. */
wc_FreeRsaKey(&rsa);
if (ret < 0) {
Expand Down Expand Up @@ -808,10 +810,12 @@ static int wolfssl_pk_encrypt_rsa_oaep(gnutls_datum_t *ciphertext,
}

/* Encrypt using RSA PKCS#1 OAEP. */
wolfssl_rng_lock();
ret = wc_RsaPublicEncrypt_ex(plaintext->data, plaintext->size,
ciphertext->data, ciphertext->size, &rsa, &priv_rng, WC_RSA_OAEP_PAD,
hash_type, mgf, params->spki.rsa_oaep_label.data,
params->spki.rsa_oaep_label.size);
wolfssl_rng_unlock();
/* No longer need RSA key. */
wc_FreeRsaKey(&rsa);
if (ret < 0) {
Expand Down Expand Up @@ -962,8 +966,10 @@ static int wolfssl_pk_decrypt_rsa(gnutls_datum_t *plaintext,
PRIVATE_KEY_UNLOCK();

/* Decrypt using RSA PKCS#1 v1.5 padding */
wolfssl_rng_lock();
ret = wc_RsaPrivateDecrypt(ciphertext->data, ciphertext->size, plain,
plain_size, &rsa);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -1076,9 +1082,11 @@ static int wolfssl_pk_decrypt_rsa_oaep(gnutls_datum_t *plaintext,
PRIVATE_KEY_UNLOCK();

/* Decrypt using RSA PKCS#1 OAEP. */
wolfssl_rng_lock();
ret = wc_RsaPrivateDecrypt_ex(ciphertext->data, ciphertext->size,
plain, plain_size, &rsa, WC_RSA_OAEP_PAD, hash_type, mgf,
params->spki.rsa_oaep_label.data, params->spki.rsa_oaep_label.size);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -1275,8 +1283,10 @@ static int wolfssl_pk_sign_rsa(gnutls_datum_t *signature,
PRIVATE_KEY_UNLOCK();

/* Decrypt using RSA PKCS#1 v1.5. */
wolfssl_rng_lock();
ret = wc_RsaSSL_Sign(vdata->data, vdata->size, signature->data,
signature->size, &rsa, &priv_rng);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -1352,9 +1362,11 @@ static int wolfssl_pk_sign_rsa_pss(gnutls_datum_t *signature,
PRIVATE_KEY_UNLOCK();

/* Decrypt using RSA PKCS#1 PSS. */
wolfssl_rng_lock();
ret = wc_RsaPSS_Sign_ex(vdata->data, vdata->size, signature->data,
signature->size, hash_type, mgf, sign_params->salt_size, &rsa,
&priv_rng);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -1436,8 +1448,10 @@ static int wolfssl_pk_sign_ecc(gnutls_datum_t *signature,
PRIVATE_KEY_UNLOCK();

/* Sign hash using ECDSA. */
wolfssl_rng_lock();
ret = wc_ecc_sign_hash(vdata->data, vdata->size, signature->data, &len,
&priv_rng, &ecc);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -2487,11 +2501,6 @@ static int wolfssl_pk_generate_keys_rsa(unsigned int bits,
}
#endif

#ifdef WC_RNG_SEED_CB
/* Set the seed callback to get entropy. */
wc_SetSeed_Cb(wc_GenerateSeed);
#endif

/* Initialize RSA key */
ret = wc_InitRsaKey(&rsa, NULL);
if (ret != 0) {
Expand All @@ -2502,7 +2511,9 @@ static int wolfssl_pk_generate_keys_rsa(unsigned int bits,
PRIVATE_KEY_UNLOCK();

/* Generate RSA key */
wolfssl_rng_lock();
ret = wc_MakeRsaKey(&rsa, bits, WC_RSA_EXPONENT, &priv_rng);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -2549,11 +2560,6 @@ static int wolfssl_pk_generate_keys_dh(unsigned int bits,
if (wolfssl_ensure_rng() != 0)
return GNUTLS_E_RANDOM_FAILED;

#ifdef WC_RNG_SEED_CB
/* Set the seed callback to get entropy. */
wc_SetSeed_Cb(wc_GenerateSeed);
#endif

/* Convert private key size to public key size. */
if (bits == 256) {
bits = 2048;
Expand Down Expand Up @@ -2610,7 +2616,9 @@ static int wolfssl_pk_generate_keys_dh(unsigned int bits,
PRIVATE_KEY_UNLOCK();

/* Generate public/private key pair for DH. */
wolfssl_rng_lock();
ret = wc_DhGenerateKeyPair(&dh, &priv_rng, priv, &privSz, pub, &pubSz);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -2673,11 +2681,6 @@ static int wolfssl_pk_generate_keys_ecc(unsigned int curve,
return ret;
}

#ifdef WC_RNG_SEED_CB
/* Set the seed callback to get entropy. */
wc_SetSeed_Cb(wc_GenerateSeed);
#endif

/* Initialize ECC key */
ret = wc_ecc_init(&ecc);
if (ret != 0) {
Expand All @@ -2688,7 +2691,9 @@ static int wolfssl_pk_generate_keys_ecc(unsigned int curve,
PRIVATE_KEY_UNLOCK();

/* Generate ECC key */
wolfssl_rng_lock();
ret = wc_ecc_make_key_ex(&priv_rng, curve_size, &ecc, curve_id);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -2749,7 +2754,9 @@ static int wolfssl_pk_generate_keys_ed25519(unsigned int curve,
PRIVATE_KEY_UNLOCK();

/* Generate Ed25519 key */
wolfssl_rng_lock();
ret = wc_ed25519_make_key(&priv_rng, ED25519_KEY_SIZE, &ed25519);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -2851,7 +2858,9 @@ static int wolfssl_pk_generate_keys_ed448(unsigned int curve,
PRIVATE_KEY_UNLOCK();

/* Generate Ed448 key */
wolfssl_rng_lock();
ret = wc_ed448_make_key(&priv_rng, ED448_KEY_SIZE, &ed448);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -2953,7 +2962,9 @@ static int wolfssl_pk_generate_keys_x25519(unsigned int curve,
PRIVATE_KEY_UNLOCK();

/* Generate X25519 key */
wolfssl_rng_lock();
ret = wc_curve25519_make_key(&priv_rng, CURVE25519_KEYSIZE, &x25519);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -3055,7 +3066,9 @@ static int wolfssl_pk_generate_keys_x448(unsigned int curve,
PRIVATE_KEY_UNLOCK();

/* Generate X448 key */
wolfssl_rng_lock();
ret = wc_curve448_make_key(&priv_rng, CURVE448_KEY_SIZE, &x448);
wolfssl_rng_unlock();

/* Random number generator no longer needed. */
PRIVATE_KEY_LOCK();
Expand Down Expand Up @@ -4117,7 +4130,9 @@ static int wolfssl_pk_derive_ecc(gnutls_datum_t *out,
PRIVATE_KEY_UNLOCK();

/* Calculate the shared secret. */
wolfssl_rng_lock();
ret = wc_ecc_shared_secret(&private, &public, out->data, &len);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down Expand Up @@ -4246,8 +4261,10 @@ static int wolfssl_pk_derive_x25519(gnutls_datum_t *out,
PRIVATE_KEY_UNLOCK();

/* Calculate the shared secret. */
wolfssl_rng_lock();
ret = wc_curve25519_shared_secret_ex(&private, &public, out->data, &len,
EC25519_LITTLE_ENDIAN);
wolfssl_rng_unlock();

PRIVATE_KEY_LOCK();

Expand Down
57 changes: 40 additions & 17 deletions wolfssl-gnutls-wrapper/src/random.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/wc_port.h>
#include <pthread.h>

#ifdef ENABLE_WOLFSSL
/** Context structure for wolfSSL RNG. */
Expand All @@ -24,19 +25,36 @@ pid_t pid = -1;
/** Indicates if the DBRG needs to be reseeded.*/
int rng_ready = 0;

/** Ensures that only one process at the time is accessing the RNGs objects */
/** Serializes all use of the RNG objects above. A WC_RNG is not thread safe
* unless wolfSSL locks it itself (5.9.4 and later, unless built with
* --disable-rng-autolock). */
static wolfSSL_Mutex wc_rng_lock;
/** indicates that the rng lock object was actually initialized */
static int wc_rng_lock_init = 0;
/** Initializes wc_rng_lock exactly once, whichever thread gets there first. */
static pthread_once_t wc_rng_lock_once = PTHREAD_ONCE_INIT;

/** Gets called every time we need to do a lock operation,
* initializes the lock object if it wasn't already. */
static inline void wc_rng_lock_once(void)
static void wc_rng_lock_init(void)
{
if (!wc_rng_lock_init) {
wc_InitMutex(&wc_rng_lock);
wc_rng_lock_init = 1;
}
wc_InitMutex(&wc_rng_lock);
}

/**
* Take the lock that guards priv_rng and pub_rng.
*
* Hold it across every wolfCrypt call that uses one of them, including calls
* on a key that keeps a pointer to one (wc_RsaSetRNG(), ecc_key.rng,
* wc_curve25519_set_rng()). Not recursive: do not call wolfssl_ensure_rng()
* while holding it.
*/
void wolfssl_rng_lock(void)
{
pthread_once(&wc_rng_lock_once, wc_rng_lock_init);
wc_LockMutex(&wc_rng_lock);
}

/** Release the lock taken by wolfssl_rng_lock(). */
void wolfssl_rng_unlock(void)
{
wc_UnLockMutex(&wc_rng_lock);
}

/* Seed DRBGs on first use or after a fork */
Expand All @@ -46,8 +64,7 @@ int wolfssl_ensure_rng(void)

pid_t p = getpid();

wc_rng_lock_once();
wc_LockMutex(&wc_rng_lock);
wolfssl_rng_lock();

/* We check if the pid is different (a fork happened)
* or if the the first time creating a context (a first seed is needed). */
Expand All @@ -58,26 +75,31 @@ int wolfssl_ensure_rng(void)
* do a reseed. */
wc_FreeRng(&priv_rng);
wc_FreeRng(&pub_rng);
/* not ready until both are re-initialized: a failed reseed
* must not leave freed DRBGs marked usable */
rng_ready = 0;
}

#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif

if (wc_InitRng(&priv_rng) != 0) {
wolfssl_rng_unlock();
return GNUTLS_E_RANDOM_FAILED;
}

if (wc_InitRng(&pub_rng) != 0) {
wc_FreeRng(&priv_rng);
wolfssl_rng_unlock();
return GNUTLS_E_RANDOM_FAILED;
}

pid = p;
rng_ready = 1;
}

wc_UnLockMutex(&wc_rng_lock);
wolfssl_rng_unlock();

return 0;
}
Expand Down Expand Up @@ -142,8 +164,7 @@ static int wolfssl_rnd(void *_ctx, int level, void *data, size_t datasize)
return GNUTLS_E_RANDOM_FAILED;
}

wc_rng_lock_once();
wc_LockMutex(&wc_rng_lock);
wolfssl_rng_lock();

/* clear output buffer before filling */
XMEMSET(data, 0, datasize);
Expand All @@ -154,7 +175,7 @@ static int wolfssl_rnd(void *_ctx, int level, void *data, size_t datasize)

ret = wc_RNG_GenerateBlock(rng, data, size);
if (ret != 0) {
wc_UnLockMutex(&wc_rng_lock);
wolfssl_rng_unlock();
WGW_ERROR("Requested %d bytes", size);
WGW_WOLFSSL_ERROR("wc_RNG_GenerateBlock", ret);
return GNUTLS_E_RANDOM_FAILED;
Expand All @@ -165,7 +186,7 @@ static int wolfssl_rnd(void *_ctx, int level, void *data, size_t datasize)
datasize -= size;
} while (datasize > 0);

wc_UnLockMutex(&wc_rng_lock);
wolfssl_rng_unlock();

return 0;
}
Expand All @@ -183,7 +204,9 @@ static void wolfssl_rnd_refresh(void *_ctx)

/* this forces a reseed of the random number generators
* on the next call (wolfssl_ensure_rng). */
wolfssl_rng_lock();
rng_ready = 0;
wolfssl_rng_unlock();
}

/**
Expand Down
2 changes: 2 additions & 0 deletions wolfssl-gnutls-wrapper/src/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ extern WC_RNG pub_rng;
extern pid_t pid;
extern int rng_ready;
int wolfssl_ensure_rng(void);
void wolfssl_rng_lock(void);
void wolfssl_rng_unlock(void);
#endif
6 changes: 3 additions & 3 deletions wolfssl-gnutls-wrapper/tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
TESTS = test_hash test_shake test_aescbc test_aescfb8 test_aesgcm test_aesccm test_aesxts test_hmac test_cmac test_gmac test_rnd test_rnd_fork test_tls_prf test_hkdf test_pbkdf2 test_ecdsa_sign_and_verify test_ecdh_encrypt_and_decrypt test_eddsa_sign_and_verify test_rsa_sign_and_verify test_rsa_encrypt_and_decrypt test_dh_encrypt_and_decrypt test_pk_import_export test_long_hash test_fips test_aessiv
TESTS = test_hash test_shake test_aescbc test_aescfb8 test_aesgcm test_aesccm test_aesxts test_hmac test_cmac test_gmac test_rnd test_rnd_fork test_tls_prf test_hkdf test_pbkdf2 test_ecdsa_sign_and_verify test_ecdh_encrypt_and_decrypt test_eddsa_sign_and_verify test_rsa_sign_and_verify test_rsa_encrypt_and_decrypt test_dh_encrypt_and_decrypt test_pk_import_export test_long_hash test_fips test_aessiv test_pk_threads

PKGCONF ?= pkg-config
UNAME_S := $(shell uname -s)
Expand Down Expand Up @@ -62,9 +62,9 @@ ifeq ($(UNAME_S),Darwin)
-L$(GNUTLS_LIBDIR)
endif

# Libraries (dl only on Linux)
# Libraries (dl and pthread only on Linux)
ifeq ($(UNAME_S),Linux)
LIBS = $(GNUTLS_LIBS) -ldl
LIBS = $(GNUTLS_LIBS) -ldl -pthread
else
LIBS = $(GNUTLS_LIBS)
endif
Expand Down
Loading
Loading