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.
This commit is contained in:
Martin Willi
2008-03-19 14:02:52 +00:00
parent c912c3d382
commit cfede7f6e2
10 changed files with 188 additions and 114 deletions
+11 -20
View File
@@ -43,25 +43,16 @@ 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)
*/
@@ -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;