Merge branch 'ikev2-kdf-modularization'
This modularizes the IKEv2 key derivation, which makes certification (e.g. FIPS) easier because it allows the two steps (PRF/prf+) to be implemented by already certified third-party libraries. For the existing third-party libraries, the two KDFs are implemented via the respective library's HKDF implementation. A generic implementation, based on existing PRFs, is provided by the new kdf plugin.
This commit is contained in:
+1
-1
@@ -17,7 +17,7 @@ include $(CLEAR_VARS)
|
||||
# this is the list of plugins that are built into libstrongswan and charon
|
||||
# also these plugins are loaded by default (if not changed in strongswan.conf)
|
||||
strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \
|
||||
pkcs1 pkcs8 pem xcbc hmac kernel-netlink socket-default android-dns \
|
||||
pkcs1 pkcs8 pem xcbc hmac kdf kernel-netlink socket-default android-dns \
|
||||
stroke eap-identity eap-mschapv2 eap-md5 eap-gtc
|
||||
|
||||
ifneq ($(strongswan_BUILD_SCEPCLIENT),)
|
||||
|
||||
@@ -148,6 +148,7 @@ ARG_ENABL_SET([gcrypt], [enables the libgcrypt plugin.])
|
||||
ARG_DISBL_SET([gmp], [disable GNU MP (libgmp) based crypto implementation plugin.])
|
||||
ARG_DISBL_SET([curve25519], [disable Curve25519 Diffie-Hellman plugin.])
|
||||
ARG_DISBL_SET([hmac], [disable HMAC crypto implementation plugin.])
|
||||
ARG_DISBL_SET([kdf], [disable KDF (prf+) implementation plugin.])
|
||||
ARG_ENABL_SET([md4], [enable MD4 software implementation plugin.])
|
||||
ARG_DISBL_SET([md5], [disable MD5 software implementation plugin.])
|
||||
ARG_ENABL_SET([mgf1], [enable the MGF1 software implementation plugin.])
|
||||
@@ -1502,6 +1503,7 @@ ADD_PLUGIN([chapoly], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([xcbc], [s charon nm cmd])
|
||||
ADD_PLUGIN([cmac], [s charon nm cmd])
|
||||
ADD_PLUGIN([hmac], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([kdf], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([ctr], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([ccm], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([gcm], [s charon scripts nm cmd])
|
||||
@@ -1656,6 +1658,7 @@ AM_CONDITIONAL(USE_DNSKEY, test x$dnskey = xtrue)
|
||||
AM_CONDITIONAL(USE_SSHKEY, test x$sshkey = xtrue)
|
||||
AM_CONDITIONAL(USE_PEM, test x$pem = xtrue)
|
||||
AM_CONDITIONAL(USE_HMAC, test x$hmac = xtrue)
|
||||
AM_CONDITIONAL(USE_KDF, test x$kdf = xtrue)
|
||||
AM_CONDITIONAL(USE_CMAC, test x$cmac = xtrue)
|
||||
AM_CONDITIONAL(USE_XCBC, test x$xcbc = xtrue)
|
||||
AM_CONDITIONAL(USE_MYSQL, test x$mysql = xtrue)
|
||||
@@ -1921,6 +1924,7 @@ AC_CONFIG_FILES([
|
||||
src/libstrongswan/plugins/random/Makefile
|
||||
src/libstrongswan/plugins/nonce/Makefile
|
||||
src/libstrongswan/plugins/hmac/Makefile
|
||||
src/libstrongswan/plugins/kdf/Makefile
|
||||
src/libstrongswan/plugins/xcbc/Makefile
|
||||
src/libstrongswan/plugins/x509/Makefile
|
||||
src/libstrongswan/plugins/revocation/Makefile
|
||||
|
||||
@@ -200,10 +200,17 @@ win*)
|
||||
if test "$APPVEYOR" != "True"; then
|
||||
TARGET=
|
||||
else
|
||||
case "$IMG" in
|
||||
2015|2017)
|
||||
# old OpenSSL versions don't provide HKDF
|
||||
CONFIG="$CONFIG --enable-kdf"
|
||||
;;
|
||||
esac
|
||||
CONFIG="$CONFIG --enable-openssl"
|
||||
CFLAGS="$CFLAGS -I$OPENSSL_DIR/include"
|
||||
LDFLAGS="-L$OPENSSL_DIR"
|
||||
export LDFLAGS
|
||||
|
||||
fi
|
||||
CFLAGS="$CFLAGS -mno-ms-bitfields"
|
||||
DEPS="gcc-mingw-w64-base"
|
||||
|
||||
@@ -6,7 +6,7 @@ include $(CLEAR_VARS)
|
||||
strongswan_USE_BYOD := true
|
||||
|
||||
strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \
|
||||
chapoly curve25519 pkcs1 pkcs8 pem xcbc hmac socket-default revocation \
|
||||
chapoly curve25519 pkcs1 pkcs8 pem xcbc hmac kdf socket-default revocation \
|
||||
eap-identity eap-mschapv2 eap-md5 eap-gtc eap-tls x509
|
||||
|
||||
ifneq ($(strongswan_USE_BYOD),)
|
||||
|
||||
@@ -50,7 +50,6 @@ typedef struct kernel_interface_t kernel_interface_t;
|
||||
typedef enum kernel_feature_t kernel_feature_t;
|
||||
|
||||
#include <networking/host.h>
|
||||
#include <crypto/prf_plus.h>
|
||||
|
||||
#include <kernel/kernel_listener.h>
|
||||
#include <kernel/kernel_ipsec.h>
|
||||
|
||||
@@ -849,6 +849,7 @@ static void list_algs(FILE *out)
|
||||
hash_algorithm_t hash;
|
||||
pseudo_random_function_t prf;
|
||||
ext_out_function_t xof;
|
||||
key_derivation_function_t kdf;
|
||||
drbg_type_t drbg;
|
||||
diffie_hellman_group_t group;
|
||||
rng_quality_t quality;
|
||||
@@ -905,6 +906,14 @@ static void list_algs(FILE *out)
|
||||
print_alg(out, &len, ext_out_function_names, xof, plugin_name);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
fprintf(out, "\n kdf: ");
|
||||
len = 13;
|
||||
enumerator = lib->crypto->create_kdf_enumerator(lib->crypto);
|
||||
while (enumerator->enumerate(enumerator, &kdf, &plugin_name))
|
||||
{
|
||||
print_alg(out, &len, key_derivation_function_names, kdf, plugin_name);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
fprintf(out, "\n drbg: ");
|
||||
len = 13;
|
||||
enumerator = lib->crypto->create_drbg_enumerator(lib->crypto);
|
||||
|
||||
@@ -1303,6 +1303,7 @@ CALLBACK(get_algorithms, vici_message_t*,
|
||||
hash_algorithm_t hash;
|
||||
pseudo_random_function_t prf;
|
||||
ext_out_function_t xof;
|
||||
key_derivation_function_t kdf;
|
||||
drbg_type_t drbg;
|
||||
diffie_hellman_group_t group;
|
||||
rng_quality_t quality;
|
||||
@@ -1364,6 +1365,15 @@ CALLBACK(get_algorithms, vici_message_t*,
|
||||
enumerator->destroy(enumerator);
|
||||
b->end_section(b);
|
||||
|
||||
b->begin_section(b, "kdf");
|
||||
enumerator = lib->crypto->create_kdf_enumerator(lib->crypto);
|
||||
while (enumerator->enumerate(enumerator, &kdf, &plugin_name))
|
||||
{
|
||||
add_algorithm(b, key_derivation_function_names, kdf, plugin_name);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
b->end_section(b);
|
||||
|
||||
b->begin_section(b, "drbg");
|
||||
enumerator = lib->crypto->create_drbg_enumerator(lib->crypto);
|
||||
while (enumerator->enumerate(enumerator, &drbg, &plugin_name))
|
||||
|
||||
@@ -29,7 +29,6 @@ typedef struct child_sa_t child_sa_t;
|
||||
typedef struct child_sa_create_t child_sa_create_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/prf_plus.h>
|
||||
#include <encoding/payloads/proposal_substructure.h>
|
||||
#include <crypto/proposal/proposal.h>
|
||||
#include <config/child_cfg.h>
|
||||
|
||||
@@ -507,6 +507,36 @@ METHOD(keymat_v1_t, derive_ike_keys, bool,
|
||||
this->aead->get_block_size(this->aead));
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive key material for CHILD_SAs according to section 5.5. in RFC 2409.
|
||||
*/
|
||||
static bool derive_child_keymat(private_keymat_v1_t *this, chunk_t seed,
|
||||
uint16_t enc_size, chunk_t *encr,
|
||||
uint16_t int_size, chunk_t *integ)
|
||||
{
|
||||
size_t block_size, i;
|
||||
chunk_t keymat, prev = chunk_empty;
|
||||
|
||||
block_size = this->prf->get_block_size(this->prf);
|
||||
keymat = chunk_alloc(round_up(enc_size + int_size, block_size));
|
||||
keymat.len = enc_size + int_size;
|
||||
|
||||
for (i = 0; i < keymat.len; i += block_size)
|
||||
{
|
||||
if (!this->prf->get_bytes(this->prf, prev, NULL) ||
|
||||
!this->prf->get_bytes(this->prf, seed, keymat.ptr + i))
|
||||
{
|
||||
chunk_clear(&keymat);
|
||||
return FALSE;
|
||||
}
|
||||
prev = chunk_create(keymat.ptr + i, block_size);
|
||||
}
|
||||
|
||||
chunk_split(keymat, "aa", enc_size, encr, int_size, integ);
|
||||
chunk_clear(&keymat);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(keymat_v1_t, derive_child_keys, bool,
|
||||
private_keymat_v1_t *this, proposal_t *proposal, diffie_hellman_t *dh,
|
||||
uint32_t spi_i, uint32_t spi_r, chunk_t nonce_i, chunk_t nonce_r,
|
||||
@@ -514,8 +544,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
|
||||
{
|
||||
uint16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
|
||||
uint8_t protocol;
|
||||
prf_plus_t *prf_plus;
|
||||
chunk_t seed, secret = chunk_empty;
|
||||
chunk_t seed = chunk_empty, secret = chunk_empty;
|
||||
bool success = FALSE;
|
||||
|
||||
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
|
||||
@@ -599,11 +628,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
|
||||
seed = chunk_cata("ccccc", secret, chunk_from_thing(protocol),
|
||||
chunk_from_thing(spi_r), nonce_i, nonce_r);
|
||||
DBG4(DBG_CHD, "initiator SA seed %B", &seed);
|
||||
|
||||
prf_plus = prf_plus_create(this->prf, FALSE, seed);
|
||||
if (!prf_plus ||
|
||||
!prf_plus->allocate_bytes(prf_plus, enc_size, encr_i) ||
|
||||
!prf_plus->allocate_bytes(prf_plus, int_size, integ_i))
|
||||
if (!derive_child_keymat(this, seed, enc_size, encr_i, int_size, integ_i))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
@@ -611,11 +636,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
|
||||
seed = chunk_cata("ccccc", secret, chunk_from_thing(protocol),
|
||||
chunk_from_thing(spi_i), nonce_i, nonce_r);
|
||||
DBG4(DBG_CHD, "responder SA seed %B", &seed);
|
||||
prf_plus->destroy(prf_plus);
|
||||
prf_plus = prf_plus_create(this->prf, FALSE, seed);
|
||||
if (!prf_plus ||
|
||||
!prf_plus->allocate_bytes(prf_plus, enc_size, encr_r) ||
|
||||
!prf_plus->allocate_bytes(prf_plus, int_size, integ_r))
|
||||
if (!derive_child_keymat(this, seed, enc_size, encr_r, int_size, integ_r))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
@@ -640,7 +661,7 @@ failure:
|
||||
chunk_clear(encr_r);
|
||||
chunk_clear(integ_r);
|
||||
}
|
||||
DESTROY_IF(prf_plus);
|
||||
memwipe(seed.ptr, seed.len);
|
||||
chunk_clear(&secret);
|
||||
|
||||
return success;
|
||||
|
||||
+217
-278
@@ -17,7 +17,6 @@
|
||||
#include "keymat_v2.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <crypto/prf_plus.h>
|
||||
#include <crypto/hashers/hash_algorithm_set.h>
|
||||
|
||||
typedef struct private_keymat_v2_t private_keymat_v2_t;
|
||||
@@ -97,13 +96,12 @@ METHOD(keymat_t, create_nonce_gen, nonce_gen_t*,
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive IKE keys for a combined AEAD algorithm
|
||||
* Create aead_t objects for a combined-mode AEAD algorithm, sets the length of
|
||||
* sk_ei and sk_er
|
||||
*/
|
||||
static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg,
|
||||
uint16_t key_size, prf_plus_t *prf_plus,
|
||||
chunk_t *sk_ei, chunk_t *sk_er)
|
||||
static bool create_ike_aead(private_keymat_v2_t *this, uint16_t alg,
|
||||
uint16_t key_size, chunk_t *sk_ei, chunk_t *sk_er)
|
||||
{
|
||||
aead_t *aead_i, *aead_r;
|
||||
u_int salt_size;
|
||||
|
||||
switch (alg)
|
||||
@@ -131,201 +129,177 @@ static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* SK_ei/SK_er used for encryption */
|
||||
aead_i = lib->crypto->create_aead(lib->crypto, alg, key_size / 8, salt_size);
|
||||
aead_r = lib->crypto->create_aead(lib->crypto, alg, key_size / 8, salt_size);
|
||||
if (aead_i == NULL || aead_r == NULL)
|
||||
this->aead_in = lib->crypto->create_aead(lib->crypto, alg, key_size / 8,
|
||||
salt_size);
|
||||
this->aead_out = lib->crypto->create_aead(lib->crypto, alg, key_size / 8,
|
||||
salt_size);
|
||||
if (!this->aead_in || !this->aead_out)
|
||||
{
|
||||
DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
|
||||
transform_type_names, ENCRYPTION_ALGORITHM,
|
||||
encryption_algorithm_names, alg, key_size);
|
||||
goto failure;
|
||||
return FALSE;
|
||||
}
|
||||
key_size = aead_i->get_key_size(aead_i);
|
||||
if (key_size != aead_r->get_key_size(aead_r))
|
||||
sk_ei->len = this->aead_in->get_key_size(this->aead_in);
|
||||
sk_er->len = this->aead_out->get_key_size(this->aead_out);
|
||||
if (sk_ei->len != sk_er->len)
|
||||
{
|
||||
goto failure;
|
||||
return FALSE;
|
||||
}
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_ei))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ei secret %B", sk_ei);
|
||||
if (!aead_i->set_key(aead_i, *sk_ei))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_er secret %B", sk_er);
|
||||
if (!aead_r->set_key(aead_r, *sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (this->initiator)
|
||||
{
|
||||
this->aead_in = aead_r;
|
||||
this->aead_out = aead_i;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->aead_in = aead_i;
|
||||
this->aead_out = aead_r;
|
||||
}
|
||||
aead_i = aead_r = NULL;
|
||||
|
||||
failure:
|
||||
DESTROY_IF(aead_i);
|
||||
DESTROY_IF(aead_r);
|
||||
return this->aead_in && this->aead_out;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive IKE keys for traditional encryption and MAC algorithms
|
||||
* Create aead_t objects for traditional encryption and MAC algorithms, sets the
|
||||
* length of key chunks
|
||||
*/
|
||||
static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg,
|
||||
uint16_t enc_size, uint16_t int_alg, prf_plus_t *prf_plus,
|
||||
chunk_t *sk_ai, chunk_t *sk_ar, chunk_t *sk_ei,
|
||||
chunk_t *sk_er)
|
||||
static bool create_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg,
|
||||
uint16_t enc_size, uint16_t int_alg, chunk_t *sk_ai,
|
||||
chunk_t *sk_ar, chunk_t *sk_ei, chunk_t *sk_er)
|
||||
{
|
||||
crypter_t *crypter_i = NULL, *crypter_r = NULL;
|
||||
signer_t *signer_i, *signer_r;
|
||||
iv_gen_t *ivg_i, *ivg_r;
|
||||
size_t key_size;
|
||||
crypter_t *crypter_i = NULL, *crypter_o = NULL;
|
||||
signer_t *signer_i, *signer_o;
|
||||
iv_gen_t *ivg_i, *ivg_o;
|
||||
|
||||
signer_i = lib->crypto->create_signer(lib->crypto, int_alg);
|
||||
signer_r = lib->crypto->create_signer(lib->crypto, int_alg);
|
||||
crypter_i = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
|
||||
crypter_r = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
|
||||
if (signer_i == NULL || signer_r == NULL)
|
||||
signer_o = lib->crypto->create_signer(lib->crypto, int_alg);
|
||||
if (!signer_i || !signer_o)
|
||||
{
|
||||
DBG1(DBG_IKE, "%N %N not supported!",
|
||||
transform_type_names, INTEGRITY_ALGORITHM,
|
||||
integrity_algorithm_names, int_alg);
|
||||
goto failure;
|
||||
}
|
||||
if (crypter_i == NULL || crypter_r == NULL)
|
||||
crypter_i = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
|
||||
crypter_o = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
|
||||
if (!crypter_i || !crypter_o)
|
||||
{
|
||||
DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
|
||||
transform_type_names, ENCRYPTION_ALGORITHM,
|
||||
encryption_algorithm_names, enc_alg, enc_size);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* SK_ai/SK_ar used for integrity protection */
|
||||
key_size = signer_i->get_key_size(signer_i);
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_ai))
|
||||
sk_ai->len = signer_i->get_key_size(signer_i);
|
||||
sk_ar->len = signer_o->get_key_size(signer_o);
|
||||
if (sk_ai->len != sk_ar->len)
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ai secret %B", sk_ai);
|
||||
if (!signer_i->set_key(signer_i, *sk_ai))
|
||||
sk_ei->len = crypter_i->get_key_size(crypter_i);
|
||||
sk_er->len = crypter_o->get_key_size(crypter_o);
|
||||
if (sk_ei->len != sk_er->len)
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_ar))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ar secret %B", sk_ar);
|
||||
if (!signer_r->set_key(signer_r, *sk_ar))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* SK_ei/SK_er used for encryption */
|
||||
key_size = crypter_i->get_key_size(crypter_i);
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_ei))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ei secret %B", sk_ei);
|
||||
if (!crypter_i->set_key(crypter_i, *sk_ei))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_er secret %B", sk_er);
|
||||
if (!crypter_r->set_key(crypter_r, *sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ivg_i = iv_gen_create_for_alg(enc_alg);
|
||||
ivg_r = iv_gen_create_for_alg(enc_alg);
|
||||
if (!ivg_i || !ivg_r)
|
||||
ivg_o = iv_gen_create_for_alg(enc_alg);
|
||||
if (!ivg_i || !ivg_o)
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (this->initiator)
|
||||
{
|
||||
this->aead_in = aead_create(crypter_r, signer_r, ivg_r);
|
||||
this->aead_out = aead_create(crypter_i, signer_i, ivg_i);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->aead_in = aead_create(crypter_i, signer_i, ivg_i);
|
||||
this->aead_out = aead_create(crypter_r, signer_r, ivg_r);
|
||||
}
|
||||
signer_i = signer_r = NULL;
|
||||
crypter_i = crypter_r = NULL;
|
||||
this->aead_in = aead_create(crypter_i, signer_i, ivg_i);
|
||||
this->aead_out = aead_create(crypter_o, signer_o, ivg_o);
|
||||
signer_i = signer_o = NULL;
|
||||
crypter_i = crypter_o = NULL;
|
||||
|
||||
failure:
|
||||
DESTROY_IF(signer_i);
|
||||
DESTROY_IF(signer_r);
|
||||
DESTROY_IF(signer_o);
|
||||
DESTROY_IF(crypter_i);
|
||||
DESTROY_IF(crypter_r);
|
||||
DESTROY_IF(crypter_o);
|
||||
return this->aead_in && this->aead_out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set keys on AEAD objects
|
||||
*/
|
||||
static bool set_aead_keys(private_keymat_v2_t *this, uint16_t enc_alg,
|
||||
chunk_t sk_ai, chunk_t sk_ar,
|
||||
chunk_t sk_ei, chunk_t sk_er)
|
||||
{
|
||||
aead_t *aead_i, *aead_r;
|
||||
chunk_t sk_i, sk_r;
|
||||
bool success;
|
||||
|
||||
aead_i = this->initiator ? this->aead_out : this->aead_in;
|
||||
aead_r = this->initiator ? this->aead_in : this->aead_out;
|
||||
|
||||
sk_i = chunk_cat("cc", sk_ai, sk_ei);
|
||||
sk_r = chunk_cat("cc", sk_ar, sk_er);
|
||||
|
||||
success = aead_i->set_key(aead_i, sk_i) &&
|
||||
aead_r->set_key(aead_r, sk_r);
|
||||
|
||||
chunk_clear(&sk_i);
|
||||
chunk_clear(&sk_r);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(keymat_v2_t, derive_ike_keys, bool,
|
||||
private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh,
|
||||
chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
|
||||
pseudo_random_function_t rekey_function, chunk_t rekey_skd)
|
||||
{
|
||||
chunk_t skeyseed = chunk_empty, secret, full_nonce, fixed_nonce;
|
||||
chunk_t prf_plus_seed, spi_i, spi_r;
|
||||
chunk_t prf_plus_seed, spi_i, spi_r, keymat = chunk_empty;
|
||||
chunk_t sk_ei = chunk_empty, sk_er = chunk_empty;
|
||||
chunk_t sk_ai = chunk_empty, sk_ar = chunk_empty, sk_pi, sk_pr;
|
||||
prf_plus_t *prf_plus = NULL;
|
||||
uint16_t alg, key_size, int_alg;
|
||||
prf_t *rekey_prf = NULL;
|
||||
kdf_t *prf = NULL, *prf_plus = NULL;
|
||||
uint16_t prf_alg, key_size, enc_alg, enc_size, int_alg;
|
||||
bool success = FALSE;
|
||||
|
||||
spi_i = chunk_alloca(sizeof(uint64_t));
|
||||
spi_r = chunk_alloca(sizeof(uint64_t));
|
||||
|
||||
if (!dh->get_shared_secret(dh, &secret))
|
||||
/* create SA's general purpose PRF first, we may use it here */
|
||||
if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &prf_alg,
|
||||
NULL))
|
||||
{
|
||||
DBG1(DBG_IKE, "no %N selected",
|
||||
transform_type_names, PSEUDO_RANDOM_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
this->prf_alg = prf_alg;
|
||||
this->prf = lib->crypto->create_prf(lib->crypto, this->prf_alg);
|
||||
if (!this->prf)
|
||||
{
|
||||
DBG1(DBG_IKE, "%N %N not supported!", transform_type_names,
|
||||
PSEUDO_RANDOM_FUNCTION, pseudo_random_function_names,
|
||||
this->prf_alg);
|
||||
return FALSE;
|
||||
}
|
||||
key_size = this->prf->get_key_size(this->prf);
|
||||
|
||||
/* create SA's AEAD instances to determine key sizes */
|
||||
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &enc_alg,
|
||||
&enc_size))
|
||||
{
|
||||
DBG1(DBG_IKE, "no %N selected", transform_type_names,
|
||||
ENCRYPTION_ALGORITHM);
|
||||
return FALSE;
|
||||
}
|
||||
if (!encryption_algorithm_is_aead(enc_alg))
|
||||
{
|
||||
if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_alg,
|
||||
NULL))
|
||||
{
|
||||
DBG1(DBG_IKE, "no %N selected", transform_type_names,
|
||||
INTEGRITY_ALGORITHM);
|
||||
return FALSE;
|
||||
}
|
||||
if (!create_ike_traditional(this, enc_alg, enc_size, int_alg,
|
||||
&sk_ai, &sk_ar, &sk_ei, &sk_er))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (!create_ike_aead(this, enc_alg, enc_size, &sk_ei, &sk_er))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create SAs general purpose PRF first, we may use it here */
|
||||
if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
|
||||
if (!dh->get_shared_secret(dh, &secret))
|
||||
{
|
||||
DBG1(DBG_IKE, "no %N selected",
|
||||
transform_type_names, PSEUDO_RANDOM_FUNCTION);
|
||||
chunk_clear(&secret);
|
||||
return FALSE;
|
||||
}
|
||||
this->prf_alg = alg;
|
||||
this->prf = lib->crypto->create_prf(lib->crypto, alg);
|
||||
if (this->prf == NULL)
|
||||
{
|
||||
DBG1(DBG_IKE, "%N %N not supported!",
|
||||
transform_type_names, PSEUDO_RANDOM_FUNCTION,
|
||||
pseudo_random_function_names, alg);
|
||||
chunk_clear(&secret);
|
||||
return FALSE;
|
||||
}
|
||||
DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &secret);
|
||||
@@ -333,7 +307,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
||||
full_nonce = chunk_cat("cc", nonce_i, nonce_r);
|
||||
/* but the PRF may need a fixed key which only uses the first bytes of
|
||||
* the nonces. */
|
||||
switch (alg)
|
||||
switch (prf_alg)
|
||||
{
|
||||
case PRF_AES128_CMAC:
|
||||
/* while variable keys may be used according to RFC 4615, RFC 7296
|
||||
@@ -345,161 +319,150 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
||||
case PRF_CAMELLIA128_XCBC:
|
||||
/* draft-kanno-ipsecme-camellia-xcbc refers to rfc 4434, we
|
||||
* assume fixed key length. */
|
||||
key_size = this->prf->get_key_size(this->prf)/2;
|
||||
nonce_i.len = min(nonce_i.len, key_size);
|
||||
nonce_r.len = min(nonce_r.len, key_size);
|
||||
nonce_i.len = min(nonce_i.len, key_size / 2);
|
||||
nonce_r.len = min(nonce_r.len, key_size / 2);
|
||||
break;
|
||||
default:
|
||||
/* all other algorithms use variable key length, full nonce */
|
||||
break;
|
||||
}
|
||||
fixed_nonce = chunk_cat("cc", nonce_i, nonce_r);
|
||||
*((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id);
|
||||
*((uint64_t*)spi_r.ptr) = id->get_responder_spi(id);
|
||||
prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r);
|
||||
|
||||
/* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
|
||||
*
|
||||
* if we are rekeying, SKEYSEED is built on another way
|
||||
*/
|
||||
if (rekey_function == PRF_UNDEFINED) /* not rekeying */
|
||||
if (rekey_function == PRF_UNDEFINED)
|
||||
{
|
||||
/* SKEYSEED = prf(Ni | Nr, g^ir) */
|
||||
if (this->prf->set_key(this->prf, fixed_nonce) &&
|
||||
this->prf->allocate_bytes(this->prf, secret, &skeyseed) &&
|
||||
this->prf->set_key(this->prf, skeyseed))
|
||||
prf = lib->crypto->create_kdf(lib->crypto, KDF_PRF, this->prf_alg);
|
||||
if (!prf)
|
||||
{
|
||||
prf_plus = prf_plus_create(this->prf, TRUE, prf_plus_seed);
|
||||
DBG1(DBG_IKE, "%N with %N not supported",
|
||||
key_derivation_function_names, KDF_PRF,
|
||||
pseudo_random_function_names, rekey_function);
|
||||
chunk_clear(&secret);
|
||||
chunk_free(&full_nonce);
|
||||
chunk_free(&fixed_nonce);
|
||||
return FALSE;
|
||||
}
|
||||
if (prf->set_param(prf, KDF_PARAM_KEY, secret) &&
|
||||
prf->set_param(prf, KDF_PARAM_SALT, fixed_nonce) &&
|
||||
prf->allocate_bytes(prf, 0, &skeyseed))
|
||||
{
|
||||
prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS,
|
||||
this->prf_alg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr)
|
||||
* use OLD SAs PRF functions for both prf_plus and prf */
|
||||
rekey_prf = lib->crypto->create_prf(lib->crypto, rekey_function);
|
||||
if (!rekey_prf)
|
||||
prf = lib->crypto->create_kdf(lib->crypto, KDF_PRF, rekey_function);
|
||||
if (!prf)
|
||||
{
|
||||
DBG1(DBG_IKE, "PRF of old SA %N not supported!",
|
||||
DBG1(DBG_IKE, "%N with PRF of old SA %N not supported",
|
||||
key_derivation_function_names, KDF_PRF,
|
||||
pseudo_random_function_names, rekey_function);
|
||||
chunk_clear(&secret);
|
||||
chunk_free(&full_nonce);
|
||||
chunk_free(&fixed_nonce);
|
||||
chunk_clear(&prf_plus_seed);
|
||||
return FALSE;
|
||||
}
|
||||
secret = chunk_cat("sc", secret, full_nonce);
|
||||
if (rekey_prf->set_key(rekey_prf, rekey_skd) &&
|
||||
rekey_prf->allocate_bytes(rekey_prf, secret, &skeyseed) &&
|
||||
rekey_prf->set_key(rekey_prf, skeyseed))
|
||||
if (prf->set_param(prf, KDF_PARAM_KEY, secret) &&
|
||||
prf->set_param(prf, KDF_PARAM_SALT, rekey_skd) &&
|
||||
prf->allocate_bytes(prf, 0, &skeyseed))
|
||||
{
|
||||
prf_plus = prf_plus_create(rekey_prf, TRUE, prf_plus_seed);
|
||||
prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS,
|
||||
rekey_function);
|
||||
}
|
||||
}
|
||||
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
|
||||
|
||||
chunk_clear(&skeyseed);
|
||||
chunk_clear(&secret);
|
||||
chunk_free(&full_nonce);
|
||||
chunk_free(&fixed_nonce);
|
||||
chunk_clear(&prf_plus_seed);
|
||||
DESTROY_IF(prf);
|
||||
|
||||
/* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
|
||||
*/
|
||||
*((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id);
|
||||
*((uint64_t*)spi_r.ptr) = id->get_responder_spi(id);
|
||||
prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r);
|
||||
|
||||
if (prf_plus &&
|
||||
(!prf_plus->set_param(prf_plus, KDF_PARAM_KEY, skeyseed) ||
|
||||
!prf_plus->set_param(prf_plus, KDF_PARAM_SALT, prf_plus_seed)))
|
||||
{
|
||||
prf_plus->destroy(prf_plus);
|
||||
prf_plus = NULL;
|
||||
}
|
||||
chunk_clear(&skeyseed);
|
||||
chunk_free(&full_nonce);
|
||||
chunk_free(&prf_plus_seed);
|
||||
|
||||
if (!prf_plus)
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr */
|
||||
/* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr
|
||||
*
|
||||
* SK_d, SK_pi and SK_pr have the size of the PRF key
|
||||
*/
|
||||
keymat.len = 3 * key_size + sk_ai.len + sk_ar.len + sk_ei.len + sk_er.len;
|
||||
if (!prf_plus->allocate_bytes(prf_plus, keymat.len, &keymat))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
chunk_split(keymat, "ammmmaa", key_size, &this->skd, sk_ai.len, &sk_ai,
|
||||
sk_ar.len, &sk_ar, sk_ei.len, &sk_ei, sk_er.len, &sk_er,
|
||||
key_size, &sk_pi, key_size, &sk_pr);
|
||||
|
||||
/* SK_d is used for generating CHILD_SA key mat => store for later use */
|
||||
key_size = this->prf->get_key_size(this->prf);
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &this->skd))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_d secret %B", &this->skd);
|
||||
|
||||
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &key_size))
|
||||
if (!encryption_algorithm_is_aead(enc_alg))
|
||||
{ /* SK_ai/SK_ar used for integrity protection */
|
||||
DBG4(DBG_IKE, "Sk_ai secret %B", &sk_ai);
|
||||
DBG4(DBG_IKE, "Sk_ar secret %B", &sk_ar);
|
||||
}
|
||||
/* SK_ei/SK_er used for encryption */
|
||||
DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei);
|
||||
DBG4(DBG_IKE, "Sk_er secret %B", &sk_er);
|
||||
if (!set_aead_keys(this, enc_alg, sk_ai, sk_ar, sk_ei, sk_er))
|
||||
{
|
||||
DBG1(DBG_IKE, "no %N selected",
|
||||
transform_type_names, ENCRYPTION_ALGORITHM);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (encryption_algorithm_is_aead(alg))
|
||||
{
|
||||
if (!derive_ike_aead(this, alg, key_size, prf_plus, &sk_ei, &sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
|
||||
&int_alg, NULL))
|
||||
{
|
||||
DBG1(DBG_IKE, "no %N selected",
|
||||
transform_type_names, INTEGRITY_ALGORITHM);
|
||||
goto failure;
|
||||
}
|
||||
if (!derive_ike_traditional(this, alg, key_size, int_alg, prf_plus,
|
||||
&sk_ai, &sk_ar, &sk_ei, &sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* SK_pi/SK_pr used for authentication => stored for later */
|
||||
key_size = this->prf->get_key_size(this->prf);
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_pi))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_pi secret %B", &sk_pi);
|
||||
if (this->initiator)
|
||||
{
|
||||
this->skp_build = sk_pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->skp_verify = sk_pi;
|
||||
}
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_pr))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_pr secret %B", &sk_pr);
|
||||
if (this->initiator)
|
||||
{
|
||||
this->skp_build = sk_pi;
|
||||
this->skp_verify = sk_pr;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->skp_build = sk_pr;
|
||||
this->skp_verify = sk_pi;
|
||||
}
|
||||
charon->bus->ike_derived_keys(charon->bus,this->skd, sk_ai, sk_ar, sk_ei,
|
||||
sk_er, sk_pi, sk_pr);
|
||||
charon->bus->ike_derived_keys(charon->bus, this->skd, sk_ai, sk_ar,
|
||||
sk_ei, sk_er, sk_pi, sk_pr);
|
||||
success = TRUE;
|
||||
|
||||
failure:
|
||||
chunk_clear(&sk_ai);
|
||||
chunk_clear(&sk_ar);
|
||||
chunk_clear(&sk_ei);
|
||||
chunk_clear(&sk_er);
|
||||
chunk_clear(&keymat);
|
||||
DESTROY_IF(prf_plus);
|
||||
DESTROY_IF(rekey_prf);
|
||||
|
||||
return this->skp_build.len && this->skp_verify.len;
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a key from the given key and a PRF that was initialized with a PPK
|
||||
* Derives a new key from the given PPK and old key
|
||||
*/
|
||||
static bool derive_ppk_key(prf_t *prf, char *name, chunk_t key,
|
||||
chunk_t *new_key)
|
||||
static bool derive_ppk_key(private_keymat_v2_t *this, char *name, chunk_t ppk,
|
||||
chunk_t key, chunk_t *new_key)
|
||||
{
|
||||
prf_plus_t *prf_plus;
|
||||
kdf_t *prf_plus;
|
||||
|
||||
prf_plus = prf_plus_create(prf, TRUE, key);
|
||||
prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS, this->prf_alg);
|
||||
if (!prf_plus ||
|
||||
!prf_plus->set_param(prf_plus, KDF_PARAM_KEY, ppk) ||
|
||||
!prf_plus->set_param(prf_plus, KDF_PARAM_SALT, key) ||
|
||||
!prf_plus->allocate_bytes(prf_plus, key.len, new_key))
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to derive %s with PPK", name);
|
||||
@@ -510,20 +473,6 @@ static bool derive_ppk_key(prf_t *prf, char *name, chunk_t key,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the given PPK to derive a new SK_pi/r
|
||||
*/
|
||||
static bool derive_skp_ppk(private_keymat_v2_t *this, chunk_t ppk, chunk_t skp,
|
||||
chunk_t *new_skp)
|
||||
{
|
||||
if (!this->prf->set_key(this->prf, ppk))
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to set PPK in PRF");
|
||||
return FALSE;
|
||||
}
|
||||
return derive_ppk_key(this->prf, "SK_p", skp, new_skp);
|
||||
}
|
||||
|
||||
METHOD(keymat_v2_t, derive_ike_keys_ppk, bool,
|
||||
private_keymat_v2_t *this, chunk_t ppk)
|
||||
{
|
||||
@@ -548,14 +497,9 @@ METHOD(keymat_v2_t, derive_ike_keys_ppk, bool,
|
||||
|
||||
DBG4(DBG_IKE, "derive keys using PPK %B", &ppk);
|
||||
|
||||
if (!this->prf->set_key(this->prf, ppk))
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to set PPK in PRF");
|
||||
return FALSE;
|
||||
}
|
||||
if (!derive_ppk_key(this->prf, "Sk_d", this->skd, &skd) ||
|
||||
!derive_ppk_key(this->prf, "Sk_pi", *skpi, &new_skpi) ||
|
||||
!derive_ppk_key(this->prf, "Sk_pr", *skpr, &new_skpr))
|
||||
if (!derive_ppk_key(this, "Sk_d", ppk, this->skd, &skd) ||
|
||||
!derive_ppk_key(this, "Sk_pi", ppk, *skpi, &new_skpi) ||
|
||||
!derive_ppk_key(this, "Sk_pr", ppk, *skpr, &new_skpr))
|
||||
{
|
||||
chunk_clear(&skd);
|
||||
chunk_clear(&new_skpi);
|
||||
@@ -583,8 +527,8 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
|
||||
chunk_t *encr_r, chunk_t *integ_r)
|
||||
{
|
||||
uint16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
|
||||
chunk_t seed, secret = chunk_empty;
|
||||
prf_plus_t *prf_plus;
|
||||
chunk_t seed, secret = chunk_empty, keymat = chunk_empty;
|
||||
kdf_t *prf_plus;
|
||||
|
||||
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
|
||||
&enc_alg, &enc_size))
|
||||
@@ -650,11 +594,6 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
|
||||
int_size /= 8;
|
||||
}
|
||||
|
||||
if (!this->prf->set_key(this->prf, this->skd))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dh)
|
||||
{
|
||||
if (!dh->get_shared_secret(dh, &secret))
|
||||
@@ -666,30 +605,30 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
|
||||
seed = chunk_cata("scc", secret, nonce_i, nonce_r);
|
||||
DBG4(DBG_CHD, "seed %B", &seed);
|
||||
|
||||
prf_plus = prf_plus_create(this->prf, TRUE, seed);
|
||||
memwipe(seed.ptr, seed.len);
|
||||
|
||||
if (!prf_plus)
|
||||
prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS, this->prf_alg);
|
||||
if (!prf_plus ||
|
||||
!prf_plus->set_param(prf_plus, KDF_PARAM_KEY, this->skd) ||
|
||||
!prf_plus->set_param(prf_plus, KDF_PARAM_SALT, seed))
|
||||
{
|
||||
DESTROY_IF(prf_plus);
|
||||
memwipe(seed.ptr, seed.len);
|
||||
return FALSE;
|
||||
}
|
||||
memwipe(seed.ptr, seed.len);
|
||||
|
||||
*encr_i = *integ_i = *encr_r = *integ_r = chunk_empty;
|
||||
if (!prf_plus->allocate_bytes(prf_plus, enc_size, encr_i) ||
|
||||
!prf_plus->allocate_bytes(prf_plus, int_size, integ_i) ||
|
||||
!prf_plus->allocate_bytes(prf_plus, enc_size, encr_r) ||
|
||||
!prf_plus->allocate_bytes(prf_plus, int_size, integ_r))
|
||||
keymat.len = 2 * enc_size + 2 * int_size;
|
||||
if (!prf_plus->allocate_bytes(prf_plus, keymat.len, &keymat))
|
||||
{
|
||||
chunk_free(encr_i);
|
||||
chunk_free(integ_i);
|
||||
chunk_free(encr_r);
|
||||
chunk_free(integ_r);
|
||||
prf_plus->destroy(prf_plus);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
prf_plus->destroy(prf_plus);
|
||||
|
||||
chunk_split(keymat, "aaaa", enc_size, encr_i, int_size, integ_i,
|
||||
enc_size, encr_r, int_size, integ_r);
|
||||
chunk_clear(&keymat);
|
||||
|
||||
if (enc_size)
|
||||
{
|
||||
DBG4(DBG_CHD, "encryption initiator key %B", encr_i);
|
||||
@@ -729,7 +668,7 @@ METHOD(keymat_v2_t, get_auth_octets, bool,
|
||||
if (ppk.ptr)
|
||||
{
|
||||
DBG4(DBG_IKE, "PPK %B", &ppk);
|
||||
if (!derive_skp_ppk(this, ppk, skp, &skp_ppk))
|
||||
if (!derive_ppk_key(this, "SK_p", ppk, skp, &skp_ppk))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -775,7 +714,7 @@ METHOD(keymat_v2_t, get_psk_sig, bool,
|
||||
secret = verify ? this->skp_verify : this->skp_build;
|
||||
if (ppk.ptr)
|
||||
{
|
||||
if (!derive_skp_ppk(this, ppk, secret, &skp_ppk))
|
||||
if (!derive_ppk_key(this, "SK_p", ppk, secret, &skp_ppk))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,13 @@
|
||||
|
||||
typedef struct private_diffie_hellman_t private_diffie_hellman_t;
|
||||
|
||||
/** Mock DH public and shared key */
|
||||
static chunk_t mock_key = chunk_from_chars(
|
||||
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08);
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
@@ -37,7 +44,7 @@ struct private_diffie_hellman_t {
|
||||
METHOD(diffie_hellman_t, get_my_public_value, bool,
|
||||
private_diffie_hellman_t *this, chunk_t *value)
|
||||
{
|
||||
*value = chunk_empty;
|
||||
*value = chunk_clone(mock_key);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -50,7 +57,7 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||
METHOD(diffie_hellman_t, get_shared_secret, bool,
|
||||
private_diffie_hellman_t *this, chunk_t *secret)
|
||||
{
|
||||
*secret = chunk_empty;
|
||||
*secret = chunk_clone(mock_key);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,11 +13,11 @@ crypto/hashers/hash_algorithm_set.c crypto/proposal/proposal.c \
|
||||
crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \
|
||||
crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \
|
||||
crypto/rngs/rng.c crypto/rngs/rng_tester.c \
|
||||
crypto/prf_plus.c crypto/signers/signer.c \
|
||||
crypto/signers/signer.c \
|
||||
crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
|
||||
crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
|
||||
crypto/iv/iv_gen.c crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
|
||||
crypto/iv/iv_gen_null.c \
|
||||
crypto/iv/iv_gen_null.c crypto/kdfs/kdf.c \
|
||||
crypto/xofs/xof.c crypto/xofs/xof_bitspender.c \
|
||||
credentials/credential_factory.c credentials/builder.c \
|
||||
credentials/cred_encoding.c credentials/keys/private_key.c \
|
||||
@@ -92,6 +92,8 @@ endif
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, hmac)
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, kdf)
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, md4)
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, md5)
|
||||
|
||||
@@ -11,11 +11,11 @@ crypto/hashers/hash_algorithm_set.c crypto/proposal/proposal.c \
|
||||
crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \
|
||||
crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \
|
||||
crypto/rngs/rng.c crypto/rngs/rng_tester.c \
|
||||
crypto/prf_plus.c crypto/signers/signer.c \
|
||||
crypto/signers/signer.c \
|
||||
crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
|
||||
crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
|
||||
crypto/iv/iv_gen.c crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
|
||||
crypto/iv/iv_gen_null.c \
|
||||
crypto/iv/iv_gen_null.c crypto/kdfs/kdf.c \
|
||||
crypto/xofs/xof.c crypto/xofs/xof_bitspender.c \
|
||||
credentials/credential_factory.c credentials/builder.c \
|
||||
credentials/cred_encoding.c credentials/keys/private_key.c \
|
||||
@@ -78,11 +78,12 @@ crypto/hashers/hash_algorithm_set.h crypto/mac.h crypto/proposal/proposal.h \
|
||||
crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \
|
||||
crypto/rngs/rng.h crypto/rngs/rng_tester.h \
|
||||
crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/nonce_gen.h \
|
||||
crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \
|
||||
crypto/signers/signer.h crypto/signers/mac_signer.h \
|
||||
crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \
|
||||
crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \
|
||||
crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h crypto/iv/iv_gen_null.h \
|
||||
crypto/xofs/xof.h crypto/xofs/xof_bitspender.h crypto/xofs/mgf1.h \
|
||||
crypto/kdfs/kdf.h \
|
||||
credentials/credential_factory.h credentials/builder.h \
|
||||
credentials/cred_encoding.h credentials/keys/private_key.h \
|
||||
credentials/keys/public_key.h credentials/keys/shared_key.h \
|
||||
@@ -394,6 +395,13 @@ if MONOLITHIC
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_KDF
|
||||
SUBDIRS += plugins/kdf
|
||||
if MONOLITHIC
|
||||
libstrongswan_la_LIBADD += plugins/kdf/libstrongswan-kdf.la
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_CMAC
|
||||
SUBDIRS += plugins/cmac
|
||||
if MONOLITHIC
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
#include <crypto/crypto_tester.h>
|
||||
#include <utils/test.h>
|
||||
|
||||
const char *default_plugin_name = "default";
|
||||
|
||||
typedef struct entry_t entry_t;
|
||||
|
||||
struct entry_t {
|
||||
@@ -53,6 +51,7 @@ struct entry_t {
|
||||
hasher_constructor_t create_hasher;
|
||||
prf_constructor_t create_prf;
|
||||
xof_constructor_t create_xof;
|
||||
kdf_constructor_t create_kdf;
|
||||
drbg_constructor_t create_drbg;
|
||||
rng_constructor_t create_rng;
|
||||
nonce_gen_constructor_t create_nonce_gen;
|
||||
@@ -103,6 +102,11 @@ struct private_crypto_factory_t {
|
||||
*/
|
||||
linked_list_t *xofs;
|
||||
|
||||
/**
|
||||
* registered kdfs, as entry_t
|
||||
*/
|
||||
linked_list_t *kdfs;
|
||||
|
||||
/**
|
||||
* registered drbgs, as entry_t
|
||||
*/
|
||||
@@ -171,7 +175,7 @@ METHOD(crypto_factory_t, create_crypter, crypter_t*,
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_crypter(this->tester, algo, key_size,
|
||||
entry->create_crypter, NULL,
|
||||
default_plugin_name))
|
||||
entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -204,7 +208,7 @@ METHOD(crypto_factory_t, create_aead, aead_t*,
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_aead(this->tester, algo, key_size,
|
||||
salt_size, entry->create_aead, NULL,
|
||||
default_plugin_name))
|
||||
entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -236,7 +240,7 @@ METHOD(crypto_factory_t, create_signer, signer_t*,
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_signer(this->tester, algo,
|
||||
entry->create_signer, NULL,
|
||||
default_plugin_name))
|
||||
entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -268,7 +272,7 @@ METHOD(crypto_factory_t, create_hasher, hasher_t*,
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_hasher(this->tester, algo,
|
||||
entry->create_hasher, NULL,
|
||||
default_plugin_name))
|
||||
entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -300,7 +304,7 @@ METHOD(crypto_factory_t, create_prf, prf_t*,
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_prf(this->tester, algo,
|
||||
entry->create_prf, NULL,
|
||||
default_plugin_name))
|
||||
entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -332,7 +336,7 @@ METHOD(crypto_factory_t, create_xof, xof_t*,
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_xof(this->tester, algo,
|
||||
entry->create_xof, NULL,
|
||||
default_plugin_name))
|
||||
entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -348,6 +352,48 @@ METHOD(crypto_factory_t, create_xof, xof_t*,
|
||||
return xof;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_kdf, kdf_t*,
|
||||
private_crypto_factory_t *this, key_derivation_function_t algo, ...)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
va_list args;
|
||||
kdf_t *kdf = NULL;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->kdfs->create_enumerator(this->kdfs);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->algo == algo)
|
||||
{
|
||||
if (this->test_on_create)
|
||||
{
|
||||
kdf_test_args_t test_args = {};
|
||||
|
||||
va_start(test_args.args, algo);
|
||||
if (!this->tester->test_kdf(this->tester, algo,
|
||||
entry->create_kdf, &test_args, NULL,
|
||||
entry->plugin_name))
|
||||
{
|
||||
va_end(test_args.args);
|
||||
continue;
|
||||
}
|
||||
va_end(test_args.args);
|
||||
}
|
||||
va_start(args, algo);
|
||||
kdf = entry->create_kdf(algo, args);
|
||||
va_end(args);
|
||||
if (kdf)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
return kdf;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_drbg, drbg_t*,
|
||||
private_crypto_factory_t *this, drbg_type_t type, uint32_t strength,
|
||||
rng_t *entropy, chunk_t personalization_str)
|
||||
@@ -365,7 +411,7 @@ METHOD(crypto_factory_t, create_drbg, drbg_t*,
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_drbg(this->tester, type,
|
||||
entry->create_drbg, NULL,
|
||||
default_plugin_name))
|
||||
entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -398,7 +444,7 @@ METHOD(crypto_factory_t, create_rng, rng_t*,
|
||||
if (this->test_on_create &&
|
||||
!this->tester->test_rng(this->tester, quality,
|
||||
entry->create_rng, NULL,
|
||||
default_plugin_name))
|
||||
entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -462,7 +508,7 @@ METHOD(crypto_factory_t, create_dh, diffie_hellman_t*,
|
||||
{
|
||||
if (this->test_on_create && group != MODP_CUSTOM &&
|
||||
!this->tester->test_dh(this->tester, group,
|
||||
entry->create_dh, NULL, default_plugin_name))
|
||||
entry->create_dh, NULL, entry->plugin_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -749,6 +795,43 @@ METHOD(crypto_factory_t, remove_xof, void,
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, add_kdf, bool,
|
||||
private_crypto_factory_t *this, key_derivation_function_t algo,
|
||||
const char *plugin_name, kdf_constructor_t create)
|
||||
{
|
||||
u_int speed = 0;
|
||||
|
||||
if (!this->test_on_add ||
|
||||
this->tester->test_kdf(this->tester, algo, create, NULL,
|
||||
this->bench ? &speed : NULL, plugin_name))
|
||||
{
|
||||
add_entry(this, this->kdfs, algo, plugin_name, 0, create);
|
||||
return TRUE;
|
||||
}
|
||||
this->test_failures++;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, remove_kdf, void,
|
||||
private_crypto_factory_t *this, kdf_constructor_t create)
|
||||
{
|
||||
entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
enumerator = this->kdfs->create_enumerator(this->kdfs);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->create_kdf == create)
|
||||
{
|
||||
this->kdfs->remove_at(this->kdfs, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, add_drbg, bool,
|
||||
private_crypto_factory_t *this, drbg_type_t type,
|
||||
const char *plugin_name, drbg_constructor_t create)
|
||||
@@ -1058,6 +1141,30 @@ METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->xofs, xof_filter);
|
||||
}
|
||||
|
||||
CALLBACK(kdf_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
entry_t *entry;
|
||||
key_derivation_function_t *algo;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, algo, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*algo = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_kdf_enumerator, enumerator_t*,
|
||||
private_crypto_factory_t *this)
|
||||
{
|
||||
return create_enumerator(this, this->kdfs, kdf_filter);
|
||||
}
|
||||
|
||||
CALLBACK(drbg_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
@@ -1169,6 +1276,8 @@ METHOD(crypto_factory_t, add_test_vector, void,
|
||||
return this->tester->add_prf_vector(this->tester, vector);
|
||||
case EXTENDED_OUTPUT_FUNCTION:
|
||||
return this->tester->add_xof_vector(this->tester, vector);
|
||||
case KEY_DERIVATION_FUNCTION:
|
||||
return this->tester->add_kdf_vector(this->tester, vector);
|
||||
case DETERMINISTIC_RANDOM_BIT_GENERATOR:
|
||||
return this->tester->add_drbg_vector(this->tester, vector);
|
||||
case RANDOM_NUMBER_GENERATOR:
|
||||
@@ -1232,6 +1341,10 @@ METHOD(enumerator_t, verify_enumerate, bool,
|
||||
*valid = this->tester->test_xof(this->tester, entry->algo,
|
||||
entry->create_xof, NULL, entry->plugin_name);
|
||||
break;
|
||||
case KEY_DERIVATION_FUNCTION:
|
||||
*valid = this->tester->test_kdf(this->tester, entry->algo,
|
||||
entry->create_kdf, NULL, NULL, entry->plugin_name);
|
||||
break;
|
||||
case DETERMINISTIC_RANDOM_BIT_GENERATOR:
|
||||
*valid = this->tester->test_drbg(this->tester, entry->algo,
|
||||
entry->create_drbg, NULL, entry->plugin_name);
|
||||
@@ -1287,6 +1400,9 @@ METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*,
|
||||
case EXTENDED_OUTPUT_FUNCTION:
|
||||
inner = this->xofs->create_enumerator(this->xofs);
|
||||
break;
|
||||
case KEY_DERIVATION_FUNCTION:
|
||||
inner = this->kdfs->create_enumerator(this->kdfs);
|
||||
break;
|
||||
case DETERMINISTIC_RANDOM_BIT_GENERATOR:
|
||||
inner = this->drbgs->create_enumerator(this->drbgs);
|
||||
break;
|
||||
@@ -1323,6 +1439,7 @@ METHOD(crypto_factory_t, destroy, void,
|
||||
this->hashers->destroy(this->hashers);
|
||||
this->prfs->destroy(this->prfs);
|
||||
this->xofs->destroy(this->xofs);
|
||||
this->kdfs->destroy(this->kdfs);
|
||||
this->drbgs->destroy(this->drbgs);
|
||||
this->rngs->destroy(this->rngs);
|
||||
this->nonce_gens->destroy(this->nonce_gens);
|
||||
@@ -1347,6 +1464,7 @@ crypto_factory_t *crypto_factory_create()
|
||||
.create_hasher = _create_hasher,
|
||||
.create_prf = _create_prf,
|
||||
.create_xof = _create_xof,
|
||||
.create_kdf = _create_kdf,
|
||||
.create_drbg = _create_drbg,
|
||||
.create_rng = _create_rng,
|
||||
.create_nonce_gen = _create_nonce_gen,
|
||||
@@ -1363,6 +1481,8 @@ crypto_factory_t *crypto_factory_create()
|
||||
.remove_prf = _remove_prf,
|
||||
.add_xof = _add_xof,
|
||||
.remove_xof = _remove_xof,
|
||||
.add_kdf = _add_kdf,
|
||||
.remove_kdf = _remove_kdf,
|
||||
.add_drbg = _add_drbg,
|
||||
.remove_drbg = _remove_drbg,
|
||||
.add_rng = _add_rng,
|
||||
@@ -1377,6 +1497,7 @@ crypto_factory_t *crypto_factory_create()
|
||||
.create_hasher_enumerator = _create_hasher_enumerator,
|
||||
.create_prf_enumerator = _create_prf_enumerator,
|
||||
.create_xof_enumerator = _create_xof_enumerator,
|
||||
.create_kdf_enumerator = _create_kdf_enumerator,
|
||||
.create_drbg_enumerator = _create_drbg_enumerator,
|
||||
.create_dh_enumerator = _create_dh_enumerator,
|
||||
.create_rng_enumerator = _create_rng_enumerator,
|
||||
@@ -1391,6 +1512,7 @@ crypto_factory_t *crypto_factory_create()
|
||||
.hashers = linked_list_create(),
|
||||
.prfs = linked_list_create(),
|
||||
.xofs = linked_list_create(),
|
||||
.kdfs = linked_list_create(),
|
||||
.drbgs = linked_list_create(),
|
||||
.rngs = linked_list_create(),
|
||||
.nonce_gens = linked_list_create(),
|
||||
|
||||
@@ -33,6 +33,7 @@ typedef struct crypto_factory_t crypto_factory_t;
|
||||
#include <crypto/prfs/prf.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
#include <crypto/xofs/xof.h>
|
||||
#include <crypto/kdfs/kdf.h>
|
||||
#include <crypto/drbgs/drbg.h>
|
||||
#include <crypto/nonce_gen.h>
|
||||
#include <crypto/diffie_hellman.h>
|
||||
@@ -70,6 +71,14 @@ typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
|
||||
*/
|
||||
typedef xof_t* (*xof_constructor_t)(ext_out_function_t algo);
|
||||
|
||||
/**
|
||||
* Constructor function for key derivation functions
|
||||
*
|
||||
* The additional arguments depend on the algorithm, see comments
|
||||
* for key_derivation_function_t.
|
||||
*/
|
||||
typedef kdf_t* (*kdf_constructor_t)(key_derivation_function_t algo, va_list args);
|
||||
|
||||
/**
|
||||
* Constructor function for deterministic random bit generators
|
||||
*/
|
||||
@@ -154,6 +163,20 @@ struct crypto_factory_t {
|
||||
*/
|
||||
xof_t* (*create_xof)(crypto_factory_t *this, ext_out_function_t algo);
|
||||
|
||||
|
||||
/**
|
||||
* Create a key derivation function instance.
|
||||
*
|
||||
* Additional arguments depend on the KDF, please refer to the comments in
|
||||
* key_derivation_function_t.
|
||||
*
|
||||
* @param algo KDF to create
|
||||
* @param ... arguments depending on algo
|
||||
* @return kdf_t instance, NULL if not supported
|
||||
*/
|
||||
kdf_t* (*create_kdf)(crypto_factory_t *this,
|
||||
key_derivation_function_t algo, ...);
|
||||
|
||||
/**
|
||||
* Create a deterministic random bit generator instance.
|
||||
*
|
||||
@@ -305,6 +328,24 @@ struct crypto_factory_t {
|
||||
*/
|
||||
void (*remove_xof)(crypto_factory_t *this, xof_constructor_t create);
|
||||
|
||||
/**
|
||||
* Register a kdf constructor.
|
||||
*
|
||||
* @param algo algorithm to constructor
|
||||
* @param plugin_name plugin that registered this algorithm
|
||||
* @param create constructor function for that algorithm
|
||||
* @return TRUE if registered, FALSE if test vector failed
|
||||
*/
|
||||
bool (*add_kdf)(crypto_factory_t *this, key_derivation_function_t algo,
|
||||
const char *plugin_name, kdf_constructor_t create);
|
||||
|
||||
/**
|
||||
* Unregister a kdf constructor.
|
||||
*
|
||||
* @param create constructor function to unregister
|
||||
*/
|
||||
void (*remove_kdf)(crypto_factory_t *this, kdf_constructor_t create);
|
||||
|
||||
/**
|
||||
* Register a drbg constructor.
|
||||
*
|
||||
@@ -419,6 +460,13 @@ struct crypto_factory_t {
|
||||
*/
|
||||
enumerator_t* (*create_xof_enumerator)(crypto_factory_t *this);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all registered KDFs.
|
||||
*
|
||||
* @return enumerator over key_derivation_function_t, plugin
|
||||
*/
|
||||
enumerator_t* (*create_kdf_enumerator)(crypto_factory_t *this);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all registered DRBGs.
|
||||
*
|
||||
|
||||
@@ -69,6 +69,11 @@ struct private_crypto_tester_t {
|
||||
*/
|
||||
linked_list_t *xof;
|
||||
|
||||
/**
|
||||
* List of KDF test vectors
|
||||
*/
|
||||
linked_list_t *kdf;
|
||||
|
||||
/**
|
||||
* List of DRBG test vectors
|
||||
*/
|
||||
@@ -1186,6 +1191,211 @@ failure:
|
||||
return !failed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a KDF using the given arguments
|
||||
*/
|
||||
static kdf_t *create_kdf_args(kdf_constructor_t create,
|
||||
key_derivation_function_t alg, ...)
|
||||
{
|
||||
va_list args;
|
||||
kdf_t *kdf;
|
||||
|
||||
va_start(args, alg);
|
||||
kdf = create(alg, args);
|
||||
va_end(args);
|
||||
return kdf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a KDF using arguments from the given test vector
|
||||
*/
|
||||
static kdf_t *create_kdf_vector(kdf_constructor_t create,
|
||||
key_derivation_function_t alg,
|
||||
kdf_test_vector_t *vector)
|
||||
{
|
||||
switch (alg)
|
||||
{
|
||||
case KDF_PRF:
|
||||
case KDF_PRF_PLUS:
|
||||
return create_kdf_args(create, alg, vector->arg.prf);
|
||||
case KDF_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given test vector applies to the passed arguments
|
||||
*/
|
||||
static bool kdf_vector_applies(key_derivation_function_t alg,
|
||||
kdf_test_args_t *args, kdf_test_vector_t *vector)
|
||||
{
|
||||
bool applies = FALSE;
|
||||
|
||||
switch (alg)
|
||||
{
|
||||
case KDF_PRF:
|
||||
case KDF_PRF_PLUS:
|
||||
{
|
||||
pseudo_random_function_t prf;
|
||||
VA_ARGS_VGET(args->args, prf);
|
||||
applies = (prf == vector->arg.prf);
|
||||
break;
|
||||
}
|
||||
case KDF_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
return applies;
|
||||
}
|
||||
|
||||
METHOD(crypto_tester_t, test_kdf, bool,
|
||||
private_crypto_tester_t *this, key_derivation_function_t alg,
|
||||
kdf_constructor_t create, kdf_test_args_t *args, u_int *speed,
|
||||
const char *plugin_name)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
kdf_test_vector_t *vector;
|
||||
va_list copy;
|
||||
bool failed = FALSE;
|
||||
u_int tested = 0, construction_failed = 0;
|
||||
|
||||
enumerator = this->kdf->create_enumerator(this->kdf);
|
||||
while (enumerator->enumerate(enumerator, &vector))
|
||||
{
|
||||
kdf_t *kdf;
|
||||
chunk_t out = chunk_empty;
|
||||
|
||||
if (vector->alg != alg ||
|
||||
(args && !kdf_vector_applies(alg, args, vector)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tested++;
|
||||
failed = TRUE;
|
||||
if (args)
|
||||
{
|
||||
va_copy(copy, args->args);
|
||||
kdf = create(alg, copy);
|
||||
va_end(copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
kdf = create_kdf_vector(create, alg, vector);
|
||||
}
|
||||
if (!kdf)
|
||||
{
|
||||
if (args)
|
||||
{
|
||||
DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
|
||||
key_derivation_function_names, alg, plugin_name);
|
||||
break;
|
||||
}
|
||||
/* while there could be a problem, the constructor might just not
|
||||
* be able to create an instance for this test vector, we check
|
||||
* for that at the end */
|
||||
construction_failed++;
|
||||
failed = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vector->key.len &&
|
||||
!kdf->set_param(kdf, KDF_PARAM_KEY, vector->key))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (vector->salt.len &&
|
||||
!kdf->set_param(kdf, KDF_PARAM_SALT, vector->salt))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (kdf_has_fixed_output_length(alg))
|
||||
{
|
||||
if (kdf->get_length(kdf) != vector->out.len)
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
else if (kdf->get_length(kdf) != SIZE_MAX)
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
/* allocated bytes */
|
||||
if (!kdf->allocate_bytes(kdf, vector->out.len, &out))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (!chunk_equals(out, vector->out))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
/* allocate without knowing the length */
|
||||
if (kdf_has_fixed_output_length(alg))
|
||||
{
|
||||
chunk_free(&out);
|
||||
if (!kdf->allocate_bytes(kdf, 0, &out))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (!chunk_equals(out, vector->out))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
/* bytes to existing buffer */
|
||||
memset(out.ptr, 0, out.len);
|
||||
if (!kdf->get_bytes(kdf, out.len, out.ptr))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
if (!chunk_equals(out, vector->out))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
failed = FALSE;
|
||||
failure:
|
||||
kdf->destroy(kdf);
|
||||
chunk_free(&out);
|
||||
if (failed)
|
||||
{
|
||||
DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
|
||||
key_derivation_function_names, alg, plugin_name,
|
||||
get_name(vector));
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!tested)
|
||||
{
|
||||
DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
|
||||
this->required ? "disabled" : "enabled ",
|
||||
key_derivation_function_names, alg, plugin_name);
|
||||
return !this->required;
|
||||
}
|
||||
tested -= construction_failed;
|
||||
if (!tested)
|
||||
{
|
||||
DBG1(DBG_LIB, "%s %N[%s]: unable to apply any available test vectors",
|
||||
this->required ? "disabled" : "enabled ",
|
||||
key_derivation_function_names, alg, plugin_name);
|
||||
return !this->required;
|
||||
}
|
||||
if (!failed)
|
||||
{
|
||||
if (speed)
|
||||
{
|
||||
DBG2(DBG_LIB, "benchmarking for %N is currently not supported",
|
||||
key_derivation_function_names, alg);
|
||||
}
|
||||
DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
|
||||
key_derivation_function_names, alg, plugin_name, tested);
|
||||
}
|
||||
return !failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Benchmark a DRBG
|
||||
*/
|
||||
@@ -1622,6 +1832,12 @@ METHOD(crypto_tester_t, add_xof_vector, void,
|
||||
this->xof->insert_last(this->xof, vector);
|
||||
}
|
||||
|
||||
METHOD(crypto_tester_t, add_kdf_vector, void,
|
||||
private_crypto_tester_t *this, kdf_test_vector_t *vector)
|
||||
{
|
||||
this->kdf->insert_last(this->kdf, vector);
|
||||
}
|
||||
|
||||
METHOD(crypto_tester_t, add_drbg_vector, void,
|
||||
private_crypto_tester_t *this, drbg_test_vector_t *vector)
|
||||
{
|
||||
@@ -1649,6 +1865,7 @@ METHOD(crypto_tester_t, destroy, void,
|
||||
this->hasher->destroy(this->hasher);
|
||||
this->prf->destroy(this->prf);
|
||||
this->xof->destroy(this->xof);
|
||||
this->kdf->destroy(this->kdf);
|
||||
this->drbg->destroy(this->drbg);
|
||||
this->rng->destroy(this->rng);
|
||||
this->dh->destroy(this->dh);
|
||||
@@ -1670,6 +1887,7 @@ crypto_tester_t *crypto_tester_create()
|
||||
.test_hasher = _test_hasher,
|
||||
.test_prf = _test_prf,
|
||||
.test_xof = _test_xof,
|
||||
.test_kdf = _test_kdf,
|
||||
.test_drbg = _test_drbg,
|
||||
.test_rng = _test_rng,
|
||||
.test_dh = _test_dh,
|
||||
@@ -1679,6 +1897,7 @@ crypto_tester_t *crypto_tester_create()
|
||||
.add_hasher_vector = _add_hasher_vector,
|
||||
.add_prf_vector = _add_prf_vector,
|
||||
.add_xof_vector = _add_xof_vector,
|
||||
.add_kdf_vector = _add_kdf_vector,
|
||||
.add_drbg_vector = _add_drbg_vector,
|
||||
.add_rng_vector = _add_rng_vector,
|
||||
.add_dh_vector = _add_dh_vector,
|
||||
@@ -1690,6 +1909,7 @@ crypto_tester_t *crypto_tester_create()
|
||||
.hasher = linked_list_create(),
|
||||
.prf = linked_list_create(),
|
||||
.xof = linked_list_create(),
|
||||
.kdf = linked_list_create(),
|
||||
.drbg = linked_list_create(),
|
||||
.rng = linked_list_create(),
|
||||
.dh = linked_list_create(),
|
||||
|
||||
@@ -32,6 +32,8 @@ typedef struct signer_test_vector_t signer_test_vector_t;
|
||||
typedef struct hasher_test_vector_t hasher_test_vector_t;
|
||||
typedef struct prf_test_vector_t prf_test_vector_t;
|
||||
typedef struct xof_test_vector_t xof_test_vector_t;
|
||||
typedef struct kdf_test_vector_t kdf_test_vector_t;
|
||||
typedef struct kdf_test_args_t kdf_test_args_t;
|
||||
typedef struct drbg_test_vector_t drbg_test_vector_t;
|
||||
typedef struct rng_test_vector_t rng_test_vector_t;
|
||||
typedef struct dh_test_vector_t dh_test_vector_t;
|
||||
@@ -130,6 +132,26 @@ struct xof_test_vector_t {
|
||||
u_char *out;
|
||||
};
|
||||
|
||||
struct kdf_test_vector_t {
|
||||
/** kdf algorithm this test vector tests */
|
||||
key_derivation_function_t alg;
|
||||
/** argument passed to constructor, type depends on alg */
|
||||
union {
|
||||
pseudo_random_function_t prf;
|
||||
} arg;
|
||||
/** optional key */
|
||||
chunk_t key;
|
||||
/** optional salt */
|
||||
chunk_t salt;
|
||||
/** expected output */
|
||||
chunk_t out;
|
||||
};
|
||||
|
||||
struct kdf_test_args_t {
|
||||
/** the arguments used to construct the KDF */
|
||||
va_list args;
|
||||
};
|
||||
|
||||
struct drbg_test_vector_t {
|
||||
/** drbg type this test vector tests */
|
||||
drbg_type_t type;
|
||||
@@ -256,6 +278,22 @@ struct crypto_tester_t {
|
||||
bool (*test_xof)(crypto_tester_t *this, ext_out_function_t alg,
|
||||
xof_constructor_t create,
|
||||
u_int *speed, const char *plugin_name);
|
||||
/**
|
||||
* Test a KDF algorithm.
|
||||
*
|
||||
* If constructor arguments are passed, only matching test vectors are
|
||||
* tried. Otherwise, all are tried and implementations are allowed to fail
|
||||
* construction with unsupported arguments.
|
||||
*
|
||||
* @param alg algorithm to test
|
||||
* @param create constructor function for the XOF
|
||||
* @param args optional arguments to pass to constructor
|
||||
* @param speed speed test result, NULL to omit
|
||||
* @return TRUE if test passed
|
||||
*/
|
||||
bool (*test_kdf)(crypto_tester_t *this, key_derivation_function_t alg,
|
||||
kdf_constructor_t create, kdf_test_args_t *args,
|
||||
u_int *speed, const char *plugin_name);
|
||||
/**
|
||||
* Test a DRBG type.
|
||||
*
|
||||
@@ -332,6 +370,13 @@ struct crypto_tester_t {
|
||||
*/
|
||||
void (*add_xof_vector)(crypto_tester_t *this, xof_test_vector_t *vector);
|
||||
|
||||
/**
|
||||
* Add a test vector to test a KDF.
|
||||
*
|
||||
* @param vector pointer to test vector
|
||||
*/
|
||||
void (*add_kdf_vector)(crypto_tester_t *this, kdf_test_vector_t *vector);
|
||||
|
||||
/**
|
||||
* Add a test vector to test a DRBG.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "kdf.h"
|
||||
|
||||
ENUM(key_derivation_function_names, KDF_UNDEFINED, KDF_PRF_PLUS,
|
||||
"KDF_UNDEFINED",
|
||||
"KDF_PRF",
|
||||
"KDF_PRF_PLUS",
|
||||
);
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool kdf_has_fixed_output_length(key_derivation_function_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case KDF_PRF:
|
||||
return TRUE;
|
||||
case KDF_PRF_PLUS:
|
||||
case KDF_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup kdf kdf
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef KDF_H_
|
||||
#define KDF_H_
|
||||
|
||||
typedef enum key_derivation_function_t key_derivation_function_t;
|
||||
typedef enum kdf_param_t kdf_param_t;
|
||||
typedef struct kdf_t kdf_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Key Derivation Functions (KDF).
|
||||
*/
|
||||
enum key_derivation_function_t {
|
||||
|
||||
KDF_UNDEFINED,
|
||||
|
||||
/**
|
||||
* RFC 7296 prf, expects a pseudo_random_function_t in the constructor,
|
||||
* parameters are KEY (DH secret) and SALT (nonces).
|
||||
* Has a fixed output length.
|
||||
*/
|
||||
KDF_PRF,
|
||||
|
||||
/**
|
||||
* RFC 7296 prf+, expects a pseudo_random_function_t in the constructor,
|
||||
* parameters are KEY (SKEYSEED/SK_d) and SALT (nonces etc.).
|
||||
*/
|
||||
KDF_PRF_PLUS,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for key_derivation_function_t.
|
||||
*/
|
||||
extern enum_name_t *key_derivation_function_names;
|
||||
|
||||
/**
|
||||
* Parameters for KDFs.
|
||||
*/
|
||||
enum kdf_param_t {
|
||||
|
||||
/**
|
||||
* Key used for the key derivation (chunk_t).
|
||||
*/
|
||||
KDF_PARAM_KEY,
|
||||
|
||||
/**
|
||||
* Salt used for the key derivation (chunk_t).
|
||||
*/
|
||||
KDF_PARAM_SALT,
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic interface for Key Derivation Functions (KDF).
|
||||
*
|
||||
* Note that in comparison to xof_t, this interface does not support streaming.
|
||||
* That is, calling get_bytes() or allocate_bytes() multiple times without
|
||||
* changing the input parameters will result in the same output.
|
||||
*/
|
||||
struct kdf_t {
|
||||
|
||||
/**
|
||||
* Return the type of KDF.
|
||||
*
|
||||
* @return KDF type
|
||||
*/
|
||||
key_derivation_function_t (*get_type)(kdf_t *this);
|
||||
|
||||
/**
|
||||
* Output length for KDFs that produce a fixed amount of output.
|
||||
*
|
||||
* @return fixed output length, SIZE_MAX for variable length
|
||||
*/
|
||||
size_t (*get_length)(kdf_t *this);
|
||||
|
||||
/**
|
||||
* Derives a key of the given length and writes it to the buffer.
|
||||
*
|
||||
* @note Fails if out_len doesn't match for KDFs with fixed output length.
|
||||
*
|
||||
* @param out_len number of key bytes requested
|
||||
* @param buffer pointer where the derived key will be written
|
||||
* @return TRUE if key derived successfully
|
||||
*/
|
||||
bool (*get_bytes)(kdf_t *this, size_t out_len,
|
||||
uint8_t *buffer) __attribute__((warn_unused_result));
|
||||
|
||||
/**
|
||||
* Derives a key of the given length and allocates space for it.
|
||||
*
|
||||
* @note Fails if out_len doesn't match for KDFs with fixed output length.
|
||||
* However, for simplified usage, 0 can be passed for out_len to
|
||||
* automatically allocate a chunk of the correct size.
|
||||
*
|
||||
* @param out_len number of key bytes requested, or 0 for KDFs with fixed
|
||||
* output length
|
||||
* @param chunk chunk which will hold the derived key
|
||||
* @return TRUE if key derived successfully
|
||||
*/
|
||||
bool (*allocate_bytes)(kdf_t *this, size_t out_len,
|
||||
chunk_t *chunk) __attribute__((warn_unused_result));
|
||||
|
||||
/**
|
||||
* Set a parameter for this KDF.
|
||||
*
|
||||
* @param param parameter to set
|
||||
* @param ... parameter values
|
||||
* @return TRUE if parameter set successfully
|
||||
*/
|
||||
bool (*set_param)(kdf_t *this, kdf_param_t param,
|
||||
...) __attribute__((warn_unused_result));
|
||||
|
||||
/**
|
||||
* Destroys this KDF object.
|
||||
*/
|
||||
void (*destroy)(kdf_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the given KDF type has a fixed output length.
|
||||
*
|
||||
* @param type KDF type
|
||||
* @return TRUE if the KDF type has a fixed output length
|
||||
*/
|
||||
bool kdf_has_fixed_output_length(key_derivation_function_t type);
|
||||
|
||||
#endif /** KDF_H_ @}*/
|
||||
@@ -131,7 +131,7 @@ static bool verify_padding(crypter_t *crypter, chunk_t *blob)
|
||||
/**
|
||||
* Prototype for key derivation functions.
|
||||
*/
|
||||
typedef bool (*kdf_t)(private_pkcs5_t *this, chunk_t password, chunk_t key);
|
||||
typedef bool (*derive_t)(private_pkcs5_t *this, chunk_t password, chunk_t key);
|
||||
|
||||
/**
|
||||
* Try to decrypt the given data with the given password using the given
|
||||
@@ -139,7 +139,7 @@ typedef bool (*kdf_t)(private_pkcs5_t *this, chunk_t password, chunk_t key);
|
||||
* to, key and iv point to the actual keys and initialization vectors resp.
|
||||
*/
|
||||
static bool decrypt_generic(private_pkcs5_t *this, chunk_t password,
|
||||
chunk_t data, chunk_t *decrypted, kdf_t kdf,
|
||||
chunk_t data, chunk_t *decrypted, derive_t kdf,
|
||||
chunk_t keymat, chunk_t key, chunk_t iv)
|
||||
{
|
||||
if (!kdf(this, password, keymat))
|
||||
@@ -341,7 +341,7 @@ METHOD(pkcs5_t, decrypt, bool,
|
||||
private_pkcs5_t *this, chunk_t password, chunk_t data, chunk_t *decrypted)
|
||||
{
|
||||
chunk_t keymat, key, iv;
|
||||
kdf_t kdf;
|
||||
derive_t kdf;
|
||||
|
||||
if (!ensure_crypto_primitives(this, data) || !decrypted)
|
||||
{
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "prf_plus.h"
|
||||
|
||||
typedef struct private_prf_plus_t private_prf_plus_t;
|
||||
|
||||
typedef bool (*apply_prf_t)(private_prf_plus_t *this);
|
||||
|
||||
/**
|
||||
* Private data of an prf_plus_t object.
|
||||
*
|
||||
*/
|
||||
struct private_prf_plus_t {
|
||||
|
||||
/**
|
||||
* Public interface of prf_plus_t.
|
||||
*/
|
||||
prf_plus_t public;
|
||||
|
||||
/**
|
||||
* PRF to use.
|
||||
*/
|
||||
prf_t *prf;
|
||||
|
||||
/**
|
||||
* Initial seed.
|
||||
*/
|
||||
chunk_t seed;
|
||||
|
||||
/**
|
||||
* Octet which will be appended to the seed if a counter is used.
|
||||
*/
|
||||
uint8_t counter;
|
||||
|
||||
/**
|
||||
* Already given out bytes in current buffer.
|
||||
*/
|
||||
size_t used;
|
||||
|
||||
/**
|
||||
* Buffer to store current PRF result.
|
||||
*/
|
||||
chunk_t buffer;
|
||||
|
||||
/**
|
||||
* The prf application method depending on whether a counter is used.
|
||||
*/
|
||||
apply_prf_t apply_prf;
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply the PRF using the running counter
|
||||
*/
|
||||
static bool apply_prf_counter(private_prf_plus_t *this)
|
||||
{
|
||||
if (!this->prf->get_bytes(this->prf, this->seed, NULL) ||
|
||||
!this->prf->get_bytes(this->prf, chunk_from_thing(this->counter),
|
||||
this->buffer.ptr))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
this->counter++;
|
||||
if (!this->counter)
|
||||
{ /* according to RFC 7296, section 2.13, prf+ is undefined once the
|
||||
* counter wrapped, so let's fail for future calls */
|
||||
this->apply_prf = (void*)return_false;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the PRF using the running counter
|
||||
*/
|
||||
static bool apply_prf(private_prf_plus_t *this)
|
||||
{
|
||||
return this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr);
|
||||
}
|
||||
|
||||
METHOD(prf_plus_t, get_bytes, bool,
|
||||
private_prf_plus_t *this, size_t length, uint8_t *buffer)
|
||||
{
|
||||
size_t round, written = 0;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
if (this->buffer.len == this->used)
|
||||
{ /* buffer used, get next round */
|
||||
if (!this->prf->get_bytes(this->prf, this->buffer, NULL))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!this->apply_prf(this))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
this->used = 0;
|
||||
}
|
||||
round = min(length, this->buffer.len - this->used);
|
||||
memcpy(buffer + written, this->buffer.ptr + this->used, round);
|
||||
|
||||
length -= round;
|
||||
this->used += round;
|
||||
written += round;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(prf_plus_t, allocate_bytes, bool,
|
||||
private_prf_plus_t *this, size_t length, chunk_t *chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(length);
|
||||
if (!get_bytes(this, length, chunk->ptr))
|
||||
{
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(prf_plus_t, destroy, void,
|
||||
private_prf_plus_t *this)
|
||||
{
|
||||
chunk_clear(&this->buffer);
|
||||
chunk_clear(&this->seed);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description in header.
|
||||
*/
|
||||
prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed)
|
||||
{
|
||||
private_prf_plus_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.prf = prf,
|
||||
.seed = chunk_clone(seed),
|
||||
.buffer = chunk_alloc(prf->get_block_size(prf)),
|
||||
.apply_prf = counter ? apply_prf_counter : apply_prf,
|
||||
.counter = 0x01,
|
||||
);
|
||||
|
||||
if (!this->apply_prf(this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup prf_plus prf_plus
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef PRF_PLUS_H_
|
||||
#define PRF_PLUS_H_
|
||||
|
||||
typedef struct prf_plus_t prf_plus_t;
|
||||
|
||||
#include <crypto/prfs/prf.h>
|
||||
|
||||
/**
|
||||
* Implementation of the prf+ function used in IKEv1/IKEv2 keymat extension.
|
||||
*/
|
||||
struct prf_plus_t {
|
||||
|
||||
/**
|
||||
* Get pseudo random bytes.
|
||||
*
|
||||
* @param length number of bytes to get
|
||||
* @param buffer pointer where the generated bytes will be written
|
||||
* @return TRUE if bytes generated successfully
|
||||
*/
|
||||
bool (*get_bytes)(prf_plus_t *this, size_t length,
|
||||
uint8_t *buffer) __attribute__((warn_unused_result));
|
||||
|
||||
/**
|
||||
* Allocate pseudo random bytes.
|
||||
*
|
||||
* @param length number of bytes to get
|
||||
* @param chunk chunk which will hold generated bytes
|
||||
* @return TRUE if bytes allocated successfully
|
||||
*/
|
||||
bool (*allocate_bytes)(prf_plus_t *this, size_t length,
|
||||
chunk_t *chunk) __attribute__((warn_unused_result));
|
||||
|
||||
/**
|
||||
* Destroys a prf_plus_t object.
|
||||
*/
|
||||
void (*destroy)(prf_plus_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new prf_plus_t object.
|
||||
*
|
||||
* @param prf prf object to use, must be destroyed after prf+.
|
||||
* @param counter use an appending counter byte (for IKEv2 variant)
|
||||
* @param seed input seed for prf
|
||||
* @return prf_plus_t object, NULL on failure
|
||||
*/
|
||||
prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed);
|
||||
|
||||
#endif /** PRF_PLUS_H_ @}*/
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <crypto/transform.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
#include <crypto/kdfs/kdf.h>
|
||||
|
||||
ENUM_BEGIN(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS,
|
||||
"ENCRYPTION_ALGORITHM",
|
||||
@@ -23,16 +24,16 @@ ENUM_BEGIN(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS
|
||||
"INTEGRITY_ALGORITHM",
|
||||
"DIFFIE_HELLMAN_GROUP",
|
||||
"EXTENDED_SEQUENCE_NUMBERS");
|
||||
ENUM_NEXT(transform_type_names, HASH_ALGORITHM, DETERMINISTIC_RANDOM_BIT_GENERATOR,
|
||||
ENUM_NEXT(transform_type_names, HASH_ALGORITHM, KEY_DERIVATION_FUNCTION,
|
||||
EXTENDED_SEQUENCE_NUMBERS,
|
||||
"HASH_ALGORITHM",
|
||||
"RANDOM_NUMBER_GENERATOR",
|
||||
"AEAD_ALGORITHM",
|
||||
"COMPRESSION_ALGORITHM",
|
||||
"EXTENDED OUTPUT FUNCTION",
|
||||
"DETERMINISTIC RANDOM BIT GENERATOR");
|
||||
ENUM_END(transform_type_names, DETERMINISTIC_RANDOM_BIT_GENERATOR);
|
||||
|
||||
"DETERMINISTIC RANDOM BIT GENERATOR",
|
||||
"KEY_DERIVATION_FUNCTION");
|
||||
ENUM_END(transform_type_names, KEY_DERIVATION_FUNCTION);
|
||||
|
||||
ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS,
|
||||
"NO_EXT_SEQ",
|
||||
@@ -65,6 +66,8 @@ enum_name_t* transform_get_enum_names(transform_type_t type)
|
||||
return ext_out_function_names;
|
||||
case DETERMINISTIC_RANDOM_BIT_GENERATOR:
|
||||
return drbg_type_names;
|
||||
case KEY_DERIVATION_FUNCTION:
|
||||
return key_derivation_function_names;
|
||||
case COMPRESSION_ALGORITHM:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ enum transform_type_t {
|
||||
COMPRESSION_ALGORITHM = 259,
|
||||
EXTENDED_OUTPUT_FUNCTION = 260,
|
||||
DETERMINISTIC_RANDOM_BIT_GENERATOR = 261,
|
||||
KEY_DERIVATION_FUNCTION = 262,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,7 @@ libstrongswan_botan_la_SOURCES = \
|
||||
botan_rng.h botan_rng.c \
|
||||
botan_hasher.h botan_hasher.c \
|
||||
botan_hmac.h botan_hmac.c \
|
||||
botan_kdf.h botan_kdf.c \
|
||||
botan_crypter.h botan_crypter.c \
|
||||
botan_rsa_public_key.h botan_rsa_public_key.c \
|
||||
botan_rsa_private_key.h botan_rsa_private_key.c \
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "botan_kdf.h"
|
||||
#include "botan_util.h"
|
||||
|
||||
#include <botan/build.h>
|
||||
|
||||
#ifdef BOTAN_HAS_HKDF
|
||||
|
||||
#include <botan/ffi.h>
|
||||
|
||||
typedef struct private_kdf_t private_kdf_t;
|
||||
|
||||
/**
|
||||
* Private data.
|
||||
*/
|
||||
struct private_kdf_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
kdf_t public;
|
||||
|
||||
/**
|
||||
* KDF type.
|
||||
*/
|
||||
key_derivation_function_t type;
|
||||
|
||||
/**
|
||||
* Name of the KDF algorithm in Botan.
|
||||
*/
|
||||
char *name;
|
||||
|
||||
/**
|
||||
* Key for KDF.
|
||||
*/
|
||||
chunk_t key;
|
||||
|
||||
/**
|
||||
* Salt for KDF.
|
||||
*/
|
||||
chunk_t salt;
|
||||
|
||||
/**
|
||||
* Length of the hash output.
|
||||
*/
|
||||
size_t hash_size;
|
||||
};
|
||||
|
||||
METHOD(kdf_t, get_type, key_derivation_function_t,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_length, size_t,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
if (this->type == KDF_PRF_PLUS)
|
||||
{
|
||||
return SIZE_MAX;
|
||||
}
|
||||
return this->hash_size;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
if (this->type == KDF_PRF)
|
||||
{
|
||||
if (out_len != get_length(this) ||
|
||||
botan_kdf(this->name, buffer, out_len, this->key.ptr, this->key.len,
|
||||
this->salt.ptr, this->salt.len, NULL, 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if BOTAN_VERSION_MAJOR == 2
|
||||
/* Botan 2 doesn't check the length, just silently prevents wrapping the
|
||||
* counter and returns truncated output, so do this manually */
|
||||
if (out_len > this->hash_size * 255)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
if (botan_kdf(this->name, buffer, out_len, this->key.ptr, this->key.len,
|
||||
NULL, 0, this->salt.ptr, this->salt.len))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, allocate_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, chunk_t *chunk)
|
||||
{
|
||||
if (this->type == KDF_PRF)
|
||||
{
|
||||
out_len = out_len ?: get_length(this);
|
||||
}
|
||||
|
||||
*chunk = chunk_alloc(out_len);
|
||||
|
||||
if (!get_bytes(this, out_len, chunk->ptr))
|
||||
{
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, set_param, bool,
|
||||
private_kdf_t *this, kdf_param_t param, ...)
|
||||
{
|
||||
chunk_t chunk;
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case KDF_PARAM_KEY:
|
||||
VA_ARGS_GET(param, chunk);
|
||||
chunk_clear(&this->key);
|
||||
this->key = chunk_clone(chunk);
|
||||
break;
|
||||
case KDF_PARAM_SALT:
|
||||
VA_ARGS_GET(param, chunk);
|
||||
chunk_clear(&this->salt);
|
||||
this->salt = chunk_clone(chunk);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, destroy, void,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
chunk_clear(&this->salt);
|
||||
chunk_clear(&this->key);
|
||||
free(this->name);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
kdf_t *botan_kdf_create(key_derivation_function_t algo, va_list args)
|
||||
{
|
||||
private_kdf_t *this;
|
||||
pseudo_random_function_t prf_alg;
|
||||
const char *hash_name;
|
||||
char *name, buf[HASH_SIZE_SHA512];
|
||||
|
||||
if (algo != KDF_PRF && algo != KDF_PRF_PLUS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VA_ARGS_VGET(args, prf_alg);
|
||||
hash_name = botan_get_hash(hasher_algorithm_from_prf(prf_alg));
|
||||
if (!hash_name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (algo == KDF_PRF)
|
||||
{
|
||||
if (asprintf(&name, "HKDF-Extract(%s)", hash_name) <= 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (asprintf(&name, "HKDF-Expand(%s)", hash_name) <= 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_type = _get_type,
|
||||
.get_length = _get_length,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.set_param = _set_param,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.type = algo,
|
||||
.name = name,
|
||||
.hash_size = hasher_hash_size(hasher_algorithm_from_prf(prf_alg)),
|
||||
);
|
||||
|
||||
/* test if we can actually use the algorithm */
|
||||
if (!get_bytes(this, algo == KDF_PRF ? get_length(this) : sizeof(buf), buf))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements key derivation functions (KDF) using Botan, in particular prf+,
|
||||
* which is implemented via Botan's HKDF implementation.
|
||||
*
|
||||
* @defgroup botan_kdf botan_kdf
|
||||
* @{ @ingroup botan_p
|
||||
*/
|
||||
|
||||
#ifndef BOTAN_KDF_H_
|
||||
#define BOTAN_KDF_H_
|
||||
|
||||
#include <crypto/kdfs/kdf.h>
|
||||
|
||||
/**
|
||||
* Creates a new kdf_t object.
|
||||
*
|
||||
* @param algo algorithm to instantiate
|
||||
* @param args algorithm-specific arguments
|
||||
* @return kdf_t object, NULL if not supported
|
||||
*/
|
||||
kdf_t *botan_kdf_create(key_derivation_function_t algo, va_list args);
|
||||
|
||||
#endif /** BOTAN_KDF_H_ @}*/
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "botan_crypter.h"
|
||||
#include "botan_diffie_hellman.h"
|
||||
#include "botan_hmac.h"
|
||||
#include "botan_kdf.h"
|
||||
#include "botan_rsa_public_key.h"
|
||||
#include "botan_rsa_private_key.h"
|
||||
#include "botan_ec_diffie_hellman.h"
|
||||
@@ -209,6 +210,13 @@ METHOD(plugin_t, get_features, int,
|
||||
#endif
|
||||
#endif /* BOTAN_HAS_HMAC */
|
||||
|
||||
/* kdfs */
|
||||
#ifdef BOTAN_HAS_HKDF
|
||||
PLUGIN_REGISTER(SIGNER, botan_kdf_create),
|
||||
PLUGIN_PROVIDE(KDF, KDF_PRF),
|
||||
PLUGIN_PROVIDE(KDF, KDF_PRF_PLUS),
|
||||
#endif /* BOTAN_HAS_HKDF */
|
||||
|
||||
/* generic key loaders */
|
||||
#if defined (BOTAN_HAS_RSA) || defined(BOTAN_HAS_ECDSA) || \
|
||||
defined(BOTAN_HAS_ED25519)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = \
|
||||
$(PLUGIN_CFLAGS)
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-kdf.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-kdf.la
|
||||
endif
|
||||
|
||||
libstrongswan_kdf_la_SOURCES = \
|
||||
kdf_plugin.h kdf_plugin.c \
|
||||
kdf_kdf.h kdf_kdf.c
|
||||
|
||||
libstrongswan_kdf_la_LDFLAGS = -module -avoid-version
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "kdf_kdf.h"
|
||||
|
||||
typedef struct private_kdf_t private_kdf_t;
|
||||
|
||||
/**
|
||||
* Private data.
|
||||
*/
|
||||
struct private_kdf_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
kdf_t public;
|
||||
|
||||
/**
|
||||
* KDF type.
|
||||
*/
|
||||
key_derivation_function_t type;
|
||||
|
||||
/**
|
||||
* Underlying PRF.
|
||||
*/
|
||||
prf_t *prf;
|
||||
|
||||
/**
|
||||
* Salt value.
|
||||
*/
|
||||
chunk_t salt;
|
||||
};
|
||||
|
||||
METHOD(kdf_t, get_type, key_derivation_function_t,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_length, size_t,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
if (this->type == KDF_PRF_PLUS)
|
||||
{
|
||||
return SIZE_MAX;
|
||||
}
|
||||
return this->prf->get_block_size(this->prf);
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_bytes_prf_plus, bool,
|
||||
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
chunk_t block, previous = chunk_empty;
|
||||
uint8_t counter = 1, *out = buffer;
|
||||
size_t len;
|
||||
bool success = TRUE;
|
||||
|
||||
block = chunk_alloca(this->prf->get_block_size(this->prf));
|
||||
if (out_len > block.len * 255)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (out_len)
|
||||
{
|
||||
if (!this->prf->get_bytes(this->prf, previous, NULL) ||
|
||||
!this->prf->get_bytes(this->prf, this->salt, NULL) ||
|
||||
!this->prf->get_bytes(this->prf, chunk_from_thing(counter),
|
||||
block.ptr))
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
len = min(out_len, block.len);
|
||||
memcpy(out, block.ptr, len);
|
||||
previous = chunk_create(out, block.len);
|
||||
|
||||
out_len -= len;
|
||||
out += len;
|
||||
counter++;
|
||||
}
|
||||
memwipe(block.ptr, block.len);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
if (out_len != get_length(this))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return this->prf->get_bytes(this->prf, this->salt, buffer);
|
||||
}
|
||||
|
||||
METHOD(kdf_t, allocate_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, chunk_t *chunk)
|
||||
{
|
||||
if (this->type == KDF_PRF)
|
||||
{
|
||||
out_len = out_len ?: get_length(this);
|
||||
}
|
||||
|
||||
*chunk = chunk_alloc(out_len);
|
||||
|
||||
if (!this->public.get_bytes(&this->public, out_len, chunk->ptr))
|
||||
{
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, set_param, bool,
|
||||
private_kdf_t *this, kdf_param_t param, ...)
|
||||
{
|
||||
chunk_t chunk;
|
||||
bool success = FALSE;
|
||||
|
||||
if (this->type == KDF_PRF)
|
||||
{ /* IKEv2 uses the nonces etc., which we receive as SALT, as PRF key and
|
||||
* the DH secret as salt */
|
||||
switch (param)
|
||||
{
|
||||
case KDF_PARAM_KEY:
|
||||
param = KDF_PARAM_SALT;
|
||||
break;
|
||||
case KDF_PARAM_SALT:
|
||||
param = KDF_PARAM_KEY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case KDF_PARAM_KEY:
|
||||
VA_ARGS_GET(param, chunk);
|
||||
success = this->prf->set_key(this->prf, chunk);
|
||||
break;
|
||||
case KDF_PARAM_SALT:
|
||||
VA_ARGS_GET(param, chunk);
|
||||
chunk_clear(&this->salt);
|
||||
this->salt = chunk_clone(chunk);
|
||||
success = TRUE;
|
||||
break;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, destroy, void,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
this->prf->destroy(this->prf);
|
||||
chunk_clear(&this->salt);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
kdf_t *kdf_kdf_create(key_derivation_function_t algo, va_list args)
|
||||
{
|
||||
private_kdf_t *this;
|
||||
pseudo_random_function_t prf_alg;
|
||||
prf_t *prf;
|
||||
|
||||
if (algo != KDF_PRF && algo != KDF_PRF_PLUS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VA_ARGS_VGET(args, prf_alg);
|
||||
prf = lib->crypto->create_prf(lib->crypto, prf_alg);
|
||||
if (!prf)
|
||||
{
|
||||
DBG1(DBG_LIB, "failed to create %N for %N",
|
||||
pseudo_random_function_names, prf_alg,
|
||||
key_derivation_function_names, algo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_type = _get_type,
|
||||
.get_length = _get_length,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.set_param = _set_param,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.type = algo,
|
||||
.prf = prf,
|
||||
);
|
||||
|
||||
if (algo == KDF_PRF_PLUS)
|
||||
{
|
||||
this->public.get_bytes = _get_bytes_prf_plus;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements a KDF wrapper around PRFs, and prf+ as defined in RFC 7296,
|
||||
* section 2.13:
|
||||
*
|
||||
* @verbatim
|
||||
prf+ (K,S) = T1 | T2 | T3 | T4 | ...
|
||||
|
||||
where:
|
||||
T1 = prf (K, S | 0x01)
|
||||
T2 = prf (K, T1 | S | 0x02)
|
||||
T3 = prf (K, T2 | S | 0x03)
|
||||
T4 = prf (K, T3 | S | 0x04)
|
||||
...
|
||||
* @endverbatim
|
||||
*
|
||||
* @defgroup kdf_kdf kdf_kdf
|
||||
* @{ @ingroup kdf_p
|
||||
*/
|
||||
|
||||
#ifndef KDF_KDF_H_
|
||||
#define KDF_KDF_H_
|
||||
|
||||
#include <crypto/kdfs/kdf.h>
|
||||
|
||||
/**
|
||||
* Create a kdf_t object
|
||||
*
|
||||
* @param algo KDF_PRF_PLUS
|
||||
* @param args pseudo_random_function_t of the underlying PRF
|
||||
* @return kdf_t object, NULL if not supported
|
||||
*/
|
||||
kdf_t *kdf_kdf_create(key_derivation_function_t algo, va_list args);
|
||||
|
||||
#endif /** KDF_KDF_H_ @}*/
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "kdf_plugin.h"
|
||||
#include "kdf_kdf.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct private_kdf_plugin_t private_kdf_plugin_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_kdf_plugin_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
kdf_plugin_t public;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_kdf_plugin_t *this)
|
||||
{
|
||||
return "kdf";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_kdf_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_REGISTER(KDF, kdf_kdf_create),
|
||||
PLUGIN_PROVIDE(KDF, KDF_PRF),
|
||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA1),
|
||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_256),
|
||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_384),
|
||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_512),
|
||||
PLUGIN_SDEPEND(PRF, PRF_AES128_XCBC),
|
||||
PLUGIN_SDEPEND(PRF, PRF_AES128_CMAC),
|
||||
PLUGIN_PROVIDE(KDF, KDF_PRF_PLUS),
|
||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA1),
|
||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_256),
|
||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_384),
|
||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_512),
|
||||
PLUGIN_SDEPEND(PRF, PRF_AES128_XCBC),
|
||||
PLUGIN_SDEPEND(PRF, PRF_AES128_CMAC),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_kdf_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
plugin_t *kdf_plugin_create()
|
||||
{
|
||||
private_kdf_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup kdf_p kdf
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @defgroup kdf_plugin kdf_plugin
|
||||
* @{ @ingroup kdf_p
|
||||
*/
|
||||
|
||||
#ifndef KDF_PLUGIN_H_
|
||||
#define KDF_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct kdf_plugin_t kdf_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin implementing the key derivation functions (KDF) in software.
|
||||
*/
|
||||
struct kdf_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** KDF_PLUGIN_H_ @}*/
|
||||
@@ -33,6 +33,7 @@ libstrongswan_openssl_la_SOURCES = \
|
||||
openssl_pkcs12.c openssl_pkcs12.h \
|
||||
openssl_rng.c openssl_rng.h \
|
||||
openssl_hmac.c openssl_hmac.h \
|
||||
openssl_kdf.c openssl_kdf.h \
|
||||
openssl_aead.c openssl_aead.h \
|
||||
openssl_x_diffie_hellman.c openssl_x_diffie_hellman.h \
|
||||
openssl_ed_private_key.c openssl_ed_private_key.h \
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#if !defined(OPENSSL_NO_HMAC) && OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/kdf.h>
|
||||
|
||||
#include "openssl_kdf.h"
|
||||
|
||||
typedef struct private_kdf_t private_kdf_t;
|
||||
|
||||
/**
|
||||
* Private data.
|
||||
*/
|
||||
struct private_kdf_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
kdf_t public;
|
||||
|
||||
/**
|
||||
* KDF type.
|
||||
*/
|
||||
key_derivation_function_t type;
|
||||
|
||||
/**
|
||||
* Hasher to use for underlying PRF.
|
||||
*/
|
||||
const EVP_MD *hasher;
|
||||
|
||||
/**
|
||||
* Key for KDF. Stored here because OpenSSL's HKDF API does not provide a
|
||||
* way to clear the "info" field in the context, new data is always
|
||||
* appended (up to 1024 bytes).
|
||||
*/
|
||||
chunk_t key;
|
||||
|
||||
/**
|
||||
* Salt for prf+ (see above).
|
||||
*/
|
||||
chunk_t salt;
|
||||
};
|
||||
|
||||
METHOD(kdf_t, get_type, key_derivation_function_t,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_length, size_t,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
if (this->type == KDF_PRF_PLUS)
|
||||
{
|
||||
return SIZE_MAX;
|
||||
}
|
||||
return EVP_MD_size(this->hasher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parameters as a appropriate for the given KDF type.
|
||||
*/
|
||||
static bool set_params(private_kdf_t *this, EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
if (this->type == KDF_PRF)
|
||||
{
|
||||
return EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) > 0 &&
|
||||
EVP_PKEY_CTX_set1_hkdf_key(ctx, this->key.ptr, this->key.len) > 0 &&
|
||||
EVP_PKEY_CTX_set1_hkdf_salt(ctx, this->salt.ptr, this->salt.len) > 0;
|
||||
}
|
||||
/* for HKDF-Expand() we map the salt to the "info" field */
|
||||
return EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) > 0 &&
|
||||
EVP_PKEY_CTX_set1_hkdf_key(ctx, this->key.ptr, this->key.len) > 0 &&
|
||||
EVP_PKEY_CTX_add1_hkdf_info(ctx, this->salt.ptr, this->salt.len) > 0;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
EVP_PKEY_CTX *ctx;
|
||||
|
||||
if (this->type == KDF_PRF && out_len != get_length(this))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
|
||||
if (!ctx ||
|
||||
EVP_PKEY_derive_init(ctx) <= 0 ||
|
||||
EVP_PKEY_CTX_set_hkdf_md(ctx, this->hasher) <= 0 ||
|
||||
!set_params(this, ctx) ||
|
||||
EVP_PKEY_derive(ctx, buffer, &out_len) <= 0)
|
||||
{
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return FALSE;
|
||||
}
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, allocate_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, chunk_t *chunk)
|
||||
{
|
||||
if (this->type == KDF_PRF)
|
||||
{
|
||||
out_len = out_len ?: get_length(this);
|
||||
}
|
||||
|
||||
*chunk = chunk_alloc(out_len);
|
||||
|
||||
if (!get_bytes(this, out_len, chunk->ptr))
|
||||
{
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, set_param, bool,
|
||||
private_kdf_t *this, kdf_param_t param, ...)
|
||||
{
|
||||
chunk_t chunk;
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case KDF_PARAM_KEY:
|
||||
VA_ARGS_GET(param, chunk);
|
||||
chunk_clear(&this->key);
|
||||
this->key = chunk_clone(chunk);
|
||||
break;
|
||||
case KDF_PARAM_SALT:
|
||||
VA_ARGS_GET(param, chunk);
|
||||
chunk_clear(&this->salt);
|
||||
this->salt = chunk_clone(chunk);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, destroy, void,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
chunk_clear(&this->salt);
|
||||
chunk_clear(&this->key);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
kdf_t *openssl_kdf_create(key_derivation_function_t algo, va_list args)
|
||||
{
|
||||
private_kdf_t *this;
|
||||
pseudo_random_function_t prf_alg;
|
||||
char *name, buf[EVP_MAX_MD_SIZE];
|
||||
|
||||
if (algo != KDF_PRF && algo != KDF_PRF_PLUS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VA_ARGS_VGET(args, prf_alg);
|
||||
name = enum_to_name(hash_algorithm_short_names,
|
||||
hasher_algorithm_from_prf(prf_alg));
|
||||
if (!name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_type = _get_type,
|
||||
.get_length = _get_length,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.set_param = _set_param,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.type = algo,
|
||||
.hasher = EVP_get_digestbyname(name),
|
||||
/* use a lengthy key to test the implementation below to make sure the
|
||||
* algorithms are usable, see openssl_hmac.c for details */
|
||||
.key = chunk_clone(chunk_from_str("00000000000000000000000000000000")),
|
||||
);
|
||||
|
||||
if (!this->hasher ||
|
||||
!get_bytes(this, algo == KDF_PRF ? get_length(this) : sizeof(buf), buf))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_NO_HMAC && OPENSSL_VERSION_NUMBER */
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements key derivation functions (KDF) via OpenSSL, in particular prf+,
|
||||
* which is implemented via OpenSSL's HKDF implementation.
|
||||
*
|
||||
* @defgroup openssl_kdf openssl_kdf
|
||||
* @{ @ingroup openssl_p
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_KDF_H_
|
||||
#define OPENSSL_KDF_H_
|
||||
|
||||
#include <crypto/kdfs/kdf.h>
|
||||
|
||||
/**
|
||||
* Creates a new kdf_t object.
|
||||
*
|
||||
* @param algo algorithm to instantiate
|
||||
* @param args algorithm-specific arguments
|
||||
* @return kdf_t object, NULL if not supported
|
||||
*/
|
||||
kdf_t *openssl_kdf_create(key_derivation_function_t algo, va_list args);
|
||||
|
||||
#endif /** OPENSSL_KDF_H_ @}*/
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "openssl_pkcs12.h"
|
||||
#include "openssl_rng.h"
|
||||
#include "openssl_hmac.h"
|
||||
#include "openssl_kdf.h"
|
||||
#include "openssl_aead.h"
|
||||
#include "openssl_x_diffie_hellman.h"
|
||||
#include "openssl_ed_public_key.h"
|
||||
@@ -654,6 +655,12 @@ METHOD(plugin_t, get_features, int,
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256),
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_512),
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||
/* HKDF is available since 1.1.0, expand-only mode only since 1.1.1 */
|
||||
PLUGIN_REGISTER(KDF, openssl_kdf_create),
|
||||
PLUGIN_PROVIDE(KDF, KDF_PRF),
|
||||
PLUGIN_PROVIDE(KDF, KDF_PRF_PLUS),
|
||||
#endif
|
||||
#endif /* OPENSSL_NO_HMAC */
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_AES)) || \
|
||||
(OPENSSL_VERSION_NUMBER >= 0x1010000fL && !defined(OPENSSL_NO_CHACHA))
|
||||
|
||||
@@ -32,6 +32,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
|
||||
"HASHER",
|
||||
"PRF",
|
||||
"XOF",
|
||||
"KDF",
|
||||
"DRBG",
|
||||
"DH",
|
||||
"RNG",
|
||||
@@ -93,6 +94,9 @@ uint32_t plugin_feature_hash(plugin_feature_t *feature)
|
||||
case FEATURE_XOF:
|
||||
data = chunk_from_thing(feature->arg.xof);
|
||||
break;
|
||||
case FEATURE_KDF:
|
||||
data = chunk_from_thing(feature->arg.kdf);
|
||||
break;
|
||||
case FEATURE_DRBG:
|
||||
data = chunk_from_thing(feature->arg.drbg);
|
||||
break;
|
||||
@@ -171,6 +175,8 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
|
||||
return a->arg.prf == b->arg.prf;
|
||||
case FEATURE_XOF:
|
||||
return a->arg.xof == b->arg.xof;
|
||||
case FEATURE_KDF:
|
||||
return a->arg.kdf == b->arg.kdf;
|
||||
case FEATURE_DRBG:
|
||||
return a->arg.drbg == b->arg.drbg;
|
||||
case FEATURE_DH:
|
||||
@@ -232,6 +238,7 @@ bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b)
|
||||
case FEATURE_HASHER:
|
||||
case FEATURE_PRF:
|
||||
case FEATURE_XOF:
|
||||
case FEATURE_KDF:
|
||||
case FEATURE_DRBG:
|
||||
case FEATURE_DH:
|
||||
case FEATURE_NONCE_GEN:
|
||||
@@ -327,6 +334,13 @@ char* plugin_feature_get_string(plugin_feature_t *feature)
|
||||
return str;
|
||||
}
|
||||
break;
|
||||
case FEATURE_KDF:
|
||||
if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
|
||||
key_derivation_function_names, feature->arg.kdf) > 0)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
break;
|
||||
case FEATURE_DRBG:
|
||||
if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
|
||||
drbg_type_names, feature->arg.drbg) > 0)
|
||||
@@ -472,6 +486,17 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
|
||||
name = plugin->get_name(plugin);
|
||||
switch (feature->type)
|
||||
{
|
||||
case FEATURE_NONE:
|
||||
case FEATURE_PRIVKEY_SIGN:
|
||||
case FEATURE_PRIVKEY_DECRYPT:
|
||||
case FEATURE_PUBKEY_VERIFY:
|
||||
case FEATURE_PUBKEY_ENCRYPT:
|
||||
case FEATURE_EAP_SERVER:
|
||||
case FEATURE_EAP_PEER:
|
||||
case FEATURE_XAUTH_SERVER:
|
||||
case FEATURE_XAUTH_PEER:
|
||||
case FEATURE_CUSTOM:
|
||||
break;
|
||||
case FEATURE_CRYPTER:
|
||||
lib->crypto->add_crypter(lib->crypto, feature->arg.crypter.alg,
|
||||
feature->arg.crypter.key_size,
|
||||
@@ -498,6 +523,10 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
|
||||
lib->crypto->add_xof(lib->crypto, feature->arg.xof,
|
||||
name, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_KDF:
|
||||
lib->crypto->add_kdf(lib->crypto, feature->arg.kdf,
|
||||
name, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_DRBG:
|
||||
lib->crypto->add_drbg(lib->crypto, feature->arg.drbg,
|
||||
name, reg->arg.reg.f);
|
||||
@@ -547,8 +576,6 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
|
||||
case FEATURE_RESOLVER:
|
||||
lib->resolver->add_resolver(lib->resolver, reg->arg.reg.f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -574,6 +601,17 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
|
||||
}
|
||||
switch (feature->type)
|
||||
{
|
||||
case FEATURE_NONE:
|
||||
case FEATURE_PRIVKEY_SIGN:
|
||||
case FEATURE_PRIVKEY_DECRYPT:
|
||||
case FEATURE_PUBKEY_VERIFY:
|
||||
case FEATURE_PUBKEY_ENCRYPT:
|
||||
case FEATURE_EAP_SERVER:
|
||||
case FEATURE_EAP_PEER:
|
||||
case FEATURE_XAUTH_SERVER:
|
||||
case FEATURE_XAUTH_PEER:
|
||||
case FEATURE_CUSTOM:
|
||||
break;
|
||||
case FEATURE_CRYPTER:
|
||||
lib->crypto->remove_crypter(lib->crypto, reg->arg.reg.f);
|
||||
break;
|
||||
@@ -592,6 +630,9 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
|
||||
case FEATURE_XOF:
|
||||
lib->crypto->remove_xof(lib->crypto, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_KDF:
|
||||
lib->crypto->remove_kdf(lib->crypto, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_DRBG:
|
||||
lib->crypto->remove_drbg(lib->crypto, reg->arg.reg.f);
|
||||
break;
|
||||
@@ -628,8 +669,6 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
|
||||
case FEATURE_RESOLVER:
|
||||
lib->resolver->remove_resolver(lib->resolver, reg->arg.reg.f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -113,6 +113,8 @@ struct plugin_feature_t {
|
||||
FEATURE_PRF,
|
||||
/** xof_t */
|
||||
FEATURE_XOF,
|
||||
/** kdf_t */
|
||||
FEATURE_KDF,
|
||||
/** drbg_t */
|
||||
FEATURE_DRBG,
|
||||
/** diffie_hellman_t */
|
||||
@@ -176,8 +178,10 @@ struct plugin_feature_t {
|
||||
integrity_algorithm_t signer;
|
||||
/** FEATURE_PRF */
|
||||
pseudo_random_function_t prf;
|
||||
/** FEATURE_XOFF */
|
||||
/** FEATURE_XOF */
|
||||
ext_out_function_t xof;
|
||||
/** FEATURE_KDF */
|
||||
key_derivation_function_t kdf;
|
||||
/** FEATURE_DRBG */
|
||||
drbg_type_t drbg;
|
||||
/** FEATURE_HASHER */
|
||||
@@ -288,6 +292,7 @@ struct plugin_feature_t {
|
||||
#define _PLUGIN_FEATURE_HASHER(kind, alg) __PLUGIN_FEATURE(kind, HASHER, .hasher = alg)
|
||||
#define _PLUGIN_FEATURE_PRF(kind, alg) __PLUGIN_FEATURE(kind, PRF, .prf = alg)
|
||||
#define _PLUGIN_FEATURE_XOF(kind, alg) __PLUGIN_FEATURE(kind, XOF, .xof = alg)
|
||||
#define _PLUGIN_FEATURE_KDF(kind, alg) __PLUGIN_FEATURE(kind, KDF, .kdf = alg)
|
||||
#define _PLUGIN_FEATURE_DRBG(kind, type) __PLUGIN_FEATURE(kind, DRBG, .drbg = type)
|
||||
#define _PLUGIN_FEATURE_DH(kind, group) __PLUGIN_FEATURE(kind, DH, .dh_group = group)
|
||||
#define _PLUGIN_FEATURE_RNG(kind, quality) __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality)
|
||||
@@ -322,6 +327,7 @@ struct plugin_feature_t {
|
||||
#define _PLUGIN_FEATURE_REGISTER_HASHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
#define _PLUGIN_FEATURE_REGISTER_PRF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
#define _PLUGIN_FEATURE_REGISTER_XOF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
#define _PLUGIN_FEATURE_REGISTER_KDF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
#define _PLUGIN_FEATURE_REGISTER_DRBG(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
#define _PLUGIN_FEATURE_REGISTER_DH(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
#define _PLUGIN_FEATURE_REGISTER_RNG(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
|
||||
@@ -30,6 +30,8 @@ libstrongswan_test_vectors_la_SOURCES = \
|
||||
test_vectors/cast.c \
|
||||
test_vectors/des.c \
|
||||
test_vectors/idea.c \
|
||||
test_vectors/kdf_prf.c \
|
||||
test_vectors/kdf_prf_plus.c \
|
||||
test_vectors/null.c \
|
||||
test_vectors/rc2.c \
|
||||
test_vectors/rc5.c \
|
||||
|
||||
@@ -220,6 +220,20 @@ TEST_VECTOR_HASHER(sha3_256_255)
|
||||
TEST_VECTOR_HASHER(sha3_384_255)
|
||||
TEST_VECTOR_HASHER(sha3_512_255)
|
||||
|
||||
TEST_VECTOR_KDF(prf_sha256_1)
|
||||
TEST_VECTOR_KDF(prf_sha256_2)
|
||||
TEST_VECTOR_KDF(prf_sha384_1)
|
||||
TEST_VECTOR_KDF(prf_sha384_2)
|
||||
TEST_VECTOR_KDF(prf_sha512_1)
|
||||
TEST_VECTOR_KDF(prf_sha512_2)
|
||||
TEST_VECTOR_KDF(prf_plus_sha256_old)
|
||||
TEST_VECTOR_KDF(prf_plus_sha256_1)
|
||||
TEST_VECTOR_KDF(prf_plus_sha256_2)
|
||||
TEST_VECTOR_KDF(prf_plus_sha384_1)
|
||||
TEST_VECTOR_KDF(prf_plus_sha384_2)
|
||||
TEST_VECTOR_KDF(prf_plus_sha512_1)
|
||||
TEST_VECTOR_KDF(prf_plus_sha512_2)
|
||||
|
||||
TEST_VECTOR_PRF(aes_xcbc_p1)
|
||||
TEST_VECTOR_PRF(aes_xcbc_p2)
|
||||
TEST_VECTOR_PRF(aes_xcbc_p3)
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <crypto/crypto_tester.h>
|
||||
|
||||
/**
|
||||
* The following test vectors are from CAVP/SP 800-135 for IKEv2.
|
||||
*
|
||||
* key = g^ir, salt = Ni | Nr (one vector with min. and one with max. size for
|
||||
* nonces)
|
||||
*/
|
||||
kdf_test_vector_t prf_sha256_1 = {
|
||||
.alg = KDF_PRF, .arg.prf = PRF_HMAC_SHA2_256,
|
||||
.key = chunk_from_chars(
|
||||
0x42,0x96,0x8e,0x5d,0x0c,0xcc,0x3c,0xfc,0x5a,0x3e,0x4b,0xc1,0xbb,0xa3,0x70,0xce,
|
||||
0xa1,0xfa,0xe0,0xd5,0x4c,0x49,0xcc,0xba,0x34,0xb2,0xbe,0xe8,0x04,0xbe,0xeb,0x2e,
|
||||
0x9e,0x8c,0x57,0xa4,0xe0,0x1b,0xd4,0x51,0x02,0xcf,0x24,0x33,0xaa,0xcc,0x6c,0xfe,
|
||||
0xc0,0x67,0x92,0xf3,0x63,0xe5,0x17,0x0e,0x6a,0xa6,0x65,0x02,0x74,0xe9,0x06,0x64,
|
||||
0x8e,0x44,0x9d,0x27,0xa8,0xf0,0x0b,0x5b,0x44,0x26,0x19,0x82,0xc9,0x83,0x5c,0x74,
|
||||
0x8a,0x75,0x1e,0xc5,0x13,0x8e,0xaa,0xcc,0x5e,0x02,0x56,0x61,0x33,0x95,0x38,0xa6,
|
||||
0x1b,0xf4,0x18,0xe4,0x54,0x69,0x9e,0x19,0xc3,0x2d,0xb8,0xd9,0xce,0x5d,0xd8,0x6b,
|
||||
0x22,0x0f,0x1e,0x89,0xaf,0xc5,0x87,0x2e,0x68,0xbe,0x36,0xcb,0x1a,0x0c,0x88,0x66),
|
||||
.salt = chunk_from_chars(
|
||||
0xed,0x80,0xdc,0x79,0x91,0x2c,0x32,0xa9,0x35,0xfb,0x6d,0x1a,0x3f,0xea,0xc0,0x78),
|
||||
.out = chunk_from_chars(
|
||||
0x37,0xfd,0xe9,0x0b,0x81,0xd6,0x36,0x92,0x62,0x0f,0x67,0x36,0x7b,0x62,0x09,0x2e,
|
||||
0x3e,0xfd,0xc6,0xa0,0x35,0x09,0x13,0x7d,0x73,0x10,0x04,0x76,0x7f,0xf3,0x50,0x10),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_sha256_2 = {
|
||||
.alg = KDF_PRF, .arg.prf = PRF_HMAC_SHA2_256,
|
||||
.key = chunk_from_chars(
|
||||
0xb0,0x70,0x20,0x8f,0x89,0x47,0xdf,0x4f,0x7d,0x12,0x76,0x16,0x1f,0x40,0x7f,0x7b,
|
||||
0x7f,0x5c,0x4a,0x49,0xac,0x79,0xf0,0xcc,0x0c,0x7d,0x4e,0x28,0x48,0x4c,0x6f,0x85,
|
||||
0x84,0xf0,0x00,0x7b,0x9b,0xf0,0xe0,0x5f,0xdb,0x59,0x61,0xa1,0x7d,0x3a,0xa8,0x5c,
|
||||
0x6e,0x3f,0x55,0x71,0x29,0x6a,0x43,0xba,0x89,0x6c,0xdc,0x88,0xc1,0xa4,0x45,0x7f,
|
||||
0xb1,0x2c,0xbe,0x56,0xca,0x4a,0x20,0xc9,0xa7,0xe1,0x9a,0xdc,0x67,0x45,0x3c,0x4a,
|
||||
0xde,0x53,0x9e,0x25,0x9f,0x82,0x5f,0xf9,0x4c,0x9a,0x83,0xf8,0x39,0x60,0x2f,0x86,
|
||||
0x51,0xc9,0x27,0x6d,0x8e,0x44,0x4e,0xcb,0x95,0xa0,0x54,0x0e,0xe7,0xea,0x32,0x20,
|
||||
0xa9,0x22,0x34,0x5e,0xd9,0x9e,0xf7,0xe7,0xad,0x32,0xb1,0x9d,0x46,0x10,0xe9,0xef),
|
||||
.salt = chunk_from_chars(
|
||||
0xef,0xa7,0x29,0x13,0x18,0x22,0x78,0xff,0xbd,0x14,0xe7,0x89,0x20,0xc0,0x62,0x51,
|
||||
0x9a,0xba,0xb8,0xc1,0x6e,0x5e,0xd7,0x0c,0x08,0x41,0xa4,0x8c,0xdb,0x98,0x23,0x7e,
|
||||
0xe9,0x3f,0x73,0x5f,0xb2,0xdf,0x18,0x43,0x58,0xaa,0xdc,0x13,0xd8,0x3f,0x43,0xfe,
|
||||
0x8d,0x87,0x05,0x17,0x6c,0x8c,0xa3,0x13,0x82,0x5a,0x1b,0xcd,0xf7,0x79,0x11,0xc5,
|
||||
0x98,0x00,0x16,0x71,0xff,0xbf,0x01,0x4e,0x37,0xa8,0xc0,0x4d,0x49,0xa7,0x83,0x9d,
|
||||
0xfe,0xa6,0xcd,0xc5,0x87,0x68,0x8d,0x45,0x88,0xfe,0x43,0x23,0x5b,0x71,0x69,0x3f,
|
||||
0xfd,0x07,0x29,0x33,0x86,0xb6,0xbf,0x4c,0x19,0x9e,0x33,0x61,0x65,0xb2,0x60,0x78,
|
||||
0x77,0x36,0xf5,0x4b,0xe9,0x5d,0xb6,0x91,0x16,0x38,0x8b,0xc2,0xec,0xa2,0xb3,0xb2,
|
||||
0x94,0x84,0x71,0x74,0x17,0xbb,0x3c,0x71,0x81,0x4c,0xe1,0x3b,0x84,0x44,0x6d,0xc3,
|
||||
0x96,0x4c,0x30,0x29,0x84,0xf9,0x77,0x81,0xf6,0x31,0x66,0x24,0x08,0x90,0x10,0x7c,
|
||||
0x2e,0x75,0x1a,0x00,0x43,0x6f,0x7c,0x3c,0x9f,0xf1,0x27,0x60,0xe4,0x9d,0x91,0x56,
|
||||
0x3b,0xe6,0x03,0xfd,0x96,0x41,0xa0,0xa6,0x49,0x18,0xa9,0x32,0x91,0xed,0x11,0x3d,
|
||||
0xb1,0x2f,0x97,0x07,0x60,0x9d,0x17,0x20,0x96,0xeb,0x58,0xf9,0x15,0x44,0x74,0xda,
|
||||
0x40,0xc1,0xf5,0xc0,0x90,0x3e,0x9c,0xa2,0xf9,0x1b,0xa6,0x60,0x07,0x75,0xdf,0x71,
|
||||
0x66,0xca,0xf8,0xe3,0x27,0x85,0x9e,0x67,0x62,0x32,0xd3,0x40,0x46,0x04,0x4c,0xee,
|
||||
0x43,0xf9,0x01,0x9f,0x04,0x68,0x56,0x12,0x63,0x5b,0x99,0xcb,0xeb,0xcb,0x36,0x3d,
|
||||
0x56,0x5e,0xaf,0x0e,0x54,0x7e,0xec,0xb9,0x41,0xc9,0x94,0xdf,0xd4,0x71,0xed,0x56,
|
||||
0x43,0xc0,0x87,0x74,0x4f,0x77,0x09,0xcc,0x3e,0x25,0x10,0xf2,0x74,0x26,0xc6,0x2c,
|
||||
0x0f,0xf3,0xac,0xb3,0xc2,0x76,0x61,0xd2,0x6a,0x6d,0x83,0xc2,0xa2,0x5e,0x13,0xa6,
|
||||
0xd4,0x65,0xbd,0x04,0x7f,0x90,0x55,0x00,0xe5,0xeb,0xbe,0x42,0x66,0x43,0x0d,0x56,
|
||||
0x67,0x14,0x0f,0x77,0xe7,0x97,0x71,0x2a,0x8c,0x8f,0x63,0xc5,0x83,0xf4,0xb4,0x64,
|
||||
0x9b,0x72,0x89,0x9e,0xa3,0x4a,0xbf,0xdb,0x17,0x61,0x7c,0x46,0x0c,0x35,0xf2,0x50,
|
||||
0x64,0x94,0x49,0x4f,0x22,0x3e,0x25,0x1a,0xc7,0x1a,0x5b,0x9b,0x7e,0xea,0x87,0xf4,
|
||||
0xf5,0xe3,0x33,0xa3,0xc1,0xbb,0xb4,0xbb,0x09,0x25,0x8b,0x6a,0x4b,0x5f,0x8c,0x9f,
|
||||
0xb8,0x2b,0xf4,0x2d,0xa9,0xd4,0xa4,0x65,0x43,0xc6,0xa9,0xeb,0x9a,0xa3,0x0e,0xa9,
|
||||
0xda,0x80,0x19,0x15,0xab,0xcc,0x17,0x12,0xd0,0x82,0xf2,0x92,0xa6,0x3f,0xd9,0xaf,
|
||||
0x71,0x54,0xa9,0x7c,0xc7,0x38,0x59,0xa4,0xbe,0x3c,0xba,0x35,0x9d,0x32,0x18,0x00,
|
||||
0x4e,0x14,0xdf,0x02,0xd0,0x9e,0xdf,0x0a,0xd5,0x79,0x6b,0xb0,0x10,0x99,0x52,0x93,
|
||||
0xab,0x5d,0x04,0x2c,0x31,0x05,0x53,0x80,0xcc,0x9c,0xb2,0xe3,0x61,0x79,0x82,0xc4,
|
||||
0x5f,0x6b,0xce,0x1f,0xb8,0xa4,0x0e,0xf9,0xea,0xc4,0x8a,0xe1,0x77,0x20,0xdf,0xec,
|
||||
0xc7,0x1e,0xc8,0x57,0xea,0x33,0xf3,0x2e,0xb3,0x46,0xba,0x60,0x36,0xe8,0xf9,0xcc,
|
||||
0xd7,0xbc,0xad,0xc6,0xc1,0xab,0x92,0xa8,0x0c,0x57,0xe7,0x89,0x59,0xd8,0xb8,0x28),
|
||||
.out = chunk_from_chars(
|
||||
0x29,0xbd,0x11,0x55,0x68,0xae,0x09,0x88,0x27,0x0f,0xc3,0x86,0xd3,0x95,0xfe,0x37,
|
||||
0x07,0xa4,0xd0,0x62,0x89,0xf3,0x52,0xbb,0xa4,0xc0,0x0a,0x9a,0xd8,0x55,0xa0,0x8d),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_sha384_1 = {
|
||||
.alg = KDF_PRF, .arg.prf = PRF_HMAC_SHA2_384,
|
||||
.key = chunk_from_chars(
|
||||
0x4d,0xf0,0x40,0xb7,0x09,0x78,0x62,0x9c,0x49,0x43,0x7c,0xff,0x41,0xa0,0xd4,0x6c,
|
||||
0xbe,0xa6,0x8c,0x8d,0x75,0xb3,0x70,0xff,0xc1,0x1d,0x7b,0x38,0x71,0x44,0xea,0x83,
|
||||
0xbb,0x59,0x03,0xfb,0xb9,0x2e,0x47,0x3d,0xf5,0x0a,0x9b,0x19,0xea,0x43,0xe9,0xc2,
|
||||
0xf3,0xda,0x9a,0x84,0x9c,0x03,0x86,0x42,0x76,0xc6,0xf2,0x64,0xec,0xf0,0x2a,0x60,
|
||||
0xd4,0x0b,0xa6,0x5c,0x06,0x65,0x6b,0x63,0x3f,0x02,0xa8,0x74,0x27,0xe9,0x28,0xeb,
|
||||
0x66,0xa2,0xda,0xbd,0x9d,0xc0,0x57,0x44,0x71,0x7b,0xca,0xf7,0xae,0x78,0xc2,0x96,
|
||||
0x87,0x2f,0x5c,0x48,0xd1,0xa8,0x12,0x0c,0x21,0x55,0xb7,0x0c,0x56,0x5c,0xe2,0x71,
|
||||
0x99,0x8e,0x3e,0x44,0xaf,0x26,0x3d,0x48,0x7e,0xa3,0xba,0x7f,0x56,0x13,0x2d,0x7d),
|
||||
.salt = chunk_from_chars(
|
||||
0xd6,0x72,0xb0,0xbc,0x85,0x28,0x29,0xb9,0x35,0x09,0xf3,0xb7,0x24,0x70,0x63,0x64),
|
||||
.out = chunk_from_chars(
|
||||
0x54,0x43,0x6a,0x9e,0xa9,0x5d,0x6f,0xf7,0x9b,0x96,0x7f,0x4b,0x07,0xf6,0xde,0x97,
|
||||
0x6a,0x37,0x6e,0x8e,0xa2,0x6a,0xa9,0x57,0x47,0x09,0xaf,0xc6,0x02,0x43,0xc9,0xc1,
|
||||
0x41,0xda,0x4c,0xa0,0xe1,0x58,0xe6,0x27,0xa7,0x5e,0xa8,0x7f,0x6f,0xeb,0x07,0xef),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_sha384_2 = {
|
||||
.alg = KDF_PRF, .arg.prf = PRF_HMAC_SHA2_384,
|
||||
.key = chunk_from_chars(
|
||||
0xae,0x50,0x50,0x82,0xac,0x47,0xff,0x9a,0xa3,0x54,0xb7,0xaf,0x2b,0x07,0x2c,0xb4,
|
||||
0x9c,0xec,0x83,0x8d,0x00,0xee,0x36,0x13,0x88,0x1a,0x99,0x77,0xb2,0x15,0x95,0x99,
|
||||
0xa0,0x24,0x95,0xf0,0xe5,0x2d,0x96,0x1a,0x51,0x6c,0x6b,0xb6,0x1e,0xd0,0x3a,0x86,
|
||||
0x37,0xbb,0x50,0x7c,0x5c,0x27,0xba,0xb5,0x8d,0xf1,0x54,0xe8,0xe5,0x01,0x48,0x21,
|
||||
0x84,0x0c,0xfc,0x50,0xb3,0xa4,0x78,0xb4,0x5d,0xd1,0x68,0xeb,0x18,0x0d,0x69,0xcb,
|
||||
0xa6,0x1a,0x1b,0x42,0x59,0x19,0x3a,0x51,0xa7,0xa4,0x95,0xc9,0x58,0x05,0x38,0x2e,
|
||||
0x3a,0xbf,0x55,0x87,0x68,0x8f,0x34,0xb6,0x3f,0x71,0x16,0x39,0x82,0xde,0x3d,0xdf,
|
||||
0x7f,0x26,0x3b,0xb6,0x9f,0x65,0xc3,0xec,0xae,0x61,0x65,0xbf,0x7f,0xdd,0x53,0x17),
|
||||
.salt = chunk_from_chars(
|
||||
0x9e,0x2a,0x62,0xf9,0x36,0x28,0x93,0xdd,0xf8,0x47,0x16,0xfe,0xc2,0xf2,0x3f,0x9d,
|
||||
0xcb,0xd9,0x01,0x0d,0xf6,0xfe,0x9e,0x0e,0xb4,0x6d,0x03,0xd9,0x14,0xf3,0x04,0xd8,
|
||||
0xfe,0x4d,0x3e,0xe2,0xd6,0xa0,0x3b,0x40,0xe5,0x6a,0x32,0x5e,0x82,0x2a,0x17,0x36,
|
||||
0x19,0x29,0x18,0x4a,0xde,0x09,0xea,0xa4,0x45,0x27,0x8d,0x38,0x70,0x41,0x7a,0x7c,
|
||||
0xf5,0x65,0x58,0x4f,0x57,0x2a,0xd3,0x4f,0xf7,0x2b,0xc7,0x78,0x1a,0x39,0xa4,0x8b,
|
||||
0x54,0xb5,0x5d,0x6e,0xb0,0xed,0x68,0x55,0x1b,0x22,0x2c,0x7a,0xfa,0xda,0x0b,0xc8,
|
||||
0x22,0x36,0xec,0x31,0xce,0x6c,0x04,0x6b,0x3b,0x2e,0xdb,0x2d,0xef,0x61,0xf4,0xd2,
|
||||
0xd8,0x57,0xb2,0xd1,0xcb,0x36,0x96,0xc0,0x23,0xe0,0x8c,0x08,0xd6,0xab,0xd0,0x4d,
|
||||
0x4f,0x69,0x09,0x2b,0x14,0x58,0x37,0x35,0xb9,0xe9,0x18,0xae,0xe5,0xa3,0x99,0x9d,
|
||||
0xcb,0xf5,0x8f,0xda,0xd6,0xfc,0xd4,0x7c,0x95,0x92,0x98,0x77,0x03,0x0e,0x54,0xb7,
|
||||
0x08,0x23,0x5f,0x2a,0x2e,0x11,0xe7,0xc5,0x85,0x84,0x61,0x9a,0xa2,0xfa,0x69,0x31,
|
||||
0x53,0x44,0xd3,0x65,0x7b,0x55,0x72,0x0a,0x25,0xeb,0xe8,0x8e,0xa0,0x77,0x69,0x72,
|
||||
0xc9,0xe2,0x24,0x69,0xb7,0xed,0x5d,0xa9,0x6b,0x3c,0x76,0x85,0xf7,0xb0,0x56,0x99,
|
||||
0x60,0xbd,0x64,0x4f,0x13,0x0b,0x44,0xa0,0xd5,0x51,0xbb,0x0e,0x90,0x2e,0xd6,0x8a,
|
||||
0xb3,0x84,0xfd,0xc2,0xfa,0xca,0xf7,0x9b,0xbf,0x8d,0x6d,0x37,0x36,0xdf,0xa9,0x52,
|
||||
0xcd,0x70,0xf4,0x74,0x6f,0x1a,0x4a,0xea,0xc2,0xbd,0xbe,0xca,0x97,0xb7,0x8f,0xc1,
|
||||
0x77,0x78,0x78,0xc1,0x28,0x59,0x43,0x35,0x52,0xa7,0x7d,0x7f,0x94,0x2e,0x5b,0x60,
|
||||
0x47,0x69,0x91,0xa1,0xe3,0xd0,0x42,0x7c,0xd6,0x77,0x34,0x5a,0x1c,0xe2,0x06,0x3a,
|
||||
0x2e,0x0e,0xc5,0x47,0xa9,0xd8,0x21,0xda,0x75,0x9f,0x1a,0x91,0xb5,0x88,0x17,0xbd,
|
||||
0x0d,0xc4,0xef,0xfc,0x12,0x6f,0x6f,0x4e,0xb0,0xb9,0x11,0xe9,0x04,0xed,0x21,0xdc,
|
||||
0x43,0x9d,0x65,0x8a,0x77,0x3f,0x97,0xe1,0x79,0xad,0x20,0xbc,0x3c,0x63,0x60,0x9f,
|
||||
0x28,0x74,0x06,0x2e,0x83,0x5f,0x6a,0xe0,0x8d,0x59,0x65,0x4f,0x9c,0x88,0x61,0xe5,
|
||||
0x27,0x03,0x9e,0xea,0xc3,0x2b,0x9e,0xed,0x29,0x3b,0xd8,0xb1,0xe0,0xe7,0xc6,0x7b,
|
||||
0xf1,0xd7,0x55,0x24,0x6a,0x1b,0x06,0x3f,0xf0,0x06,0x32,0xa4,0x6d,0xd5,0xcf,0x69,
|
||||
0x48,0xf0,0xee,0xd9,0xb6,0x5c,0x59,0x39,0xdf,0xd2,0x14,0x80,0xa6,0x3d,0xf0,0xca,
|
||||
0xb0,0xa7,0x50,0x9c,0x42,0x45,0xa1,0xbe,0x75,0x47,0xcc,0xc6,0xf7,0x3c,0x72,0x4b,
|
||||
0x48,0xb7,0x86,0x70,0x12,0xe0,0xca,0x3e,0x47,0x2e,0x0d,0x55,0x06,0x49,0xa7,0x34,
|
||||
0x44,0x0f,0xef,0xfc,0x8e,0x73,0x68,0x2c,0xb6,0x04,0x53,0xe7,0xa4,0x7e,0x72,0xfe,
|
||||
0x08,0x74,0xeb,0x40,0xac,0xd0,0xd4,0x8e,0x4e,0x57,0x19,0x74,0x16,0x11,0x2b,0xcd,
|
||||
0xc8,0xbb,0x7a,0x58,0xbe,0xa7,0x45,0xfd,0xd6,0x4c,0x16,0xf6,0x66,0xc8,0x8d,0x9e,
|
||||
0x3b,0xd2,0x35,0xb1,0x37,0x20,0x6f,0x6c,0xdb,0xa1,0x90,0xbe,0x65,0xec,0x03,0x3c,
|
||||
0x19,0x1f,0x67,0x6b,0x42,0x8e,0xc1,0x20,0x5d,0xc5,0xe9,0x45,0x82,0x85,0x08,0xd8),
|
||||
.out = chunk_from_chars(
|
||||
0xff,0x66,0xe9,0xd0,0x92,0xdc,0x01,0xe0,0xb8,0x1f,0x93,0x9f,0x52,0xf5,0xc0,0x7d,
|
||||
0x38,0xd8,0x05,0xb9,0x86,0x28,0xce,0x1a,0xc5,0xfe,0x94,0xc0,0x98,0x57,0x76,0x47,
|
||||
0x33,0x9f,0xad,0x68,0x94,0x1f,0xfe,0x21,0xe0,0x1e,0xfb,0x4e,0x70,0x50,0x21,0x3b),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_sha512_1 = {
|
||||
.alg = KDF_PRF, .arg.prf = PRF_HMAC_SHA2_512,
|
||||
.key = chunk_from_chars(
|
||||
0x1e,0x3b,0x00,0x7d,0x2d,0xa9,0x13,0xca,0x60,0xec,0xc9,0x8c,0x25,0xa2,0x2d,0xb0,
|
||||
0x80,0x73,0xd5,0xc3,0x5c,0x11,0xb2,0x52,0x4b,0x29,0x8a,0x92,0x2b,0x6a,0xbf,0xe6,
|
||||
0xac,0xf7,0x35,0x9d,0xb6,0x6a,0xe5,0xf8,0x5d,0x67,0xaa,0xcf,0xf6,0x86,0x41,0x9c,
|
||||
0xd8,0x66,0x6d,0x05,0xae,0x79,0x77,0xce,0xfa,0xd7,0xf5,0x4d,0xd8,0xe3,0x12,0xa8,
|
||||
0xe8,0xe5,0xe0,0x37,0x0f,0x88,0x14,0x2f,0xbd,0xd6,0x59,0xdd,0x6f,0xde,0x22,0xbd,
|
||||
0xd5,0x31,0xf5,0x40,0x28,0x81,0xa8,0xde,0x85,0xc1,0x02,0x4e,0x59,0x5e,0xc9,0x3c,
|
||||
0x57,0x56,0x18,0xaf,0x7f,0xd3,0xdb,0xac,0x79,0x82,0x91,0x90,0x78,0xd7,0x1c,0xc1,
|
||||
0x3e,0xff,0x19,0x10,0xa0,0x32,0x75,0x0e,0x1f,0xf4,0x28,0x67,0x5d,0xe1,0x89,0xee),
|
||||
.salt = chunk_from_chars(
|
||||
0xdf,0x79,0x31,0xdb,0x9b,0x42,0x9e,0x10,0xb8,0xaa,0x8e,0x4d,0x46,0x04,0x23,0x93),
|
||||
.out = chunk_from_chars(
|
||||
0xda,0xf9,0xbd,0x6f,0x2f,0x91,0x2d,0xa5,0x53,0x86,0x79,0x66,0xaf,0x38,0x6e,0x67,
|
||||
0x90,0x9a,0x8d,0xf0,0xca,0x7e,0x84,0xb8,0x3b,0x35,0x5c,0xb7,0xd7,0xf1,0x02,0x6f,
|
||||
0x17,0xd8,0xea,0x34,0xb5,0xd5,0x7f,0xd0,0xd1,0xba,0x38,0x95,0x28,0xfc,0xa1,0xe8,
|
||||
0x1d,0x1c,0x8c,0xe5,0x11,0xb2,0x8a,0x24,0x58,0x24,0x11,0x43,0xfe,0xe3,0x0c,0xcc),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_sha512_2 = {
|
||||
.alg = KDF_PRF, .arg.prf = PRF_HMAC_SHA2_512,
|
||||
.key = chunk_from_chars(
|
||||
0x9c,0xb4,0xbf,0x24,0x46,0x17,0x0a,0xc3,0x81,0x02,0x52,0x66,0xa1,0xa4,0xb8,0x65,
|
||||
0x13,0xdf,0x60,0xea,0x7d,0x07,0xb1,0xb2,0x13,0x9d,0x78,0xf3,0x31,0xef,0x7e,0xb7,
|
||||
0xbe,0x8b,0x15,0xd8,0x6c,0xd8,0x5e,0x2a,0x6a,0x34,0xa5,0x58,0x69,0xf8,0xdc,0xc9,
|
||||
0x75,0x4f,0x49,0x69,0x73,0x31,0xb9,0xb6,0x50,0xce,0x25,0x6e,0xdb,0x33,0x71,0xa9,
|
||||
0x4b,0x7c,0x2a,0x13,0x2f,0x2f,0xc9,0x9d,0x22,0x30,0x37,0x17,0xc3,0x67,0x39,0xd1,
|
||||
0x7c,0x0e,0x97,0x18,0xd7,0xc0,0x52,0xe7,0xab,0x4d,0x48,0x58,0xad,0xeb,0x9b,0x8b,
|
||||
0x4d,0x33,0x03,0xa9,0xe1,0xb6,0xbe,0xf2,0x9f,0x03,0x03,0x5b,0xee,0xd0,0x71,0xd3,
|
||||
0xbb,0x81,0x0d,0x85,0x39,0x71,0xa7,0x48,0xc5,0x6c,0x59,0xe0,0xba,0xfb,0x9b,0x5a),
|
||||
.salt = chunk_from_chars(
|
||||
0xd8,0x96,0x84,0xe3,0xcb,0x17,0xf3,0xaa,0xbd,0x85,0x3a,0x78,0xdb,0x3e,0xcd,0x5a,
|
||||
0xac,0xc1,0xed,0x71,0xc7,0x0b,0x88,0xa2,0x97,0x56,0xf4,0x6f,0xc7,0x19,0x7c,0x80,
|
||||
0x4e,0xc0,0x01,0x54,0x40,0x02,0xa8,0xae,0xa3,0x60,0x68,0x4b,0x18,0x00,0x6d,0xef,
|
||||
0x0d,0xbd,0x86,0x33,0xb1,0x01,0x9f,0xbc,0xfa,0x85,0xb9,0x4c,0xac,0x2b,0xb8,0x21,
|
||||
0x25,0x84,0xbe,0x62,0xad,0xab,0x0e,0xe4,0xbb,0x8a,0x36,0xae,0xe2,0x52,0x75,0xef,
|
||||
0x07,0x13,0x90,0x48,0x0e,0xef,0xa2,0x09,0x2e,0xb3,0x08,0xaa,0x73,0x37,0xc5,0xce,
|
||||
0xb6,0x06,0x9a,0xb6,0x90,0xe8,0x96,0x2f,0xbf,0xe0,0x98,0x6e,0x4f,0x5c,0x18,0xf4,
|
||||
0x86,0x86,0x1e,0xd3,0xf1,0xdc,0xbe,0xe4,0xc9,0xe4,0xa7,0x66,0x9d,0x74,0x0c,0xa2,
|
||||
0xb0,0xe8,0xed,0x40,0x31,0xb0,0xa4,0x99,0xdc,0x31,0x5c,0xed,0xe7,0xef,0x03,0x39,
|
||||
0x9c,0xbc,0x33,0xdc,0xd6,0x29,0x70,0x34,0x9f,0x12,0x20,0x88,0x1b,0x55,0x45,0x2e,
|
||||
0x0c,0x6c,0x9b,0x52,0xa8,0x8b,0x67,0xf5,0x97,0x58,0x67,0x95,0xb2,0x25,0x70,0x73,
|
||||
0x3f,0xd4,0xff,0x2c,0xc2,0xad,0x93,0x1d,0x83,0x30,0x16,0x5a,0x9e,0x45,0x0e,0x38,
|
||||
0x88,0x59,0xce,0x62,0x4f,0x01,0xdb,0x17,0xc2,0x50,0x2b,0x4e,0x66,0xad,0xf9,0x65,
|
||||
0x27,0x36,0x3d,0x6f,0x90,0x6b,0x20,0x23,0xe8,0xed,0x74,0xd5,0xaf,0x0a,0xa6,0x02,
|
||||
0x46,0xb0,0xb9,0x2f,0x49,0xc4,0x93,0x3e,0xf3,0x12,0xf8,0xa2,0x54,0x34,0xee,0x96,
|
||||
0x98,0xd6,0xd9,0x20,0x43,0x45,0xbd,0x10,0xbb,0x11,0xaa,0x39,0x86,0x56,0x16,0xd5,
|
||||
0xad,0x1b,0x57,0x44,0x70,0x6c,0xfd,0x4e,0xa1,0x40,0x8e,0x20,0xc8,0xfd,0xcf,0x85,
|
||||
0x51,0xee,0xe8,0x81,0x4b,0x7b,0x37,0x33,0x0b,0x05,0x26,0xf0,0xbc,0x5e,0xe1,0x5d,
|
||||
0x4e,0xcd,0xa7,0xa1,0xbd,0x25,0xaa,0x97,0xf2,0x45,0x84,0xd8,0x5d,0x3f,0x52,0x49,
|
||||
0x69,0x4b,0x9f,0x43,0x53,0x9e,0x69,0xea,0x35,0xbf,0xe7,0xfd,0x44,0x07,0xbc,0x8e,
|
||||
0x9d,0xca,0x8a,0x9f,0xae,0x4b,0xdc,0x6b,0x7b,0xb3,0x8c,0x6d,0x68,0xf8,0x99,0xe1,
|
||||
0xd3,0x2c,0x85,0xbc,0xd6,0x17,0xa5,0x67,0x67,0x8c,0xf8,0x5d,0x22,0x17,0xa4,0xe8,
|
||||
0x6a,0x75,0x56,0x24,0xb6,0x40,0x02,0x35,0x4c,0x02,0x68,0x42,0xbc,0x95,0x42,0x49,
|
||||
0x1a,0xf1,0xc3,0xd6,0x29,0x09,0x70,0x55,0x9a,0xf1,0x1b,0xdc,0x2c,0x83,0xb5,0x4c,
|
||||
0x74,0x14,0x49,0x05,0xc0,0xa3,0x58,0xf3,0x15,0x3d,0xb7,0x67,0xa5,0xda,0x2a,0x86,
|
||||
0x27,0xf6,0x96,0x27,0xe1,0xd4,0x1e,0xde,0x9c,0x90,0x7c,0x79,0xb5,0x1f,0xf8,0x15,
|
||||
0xe4,0x64,0x5c,0x33,0x75,0xe0,0xf6,0x3f,0x84,0xfc,0xf5,0xd7,0xc3,0x40,0x7a,0x1d,
|
||||
0xd6,0x83,0x9e,0x19,0x06,0xa1,0xe3,0x80,0x2c,0xcf,0x5e,0x82,0x30,0xd9,0x5c,0xf4,
|
||||
0xb8,0x27,0xb4,0x1c,0x48,0x34,0x25,0xa8,0xa6,0x0b,0xfa,0x51,0x89,0xda,0xc4,0x38,
|
||||
0x06,0x0f,0x2f,0x5c,0xd5,0x26,0x66,0x2f,0x29,0x06,0xc1,0xdd,0x64,0xf4,0x84,0x4e,
|
||||
0x94,0x2c,0xa8,0x4d,0xae,0xce,0x6d,0xd7,0xbb,0xf7,0x19,0x4d,0x8c,0xe5,0x6b,0xc2,
|
||||
0x83,0x10,0x85,0xa7,0xd3,0x10,0xe4,0x94,0x4c,0xfa,0xe7,0x62,0x60,0xaa,0xbf,0x6b),
|
||||
.out = chunk_from_chars(
|
||||
0xe5,0x70,0xe7,0x48,0x46,0x34,0x30,0x0d,0x7a,0xdd,0xf5,0xa8,0x52,0x7c,0x13,0x8b,
|
||||
0x76,0x96,0xdb,0xc3,0xd8,0xbe,0x09,0x69,0xb7,0x52,0x15,0x31,0x8a,0x11,0xad,0xa2,
|
||||
0x13,0x53,0x8f,0x62,0x93,0xb0,0xee,0xe5,0xb3,0x09,0xad,0x8f,0x5d,0x8d,0x94,0xdb,
|
||||
0xe5,0x73,0x61,0x27,0xe0,0xd2,0x56,0x0f,0x28,0x1c,0x9c,0x58,0x6b,0xf7,0xc8,0x6f),
|
||||
};
|
||||
@@ -0,0 +1,290 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <crypto/crypto_tester.h>
|
||||
|
||||
/**
|
||||
* This is an old test vector derived from one in RFC 4868.
|
||||
*/
|
||||
kdf_test_vector_t prf_plus_sha256_old = {
|
||||
.alg = KDF_PRF_PLUS, .arg.prf = PRF_HMAC_SHA2_256,
|
||||
.key = chunk_from_chars(
|
||||
0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
|
||||
0x0b,0x0b,0x0b,0x0b),
|
||||
.salt = chunk_from_chars(
|
||||
0x48,0x69,0x20,0x54,0x68,0x65,0x72,0x65),
|
||||
.out = chunk_from_chars(
|
||||
0xb9,0xbd,0xc0,0x89,0x88,0xb4,0xc2,0xb7,0x5a,0xa9,0x3e,0x59,0x6a,0xc8,0x42,0x05,
|
||||
0xfa,0x2d,0xdd,0xe1,0xbf,0x7a,0x25,0x72,0x06,0x7b,0x00,0xe1,0x4b,0x23,0x77,0x32,
|
||||
0x83,0x05,0x09,0x98,0x1a,0xd2,0xf9,0x4a,0x8c,0x32,0xa4,0x7d,0xaa,0x22,0x55,0xb6,
|
||||
0x60,0xc4,0x36,0x34,0x7a,0xe7,0x56,0xa6,0xed,0xc0,0x23,0x47,0x7d,0x80,0x95,0x90,
|
||||
0xe6,0x82,0xf6,0x1d,0x9c,0x04,0xb0,0x6b,0x4a,0xd9,0x71,0xa3,0x4c,0x81,0x47,0xfa,
|
||||
0x66,0x79,0x2f,0xf1,0x43,0x4b,0x93,0xc7,0x22,0xb3,0x2e,0x12,0xf4,0x88,0x32,0xeb,
|
||||
0xc1,0x5c,0xe2,0x36,0x9c,0xe7,0x1f,0xe9,0xb7,0xb8,0x1e,0x57,0x04,0xc1,0x4d,0x0f,
|
||||
0x52,0x80,0xa6,0xec,0x62,0x6e,0x99,0x2d,0x7a,0x9f),
|
||||
};
|
||||
|
||||
/**
|
||||
* The following test vectors are from CAVP/SP 800-135 for IKEv2.
|
||||
*
|
||||
* key = SKEYSEED, salt = Ni | Nr | SPIi | SPIr (one vector with min. and one
|
||||
* with max. size for nonces)
|
||||
*/
|
||||
kdf_test_vector_t prf_plus_sha256_1 = {
|
||||
.alg = KDF_PRF_PLUS, .arg.prf = PRF_HMAC_SHA2_256,
|
||||
.key = chunk_from_chars(
|
||||
0x37,0xfd,0xe9,0x0b,0x81,0xd6,0x36,0x92,0x62,0x0f,0x67,0x36,0x7b,0x62,0x09,0x2e,
|
||||
0x3e,0xfd,0xc6,0xa0,0x35,0x09,0x13,0x7d,0x73,0x10,0x04,0x76,0x7f,0xf3,0x50,0x10),
|
||||
.salt = chunk_from_chars(
|
||||
0xed,0x80,0xdc,0x79,0x91,0x2c,0x32,0xa9,0x35,0xfb,0x6d,0x1a,0x3f,0xea,0xc0,0x78,
|
||||
0x47,0xc1,0x85,0x8e,0xfc,0x93,0x2e,0xa4,0x60,0x6f,0xd0,0x56,0x09,0x62,0x40,0x02),
|
||||
.out = chunk_from_chars(
|
||||
0x63,0xd0,0x18,0xa0,0x8f,0x7a,0x29,0xda,0xa7,0xd1,0xf9,0x2c,0xb6,0x3f,0x45,0xfa,
|
||||
0x39,0xbb,0xaf,0x5e,0x5f,0x1a,0x78,0x13,0x96,0x13,0xbb,0x89,0x1e,0x3e,0x6b,0xf9,
|
||||
0xd0,0x44,0x8f,0x7c,0x74,0xe0,0x5b,0x4c,0x1a,0x25,0xc0,0xb6,0x1e,0x62,0xc8,0x75,
|
||||
0xe8,0x52,0xf2,0x87,0xe1,0x92,0xd4,0xae,0x53,0x61,0x12,0xdb,0x51,0x97,0x21,0x64,
|
||||
0x00,0xbd,0x5e,0x12,0x34,0x70,0xef,0xc1,0x5f,0x53,0x16,0x18,0x65,0xfe,0x8b,0x19,
|
||||
0xa1,0x41,0x65,0x18,0xa1,0x57,0xd6,0x51,0xec,0xd2,0xca,0xdd,0xab,0x6a,0x9e,0xae,
|
||||
0x6a,0x27,0xa5,0x5a,0xf0,0x88,0x21,0x8d,0x51,0x56,0xed,0xaa,0x97,0x89,0xf9,0x34,
|
||||
0xd9,0x83,0x6e,0xd4,0x3e,0xdf,0xfd,0xa5,0x53,0x82,0x22,0x02,0xff,0x9f,0x7d,0x48,
|
||||
0x60,0xca,0x72,0xe0),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_plus_sha256_2 = {
|
||||
.alg = KDF_PRF_PLUS, .arg.prf = PRF_HMAC_SHA2_256,
|
||||
.key = chunk_from_chars(
|
||||
0x29,0xbd,0x11,0x55,0x68,0xae,0x09,0x88,0x27,0x0f,0xc3,0x86,0xd3,0x95,0xfe,0x37,
|
||||
0x07,0xa4,0xd0,0x62,0x89,0xf3,0x52,0xbb,0xa4,0xc0,0x0a,0x9a,0xd8,0x55,0xa0,0x8d),
|
||||
.salt = chunk_from_chars(
|
||||
0xef,0xa7,0x29,0x13,0x18,0x22,0x78,0xff,0xbd,0x14,0xe7,0x89,0x20,0xc0,0x62,0x51,
|
||||
0x9a,0xba,0xb8,0xc1,0x6e,0x5e,0xd7,0x0c,0x08,0x41,0xa4,0x8c,0xdb,0x98,0x23,0x7e,
|
||||
0xe9,0x3f,0x73,0x5f,0xb2,0xdf,0x18,0x43,0x58,0xaa,0xdc,0x13,0xd8,0x3f,0x43,0xfe,
|
||||
0x8d,0x87,0x05,0x17,0x6c,0x8c,0xa3,0x13,0x82,0x5a,0x1b,0xcd,0xf7,0x79,0x11,0xc5,
|
||||
0x98,0x00,0x16,0x71,0xff,0xbf,0x01,0x4e,0x37,0xa8,0xc0,0x4d,0x49,0xa7,0x83,0x9d,
|
||||
0xfe,0xa6,0xcd,0xc5,0x87,0x68,0x8d,0x45,0x88,0xfe,0x43,0x23,0x5b,0x71,0x69,0x3f,
|
||||
0xfd,0x07,0x29,0x33,0x86,0xb6,0xbf,0x4c,0x19,0x9e,0x33,0x61,0x65,0xb2,0x60,0x78,
|
||||
0x77,0x36,0xf5,0x4b,0xe9,0x5d,0xb6,0x91,0x16,0x38,0x8b,0xc2,0xec,0xa2,0xb3,0xb2,
|
||||
0x94,0x84,0x71,0x74,0x17,0xbb,0x3c,0x71,0x81,0x4c,0xe1,0x3b,0x84,0x44,0x6d,0xc3,
|
||||
0x96,0x4c,0x30,0x29,0x84,0xf9,0x77,0x81,0xf6,0x31,0x66,0x24,0x08,0x90,0x10,0x7c,
|
||||
0x2e,0x75,0x1a,0x00,0x43,0x6f,0x7c,0x3c,0x9f,0xf1,0x27,0x60,0xe4,0x9d,0x91,0x56,
|
||||
0x3b,0xe6,0x03,0xfd,0x96,0x41,0xa0,0xa6,0x49,0x18,0xa9,0x32,0x91,0xed,0x11,0x3d,
|
||||
0xb1,0x2f,0x97,0x07,0x60,0x9d,0x17,0x20,0x96,0xeb,0x58,0xf9,0x15,0x44,0x74,0xda,
|
||||
0x40,0xc1,0xf5,0xc0,0x90,0x3e,0x9c,0xa2,0xf9,0x1b,0xa6,0x60,0x07,0x75,0xdf,0x71,
|
||||
0x66,0xca,0xf8,0xe3,0x27,0x85,0x9e,0x67,0x62,0x32,0xd3,0x40,0x46,0x04,0x4c,0xee,
|
||||
0x43,0xf9,0x01,0x9f,0x04,0x68,0x56,0x12,0x63,0x5b,0x99,0xcb,0xeb,0xcb,0x36,0x3d,
|
||||
0x56,0x5e,0xaf,0x0e,0x54,0x7e,0xec,0xb9,0x41,0xc9,0x94,0xdf,0xd4,0x71,0xed,0x56,
|
||||
0x43,0xc0,0x87,0x74,0x4f,0x77,0x09,0xcc,0x3e,0x25,0x10,0xf2,0x74,0x26,0xc6,0x2c,
|
||||
0x0f,0xf3,0xac,0xb3,0xc2,0x76,0x61,0xd2,0x6a,0x6d,0x83,0xc2,0xa2,0x5e,0x13,0xa6,
|
||||
0xd4,0x65,0xbd,0x04,0x7f,0x90,0x55,0x00,0xe5,0xeb,0xbe,0x42,0x66,0x43,0x0d,0x56,
|
||||
0x67,0x14,0x0f,0x77,0xe7,0x97,0x71,0x2a,0x8c,0x8f,0x63,0xc5,0x83,0xf4,0xb4,0x64,
|
||||
0x9b,0x72,0x89,0x9e,0xa3,0x4a,0xbf,0xdb,0x17,0x61,0x7c,0x46,0x0c,0x35,0xf2,0x50,
|
||||
0x64,0x94,0x49,0x4f,0x22,0x3e,0x25,0x1a,0xc7,0x1a,0x5b,0x9b,0x7e,0xea,0x87,0xf4,
|
||||
0xf5,0xe3,0x33,0xa3,0xc1,0xbb,0xb4,0xbb,0x09,0x25,0x8b,0x6a,0x4b,0x5f,0x8c,0x9f,
|
||||
0xb8,0x2b,0xf4,0x2d,0xa9,0xd4,0xa4,0x65,0x43,0xc6,0xa9,0xeb,0x9a,0xa3,0x0e,0xa9,
|
||||
0xda,0x80,0x19,0x15,0xab,0xcc,0x17,0x12,0xd0,0x82,0xf2,0x92,0xa6,0x3f,0xd9,0xaf,
|
||||
0x71,0x54,0xa9,0x7c,0xc7,0x38,0x59,0xa4,0xbe,0x3c,0xba,0x35,0x9d,0x32,0x18,0x00,
|
||||
0x4e,0x14,0xdf,0x02,0xd0,0x9e,0xdf,0x0a,0xd5,0x79,0x6b,0xb0,0x10,0x99,0x52,0x93,
|
||||
0xab,0x5d,0x04,0x2c,0x31,0x05,0x53,0x80,0xcc,0x9c,0xb2,0xe3,0x61,0x79,0x82,0xc4,
|
||||
0x5f,0x6b,0xce,0x1f,0xb8,0xa4,0x0e,0xf9,0xea,0xc4,0x8a,0xe1,0x77,0x20,0xdf,0xec,
|
||||
0xc7,0x1e,0xc8,0x57,0xea,0x33,0xf3,0x2e,0xb3,0x46,0xba,0x60,0x36,0xe8,0xf9,0xcc,
|
||||
0xd7,0xbc,0xad,0xc6,0xc1,0xab,0x92,0xa8,0x0c,0x57,0xe7,0x89,0x59,0xd8,0xb8,0x28,
|
||||
0x57,0xe9,0x1d,0xf9,0xc5,0xff,0xb8,0x42,0x4d,0x5e,0xad,0xac,0x0e,0x57,0x0f,0x7c),
|
||||
.out = chunk_from_chars(
|
||||
0xd5,0x03,0x3d,0x08,0x79,0x34,0xc6,0x15,0x38,0xb2,0x3d,0xff,0x87,0x5b,0x3b,0xa9,
|
||||
0x20,0xe0,0x5c,0x1b,0x42,0xac,0x7f,0x97,0x93,0x99,0x5e,0x76,0xba,0x3e,0x46,0x1d,
|
||||
0x6e,0x83,0xb2,0xfb,0xe0,0xfa,0x68,0x1b,0xa2,0x85,0x69,0x6d,0x53,0xb1,0x75,0xe0,
|
||||
0x70,0xc4,0xc1,0xcb,0xc7,0x40,0x43,0xf7,0xca,0xc5,0x58,0xc4,0x94,0xac,0xd2,0x3a,
|
||||
0xab,0xfc,0x7a,0x68,0x5b,0x62,0x74,0x13,0x44,0x08,0xca,0xfc,0x16,0x92,0x85,0x2a,
|
||||
0xca,0x66,0x3c,0xef,0xd7,0xdd,0x0c,0x8a,0x87,0x2a,0x36,0xa1,0x41,0x4d,0xb4,0xb7,
|
||||
0xf3,0x14,0xad,0x0e,0x49,0xf2,0xc1,0x87,0x16,0x2e,0x28,0x76,0xc6,0x05,0x3d,0xbe,
|
||||
0xf5,0xa2,0xea,0x8c,0x33,0xdc,0xd3,0xdd,0x91,0x68,0x76,0x44,0x37,0x7c,0x45,0xf4,
|
||||
0xb5,0xc4,0x18,0xe1,0xe1,0x0b,0xec,0x22,0xba,0xac,0x31,0x3b,0x90,0x2b,0xdf,0xfc,
|
||||
0xfb,0x69,0xc6,0x8e,0xf4,0xe7,0x1c,0x5a,0xcc,0x39,0xa9,0xf0,0x7a,0xcb,0x1f,0xc3,
|
||||
0xba,0x8e,0x92,0xc6,0xdc,0xa8,0x61,0xa6,0x41,0x63,0xb0,0x68,0x9d,0xa4,0xa9,0x7f,
|
||||
0x12,0x40,0x26,0x36,0x09,0x90,0xc9,0xf1,0xae,0x4e,0x8d,0x02,0x98,0xf0,0x77,0xfc,
|
||||
0xbb,0x0c,0x20,0x3f,0xd2,0xca,0x82,0x1d,0xea,0xb0,0x59,0x1a,0x22,0x1d,0x9d,0x0a,
|
||||
0x79,0x8d,0x02,0xf0,0x78,0xd8,0xfb,0x6e,0x93,0x1c,0xa4,0x46,0xa1,0x3f,0x11,0x63,
|
||||
0x8c,0x6b,0x6a,0xfb,0x82,0x25,0xa0,0x08,0xf9,0x38,0xa6,0x87,0x8c,0x5b,0x57,0x7e,
|
||||
0x03,0xae,0xcf,0xa7,0x31,0x41,0x01,0xed,0xd0,0xfd,0xa3,0xbd,0xbe,0xa4,0x98,0x5c),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_plus_sha384_1 = {
|
||||
.alg = KDF_PRF_PLUS, .arg.prf = PRF_HMAC_SHA2_384,
|
||||
.key = chunk_from_chars(
|
||||
0x54,0x43,0x6a,0x9e,0xa9,0x5d,0x6f,0xf7,0x9b,0x96,0x7f,0x4b,0x07,0xf6,0xde,0x97,
|
||||
0x6a,0x37,0x6e,0x8e,0xa2,0x6a,0xa9,0x57,0x47,0x09,0xaf,0xc6,0x02,0x43,0xc9,0xc1,
|
||||
0x41,0xda,0x4c,0xa0,0xe1,0x58,0xe6,0x27,0xa7,0x5e,0xa8,0x7f,0x6f,0xeb,0x07,0xef),
|
||||
.salt = chunk_from_chars(
|
||||
0xd6,0x72,0xb0,0xbc,0x85,0x28,0x29,0xb9,0x35,0x09,0xf3,0xb7,0x24,0x70,0x63,0x64,
|
||||
0x0f,0x9a,0x01,0x6d,0x7b,0x22,0x22,0x3c,0x85,0xf7,0x10,0xda,0xf8,0xb9,0x82,0xd8),
|
||||
.out = chunk_from_chars(
|
||||
0x10,0xb0,0x0a,0x65,0x46,0x43,0xb3,0xb9,0x85,0x76,0x4f,0x86,0xe2,0x3e,0xf6,0x24,
|
||||
0x31,0x12,0x2f,0xcc,0x96,0xde,0x16,0xe3,0x38,0xa3,0x72,0xbe,0xe4,0x93,0x91,0xdb,
|
||||
0x1f,0x83,0xa7,0x35,0x8c,0x08,0x03,0x80,0xab,0xbf,0x4a,0xf4,0x7c,0xdb,0x83,0xb9,
|
||||
0x53,0x03,0x43,0x16,0x8f,0x7d,0xbc,0x92,0x21,0x26,0x0e,0x15,0x46,0xc6,0xb3,0x83,
|
||||
0xe2,0x23,0x5d,0x27,0x05,0xa7,0x27,0xf0,0xb4,0x1a,0xeb,0xf6,0xa1,0xb4,0xc6,0x1c,
|
||||
0xb4,0x60,0x66,0x01,0x52,0xa1,0x7b,0xa7,0x4c,0x20,0xd5,0x19,0x1b,0xa6,0x84,0x17,
|
||||
0x94,0x94,0x52,0x70,0xd8,0x29,0x58,0x7b,0x7f,0x32,0x94,0x63,0x9e,0xa7,0xb7,0x71,
|
||||
0x49,0xe1,0xd0,0x72,0x30,0xac,0x16,0xe0,0xcd,0x5a,0xb2,0x36,0xfa,0x32,0x12,0xbd,
|
||||
0x56,0x9e,0xe7,0x0f),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_plus_sha384_2 = {
|
||||
.alg = KDF_PRF_PLUS, .arg.prf = PRF_HMAC_SHA2_384,
|
||||
.key = chunk_from_chars(
|
||||
0xff,0x66,0xe9,0xd0,0x92,0xdc,0x01,0xe0,0xb8,0x1f,0x93,0x9f,0x52,0xf5,0xc0,0x7d,
|
||||
0x38,0xd8,0x05,0xb9,0x86,0x28,0xce,0x1a,0xc5,0xfe,0x94,0xc0,0x98,0x57,0x76,0x47,
|
||||
0x33,0x9f,0xad,0x68,0x94,0x1f,0xfe,0x21,0xe0,0x1e,0xfb,0x4e,0x70,0x50,0x21,0x3b),
|
||||
.salt = chunk_from_chars(
|
||||
0x9e,0x2a,0x62,0xf9,0x36,0x28,0x93,0xdd,0xf8,0x47,0x16,0xfe,0xc2,0xf2,0x3f,0x9d,
|
||||
0xcb,0xd9,0x01,0x0d,0xf6,0xfe,0x9e,0x0e,0xb4,0x6d,0x03,0xd9,0x14,0xf3,0x04,0xd8,
|
||||
0xfe,0x4d,0x3e,0xe2,0xd6,0xa0,0x3b,0x40,0xe5,0x6a,0x32,0x5e,0x82,0x2a,0x17,0x36,
|
||||
0x19,0x29,0x18,0x4a,0xde,0x09,0xea,0xa4,0x45,0x27,0x8d,0x38,0x70,0x41,0x7a,0x7c,
|
||||
0xf5,0x65,0x58,0x4f,0x57,0x2a,0xd3,0x4f,0xf7,0x2b,0xc7,0x78,0x1a,0x39,0xa4,0x8b,
|
||||
0x54,0xb5,0x5d,0x6e,0xb0,0xed,0x68,0x55,0x1b,0x22,0x2c,0x7a,0xfa,0xda,0x0b,0xc8,
|
||||
0x22,0x36,0xec,0x31,0xce,0x6c,0x04,0x6b,0x3b,0x2e,0xdb,0x2d,0xef,0x61,0xf4,0xd2,
|
||||
0xd8,0x57,0xb2,0xd1,0xcb,0x36,0x96,0xc0,0x23,0xe0,0x8c,0x08,0xd6,0xab,0xd0,0x4d,
|
||||
0x4f,0x69,0x09,0x2b,0x14,0x58,0x37,0x35,0xb9,0xe9,0x18,0xae,0xe5,0xa3,0x99,0x9d,
|
||||
0xcb,0xf5,0x8f,0xda,0xd6,0xfc,0xd4,0x7c,0x95,0x92,0x98,0x77,0x03,0x0e,0x54,0xb7,
|
||||
0x08,0x23,0x5f,0x2a,0x2e,0x11,0xe7,0xc5,0x85,0x84,0x61,0x9a,0xa2,0xfa,0x69,0x31,
|
||||
0x53,0x44,0xd3,0x65,0x7b,0x55,0x72,0x0a,0x25,0xeb,0xe8,0x8e,0xa0,0x77,0x69,0x72,
|
||||
0xc9,0xe2,0x24,0x69,0xb7,0xed,0x5d,0xa9,0x6b,0x3c,0x76,0x85,0xf7,0xb0,0x56,0x99,
|
||||
0x60,0xbd,0x64,0x4f,0x13,0x0b,0x44,0xa0,0xd5,0x51,0xbb,0x0e,0x90,0x2e,0xd6,0x8a,
|
||||
0xb3,0x84,0xfd,0xc2,0xfa,0xca,0xf7,0x9b,0xbf,0x8d,0x6d,0x37,0x36,0xdf,0xa9,0x52,
|
||||
0xcd,0x70,0xf4,0x74,0x6f,0x1a,0x4a,0xea,0xc2,0xbd,0xbe,0xca,0x97,0xb7,0x8f,0xc1,
|
||||
0x77,0x78,0x78,0xc1,0x28,0x59,0x43,0x35,0x52,0xa7,0x7d,0x7f,0x94,0x2e,0x5b,0x60,
|
||||
0x47,0x69,0x91,0xa1,0xe3,0xd0,0x42,0x7c,0xd6,0x77,0x34,0x5a,0x1c,0xe2,0x06,0x3a,
|
||||
0x2e,0x0e,0xc5,0x47,0xa9,0xd8,0x21,0xda,0x75,0x9f,0x1a,0x91,0xb5,0x88,0x17,0xbd,
|
||||
0x0d,0xc4,0xef,0xfc,0x12,0x6f,0x6f,0x4e,0xb0,0xb9,0x11,0xe9,0x04,0xed,0x21,0xdc,
|
||||
0x43,0x9d,0x65,0x8a,0x77,0x3f,0x97,0xe1,0x79,0xad,0x20,0xbc,0x3c,0x63,0x60,0x9f,
|
||||
0x28,0x74,0x06,0x2e,0x83,0x5f,0x6a,0xe0,0x8d,0x59,0x65,0x4f,0x9c,0x88,0x61,0xe5,
|
||||
0x27,0x03,0x9e,0xea,0xc3,0x2b,0x9e,0xed,0x29,0x3b,0xd8,0xb1,0xe0,0xe7,0xc6,0x7b,
|
||||
0xf1,0xd7,0x55,0x24,0x6a,0x1b,0x06,0x3f,0xf0,0x06,0x32,0xa4,0x6d,0xd5,0xcf,0x69,
|
||||
0x48,0xf0,0xee,0xd9,0xb6,0x5c,0x59,0x39,0xdf,0xd2,0x14,0x80,0xa6,0x3d,0xf0,0xca,
|
||||
0xb0,0xa7,0x50,0x9c,0x42,0x45,0xa1,0xbe,0x75,0x47,0xcc,0xc6,0xf7,0x3c,0x72,0x4b,
|
||||
0x48,0xb7,0x86,0x70,0x12,0xe0,0xca,0x3e,0x47,0x2e,0x0d,0x55,0x06,0x49,0xa7,0x34,
|
||||
0x44,0x0f,0xef,0xfc,0x8e,0x73,0x68,0x2c,0xb6,0x04,0x53,0xe7,0xa4,0x7e,0x72,0xfe,
|
||||
0x08,0x74,0xeb,0x40,0xac,0xd0,0xd4,0x8e,0x4e,0x57,0x19,0x74,0x16,0x11,0x2b,0xcd,
|
||||
0xc8,0xbb,0x7a,0x58,0xbe,0xa7,0x45,0xfd,0xd6,0x4c,0x16,0xf6,0x66,0xc8,0x8d,0x9e,
|
||||
0x3b,0xd2,0x35,0xb1,0x37,0x20,0x6f,0x6c,0xdb,0xa1,0x90,0xbe,0x65,0xec,0x03,0x3c,
|
||||
0x19,0x1f,0x67,0x6b,0x42,0x8e,0xc1,0x20,0x5d,0xc5,0xe9,0x45,0x82,0x85,0x08,0xd8,
|
||||
0x6f,0xd4,0xbc,0x62,0x54,0x02,0xaa,0x68,0x5f,0x60,0x72,0x5e,0xfd,0xb4,0x25,0x96),
|
||||
.out = chunk_from_chars(
|
||||
0x28,0x10,0x28,0x8a,0x45,0xa5,0x02,0x21,0x1f,0xea,0xde,0x99,0x43,0xb4,0x22,0x4a,
|
||||
0x3f,0x54,0xcf,0x97,0xf1,0x91,0xb6,0x21,0xd8,0x0a,0x19,0xf3,0xf1,0xb0,0x36,0x6d,
|
||||
0x5e,0xd7,0x3d,0x19,0x5b,0x73,0x2a,0x15,0xb5,0x99,0x05,0x1a,0x13,0xb7,0xc5,0x84,
|
||||
0x17,0x55,0x21,0xe3,0xa9,0x7c,0xdb,0x22,0x0c,0x89,0x24,0xb0,0xec,0x23,0x4a,0x94,
|
||||
0x2e,0x05,0x79,0x67,0x5f,0x19,0x39,0x26,0xab,0x33,0x29,0x70,0x58,0x55,0x53,0xe2,
|
||||
0x30,0xe3,0x42,0x9c,0x6e,0x8b,0xa7,0x1b,0x93,0x74,0xbd,0x4a,0x8d,0xf9,0x69,0x45,
|
||||
0x68,0x40,0x52,0x7f,0x2c,0xf6,0x35,0x39,0x2b,0xe9,0xc1,0x7c,0xa8,0x47,0x4c,0xf0,
|
||||
0x1b,0x33,0x2b,0x81,0x08,0xb5,0x4c,0x48,0xaa,0xfc,0x86,0xac,0x4c,0xfc,0xe7,0x05,
|
||||
0x8e,0xe1,0x14,0x54,0x0e,0x5a,0x1b,0x95,0x22,0x01,0xee,0x3d,0x0a,0xc9,0xd3,0xe3,
|
||||
0x3f,0x01,0x80,0x75,0x84,0x33,0x9a,0xc3,0xf4,0x3c,0xcd,0xd3,0x95,0xc5,0x8b,0xb3,
|
||||
0xf4,0xa4,0xcc,0x5c,0x57,0x87,0x1e,0xa1,0xd3,0xea,0xa8,0xd0,0x30,0x2b,0xb3,0x08,
|
||||
0xd1,0xd2,0x03,0xaf,0x13,0x14,0x7e,0x87,0xab,0x2b,0x91,0x59,0xae,0x36,0x1e,0xc0,
|
||||
0x11,0xd6,0x73,0xfe,0x3f,0x16,0x2b,0x39,0x89,0xda,0x34,0x88,0xd8,0xff,0xea,0x2b,
|
||||
0x51,0xe7,0x46,0x5f,0xad,0xdc,0xa6,0x7d,0x1d,0x54,0xc8,0x94,0x0a,0x8a,0xb6,0x2e,
|
||||
0x8a,0xbe,0x41,0x45,0xcb,0x25,0x15,0x91,0x25,0x95,0x01,0x19,0xe3,0xc0,0x1a,0x81,
|
||||
0x35,0x75,0xf0,0xa9,0x59,0xb1,0x43,0xbc,0x31,0xf6,0x2b,0x47,0x34,0xaa,0x45,0xe2),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_plus_sha512_1 = {
|
||||
.alg = KDF_PRF_PLUS, .arg.prf = PRF_HMAC_SHA2_512,
|
||||
.key = chunk_from_chars(
|
||||
0xda,0xf9,0xbd,0x6f,0x2f,0x91,0x2d,0xa5,0x53,0x86,0x79,0x66,0xaf,0x38,0x6e,0x67,
|
||||
0x90,0x9a,0x8d,0xf0,0xca,0x7e,0x84,0xb8,0x3b,0x35,0x5c,0xb7,0xd7,0xf1,0x02,0x6f,
|
||||
0x17,0xd8,0xea,0x34,0xb5,0xd5,0x7f,0xd0,0xd1,0xba,0x38,0x95,0x28,0xfc,0xa1,0xe8,
|
||||
0x1d,0x1c,0x8c,0xe5,0x11,0xb2,0x8a,0x24,0x58,0x24,0x11,0x43,0xfe,0xe3,0x0c,0xcc),
|
||||
.salt = chunk_from_chars(
|
||||
0xdf,0x79,0x31,0xdb,0x9b,0x42,0x9e,0x10,0xb8,0xaa,0x8e,0x4d,0x46,0x04,0x23,0x93,
|
||||
0x9b,0xa4,0x0a,0xf9,0x15,0x7f,0x47,0x92,0x53,0x83,0xc7,0xcd,0x3d,0x10,0x46,0xe6),
|
||||
.out = chunk_from_chars(
|
||||
0x91,0x9a,0x75,0xde,0xae,0xcc,0xbd,0x39,0x3b,0xeb,0xc8,0x96,0x15,0xf8,0xa2,0x15,
|
||||
0xed,0xb7,0x07,0x3b,0x23,0x19,0xd8,0x67,0x40,0x22,0x1e,0xee,0x7a,0x2d,0xeb,0x92,
|
||||
0x50,0x90,0x44,0xd7,0xe6,0x1f,0xcb,0x1b,0xf9,0x67,0x6b,0x38,0x81,0xc7,0xce,0xd4,
|
||||
0x9e,0x6b,0xba,0x15,0x49,0xda,0x31,0x13,0x60,0x16,0x77,0xa2,0x44,0x5d,0x91,0xac,
|
||||
0x13,0xa5,0x97,0x33,0x57,0x82,0xdd,0x3a,0x9c,0xf4,0x96,0xd9,0xe1,0x9b,0x93,0x2f,
|
||||
0x27,0xdd,0x35,0xe3,0x6f,0x80,0x70,0xd2,0x32,0xd0,0xa3,0xb3,0xf4,0xc4,0xa0,0xb4,
|
||||
0xba,0x44,0x70,0x77,0x8d,0xc0,0x90,0xf3,0x1f,0x52,0xab,0x1b,0x6d,0x81,0xe4,0xc7,
|
||||
0xdf,0xb3,0x50,0x63,0xad,0x96,0xc3,0x27,0xad,0xcd,0xbd,0xe7,0x14,0xcc,0x9a,0x6b,
|
||||
0x5e,0xf0,0x49,0xb8),
|
||||
};
|
||||
|
||||
kdf_test_vector_t prf_plus_sha512_2 = {
|
||||
.alg = KDF_PRF_PLUS, .arg.prf = PRF_HMAC_SHA2_512,
|
||||
.key = chunk_from_chars(
|
||||
0xe5,0x70,0xe7,0x48,0x46,0x34,0x30,0x0d,0x7a,0xdd,0xf5,0xa8,0x52,0x7c,0x13,0x8b,
|
||||
0x76,0x96,0xdb,0xc3,0xd8,0xbe,0x09,0x69,0xb7,0x52,0x15,0x31,0x8a,0x11,0xad,0xa2,
|
||||
0x13,0x53,0x8f,0x62,0x93,0xb0,0xee,0xe5,0xb3,0x09,0xad,0x8f,0x5d,0x8d,0x94,0xdb,
|
||||
0xe5,0x73,0x61,0x27,0xe0,0xd2,0x56,0x0f,0x28,0x1c,0x9c,0x58,0x6b,0xf7,0xc8,0x6f),
|
||||
.salt = chunk_from_chars(
|
||||
0xd8,0x96,0x84,0xe3,0xcb,0x17,0xf3,0xaa,0xbd,0x85,0x3a,0x78,0xdb,0x3e,0xcd,0x5a,
|
||||
0xac,0xc1,0xed,0x71,0xc7,0x0b,0x88,0xa2,0x97,0x56,0xf4,0x6f,0xc7,0x19,0x7c,0x80,
|
||||
0x4e,0xc0,0x01,0x54,0x40,0x02,0xa8,0xae,0xa3,0x60,0x68,0x4b,0x18,0x00,0x6d,0xef,
|
||||
0x0d,0xbd,0x86,0x33,0xb1,0x01,0x9f,0xbc,0xfa,0x85,0xb9,0x4c,0xac,0x2b,0xb8,0x21,
|
||||
0x25,0x84,0xbe,0x62,0xad,0xab,0x0e,0xe4,0xbb,0x8a,0x36,0xae,0xe2,0x52,0x75,0xef,
|
||||
0x07,0x13,0x90,0x48,0x0e,0xef,0xa2,0x09,0x2e,0xb3,0x08,0xaa,0x73,0x37,0xc5,0xce,
|
||||
0xb6,0x06,0x9a,0xb6,0x90,0xe8,0x96,0x2f,0xbf,0xe0,0x98,0x6e,0x4f,0x5c,0x18,0xf4,
|
||||
0x86,0x86,0x1e,0xd3,0xf1,0xdc,0xbe,0xe4,0xc9,0xe4,0xa7,0x66,0x9d,0x74,0x0c,0xa2,
|
||||
0xb0,0xe8,0xed,0x40,0x31,0xb0,0xa4,0x99,0xdc,0x31,0x5c,0xed,0xe7,0xef,0x03,0x39,
|
||||
0x9c,0xbc,0x33,0xdc,0xd6,0x29,0x70,0x34,0x9f,0x12,0x20,0x88,0x1b,0x55,0x45,0x2e,
|
||||
0x0c,0x6c,0x9b,0x52,0xa8,0x8b,0x67,0xf5,0x97,0x58,0x67,0x95,0xb2,0x25,0x70,0x73,
|
||||
0x3f,0xd4,0xff,0x2c,0xc2,0xad,0x93,0x1d,0x83,0x30,0x16,0x5a,0x9e,0x45,0x0e,0x38,
|
||||
0x88,0x59,0xce,0x62,0x4f,0x01,0xdb,0x17,0xc2,0x50,0x2b,0x4e,0x66,0xad,0xf9,0x65,
|
||||
0x27,0x36,0x3d,0x6f,0x90,0x6b,0x20,0x23,0xe8,0xed,0x74,0xd5,0xaf,0x0a,0xa6,0x02,
|
||||
0x46,0xb0,0xb9,0x2f,0x49,0xc4,0x93,0x3e,0xf3,0x12,0xf8,0xa2,0x54,0x34,0xee,0x96,
|
||||
0x98,0xd6,0xd9,0x20,0x43,0x45,0xbd,0x10,0xbb,0x11,0xaa,0x39,0x86,0x56,0x16,0xd5,
|
||||
0xad,0x1b,0x57,0x44,0x70,0x6c,0xfd,0x4e,0xa1,0x40,0x8e,0x20,0xc8,0xfd,0xcf,0x85,
|
||||
0x51,0xee,0xe8,0x81,0x4b,0x7b,0x37,0x33,0x0b,0x05,0x26,0xf0,0xbc,0x5e,0xe1,0x5d,
|
||||
0x4e,0xcd,0xa7,0xa1,0xbd,0x25,0xaa,0x97,0xf2,0x45,0x84,0xd8,0x5d,0x3f,0x52,0x49,
|
||||
0x69,0x4b,0x9f,0x43,0x53,0x9e,0x69,0xea,0x35,0xbf,0xe7,0xfd,0x44,0x07,0xbc,0x8e,
|
||||
0x9d,0xca,0x8a,0x9f,0xae,0x4b,0xdc,0x6b,0x7b,0xb3,0x8c,0x6d,0x68,0xf8,0x99,0xe1,
|
||||
0xd3,0x2c,0x85,0xbc,0xd6,0x17,0xa5,0x67,0x67,0x8c,0xf8,0x5d,0x22,0x17,0xa4,0xe8,
|
||||
0x6a,0x75,0x56,0x24,0xb6,0x40,0x02,0x35,0x4c,0x02,0x68,0x42,0xbc,0x95,0x42,0x49,
|
||||
0x1a,0xf1,0xc3,0xd6,0x29,0x09,0x70,0x55,0x9a,0xf1,0x1b,0xdc,0x2c,0x83,0xb5,0x4c,
|
||||
0x74,0x14,0x49,0x05,0xc0,0xa3,0x58,0xf3,0x15,0x3d,0xb7,0x67,0xa5,0xda,0x2a,0x86,
|
||||
0x27,0xf6,0x96,0x27,0xe1,0xd4,0x1e,0xde,0x9c,0x90,0x7c,0x79,0xb5,0x1f,0xf8,0x15,
|
||||
0xe4,0x64,0x5c,0x33,0x75,0xe0,0xf6,0x3f,0x84,0xfc,0xf5,0xd7,0xc3,0x40,0x7a,0x1d,
|
||||
0xd6,0x83,0x9e,0x19,0x06,0xa1,0xe3,0x80,0x2c,0xcf,0x5e,0x82,0x30,0xd9,0x5c,0xf4,
|
||||
0xb8,0x27,0xb4,0x1c,0x48,0x34,0x25,0xa8,0xa6,0x0b,0xfa,0x51,0x89,0xda,0xc4,0x38,
|
||||
0x06,0x0f,0x2f,0x5c,0xd5,0x26,0x66,0x2f,0x29,0x06,0xc1,0xdd,0x64,0xf4,0x84,0x4e,
|
||||
0x94,0x2c,0xa8,0x4d,0xae,0xce,0x6d,0xd7,0xbb,0xf7,0x19,0x4d,0x8c,0xe5,0x6b,0xc2,
|
||||
0x83,0x10,0x85,0xa7,0xd3,0x10,0xe4,0x94,0x4c,0xfa,0xe7,0x62,0x60,0xaa,0xbf,0x6b,
|
||||
0x60,0x9d,0x88,0x78,0x9b,0x8a,0x1a,0xbf,0x50,0x01,0x86,0xc3,0xd9,0x7e,0xd2,0xab),
|
||||
.out = chunk_from_chars(
|
||||
0x98,0x7f,0xad,0xd8,0x04,0x99,0x45,0x67,0xd5,0x7f,0x98,0x9b,0x6c,0xda,0x66,0xef,
|
||||
0xbf,0xfc,0xab,0x28,0xac,0x3e,0x3b,0xc6,0x10,0x78,0x05,0x95,0x4e,0xb1,0xea,0xd0,
|
||||
0xce,0xa6,0xfb,0x49,0xaa,0x96,0x1c,0xbe,0x98,0xfd,0xad,0x57,0xdd,0x9c,0x45,0x56,
|
||||
0x7c,0xe4,0x96,0x74,0x78,0x62,0xf8,0x8b,0xcd,0x9f,0xc5,0x75,0x59,0xa0,0x7e,0xa9,
|
||||
0x27,0xa4,0x20,0x82,0xba,0x87,0xe0,0xf5,0x1b,0x3d,0x5b,0x8c,0xbd,0xea,0xdd,0xed,
|
||||
0xa3,0xae,0x4c,0x73,0xb1,0xa5,0x1d,0xd0,0xdc,0xe3,0xcc,0x8e,0xb3,0xb1,0x41,0x9b,
|
||||
0x93,0xf2,0x9d,0xc6,0x52,0x2b,0x2f,0x5e,0x93,0x75,0x23,0x82,0x03,0xec,0xa9,0x8e,
|
||||
0xd8,0x6b,0xf1,0xe6,0x86,0x8a,0xb4,0x28,0xd8,0x63,0xa5,0xf3,0xb9,0x87,0xd6,0xc0,
|
||||
0xf9,0x57,0xaf,0x08,0xa1,0x63,0x1f,0x7c,0xdc,0x00,0x8c,0xbb,0xff,0xc2,0x4b,0x02,
|
||||
0x93,0x1a,0x02,0x01,0x94,0xe3,0x68,0xd6,0xb5,0x70,0x2e,0x7f,0x8b,0x96,0x0d,0xbc,
|
||||
0x93,0xca,0x56,0xed,0x5a,0x68,0xda,0xe0,0x20,0x69,0x94,0xed,0xf1,0x47,0x6f,0x5f,
|
||||
0xa3,0x4e,0xfb,0xda,0xa9,0x73,0xd2,0x7b,0xa3,0x68,0xce,0xdc,0xc6,0x66,0xd7,0x63,
|
||||
0xbd,0x6a,0xd5,0x60,0x57,0x38,0x51,0xbf,0xfb,0x70,0x99,0xaf,0x58,0x8f,0x34,0xff,
|
||||
0x2e,0x59,0x9b,0x0e,0x87,0xf7,0x0a,0x7f,0x4a,0xa4,0x8e,0x95,0x1d,0x0c,0x5c,0x30,
|
||||
0xdd,0xfc,0x1f,0x98,0xc1,0x28,0x63,0x15,0x90,0xcd,0xe0,0x0a,0x7c,0x93,0x15,0x8d,
|
||||
0xbf,0x4c,0xaa,0x53,0x7b,0x31,0x59,0x31,0xb7,0x14,0xd7,0x2f,0x4d,0x2a,0x01,0xc9),
|
||||
};
|
||||
@@ -25,6 +25,7 @@
|
||||
#define TEST_VECTOR_HASHER(x) extern hasher_test_vector_t x;
|
||||
#define TEST_VECTOR_PRF(x) extern prf_test_vector_t x;
|
||||
#define TEST_VECTOR_XOF(x) extern xof_test_vector_t x;
|
||||
#define TEST_VECTOR_KDF(x) extern kdf_test_vector_t x;
|
||||
#define TEST_VECTOR_DRBG(x) extern drbg_test_vector_t x;
|
||||
#define TEST_VECTOR_RNG(x) extern rng_test_vector_t x;
|
||||
#define TEST_VECTOR_DH(x) extern dh_test_vector_t x;
|
||||
@@ -37,6 +38,7 @@
|
||||
#undef TEST_VECTOR_HASHER
|
||||
#undef TEST_VECTOR_PRF
|
||||
#undef TEST_VECTOR_XOF
|
||||
#undef TEST_VECTOR_KDF
|
||||
#undef TEST_VECTOR_DRBG
|
||||
#undef TEST_VECTOR_RNG
|
||||
#undef TEST_VECTOR_DH
|
||||
@@ -47,6 +49,7 @@
|
||||
#define TEST_VECTOR_HASHER(x)
|
||||
#define TEST_VECTOR_PRF(x)
|
||||
#define TEST_VECTOR_XOF(x)
|
||||
#define TEST_VECTOR_KDF(x)
|
||||
#define TEST_VECTOR_DRBG(x)
|
||||
#define TEST_VECTOR_RNG(x)
|
||||
#define TEST_VECTOR_DH(x)
|
||||
@@ -100,6 +103,14 @@ static xof_test_vector_t *xof[] = {
|
||||
#undef TEST_VECTOR_XOF
|
||||
#define TEST_VECTOR_XOF(x)
|
||||
|
||||
#undef TEST_VECTOR_KDF
|
||||
#define TEST_VECTOR_KDF(x) &x,
|
||||
static kdf_test_vector_t *kdf[] = {
|
||||
#include "test_vectors.h"
|
||||
};
|
||||
#undef TEST_VECTOR_KDF
|
||||
#define TEST_VECTOR_KDF(x)
|
||||
|
||||
#undef TEST_VECTOR_DRBG
|
||||
#define TEST_VECTOR_DRBG(x) &x,
|
||||
static drbg_test_vector_t *drbg[] = {
|
||||
@@ -208,6 +219,11 @@ plugin_t *test_vectors_plugin_create()
|
||||
lib->crypto->add_test_vector(lib->crypto,
|
||||
EXTENDED_OUTPUT_FUNCTION, xof[i]);
|
||||
}
|
||||
for (i = 0; i < countof(kdf); i++)
|
||||
{
|
||||
lib->crypto->add_test_vector(lib->crypto,
|
||||
KEY_DERIVATION_FUNCTION, kdf[i]);
|
||||
}
|
||||
for (i = 0; i < countof(drbg); i++)
|
||||
{
|
||||
lib->crypto->add_test_vector(lib->crypto,
|
||||
|
||||
@@ -24,6 +24,7 @@ libstrongswan_wolfssl_la_SOURCES = \
|
||||
wolfssl_ed_public_key.h wolfssl_ed_public_key.c \
|
||||
wolfssl_hasher.h wolfssl_hasher.c \
|
||||
wolfssl_hmac.h wolfssl_hmac.c \
|
||||
wolfssl_kdf.h wolfssl_kdf.c \
|
||||
wolfssl_rsa_public_key.h wolfssl_rsa_public_key.c \
|
||||
wolfssl_rsa_private_key.h wolfssl_rsa_private_key.c \
|
||||
wolfssl_rng.h wolfssl_rng.c \
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "wolfssl_common.h"
|
||||
|
||||
#if !defined(NO_HMAC) && defined(HAVE_HKDF)
|
||||
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "wolfssl_kdf.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
typedef struct private_kdf_t private_kdf_t;
|
||||
|
||||
/**
|
||||
* Private data.
|
||||
*/
|
||||
struct private_kdf_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
kdf_t public;
|
||||
|
||||
/**
|
||||
* KDF type.
|
||||
*/
|
||||
key_derivation_function_t type;
|
||||
|
||||
/**
|
||||
* Hash algorithm type.
|
||||
*/
|
||||
enum wc_HashType hash;
|
||||
|
||||
/**
|
||||
* Key for KDF.
|
||||
*/
|
||||
chunk_t key;
|
||||
|
||||
/**
|
||||
* Salt for KDF.
|
||||
*/
|
||||
chunk_t salt;
|
||||
};
|
||||
|
||||
METHOD(kdf_t, get_type, key_derivation_function_t,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_length, size_t,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
if (this->type == KDF_PRF_PLUS)
|
||||
{
|
||||
return SIZE_MAX;
|
||||
}
|
||||
return wc_HashGetDigestSize(this->hash);
|
||||
}
|
||||
|
||||
METHOD(kdf_t, get_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
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))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (wc_HKDF_Expand(this->hash, this->key.ptr, this->key.len,
|
||||
this->salt.ptr, this->salt.len, buffer, out_len))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, allocate_bytes, bool,
|
||||
private_kdf_t *this, size_t out_len, chunk_t *chunk)
|
||||
{
|
||||
if (this->type == KDF_PRF)
|
||||
{
|
||||
out_len = out_len ?: get_length(this);
|
||||
}
|
||||
|
||||
*chunk = chunk_alloc(out_len);
|
||||
|
||||
if (!get_bytes(this, out_len, chunk->ptr))
|
||||
{
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, set_param, bool,
|
||||
private_kdf_t *this, kdf_param_t param, ...)
|
||||
{
|
||||
chunk_t chunk;
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case KDF_PARAM_KEY:
|
||||
VA_ARGS_GET(param, chunk);
|
||||
chunk_clear(&this->key);
|
||||
this->key = chunk_clone(chunk);
|
||||
break;
|
||||
case KDF_PARAM_SALT:
|
||||
VA_ARGS_GET(param, chunk);
|
||||
chunk_clear(&this->salt);
|
||||
this->salt = chunk_clone(chunk);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(kdf_t, destroy, void,
|
||||
private_kdf_t *this)
|
||||
{
|
||||
chunk_clear(&this->salt);
|
||||
chunk_clear(&this->key);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
kdf_t *wolfssl_kdf_create(key_derivation_function_t algo, va_list args)
|
||||
{
|
||||
private_kdf_t *this;
|
||||
pseudo_random_function_t prf_alg;
|
||||
enum wc_HashType hash;
|
||||
char buf[HASH_SIZE_SHA512];
|
||||
|
||||
if (algo != KDF_PRF && algo != KDF_PRF_PLUS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VA_ARGS_VGET(args, prf_alg);
|
||||
if (!wolfssl_hash2type(hasher_algorithm_from_prf(prf_alg), &hash))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_type = _get_type,
|
||||
.get_length = _get_length,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.set_param = _set_param,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.type = algo,
|
||||
.hash = hash,
|
||||
);
|
||||
|
||||
/* test if we can actually use the algorithm */
|
||||
if (!get_bytes(this, algo == KDF_PRF ? get_length(this) : sizeof(buf), buf))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* !NO_HMAC && HAVE_HKDF */
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Tobias Brunner, codelabs GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements key derivation functions (KDF) using wolfSSL, in particular prf+,
|
||||
* which is implemented via wolfSSL's HKDF implementation.
|
||||
*
|
||||
* @defgroup wolfssl_kdf wolfssl_kdf
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_KDF_H_
|
||||
#define WOLFSSL_KDF_H_
|
||||
|
||||
#include <crypto/kdfs/kdf.h>
|
||||
|
||||
/**
|
||||
* Creates a new kdf_t object.
|
||||
*
|
||||
* @param algo algorithm to instantiate
|
||||
* @param args algorithm-specific arguments
|
||||
* @return kdf_t object, NULL if not supported
|
||||
*/
|
||||
kdf_t *wolfssl_kdf_create(key_derivation_function_t algo, va_list args);
|
||||
|
||||
#endif /** WOLFSSL_KDF_H_ @}*/
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "wolfssl_ed_public_key.h"
|
||||
#include "wolfssl_hasher.h"
|
||||
#include "wolfssl_hmac.h"
|
||||
#include "wolfssl_kdf.h"
|
||||
#include "wolfssl_rsa_private_key.h"
|
||||
#include "wolfssl_rsa_public_key.h"
|
||||
#include "wolfssl_rng.h"
|
||||
@@ -185,6 +186,11 @@ METHOD(plugin_t, get_features, int,
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256),
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_512),
|
||||
#endif
|
||||
#ifdef HAVE_HKDF
|
||||
PLUGIN_REGISTER(KDF, wolfssl_kdf_create),
|
||||
PLUGIN_PROVIDE(KDF, KDF_PRF),
|
||||
PLUGIN_PROVIDE(KDF, KDF_PRF_PLUS),
|
||||
#endif
|
||||
#endif /* NO_HMAC */
|
||||
#if (!defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AESCCM))) || \
|
||||
(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
|
||||
|
||||
@@ -15,129 +15,138 @@
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <crypto/prf_plus.h>
|
||||
#include <library.h>
|
||||
|
||||
static struct {
|
||||
chunk_t key;
|
||||
chunk_t seed;
|
||||
chunk_t iterations[10];
|
||||
} counter_data[] = {
|
||||
chunk_t expected;
|
||||
} test_data[] = {
|
||||
{ .key = chunk_from_chars(0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
|
||||
0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
|
||||
0x0b,0x0b,0x0b,0x0b),
|
||||
.seed = chunk_from_chars(0x48,0x69,0x20,0x54,0x68,0x65,0x72,0x65),
|
||||
.iterations = {
|
||||
chunk_from_chars(0xb9,0xbd,0xc0),
|
||||
chunk_from_chars(0x89,0x88,0xb4,0xc2,0xb7,0x5a),
|
||||
chunk_from_chars(0xa9,0x3e,0x59,0x6a,0xc8,0x42,0x05),
|
||||
chunk_from_chars(0xfa,0x2d,0xdd,0xe1,0xbf,0x7a,0x25,0x72,
|
||||
0x06,0x7b,0x00,0xe1,0x4b,0x23,0x77,0x32),
|
||||
chunk_from_chars(0x83,0x05,0x09,0x98,0x1a,0xd2,0xf9,0x4a),
|
||||
chunk_from_chars(0x8c,0x32,0xa4,0x7d,0xaa,0x22,0x55,0xb6),
|
||||
chunk_from_chars(0x60,0xc4,0x36,0x34,0x7a,0xe7,0x56,0xa6,
|
||||
0xed,0xc0,0x23,0x47,0x7d,0x80),
|
||||
chunk_from_chars(0x95,0x90,0xe6,0x82,0xf6,0x1d,0x9c,0x04,
|
||||
0xb0,0x6b,0x4a,0xd9,0x71,0xa3,0x4c,0x81,
|
||||
0x47,0xfa,0x66,0x79),
|
||||
chunk_from_chars(0x2f,0xf1,0x43,0x4b,0x93,0xc7,0x22,0xb3,
|
||||
0x2e,0x12,0xf4,0x88,0x32,0xeb,0xc1,0x5c,
|
||||
0xe2,0x36,0x9c,0xe7,0x1f,0xe9,0xb7,0xb8,
|
||||
0x1e,0x57,0x04,0xc1,0x4d,0x0f,0x52,0x80,
|
||||
0xa6,0xec,0x62,0x6e,0x99,0x2d,0x7a,0x9f),
|
||||
},
|
||||
.expected = chunk_from_chars(0xb9,0xbd,0xc0,0x89,0x88,0xb4,0xc2,0xb7,
|
||||
0x5a,0xa9,0x3e,0x59,0x6a,0xc8,0x42,0x05,
|
||||
0xfa,0x2d,0xdd,0xe1,0xbf,0x7a,0x25,0x72,
|
||||
0x06,0x7b,0x00,0xe1,0x4b,0x23,0x77,0x32,
|
||||
0x83,0x05,0x09,0x98,0x1a,0xd2,0xf9,0x4a,
|
||||
0x8c,0x32,0xa4,0x7d,0xaa,0x22,0x55,0xb6,
|
||||
0x60,0xc4,0x36,0x34,0x7a,0xe7,0x56,0xa6,
|
||||
0xed,0xc0,0x23,0x47,0x7d,0x80,0x95,0x90,
|
||||
0xe6,0x82,0xf6,0x1d,0x9c,0x04,0xb0,0x6b,
|
||||
0x4a,0xd9,0x71,0xa3,0x4c,0x81,0x47,0xfa,
|
||||
0x66,0x79,0x2f,0xf1,0x43,0x4b,0x93,0xc7,
|
||||
0x22,0xb3,0x2e,0x12,0xf4,0x88,0x32,0xeb,
|
||||
0xc1,0x5c,0xe2,0x36,0x9c,0xe7,0x1f,0xe9,
|
||||
0xb7,0xb8,0x1e,0x57,0x04,0xc1,0x4d,0x0f,
|
||||
0x52,0x80,0xa6,0xec,0x62,0x6e,0x99,0x2d,
|
||||
0x7a,0x9f),
|
||||
},
|
||||
/* change the key, keep the seed */
|
||||
{ .key = chunk_from_chars(0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
|
||||
0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
|
||||
0x0a,0x0a,0x0a,0x0a),
|
||||
.expected = chunk_from_chars(0x1a,0x2f,0xc7,0x4a,0x06,0x8c,0xae,0x76,
|
||||
0xfa,0xb3,0xd6,0x34,0xae,0xe9,0x81,0x55,
|
||||
0x11,0x6a,0x4b,0x21,0xe1,0x0d,0x1b,0x16,
|
||||
0x45,0x7a,0x06,0xd9,0x42,0x27,0x93,0x98,
|
||||
0xf7,0x4d,0xf1,0x59,0xc1,0x25,0x21,0xae,
|
||||
0xe6,0xf4,0x80,0x01,0xe5,0x86,0x8e,0xa7,
|
||||
0x4b,0x1e,0x13,0xd1,0xcf,0xdc,0xb7,0x7b,
|
||||
0xf8,0xcf,0x75,0x2c,0x67,0x13,0x18,0x7a,
|
||||
0x38,0x55,0xba,0x4b,0xf2,0x57,0x55,0xcd,
|
||||
0x96,0x20,0xcb,0xe3,0xc4,0x8a,0x7f,0xa3,
|
||||
0x86,0xa5,0xc6,0x26,0x8e,0x57,0xd8,0xe0,
|
||||
0xb6,0xf9,0x8a,0x41,0x16,0x82,0x64,0x8a),
|
||||
},
|
||||
/* change the seed, keep the key */
|
||||
{ .seed = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||
0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10),
|
||||
.expected = chunk_from_chars(0x8b,0x90,0x9c,0xbc,0xbb,0xf1,0x72,0x63,
|
||||
0x6b,0x4e,0x63,0xcd,0x7e,0xc5,0xe3,0x45,
|
||||
0x57,0x3e,0xbf,0x72,0x8f,0x62,0xa4,0x9b,
|
||||
0x83,0x7b,0xd9,0x53,0xc0,0x0c,0xad,0x3d,
|
||||
0x19,0x16,0x28,0x81,0x85,0xf9,0x27,0xb6,
|
||||
0xc4,0x0c,0x48,0x31,0x45,0x12,0x3b,0x5a,
|
||||
0xb8,0x47,0xd0,0x19,0x6e,0x6b,0x1c,0x5a,
|
||||
0x2a,0xc1,0xe5,0x1e,0xc5,0x43,0xcc,0xd4,
|
||||
0x28,0xba,0x30,0x4b,0x5e,0xad,0x97,0xa7,
|
||||
0xc0,0x9d,0x13,0xdd,0xfb,0x4a,0x42,0x43,
|
||||
0x87,0xd6,0x22,0xf6,0x03,0x19,0x21,0x31,
|
||||
0x6a,0xa6,0x38,0x44,0xa5,0x61,0xf6,0x23,
|
||||
0x0c,0x50,0x14,0xcc,0xce,0x09,0x5f,0xb3,
|
||||
0xcc,0xe4,0xcb,0x8f,0x43,0xdc,0x2b,0x65,
|
||||
0xfd,0x42,0xcc,0xeb,0x49,0x0e,0xcb,0xeb,
|
||||
0x47,0x30,0xb5,0x18,0x6d,0x34,0x7a,0xea,
|
||||
0xad,0xfd,0x66,0xa7,0x7e,0xd3,0x3f,0x42,
|
||||
0xdf,0x75,0x54,0xef,0x5f,0x4f,0x7e,0x26,
|
||||
0xf9,0x38,0x73,0x26,0x92,0x7a,0xc7,0x80),
|
||||
},
|
||||
};
|
||||
|
||||
START_TEST(test_vectors_counter)
|
||||
START_TEST(test_params)
|
||||
{
|
||||
prf_plus_t *prf_plus;
|
||||
prf_t *prf;
|
||||
chunk_t *iter = counter_data[_i].iterations, out;
|
||||
kdf_t *kdf;
|
||||
chunk_t out;
|
||||
int i;
|
||||
|
||||
prf = lib->crypto->create_prf(lib->crypto, PRF_HMAC_SHA2_256);
|
||||
ck_assert(prf->set_key(prf, counter_data[_i].key));
|
||||
prf_plus = prf_plus_create(prf, TRUE, counter_data[_i].seed);
|
||||
while (iter->ptr)
|
||||
kdf = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS, PRF_HMAC_SHA2_256);
|
||||
if (!kdf)
|
||||
{
|
||||
ck_assert(prf_plus->allocate_bytes(prf_plus, iter->len, &out));
|
||||
ck_assert_chunk_eq(*iter, out);
|
||||
chunk_free(&out);
|
||||
iter++;
|
||||
warn("%N (%N) not supported", key_derivation_function_names,
|
||||
KDF_PRF_PLUS, pseudo_random_function_names, PRF_HMAC_SHA2_256);
|
||||
return;
|
||||
}
|
||||
prf_plus->destroy(prf_plus);
|
||||
prf->destroy(prf);
|
||||
for (i = 0; i < countof(test_data); i++)
|
||||
{
|
||||
if (test_data[i].key.len)
|
||||
{
|
||||
ck_assert(kdf->set_param(kdf, KDF_PARAM_KEY, test_data[i].key));
|
||||
}
|
||||
if (test_data[i].seed.len)
|
||||
{
|
||||
ck_assert(kdf->set_param(kdf, KDF_PARAM_SALT, test_data[i].seed));
|
||||
}
|
||||
ck_assert(kdf->allocate_bytes(kdf, test_data[i].expected.len, &out));
|
||||
ck_assert_chunk_eq(test_data[i].expected, out);
|
||||
chunk_free(&out);
|
||||
/* same output the second time */
|
||||
ck_assert(kdf->allocate_bytes(kdf, test_data[i].expected.len, &out));
|
||||
ck_assert_chunk_eq(test_data[i].expected, out);
|
||||
chunk_free(&out);
|
||||
}
|
||||
kdf->destroy(kdf);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_wrap)
|
||||
{
|
||||
prf_plus_t *prf_plus;
|
||||
prf_t *prf;
|
||||
u_char buf[32];
|
||||
int i;
|
||||
kdf_t *kdf;
|
||||
chunk_t out;
|
||||
|
||||
prf = lib->crypto->create_prf(lib->crypto, PRF_HMAC_SHA2_256);
|
||||
ck_assert(prf->set_key(prf, counter_data[0].key));
|
||||
prf_plus = prf_plus_create(prf, TRUE, counter_data[0].seed);
|
||||
for (i = 1; i < 256; i++)
|
||||
kdf = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS, PRF_HMAC_SHA2_256);
|
||||
if (!kdf)
|
||||
{
|
||||
ck_assert(prf_plus->get_bytes(prf_plus, sizeof(buf), buf));
|
||||
warn("%N (%N) not supported", key_derivation_function_names,
|
||||
KDF_PRF_PLUS, pseudo_random_function_names, PRF_HMAC_SHA2_256);
|
||||
return;
|
||||
}
|
||||
ck_assert(!prf_plus->get_bytes(prf_plus, sizeof(buf), buf));
|
||||
prf_plus->destroy(prf_plus);
|
||||
prf->destroy(prf);
|
||||
}
|
||||
END_TEST
|
||||
ck_assert(kdf->set_param(kdf, KDF_PARAM_KEY, test_data[0].key));
|
||||
ck_assert(kdf->set_param(kdf, KDF_PARAM_SALT, test_data[0].seed));
|
||||
|
||||
static struct {
|
||||
chunk_t key;
|
||||
chunk_t seed;
|
||||
chunk_t iterations[10];
|
||||
} classic_data[] = {
|
||||
{ .key = chunk_from_chars(0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
|
||||
0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
|
||||
0x0b,0x0b,0x0b,0x0b),
|
||||
.seed = chunk_from_chars(0x48,0x69,0x20,0x54,0x68,0x65,0x72,0x65),
|
||||
.iterations = {
|
||||
chunk_from_chars(0xb0,0x34,0x4c),
|
||||
chunk_from_chars(0x61,0xd8,0xdb,0x38,0x53,0x5c),
|
||||
chunk_from_chars(0xa8,0xaf,0xce,0xaf,0x0b,0xf1,0x2b),
|
||||
chunk_from_chars(0x88,0x1d,0xc2,0x00,0xc9,0x83,0x3d,0xa7,
|
||||
0x26,0xe9,0x37,0x6c,0x2e,0x32,0xcf,0xf7),
|
||||
chunk_from_chars(0xd0,0x9a,0xe2,0x4b,0x3a,0x83,0xff,0xd4),
|
||||
chunk_from_chars(0xb1,0xef,0xa5,0x94,0x5c,0xc5,0xed,0x85),
|
||||
chunk_from_chars(0xb0,0xb2,0xcc,0x56,0xfc,0xf7,0x5d,0x23,
|
||||
0xa0,0xa3,0x4c,0xa4,0xdb,0xff,),
|
||||
chunk_from_chars(0xea,0xfd,0xaa,0x6a,0x3b,0xf4,0x11,0x34,
|
||||
0x24,0xe4,0x50,0x2d,0xf9,0x7a,0x76,0x93,
|
||||
0x24,0xf6,0x11,0x24),
|
||||
chunk_from_chars(0x24,0x3b,0x99,0x6e,0x7d,0x0f,0x35,0x99,
|
||||
0x88,0x79,0x73,0x6b,0xdb,0x70,0x65,0x9a,
|
||||
0x6e,0xfa,0xd2,0x39,0x94,0x10,0xe6,0xce,
|
||||
0x80,0x45,0x6e,0xb6,0x07,0x07,0x8f,0xe1,
|
||||
0xc4,0x7c,0x6b,0x5e,0x81,0x65,0x47,0x8a),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
START_TEST(test_vectors_classic)
|
||||
{
|
||||
prf_plus_t *prf_plus;
|
||||
prf_t *prf;
|
||||
chunk_t *iter = classic_data[_i].iterations, out;
|
||||
|
||||
prf = lib->crypto->create_prf(lib->crypto, PRF_HMAC_SHA2_256);
|
||||
ck_assert(prf->set_key(prf, classic_data[_i].key));
|
||||
prf_plus = prf_plus_create(prf, FALSE, classic_data[_i].seed);
|
||||
while (iter->ptr)
|
||||
{
|
||||
ck_assert(prf_plus->allocate_bytes(prf_plus, iter->len, &out));
|
||||
ck_assert_chunk_eq(*iter, out);
|
||||
chunk_free(&out);
|
||||
iter++;
|
||||
/* the 1-byte counter overflows after 255 blocks of the underlying PRF */
|
||||
out = chunk_alloc(32 * 255 + 1);
|
||||
ck_assert(kdf->get_bytes(kdf, out.len - 2, out.ptr));
|
||||
if (!kdf->get_bytes(kdf, out.len - 1, out.ptr))
|
||||
{ /* Botan 3.x has a check for (len/bs) >= 255 blocks, so we allow this */
|
||||
warn("unable to generate maximum-sized key for %N (%N) but maximum-1 "
|
||||
"is fine", key_derivation_function_names, KDF_PRF_PLUS,
|
||||
pseudo_random_function_names, PRF_HMAC_SHA2_256);
|
||||
}
|
||||
prf_plus->destroy(prf_plus);
|
||||
prf->destroy(prf);
|
||||
ck_assert(!kdf->get_bytes(kdf, out.len, out.ptr));
|
||||
chunk_free(&out);
|
||||
kdf->destroy(kdf);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@@ -148,13 +157,12 @@ Suite *prf_plus_suite_create()
|
||||
|
||||
s = suite_create("prf_plus");
|
||||
|
||||
tc = tcase_create("counter");
|
||||
tcase_add_loop_test(tc, test_vectors_counter, 0, countof(counter_data));
|
||||
tcase_add_test(tc, test_wrap);
|
||||
tc = tcase_create("params");
|
||||
tcase_add_test(tc, test_params);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("no counter");
|
||||
tcase_add_loop_test(tc, test_vectors_classic, 0, countof(classic_data));
|
||||
tc = tcase_create("wrap");
|
||||
tcase_add_test(tc, test_wrap);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
|
||||
@@ -29,6 +29,7 @@ static transform_type_t tfs[] = {
|
||||
HASH_ALGORITHM,
|
||||
PSEUDO_RANDOM_FUNCTION,
|
||||
EXTENDED_OUTPUT_FUNCTION,
|
||||
KEY_DERIVATION_FUNCTION,
|
||||
DETERMINISTIC_RANDOM_BIT_GENERATOR,
|
||||
RANDOM_NUMBER_GENERATOR,
|
||||
DIFFIE_HELLMAN_GROUP,
|
||||
|
||||
@@ -55,7 +55,7 @@ TEST_SUITE(asn1_parser_suite_create)
|
||||
TEST_SUITE(rng_tester_suite_create)
|
||||
TEST_SUITE_DEPEND(mgf1_sha1_suite_create, XOF, XOF_MGF1_SHA1)
|
||||
TEST_SUITE_DEPEND(mgf1_sha256_suite_create, XOF, XOF_MGF1_SHA256)
|
||||
TEST_SUITE_DEPEND(prf_plus_suite_create, PRF, PRF_HMAC_SHA2_256)
|
||||
TEST_SUITE_DEPEND(prf_plus_suite_create, KDF, KDF_PRF_PLUS)
|
||||
TEST_SUITE_DEPEND(ntru_suite_create, DH, NTRU_112_BIT)
|
||||
TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://")
|
||||
TEST_SUITE_DEPEND(ed25519_suite_create, PRIVKEY_GEN, KEY_ED25519)
|
||||
|
||||
@@ -637,6 +637,7 @@ static char *whitelist[] = {
|
||||
"botan_privkey_create",
|
||||
"botan_privkey_load_ecdh",
|
||||
"botan_privkey_load",
|
||||
"botan_kdf",
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+17
-15
@@ -18,7 +18,6 @@
|
||||
#include "tls_hkdf.h"
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <crypto/prf_plus.h>
|
||||
|
||||
typedef struct private_tls_hkdf_t private_tls_hkdf_t;
|
||||
|
||||
@@ -51,6 +50,11 @@ struct private_tls_hkdf_t {
|
||||
*/
|
||||
prf_t *prf;
|
||||
|
||||
/**
|
||||
* prf+ implementation.
|
||||
*/
|
||||
kdf_t *prf_plus;
|
||||
|
||||
/**
|
||||
* Hasher used.
|
||||
*/
|
||||
@@ -115,7 +119,6 @@ static bool extract(private_tls_hkdf_t *this, chunk_t salt, chunk_t ikm,
|
||||
}
|
||||
|
||||
DBG4(DBG_TLS, "PRK: %B", prk);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -126,24 +129,15 @@ static bool extract(private_tls_hkdf_t *this, chunk_t salt, chunk_t ikm,
|
||||
static bool expand(private_tls_hkdf_t *this, chunk_t prk, chunk_t info,
|
||||
size_t length, chunk_t *okm)
|
||||
{
|
||||
prf_plus_t *prf_plus;
|
||||
|
||||
if (!this->prf->set_key(this->prf, prk))
|
||||
{
|
||||
DBG1(DBG_TLS, "unable to set PRF secret to PRK");
|
||||
return FALSE;
|
||||
}
|
||||
prf_plus = prf_plus_create(this->prf, TRUE, info);
|
||||
if (!prf_plus || !prf_plus->allocate_bytes(prf_plus, length, okm))
|
||||
if (!this->prf_plus->set_param(this->prf_plus, KDF_PARAM_KEY, prk) ||
|
||||
!this->prf_plus->set_param(this->prf_plus, KDF_PARAM_SALT, info) ||
|
||||
!this->prf_plus->allocate_bytes(this->prf_plus, length, okm))
|
||||
{
|
||||
DBG1(DBG_TLS, "unable to allocate PRF+ result");
|
||||
DESTROY_IF(prf_plus);
|
||||
return FALSE;
|
||||
}
|
||||
prf_plus->destroy(prf_plus);
|
||||
|
||||
DBG4(DBG_TLS, "OKM: %B", okm);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -681,6 +675,7 @@ METHOD(tls_hkdf_t, destroy, void,
|
||||
destroy_secrets(&this->handshake_traffic_secrets);
|
||||
destroy_secrets(&this->traffic_secrets);
|
||||
DESTROY_IF(this->prf);
|
||||
DESTROY_IF(this->prf_plus);
|
||||
DESTROY_IF(this->hasher);
|
||||
free(this);
|
||||
}
|
||||
@@ -720,16 +715,23 @@ tls_hkdf_t *tls_hkdf_create(hash_algorithm_t hash_algorithm, chunk_t psk)
|
||||
.phase = HKDF_PHASE_0,
|
||||
.psk = psk.ptr ? chunk_clone(psk) : chunk_empty,
|
||||
.prf = lib->crypto->create_prf(lib->crypto, prf_algorithm),
|
||||
.prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS,
|
||||
prf_algorithm),
|
||||
.hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm),
|
||||
);
|
||||
|
||||
if (!this->prf || !this->hasher)
|
||||
if (!this->prf || !this->prf_plus || !this->hasher)
|
||||
{
|
||||
if (!this->prf)
|
||||
{
|
||||
DBG1(DBG_TLS, "%N not supported", pseudo_random_function_names,
|
||||
prf_algorithm);
|
||||
}
|
||||
if (!this->prf_plus)
|
||||
{
|
||||
DBG1(DBG_TLS, "%N (%N) not supported", key_derivation_function_names,
|
||||
KDF_PRF_PLUS, pseudo_random_function_names, prf_algorithm);
|
||||
}
|
||||
if (!this->hasher)
|
||||
{
|
||||
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
load = sha1 sha2 md5 aes des hmac kdf pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
load = sha1 sha2 md5 aes des hmac kdf pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
load = sha1 sha2 md5 aes des hmac kdf pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
load = sha1 sha2 md5 aes des hmac kdf pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
load = sha1 sha2 md5 aes des hmac kdf pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
load = sha1 sha2 md5 aes des hmac kdf pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
load = sha1 sha2 md5 aes des hmac kdf pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce pem pkcs1 af-alg gmp x509 revocation kernel-netlink curl socket-default updown vici
|
||||
load = random nonce kdf pem pkcs1 af-alg gmp x509 revocation kernel-netlink curl socket-default updown vici
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce pem pkcs1 af-alg gmp x509 revocation kernel-netlink curl socket-default updown vici
|
||||
load = random nonce kdf pem pkcs1 af-alg gmp x509 revocation kernel-netlink curl socket-default updown vici
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce test-vectors pem pkcs1 af-alg gmp x509 revocation curl ctr ccm gcm kernel-netlink socket-default updown vici
|
||||
load = random nonce kdf test-vectors pem pkcs1 af-alg gmp x509 revocation curl ctr ccm gcm kernel-netlink socket-default updown vici
|
||||
integrity_test = yes
|
||||
crypto_test {
|
||||
on_add = yes
|
||||
|
||||
@@ -5,7 +5,7 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce test-vectors aes des sha1 sha2 md5 pem pkcs1 gmp x509 revocation curl hmac xcbc ctr ccm gcm kernel-netlink socket-default updown vici
|
||||
load = random nonce kdf test-vectors aes des sha1 sha2 md5 pem pkcs1 gmp x509 revocation curl hmac kdf xcbc ctr ccm gcm kernel-netlink socket-default updown vici
|
||||
integrity_test = yes
|
||||
crypto_test {
|
||||
on_add = yes
|
||||
|
||||
@@ -5,7 +5,7 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce test-vectors pem pkcs1 af-alg gmp x509 revocation curl ctr ccm gcm kernel-netlink socket-default updown vici
|
||||
load = random nonce kdf test-vectors pem pkcs1 af-alg gmp x509 revocation curl ctr ccm gcm kernel-netlink socket-default updown vici
|
||||
integrity_test = yes
|
||||
crypto_test {
|
||||
on_add = yes
|
||||
|
||||
@@ -5,5 +5,5 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 hmac pem pkcs1 pkcs8 x509 revocation constraints curve25519 curl kernel-netlink socket-default updown vici
|
||||
load = random nonce aes sha1 sha2 hmac kdf pem pkcs1 pkcs8 x509 revocation constraints curve25519 curl kernel-netlink socket-default updown vici
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce sha1 sha2 aes curve25519 hmac mgf1 pem pkcs1 x509 revocation constraints pubkey gmp curl kernel-netlink socket-default updown vici
|
||||
load = random nonce sha1 sha2 aes curve25519 hmac kdf mgf1 pem pkcs1 x509 revocation constraints pubkey gmp curl kernel-netlink socket-default updown vici
|
||||
|
||||
rsa_pss = yes
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce sha1 sha2 aes hmac mgf1 pem pkcs1 x509 revocation constraints pubkey gmp curl kernel-netlink socket-default updown vici
|
||||
load = random nonce sha1 sha2 aes hmac kdf mgf1 pem pkcs1 x509 revocation constraints pubkey gmp curl kernel-netlink socket-default updown vici
|
||||
|
||||
rsa_pss = yes
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = nonce pem pkcs1 gcrypt hmac x509 revocation curl vici kernel-netlink socket-default
|
||||
load = nonce pem pkcs1 gcrypt hmac kdf x509 revocation curl vici kernel-netlink socket-default
|
||||
send_vendor_id = yes
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = nonce pem pkcs1 gcrypt hmac x509 revocation vici kernel-netlink socket-default
|
||||
load = nonce pem pkcs1 gcrypt hmac kdf x509 revocation vici kernel-netlink socket-default
|
||||
send_vendor_id = yes
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = nonce pem pkcs1 gcrypt hmac x509 revocation curl vici kernel-netlink socket-default
|
||||
load = nonce pem pkcs1 gcrypt hmac kdf x509 revocation curl vici kernel-netlink socket-default
|
||||
send_vendor_id = yes
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = nonce pem pkcs1 gcrypt hmac x509 revocation vici kernel-netlink socket-default
|
||||
load = nonce pem pkcs1 gcrypt hmac kdf x509 revocation vici kernel-netlink socket-default
|
||||
send_vendor_id = yes
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce pem pkcs1 gcrypt hmac x509 revocation kernel-netlink curl socket-default updown vici
|
||||
load = random nonce pem pkcs1 gcrypt hmac kdf x509 revocation kernel-netlink curl socket-default updown vici
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce pem pkcs1 gcrypt hmac x509 revocation kernel-netlink curl socket-default updown vici
|
||||
load = random nonce pem pkcs1 gcrypt hmac kdf x509 revocation kernel-netlink curl socket-default updown vici
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = curl test-vectors pem pkcs1 gcrypt nonce x509 revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
|
||||
load = curl test-vectors pem pkcs1 gcrypt nonce x509 revocation hmac kdf xcbc ctr ccm gcm vici kernel-netlink socket-default updown
|
||||
integrity_test = yes
|
||||
crypto_test {
|
||||
on_add = yes
|
||||
|
||||
@@ -5,7 +5,7 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = test-vectors aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac xcbc ctr ccm vici stroke kernel-netlink socket-default updown
|
||||
load = test-vectors aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac kdf xcbc ctr ccm vici stroke kernel-netlink socket-default updown
|
||||
integrity_test = yes
|
||||
crypto_test {
|
||||
required = yes
|
||||
|
||||
@@ -5,7 +5,7 @@ swanctl {
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = curl test-vectors pem pkcs1 gcrypt nonce x509 revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
|
||||
load = curl test-vectors pem pkcs1 gcrypt nonce x509 revocation hmac kdf xcbc ctr ccm gcm vici kernel-netlink socket-default updown
|
||||
integrity_test = yes
|
||||
crypto_test {
|
||||
on_add = yes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default ha
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default ha
|
||||
|
||||
plugins {
|
||||
ha {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default updown
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default updown
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default ha
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default ha
|
||||
|
||||
plugins {
|
||||
ha {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default ha
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default ha
|
||||
|
||||
plugins {
|
||||
ha {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default updown
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default updown
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default ha
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default ha
|
||||
|
||||
plugins {
|
||||
ha {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac stroke kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf stroke kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac stroke kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf stroke kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac stroke kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf stroke kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp hmac x509 curl revocation stroke kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp hmac kdf x509 curl revocation stroke kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp hmac x509 curl revocation stroke kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp hmac kdf x509 curl revocation stroke kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp hmac x509 curl revocation stroke kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp hmac kdf x509 curl revocation stroke kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce des md5 sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce des md5 sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce des md5 sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce des md5 sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce blowfish sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce blowfish sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce blowfish sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce blowfish sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce blowfish sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce blowfish sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user