Merge branch 'wolfssl-fips'

Fixes various issues when building the wolfssl plugin against wolfSSL's
FIPS module.

References strongswan/strongswan#2603
Closes strongswan/strongswan#2771
This commit is contained in:
Tobias Brunner
2025-06-02 11:31:03 +02:00
8 changed files with 76 additions and 74 deletions
@@ -270,19 +270,16 @@ TEST_VECTOR_PRF(sha256_hmac_p2)
TEST_VECTOR_PRF(sha256_hmac_p3)
TEST_VECTOR_PRF(sha256_hmac_p4)
TEST_VECTOR_PRF(sha256_hmac_p5)
TEST_VECTOR_PRF(sha256_hmac_p6)
TEST_VECTOR_PRF(sha384_hmac_p1)
TEST_VECTOR_PRF(sha384_hmac_p2)
TEST_VECTOR_PRF(sha384_hmac_p3)
TEST_VECTOR_PRF(sha384_hmac_p4)
TEST_VECTOR_PRF(sha384_hmac_p5)
TEST_VECTOR_PRF(sha384_hmac_p6)
TEST_VECTOR_PRF(sha512_hmac_p1)
TEST_VECTOR_PRF(sha512_hmac_p2)
TEST_VECTOR_PRF(sha512_hmac_p3)
TEST_VECTOR_PRF(sha512_hmac_p4)
TEST_VECTOR_PRF(sha512_hmac_p5)
TEST_VECTOR_PRF(sha512_hmac_p6)
TEST_VECTOR_PRF(fips_prf_1)
TEST_VECTOR_XOF(shake_128_0)
@@ -17,7 +17,9 @@
#include <crypto/crypto_tester.h>
/**
* SHA-256, SHA384, SHA512 hmac test vectors from RFC 4868
* SHA-256, SHA384, SHA512 HMAC test vectors from RFC 4868, except the ones with
* key size 4, which are problematic for implementations that enforce a minimum
* key size (e.g. in FIPS mode).
*/
prf_test_vector_t sha256_hmac_p1 = {
.alg = PRF_HMAC_SHA2_256, .key_size = 20, .len = 8,
@@ -78,14 +80,6 @@ signer_test_vector_t sha512_hmac_s1 = {
"\x23\xda\x3e\x92\x43\x9e\x59\x0e\x43\xe7\x61\xb3\x3e\x91\x0f\xb8"
};
prf_test_vector_t sha256_hmac_p2 = {
.alg = PRF_HMAC_SHA2_256, .key_size = 4, .len = 28,
.key = "Jefe",
.seed = "what do ya want for nothing?",
.out = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7"
"\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43"
};
signer_test_vector_t sha256_hmac_s2 = {
.alg = AUTH_HMAC_SHA2_256_128, .len = 28,
.key = "JefeJefeJefeJefeJefeJefeJefeJefe",
@@ -93,15 +87,6 @@ signer_test_vector_t sha256_hmac_s2 = {
.mac = "\x16\x7f\x92\x85\x88\xc5\xcc\x2e\xef\x8e\x30\x93\xca\xa0\xe8\x7c"
};
prf_test_vector_t sha384_hmac_p2 = {
.alg = PRF_HMAC_SHA2_384, .key_size = 4, .len = 28,
.key = "Jefe",
.seed = "what do ya want for nothing?",
.out = "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
"\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
"\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49"
};
signer_test_vector_t sha384_hmac_s2 = {
.alg = AUTH_HMAC_SHA2_384_192, .len = 28,
.key = "JefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefe",
@@ -110,16 +95,6 @@ signer_test_vector_t sha384_hmac_s2 = {
"\xb2\x8c\x0b\x59\x4c\xfb\x18\x4d"
};
prf_test_vector_t sha512_hmac_p2 = {
.alg = PRF_HMAC_SHA2_512, .key_size = 4, .len = 28,
.key = "Jefe",
.seed = "what do ya want for nothing?",
.out = "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
"\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54"
"\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
"\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37"
};
signer_test_vector_t sha512_hmac_s2 = {
.alg = AUTH_HMAC_SHA2_512_256, .len = 28,
.key = "JefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefe",
@@ -128,7 +103,7 @@ signer_test_vector_t sha512_hmac_s2 = {
"\x1c\x17\x3b\x2a\x93\x62\xc1\x5d\xf2\x35\xdf\xb2\x51\xb1\x54\x54"
};
prf_test_vector_t sha256_hmac_p3 = {
prf_test_vector_t sha256_hmac_p2 = {
.alg = PRF_HMAC_SHA2_256, .key_size = 20, .len = 50,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa",
@@ -151,7 +126,7 @@ signer_test_vector_t sha256_hmac_s3 = {
.mac = "\xcd\xcb\x12\x20\xd1\xec\xcc\xea\x91\xe5\x3a\xba\x30\x92\xf9\x62"
};
prf_test_vector_t sha384_hmac_p3 = {
prf_test_vector_t sha384_hmac_p2 = {
.alg = PRF_HMAC_SHA2_384, .key_size = 20, .len = 50,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa",
@@ -177,7 +152,7 @@ signer_test_vector_t sha384_hmac_s3 = {
"\x55\x4a\x50\x81\x84\xa0\xc3\x16"
};
prf_test_vector_t sha512_hmac_p3 = {
prf_test_vector_t sha512_hmac_p2 = {
.alg = PRF_HMAC_SHA2_512, .key_size = 20, .len = 50,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa",
@@ -205,7 +180,7 @@ signer_test_vector_t sha512_hmac_s3 = {
"\xb9\xf9\xb0\x51\x0c\x87\xe4\x9e\x58\x6c\xc9\xbf\x96\x17\x33\xd8"
};
prf_test_vector_t sha256_hmac_p4 = {
prf_test_vector_t sha256_hmac_p3 = {
.alg = PRF_HMAC_SHA2_256, .key_size = 25, .len = 50,
.key = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
@@ -217,7 +192,7 @@ prf_test_vector_t sha256_hmac_p4 = {
"\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b"
};
prf_test_vector_t sha384_hmac_p4 = {
prf_test_vector_t sha384_hmac_p3 = {
.alg = PRF_HMAC_SHA2_384, .key_size = 25, .len = 50,
.key = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
@@ -230,7 +205,7 @@ prf_test_vector_t sha384_hmac_p4 = {
"\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb"
};
prf_test_vector_t sha512_hmac_p4 = {
prf_test_vector_t sha512_hmac_p3 = {
.alg = PRF_HMAC_SHA2_512, .key_size = 25, .len = 50,
.key = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
@@ -244,7 +219,7 @@ prf_test_vector_t sha512_hmac_p4 = {
"\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd"
};
prf_test_vector_t sha256_hmac_p5 = {
prf_test_vector_t sha256_hmac_p4 = {
.alg = PRF_HMAC_SHA2_256, .key_size = 131, .len = 54,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -260,7 +235,7 @@ prf_test_vector_t sha256_hmac_p5 = {
"\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54"
};
prf_test_vector_t sha384_hmac_p5 = {
prf_test_vector_t sha384_hmac_p4 = {
.alg = PRF_HMAC_SHA2_384, .key_size = 131, .len = 54,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -277,7 +252,7 @@ prf_test_vector_t sha384_hmac_p5 = {
"\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52"
};
prf_test_vector_t sha512_hmac_p5 = {
prf_test_vector_t sha512_hmac_p4 = {
.alg = PRF_HMAC_SHA2_512, .key_size = 131, .len = 54,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -295,7 +270,7 @@ prf_test_vector_t sha512_hmac_p5 = {
"\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98"
};
prf_test_vector_t sha256_hmac_p6 = {
prf_test_vector_t sha256_hmac_p5 = {
.alg = PRF_HMAC_SHA2_256, .key_size = 131, .len = 152,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -313,7 +288,7 @@ prf_test_vector_t sha256_hmac_p6 = {
"\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2"
};
prf_test_vector_t sha384_hmac_p6 = {
prf_test_vector_t sha384_hmac_p5 = {
.alg = PRF_HMAC_SHA2_384, .key_size = 131, .len = 152,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -332,7 +307,7 @@ prf_test_vector_t sha384_hmac_p6 = {
"\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e"
};
prf_test_vector_t sha512_hmac_p6 = {
prf_test_vector_t sha512_hmac_p5 = {
.alg = PRF_HMAC_SHA2_512, .key_size = 131, .len = 152,
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -50,6 +50,7 @@
#ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
/* Disable inclusion of the wolfSSL OpenSSL compatibility layer header (if
* configured) as it is not used by the plugin and causes conflicts */
@@ -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);
@@ -339,9 +339,16 @@ static private_wolfssl_ec_private_key_t *create_empty(void)
.ref = 1,
);
if (wc_InitRng(&this->rng) < 0)
if (wc_ecc_init(&this->ec) != 0)
{
DBG1(DBG_LIB, "RNG init failed");
DBG1(DBG_LIB, "EC private key initialization failed");
free(this);
return NULL;
}
if (wc_InitRng(&this->rng) != 0)
{
DBG1(DBG_LIB, "RNG initialization for EC private key failed");
wc_ecc_free(&this->ec);
free(this);
return NULL;
}
@@ -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,
@@ -156,6 +161,7 @@ kdf_t *wolfssl_kdf_create(key_derivation_function_t algo, va_list args)
pseudo_random_function_t prf_alg;
enum wc_HashType hash;
char buf[HASH_SIZE_SHA512];
chunk_t dummy_key = chunk_create(buf, sizeof(buf));
if (algo != KDF_PRF && algo != KDF_PRF_PLUS)
{
@@ -179,9 +185,11 @@ kdf_t *wolfssl_kdf_create(key_derivation_function_t algo, va_list args)
},
.type = algo,
.hash = hash,
.key = chunk_clone(dummy_key),
);
/* test if we can actually use the algorithm */
/* test if we can actually use the algorithm (using a long dummy key in
* case FIPS mode is used) */
if (!get_bytes(this, algo == KDF_PRF ? get_length(this) : sizeof(buf), buf))
{
destroy(this);
@@ -408,22 +408,13 @@ METHOD(plugin_t, get_features, int,
#endif /* !WC_NO_RSA_OAEP */
#endif /* !NO_RSA */
#ifdef HAVE_ECC
#ifdef HAVE_ECC_KEY_IMPORT
#ifdef HAVE_ECC_SIGN
/* EC private/public key loading */
PLUGIN_REGISTER(PRIVKEY, wolfssl_ec_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
#endif
#ifdef HAVE_ECC_DHE
PLUGIN_REGISTER(PRIVKEY_GEN, wolfssl_ec_private_key_gen, FALSE),
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA),
#endif
#ifdef HAVE_ECC_KEY_IMPORT
PLUGIN_REGISTER(PUBKEY, wolfssl_ec_public_key_load, TRUE),
PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
#endif
#ifdef HAVE_ECC_SIGN
/* signature encryption schemes */
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL),
#ifndef NO_SHA
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA1_DER),
@@ -440,9 +431,10 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA512_DER),
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_521),
#endif
#endif /* HAVE_ECC_SIGN */
#endif
#ifdef HAVE_ECC_VERIFY
/* signature encryption schemes */
PLUGIN_REGISTER(PUBKEY, wolfssl_ec_public_key_load, TRUE),
PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL),
#ifndef NO_SHA
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA1_DER),
@@ -547,6 +539,11 @@ plugin_t *wolfssl_plugin_create()
fips_mode = lib->settings->get_bool(lib->settings,
"%s.plugins.wolfssl.fips_mode", FALSE, lib->ns);
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
#ifdef HAVE_FIPS
if (fips_mode)
{