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)
|
||||
{
|
||||
word32 len;
|
||||
int ret;
|
||||
|
||||
if (!this->shared_secret.len)
|
||||
{
|
||||
this->shared_secret = chunk_alloc(this->len);
|
||||
if (wc_DhAgree(&this->dh, this->shared_secret.ptr, &len, this->priv.ptr,
|
||||
this->priv.len, this->other.ptr, this->other.len) != 0)
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
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");
|
||||
chunk_free(&this->shared_secret);
|
||||
@@ -132,6 +137,7 @@ METHOD(key_exchange_t, set_seed, bool,
|
||||
bool success = FALSE;
|
||||
chunk_t g;
|
||||
word32 len;
|
||||
int ret;
|
||||
|
||||
chunk_clear(&this->priv);
|
||||
this->priv = chunk_clone(value);
|
||||
@@ -140,8 +146,11 @@ METHOD(key_exchange_t, set_seed, bool,
|
||||
if (wolfssl_mp2chunk(&this->dh.g, &g))
|
||||
{
|
||||
len = this->pub.len;
|
||||
if (wc_DhAgree(&this->dh, this->pub.ptr, &len, this->priv.ptr,
|
||||
this->priv.len, g.ptr, g.len) == 0)
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
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;
|
||||
success = TRUE;
|
||||
@@ -220,6 +229,7 @@ static wolfssl_diffie_hellman_t *create_generic(key_exchange_method_t group,
|
||||
private_wolfssl_diffie_hellman_t *this;
|
||||
word32 privLen, pubLen;
|
||||
WC_RNG rng;
|
||||
int ret;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
@@ -262,8 +272,11 @@ static wolfssl_diffie_hellman_t *create_generic(key_exchange_method_t group,
|
||||
privLen = this->priv.len;
|
||||
pubLen = this->pub.len;
|
||||
/* generate my public and private values */
|
||||
if (wc_DhGenerateKeyPair(&this->dh, &rng, this->priv.ptr, &privLen,
|
||||
this->pub.ptr, &pubLen) != 0)
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_DhGenerateKeyPair(&this->dh, &rng, this->priv.ptr, &privLen,
|
||||
this->pub.ptr, &pubLen);
|
||||
PRIVATE_KEY_LOCK();
|
||||
if (ret != 0)
|
||||
{
|
||||
wc_FreeRng(&rng);
|
||||
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)
|
||||
{
|
||||
word32 len;
|
||||
int ret;
|
||||
#ifdef USE_RNG_FOR_TIMING_RESISTANCE
|
||||
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);
|
||||
len = this->shared_secret.len;
|
||||
|
||||
if (wc_ecc_shared_secret(&this->key, &this->pubkey, this->shared_secret.ptr,
|
||||
&len) != 0)
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
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");
|
||||
chunk_clear(&this->shared_secret);
|
||||
|
||||
@@ -82,22 +82,27 @@ METHOD(kdf_t, get_length, size_t,
|
||||
METHOD(kdf_t, get_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (this->type == KDF_PRF)
|
||||
{
|
||||
if (out_len != get_length(this) ||
|
||||
wc_HKDF_Extract(this->hash, this->salt.ptr, this->salt.len,
|
||||
this->key.ptr, this->key.len, buffer))
|
||||
if (out_len != get_length(this))
|
||||
{
|
||||
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,
|
||||
this->salt.ptr, this->salt.len, buffer, out_len))
|
||||
else
|
||||
{
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user