wolfssl: Unlock keys if necessary when using FIPS module
Wrap the functions that require it in PRIVATE_KEY_UNLOCK/PRIVATE_KEY_LOCK. This can't be done at plugin initialization because it needs to be done for every thread. strongSwan currently doesn't provide on-thread-create callbacks for plugins so we need to wrap each direct call. Another reason to do so is that some functions we call (e.g. wc_EccKeyToDer) internally call PRIVATE_KEY_UNLOCK/PRIVATE_KEY_LOCK and would leave the keys locked for that particular thread.
This commit is contained in:
committed by
Tobias Brunner
parent
85eb5c7812
commit
f38bb91654
@@ -90,12 +90,17 @@ METHOD(key_exchange_t, get_shared_secret, bool,
|
|||||||
private_wolfssl_diffie_hellman_t *this, chunk_t *secret)
|
private_wolfssl_diffie_hellman_t *this, chunk_t *secret)
|
||||||
{
|
{
|
||||||
word32 len;
|
word32 len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!this->shared_secret.len)
|
if (!this->shared_secret.len)
|
||||||
{
|
{
|
||||||
this->shared_secret = chunk_alloc(this->len);
|
this->shared_secret = chunk_alloc(this->len);
|
||||||
if (wc_DhAgree(&this->dh, this->shared_secret.ptr, &len, this->priv.ptr,
|
PRIVATE_KEY_UNLOCK();
|
||||||
this->priv.len, this->other.ptr, this->other.len) != 0)
|
ret = wc_DhAgree(&this->dh, this->shared_secret.ptr, &len,
|
||||||
|
this->priv.ptr, this->priv.len, this->other.ptr,
|
||||||
|
this->other.len);
|
||||||
|
PRIVATE_KEY_LOCK();
|
||||||
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "DH shared secret computation failed");
|
DBG1(DBG_LIB, "DH shared secret computation failed");
|
||||||
chunk_free(&this->shared_secret);
|
chunk_free(&this->shared_secret);
|
||||||
@@ -132,6 +137,7 @@ METHOD(key_exchange_t, set_seed, bool,
|
|||||||
bool success = FALSE;
|
bool success = FALSE;
|
||||||
chunk_t g;
|
chunk_t g;
|
||||||
word32 len;
|
word32 len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
chunk_clear(&this->priv);
|
chunk_clear(&this->priv);
|
||||||
this->priv = chunk_clone(value);
|
this->priv = chunk_clone(value);
|
||||||
@@ -140,8 +146,11 @@ METHOD(key_exchange_t, set_seed, bool,
|
|||||||
if (wolfssl_mp2chunk(&this->dh.g, &g))
|
if (wolfssl_mp2chunk(&this->dh.g, &g))
|
||||||
{
|
{
|
||||||
len = this->pub.len;
|
len = this->pub.len;
|
||||||
if (wc_DhAgree(&this->dh, this->pub.ptr, &len, this->priv.ptr,
|
PRIVATE_KEY_UNLOCK();
|
||||||
this->priv.len, g.ptr, g.len) == 0)
|
ret = wc_DhAgree(&this->dh, this->pub.ptr, &len, this->priv.ptr,
|
||||||
|
this->priv.len, g.ptr, g.len);
|
||||||
|
PRIVATE_KEY_LOCK();
|
||||||
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
this->pub.len = len;
|
this->pub.len = len;
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
@@ -220,6 +229,7 @@ static wolfssl_diffie_hellman_t *create_generic(key_exchange_method_t group,
|
|||||||
private_wolfssl_diffie_hellman_t *this;
|
private_wolfssl_diffie_hellman_t *this;
|
||||||
word32 privLen, pubLen;
|
word32 privLen, pubLen;
|
||||||
WC_RNG rng;
|
WC_RNG rng;
|
||||||
|
int ret;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
@@ -262,8 +272,11 @@ static wolfssl_diffie_hellman_t *create_generic(key_exchange_method_t group,
|
|||||||
privLen = this->priv.len;
|
privLen = this->priv.len;
|
||||||
pubLen = this->pub.len;
|
pubLen = this->pub.len;
|
||||||
/* generate my public and private values */
|
/* generate my public and private values */
|
||||||
if (wc_DhGenerateKeyPair(&this->dh, &rng, this->priv.ptr, &privLen,
|
PRIVATE_KEY_UNLOCK();
|
||||||
this->pub.ptr, &pubLen) != 0)
|
ret = wc_DhGenerateKeyPair(&this->dh, &rng, this->priv.ptr, &privLen,
|
||||||
|
this->pub.ptr, &pubLen);
|
||||||
|
PRIVATE_KEY_LOCK();
|
||||||
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
wc_FreeRng(&rng);
|
wc_FreeRng(&rng);
|
||||||
destroy(this);
|
destroy(this);
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ METHOD(key_exchange_t, set_seed, bool,
|
|||||||
static bool compute_shared_key(private_wolfssl_ec_diffie_hellman_t *this)
|
static bool compute_shared_key(private_wolfssl_ec_diffie_hellman_t *this)
|
||||||
{
|
{
|
||||||
word32 len;
|
word32 len;
|
||||||
|
int ret;
|
||||||
#ifdef USE_RNG_FOR_TIMING_RESISTANCE
|
#ifdef USE_RNG_FOR_TIMING_RESISTANCE
|
||||||
WC_RNG rng;
|
WC_RNG rng;
|
||||||
|
|
||||||
@@ -237,8 +238,11 @@ static bool compute_shared_key(private_wolfssl_ec_diffie_hellman_t *this)
|
|||||||
this->shared_secret = chunk_alloc(this->keysize);
|
this->shared_secret = chunk_alloc(this->keysize);
|
||||||
len = this->shared_secret.len;
|
len = this->shared_secret.len;
|
||||||
|
|
||||||
if (wc_ecc_shared_secret(&this->key, &this->pubkey, this->shared_secret.ptr,
|
PRIVATE_KEY_UNLOCK();
|
||||||
&len) != 0)
|
ret = wc_ecc_shared_secret(&this->key, &this->pubkey,
|
||||||
|
this->shared_secret.ptr, &len);
|
||||||
|
PRIVATE_KEY_LOCK();
|
||||||
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "ECDH shared secret computation failed");
|
DBG1(DBG_LIB, "ECDH shared secret computation failed");
|
||||||
chunk_clear(&this->shared_secret);
|
chunk_clear(&this->shared_secret);
|
||||||
|
|||||||
@@ -82,22 +82,27 @@ METHOD(kdf_t, get_length, size_t,
|
|||||||
METHOD(kdf_t, get_bytes, bool,
|
METHOD(kdf_t, get_bytes, bool,
|
||||||
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (this->type == KDF_PRF)
|
if (this->type == KDF_PRF)
|
||||||
{
|
{
|
||||||
if (out_len != get_length(this) ||
|
if (out_len != get_length(this))
|
||||||
wc_HKDF_Extract(this->hash, this->salt.ptr, this->salt.len,
|
|
||||||
this->key.ptr, this->key.len, buffer))
|
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
PRIVATE_KEY_UNLOCK();
|
||||||
|
ret = wc_HKDF_Extract(this->hash, this->salt.ptr, this->salt.len,
|
||||||
|
this->key.ptr, this->key.len, buffer);
|
||||||
|
PRIVATE_KEY_LOCK();
|
||||||
}
|
}
|
||||||
if (wc_HKDF_Expand(this->hash, this->key.ptr, this->key.len,
|
else
|
||||||
this->salt.ptr, this->salt.len, buffer, out_len))
|
|
||||||
{
|
{
|
||||||
return FALSE;
|
PRIVATE_KEY_UNLOCK();
|
||||||
|
ret = wc_HKDF_Expand(this->hash, this->key.ptr, this->key.len,
|
||||||
|
this->salt.ptr, this->salt.len, buffer, out_len);
|
||||||
|
PRIVATE_KEY_LOCK();
|
||||||
}
|
}
|
||||||
return TRUE;
|
return ret == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kdf_t, allocate_bytes, bool,
|
METHOD(kdf_t, allocate_bytes, bool,
|
||||||
|
|||||||
Reference in New Issue
Block a user