Cryptography Reference
In-Depth Information
large amount of random data that two compliant implementations, both of which
share the secret, can reproduce consistently.
In code, this is shown in Listing 6-33.
Listing 6-33: “prf.c” PRF function
/**
* P_MD5 or P_SHA, depending on the value of the “new_digest” function
* pointer.
* HMAC_hash( secret, A(1) + seed ) + HMAC_hash( secret, A(2) + seed ) + ...
* where + indicates concatenation and A(0) = seed, A(i) =
* HMAC_hash( secret, A(i - 1) )
*/
static void P_hash( const unsigned char *secret,
int secret_len,
const unsigned char *seed,
int seed_len,
unsigned char *output,
int out_len,
void (*new_digest)( digest_ctx *context ) )
{
unsigned char *A;
int hash_len; // length of the hash code in bytes
digest_ctx A_ctx, h;
int adv;
int i;
new_digest( &A_ctx );
hmac( secret, secret_len, seed, seed_len, &A_ctx );
hash_len = A_ctx.hash_len * sizeof( int );
A = malloc( hash_len + seed_len );
memcpy( A, A_ctx.hash, hash_len );
memcpy( A + hash_len, seed, seed_len );
i = 2;
while ( out_len > 0 )
{
new_digest( &h );
// HMAC_Hash( secret, A(i) + seed )
hmac( secret, secret_len, A, hash_len + seed_len, &h );
adv = ( h.hash_len * sizeof( int ) ) < out_len ?
h.hash_len * sizeof( int ) : out_len;
memcpy( output, h.hash, adv );
out_len -= adv;
output += adv;
// Set A for next iteration
// A(i) = HMAC_hash( secret, A(i-1) )
new_digest( &A_ctx );
hmac( secret, secret_len, A, hash_len, &A_ctx );
memcpy( A, A_ctx.hash, hash_len );
(Continued)
 
Search WWH ::




Custom Search