aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2008-03-19 14:02:52 +0000
committerMartin Willi <martin@strongswan.org>2008-03-19 14:02:52 +0000
commitcfede7f6e26351e9edf4a10ab40c292d2f7142bc (patch)
tree6cd01db7a5b7c71fa05e4034db086ecce5afe1ab
parentc912c3d382172999be8a0827180a0cabd0f982b9 (diff)
downloadstrongswan-cfede7f6e26351e9edf4a10ab40c292d2f7142bc.tar.bz2
strongswan-cfede7f6e26351e9edf4a10ab40c292d2f7142bc.tar.xz
The introduced SHA1_NOFINAL hasher was not sufficient for EAP-AKA,
as it requires to XOR the key into the hashers state. A new SHA1 based keyed hash function, implemented as PRF, enables EAP-AKA and the FIPS-PRF function to properly use the existing SHA1 implementation.
-rw-r--r--src/charon/plugins/eap_aka/eap_aka.c60
-rw-r--r--src/charon/plugins/unit_tester/tests/test_fips_prf.c3
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.c1
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.h8
-rw-r--r--src/libstrongswan/crypto/prfs/prf.c7
-rw-r--r--src/libstrongswan/crypto/prfs/prf.h5
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf.c31
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_hasher.c146
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_hasher.h25
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_plugin.c6
10 files changed, 183 insertions, 109 deletions
diff --git a/src/charon/plugins/eap_aka/eap_aka.c b/src/charon/plugins/eap_aka/eap_aka.c
index 3dd842b9e..a8bef728e 100644
--- a/src/charon/plugins/eap_aka/eap_aka.c
+++ b/src/charon/plugins/eap_aka/eap_aka.c
@@ -204,11 +204,6 @@ struct private_eap_aka_t {
hasher_t *sha1;
/**
- * SHA1_NOFINAL hasher for G() function
- */
- hasher_t *sha1_nof;
-
- /**
* MAC function used in EAP-AKA
*/
signer_t *signer;
@@ -219,6 +214,11 @@ struct private_eap_aka_t {
prf_t *prf;
/**
+ * Special keyed SHA1 hasher used in EAP-AKA, implemented as PRF
+ */
+ prf_t *keyed_prf;
+
+ /**
* Key for EAP MAC
*/
chunk_t k_auth;
@@ -437,48 +437,31 @@ static void step4(private_eap_aka_t *this, u_int8_t x[])
}
/**
- * Implementation of the G() function based on SHA1
+ * Step 3 of the various fx() functions:
+ * XOR the key into the SHA1 IV
*/
-static void g_sha1(private_eap_aka_t *this,
- u_int8_t t[], chunk_t c, u_int8_t res[])
+static void step3(private_eap_aka_t *this,
+ chunk_t k, chunk_t payload, u_int8_t h[])
{
u_int8_t buf[64];
- if (c.len < sizeof(buf))
+ if (payload.len < sizeof(buf))
{
/* pad c with zeros */
memset(buf, 0, sizeof(buf));
- memcpy(buf, c.ptr, c.len);
- c.ptr = buf;
- c.len = sizeof(buf);
+ memcpy(buf, payload.ptr, payload.len);
+ payload.ptr = buf;
+ payload.len = sizeof(buf);
}
else
{
/* not more than 512 bits can be G()-ed */
- c.len = sizeof(buf);
+ payload.len = sizeof(buf);
}
- /* calculate the special (HASH_SHA1_STATE) hash*/
- this->sha1_nof->get_hash(this->sha1_nof, c, res);
-}
-
-/**
- * Step 3 of the various fx() functions:
- * XOR the key into the SHA1 IV
- */
-static void step3(private_eap_aka_t *this,
- chunk_t k, chunk_t payload, u_int8_t h[])
-{
- u_int8_t iv[] = {
- 0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
- 0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
- };
-
- /* XOR key into IV */
- memxor(iv, k.ptr, k.len);
-
- /* hash it with the G() function defined in FIPS 186-2 from fips_prf.h */
- g_sha1(this, iv, payload, h);
+ /* use the keyed hasher to build the hash */
+ this->keyed_prf->set_key(this->keyed_prf, k);
+ this->keyed_prf->get_bytes(this->keyed_prf, payload, h);
}
/**
@@ -1282,6 +1265,7 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
/* verify EAP message MAC AT_MAC */
DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
DBG3(DBG_IKE, "using key %B", &this->k_auth);
+ this->signer->set_key(this->signer, this->k_auth);
if (!this->signer->verify_signature(this->signer, message, at_mac))
{
*out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
@@ -1468,9 +1452,9 @@ static bool is_mutual(private_eap_aka_t *this)
static void destroy(private_eap_aka_t *this)
{
DESTROY_IF(this->sha1);
- DESTROY_IF(this->sha1_nof);
DESTROY_IF(this->signer);
DESTROY_IF(this->prf);
+ DESTROY_IF(this->keyed_prf);
chunk_free(&this->k_encr);
chunk_free(&this->k_auth);
chunk_free(&this->msk);
@@ -1508,17 +1492,17 @@ static private_eap_aka_t *eap_aka_create_generic(identification_t *server,
this->rand = chunk_empty;
this->sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- this->sha1_nof = lib->crypto->create_hasher(lib->crypto, HASH_SHA1_NOFINAL);
this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
this->prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
+ this->keyed_prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
- if (!this->sha1 || !this->sha1_nof || !this->signer || !this->prf)
+ if (!this->sha1 || !this->signer || !this->prf || !this->keyed_prf)
{
DBG1(DBG_IKE, "unable to initiate EAP-AKA, FIPS-PRF/SHA1 not supported");
DESTROY_IF(this->sha1);
- DESTROY_IF(this->sha1_nof);
DESTROY_IF(this->signer);
DESTROY_IF(this->prf);
+ DESTROY_IF(this->keyed_prf);
destroy(this);
return NULL;
}
diff --git a/src/charon/plugins/unit_tester/tests/test_fips_prf.c b/src/charon/plugins/unit_tester/tests/test_fips_prf.c
index 56ba556f5..29612143e 100644
--- a/src/charon/plugins/unit_tester/tests/test_fips_prf.c
+++ b/src/charon/plugins/unit_tester/tests/test_fips_prf.c
@@ -45,6 +45,7 @@ bool fips_prf_test()
prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
if (prf == NULL)
{
+ DBG1(DBG_CFG, "FIPS PRF implementation not found");
return FALSE;
}
prf->set_key(prf, key);
@@ -52,6 +53,8 @@ bool fips_prf_test()
prf->destroy(prf);
if (!chunk_equals(result, expected))
{
+ DBG1(DBG_CFG, "FIPS PRF result invalid:\nexpected: %Bresult: %B",
+ &expected, &result);
chunk_free(&result);
return FALSE;
}
diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c
index ea4b4b08b..ce208a110 100644
--- a/src/libstrongswan/crypto/hashers/hasher.c
+++ b/src/libstrongswan/crypto/hashers/hasher.c
@@ -27,7 +27,6 @@ ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
"HASH_MD2",
"HASH_MD5",
"HASH_SHA1",
- "HASH_SHA1_NOFINAL",
"HASH_SHA256",
"HASH_SHA384",
"HASH_SHA512"
diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h
index 4aa4ba357..a374da059 100644
--- a/src/libstrongswan/crypto/hashers/hasher.h
+++ b/src/libstrongswan/crypto/hashers/hasher.h
@@ -41,11 +41,9 @@ enum hash_algorithm_t {
HASH_MD2 = 2,
HASH_MD5 = 3,
HASH_SHA1 = 4,
- /** special SHA1 which does not run SHA1Final, but copies the state */
- HASH_SHA1_NOFINAL = 5,
- HASH_SHA256 = 6,
- HASH_SHA384 = 7,
- HASH_SHA512 = 8,
+ HASH_SHA256 = 5,
+ HASH_SHA384 = 6,
+ HASH_SHA512 = 7,
};
#define HASH_SIZE_MD2 16
diff --git a/src/libstrongswan/crypto/prfs/prf.c b/src/libstrongswan/crypto/prfs/prf.c
index c1fa1e152..638873650 100644
--- a/src/libstrongswan/crypto/prfs/prf.c
+++ b/src/libstrongswan/crypto/prfs/prf.c
@@ -18,11 +18,12 @@
#include "prf.h"
-ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_FIPS_DES,
+ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_KEYED_SHA1,
"PRF_UNDEFINED",
"PRF_FIPS_SHA1_160",
- "PRF_FIPS_DES");
-ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIPS_DES,
+ "PRF_FIPS_DES",
+ "PRF_KEYED_SHA1");
+ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_KEYED_SHA1,
"PRF_HMAC_MD5",
"PRF_HMAC_SHA1",
"PRF_HMAC_TIGER",
diff --git a/src/libstrongswan/crypto/prfs/prf.h b/src/libstrongswan/crypto/prfs/prf.h
index 662a95938..135d7889f 100644
--- a/src/libstrongswan/crypto/prfs/prf.h
+++ b/src/libstrongswan/crypto/prfs/prf.h
@@ -53,6 +53,11 @@ enum pseudo_random_function_t {
PRF_FIPS_SHA1_160 = 1025,
/** Could be implemented via fips_prf_t, uses fixed output size of 160bit */
PRF_FIPS_DES = 1026,
+ /**
+ * Keyed hash algorithm using SHA1, used in EAP-AKA:
+ * This PRF uses SHA1, but XORs the key into the IV. No "Final()" operation
+ * is applied to the SHA1 state. */
+ PRF_KEYED_SHA1 = 1027,
};
/**
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c
index 20b752e30..11adad086 100644
--- a/src/libstrongswan/plugins/fips_prf/fips_prf.c
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c
@@ -43,26 +43,17 @@ struct private_fips_prf_t {
size_t b;
/**
- * associated hasher when using SHA1 mode
+ * Keyed SHA1 prf: It does not use SHA1Final operation
*/
- hasher_t *hasher;
+ prf_t *keyed_prf;
/**
* G function, either SHA1 or DES
*/
- void (*g)(private_fips_prf_t *this, u_int8_t t[], chunk_t c, u_int8_t res[]);
+ void (*g)(private_fips_prf_t *this, chunk_t c, u_int8_t res[]);
};
/**
- * t used in G(), equals to initial SHA1 value
- */
-static u_int8_t t[] = {
- 0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
- 0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
-};
-
-
-/**
* sum = (a + b) mod 2 ^ (length * 8)
*/
static void add_mod(size_t length, u_int8_t a[], u_int8_t b[], u_int8_t sum[])
@@ -140,7 +131,7 @@ static void get_bytes(private_fips_prf_t *this, chunk_t seed, u_int8_t w[])
add_mod(this->b, xkey, xseed, xval);
DBG3("XVAL %b", xval, this->b);
/* b. wi = G(t, XVAL ) */
- this->g(this, t, xval_chunk, &w[i * this->b]);
+ this->g(this, xval_chunk, &w[i * this->b]);
DBG3("w[%d] %b", i, &w[i * this->b], this->b);
/* c. XKEY = (1 + XKEY + wi) mod 2b */
add_mod(this->b, xkey, &w[i * this->b], sum);
@@ -187,7 +178,7 @@ static void set_key(private_fips_prf_t *this, chunk_t key)
/**
* Implementation of the G() function based on SHA1
*/
-void g_sha1(private_fips_prf_t *this, u_int8_t t[], chunk_t c, u_int8_t res[])
+void g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[])
{
u_int8_t buf[64];
@@ -205,8 +196,9 @@ void g_sha1(private_fips_prf_t *this, u_int8_t t[], chunk_t c, u_int8_t res[])
c.len = sizeof(buf);
}
- /* calculate the special (HASH_SHA1_STATE) hash*/
- this->hasher->get_hash(this->hasher, c, res);
+ /* use the keyed hasher, but use an empty key to use SHA1 IV */
+ this->keyed_prf->set_key(this->keyed_prf, chunk_empty);
+ this->keyed_prf->get_bytes(this->keyed_prf, c, res);
}
/**
@@ -214,7 +206,7 @@ void g_sha1(private_fips_prf_t *this, u_int8_t t[], chunk_t c, u_int8_t res[])
*/
static void destroy(private_fips_prf_t *this)
{
- this->hasher->destroy(this->hasher);
+ this->keyed_prf->destroy(this->keyed_prf);
free(this->key);
free(this);
}
@@ -239,9 +231,8 @@ fips_prf_t *fips_prf_create(pseudo_random_function_t algo)
{
this->g = g_sha1;
this->b = 20;
- this->hasher = lib->crypto->create_hasher(lib->crypto,
- HASH_SHA1_NOFINAL);
- if (this->hasher == NULL)
+ this->keyed_prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
+ if (this->keyed_prf == NULL)
{
free(this);
return NULL;
diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.c b/src/libstrongswan/plugins/sha1/sha1_hasher.c
index 97a2f207f..8d8e56382 100644
--- a/src/libstrongswan/plugins/sha1/sha1_hasher.c
+++ b/src/libstrongswan/plugins/sha1/sha1_hasher.c
@@ -47,6 +47,7 @@
typedef struct private_sha1_hasher_t private_sha1_hasher_t;
+typedef struct private_sha1_keyed_prf_t private_sha1_keyed_prf_t;
/**
* Private data structure with hasing context.
@@ -57,11 +58,6 @@ struct private_sha1_hasher_t {
*/
sha1_hasher_t public;
- /**
- * implemented algorithm
- */
- hash_algorithm_t algo;
-
/*
* State of the hasher.
*/
@@ -70,6 +66,21 @@ struct private_sha1_hasher_t {
u_int8_t buffer[64];
};
+/**
+ * Private data structure with keyed prf context.
+ */
+struct private_sha1_keyed_prf_t {
+ /**
+ * public prf interface
+ */
+ sha1_keyed_prf_t public;
+
+ /**
+ * internal used hasher
+ */
+ private_sha1_hasher_t *hasher;
+};
+
/*
* Hash a single 512-bit block. This is the core of the algorithm. *
*/
@@ -197,19 +208,6 @@ static void reset(private_sha1_hasher_t *this)
}
/**
- * copy hasher state to buf
- */
-static void state_to_buf(private_sha1_hasher_t *this, u_int8_t *buffer)
-{
- u_int32_t *hash = (u_int32_t*)buffer;
- hash[0] = htonl(this->state[0]);
- hash[1] = htonl(this->state[1]);
- hash[2] = htonl(this->state[2]);
- hash[3] = htonl(this->state[3]);
- hash[4] = htonl(this->state[4]);
-}
-
-/**
* Implementation of hasher_t.get_hash.
*/
static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
@@ -217,19 +215,11 @@ static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffe
SHA1Update(this, chunk.ptr, chunk.len);
if (buffer != NULL)
{
- if (this->algo == HASH_SHA1_NOFINAL)
- {
- state_to_buf(this, buffer);
- }
- else
- {
- SHA1Final(this, buffer);
- }
+ SHA1Final(this, buffer);
reset(this);
}
}
-
/**
* Implementation of hasher_t.allocate_hash.
*/
@@ -241,14 +231,7 @@ static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *h
hash->ptr = malloc(HASH_SIZE_SHA1);
hash->len = HASH_SIZE_SHA1;
- if (this->algo == HASH_SHA1_NOFINAL)
- {
- state_to_buf(this, hash->ptr);
- }
- else
- {
- SHA1Final(this, hash->ptr);
- }
+ SHA1Final(this, hash->ptr);
reset(this);
}
}
@@ -275,12 +258,11 @@ static void destroy(private_sha1_hasher_t *this)
sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo)
{
private_sha1_hasher_t *this;
- if (algo != HASH_SHA1 && algo != HASH_SHA1_NOFINAL)
+ if (algo != HASH_SHA1)
{
return NULL;
}
this = malloc_thing(private_sha1_hasher_t);
- this->algo = algo;
this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
@@ -292,3 +274,93 @@ sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo)
return &(this->public);
}
+
+/**
+ * Implementation of prf_t.get_bytes.
+ */
+static void get_bytes(private_sha1_keyed_prf_t *this, chunk_t seed, u_int8_t *bytes)
+{
+ u_int32_t *hash = (u_int32_t*)bytes;
+
+ SHA1Update(this->hasher, seed.ptr, seed.len);
+
+ hash[0] = htonl(this->hasher->state[0]);
+ hash[1] = htonl(this->hasher->state[1]);
+ hash[2] = htonl(this->hasher->state[2]);
+ hash[3] = htonl(this->hasher->state[3]);
+ hash[4] = htonl(this->hasher->state[4]);
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_block_size(private_sha1_keyed_prf_t *this)
+{
+ return HASH_SIZE_SHA1;
+}
+
+/**
+ * Implementation of prf_t.allocate_bytes.
+ */
+static void allocate_bytes(private_sha1_keyed_prf_t *this, chunk_t seed, chunk_t *chunk)
+{
+ *chunk = chunk_alloc(HASH_SIZE_SHA1);
+ get_bytes(this, seed, chunk->ptr);
+}
+
+/**
+ * Implementation of prf_t.get_key_size.
+ */
+static size_t get_key_size(private_sha1_keyed_prf_t *this)
+{
+ return sizeof(this->hasher->state);
+}
+
+/**
+ * Implementation of prf_t.set_key.
+ */
+static void set_key(private_sha1_keyed_prf_t *this, chunk_t key)
+{
+ int i, rounds;
+ u_int32_t *iv = (u_int32_t*)key.ptr;
+
+ reset(this->hasher);
+ rounds = min(key.len/sizeof(u_int32_t), sizeof(this->hasher->state));
+ for (i = 0; i < rounds; i++)
+ {
+ this->hasher->state[i] ^= htonl(iv[i]);
+ }
+}
+
+/**
+ * Implementation of prf_t.destroy.
+ */
+static void destroy_p(private_sha1_keyed_prf_t *this)
+{
+ destroy(this->hasher);
+ free(this);
+}
+
+/**
+ * see header
+ */
+sha1_keyed_prf_t *sha1_keyed_prf_create(pseudo_random_function_t algo)
+{
+ private_sha1_keyed_prf_t *this;
+ if (algo != PRF_KEYED_SHA1)
+ {
+ return NULL;
+ }
+ this = malloc_thing(private_sha1_keyed_prf_t);
+ this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+ this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+ this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+ this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+ this->public.prf_interface.destroy = (void (*) (prf_t *))destroy_p;
+
+ this->hasher = (private_sha1_hasher_t*)sha1_hasher_create(HASH_SHA1);
+
+ return &(this->public);
+}
+
diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.h b/src/libstrongswan/plugins/sha1/sha1_hasher.h
index aff0eae11..2e44797d8 100644
--- a/src/libstrongswan/plugins/sha1/sha1_hasher.h
+++ b/src/libstrongswan/plugins/sha1/sha1_hasher.h
@@ -23,8 +23,10 @@
#define SHA1_HASHER_H_
typedef struct sha1_hasher_t sha1_hasher_t;
+typedef struct sha1_keyed_prf_t sha1_keyed_prf_t;
#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
/**
* Implementation of hasher_t interface using the SHA1 algorithm.
@@ -38,13 +40,30 @@ struct sha1_hasher_t {
};
/**
+ * Implementation of prf_t interface using keyed SHA1 algorithm (used for EAP-AKA).
+ */
+struct sha1_keyed_prf_t {
+
+ /**
+ * Implements prf_t interface.
+ */
+ prf_t prf_interface;
+};
+
+/**
* Creates a new sha1_hasher_t.
- *
- * This implementation supports two algorithms, HASH_SHA1 and HASH_SHA1_NOFINAL
*
- * @param algo algorithm
+ * @param algo algorithm, must be HASH_SHA1
* @return sha1_hasher_t object
*/
sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo);
+/**
+ * Creates a new sha1_keyed_prf_t.
+ *
+ * @param algo algorithm, must be PRF_KEYED_SHA1
+ * @return sha1_keyed_prf_tobject
+ */
+sha1_keyed_prf_t *sha1_keyed_prf_create(pseudo_random_function_t algo);
+
#endif /*SHA1_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.c b/src/libstrongswan/plugins/sha1/sha1_plugin.c
index 4a69c4e76..391664f5e 100644
--- a/src/libstrongswan/plugins/sha1/sha1_plugin.c
+++ b/src/libstrongswan/plugins/sha1/sha1_plugin.c
@@ -40,6 +40,8 @@ static void destroy(private_sha1_plugin_t *this)
{
lib->crypto->remove_hasher(lib->crypto,
(hasher_constructor_t)sha1_hasher_create);
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)sha1_keyed_prf_create);
free(this);
}
@@ -54,8 +56,8 @@ plugin_t *plugin_create()
lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
(hasher_constructor_t)sha1_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA1_NOFINAL,
- (hasher_constructor_t)sha1_hasher_create);
+ lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1,
+ (prf_constructor_t)sha1_keyed_prf_create);
return &this->public.plugin;
}