From: Juliusz Sosinowicz Date: Wed, 23 Apr 2025 14:32:52 +0000 (+0200) Subject: wolfssl: Unlock keys if necessary when using FIPS module X-Git-Tag: 6.0.2dr1~3^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f38bb91654769e9a5994975afb8322941bb741da;p=thirdparty%2Fstrongswan.git 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. --- diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c b/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c index b32b40e058..7591196068 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c @@ -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); diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c index 969099b790..94a92ff0bc 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c @@ -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); diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c b/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c index da06cab310..dd5a87d78b 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c @@ -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,