Cryptography Reference
In-Depth Information
Here,
key
and
key_length
describe the shared secret;
text
and
text_length
describe the data to be HMAC-ed;
hash_block_operate
and
hash_block_final-
ize
describe the hash operation;
hash_block_length
describes the length of a
block in bytes (which is always 64 for MD5 and SHA-1);
hash_code_length
is
the length of the resultant hash in
int
s (4 for MD5, 5 for SHA-1); and
hash_out
is a pointer to the hash code to be generated.
Because you don't need to deal with shared secrets that are greater than 64
bytes for SSL, just ignore them:
// TODO if key_length > hash_block_length, should hash it using “hash_
// function” first and then use that as the key.
assert( key_length < hash_block_length );
NOTE
Note that
hash_out
must be initialized properly, according to the
secure hashing algorithm. Alternatively, you could have added an initialization
parameter, but you're already up to nine parameters here.
Remember that HMAC requires that you compute an initial hash based on
the text to be hashed, prepended with a block of 0x36s XORed with the shared
secret, called the key here. This section of the HMAC function builds this block
of data:
hash1 = ( unsigned int * ) malloc( hash_code_length * sizeof( unsigned int ) );
ipad = ( unsigned char * ) malloc( hash_block_length );
padded_block = ( unsigned char * ) malloc( text_length
hash_block_length );
memset( ipad, 0x36, hash_block_length );
memset( padded_block, '\0', hash_block_length );
memcpy( padded_block, key, key_length );
for ( i = 0; i < hash_block_length; i
)
{
padded_block[ i ] ^= ipad[ i ];
}
You allocate a new block of memory as long as the text to be hashed plus one
extra block, fi ll it with 0x36s, and XOR that with the key. Finally, compute the
hash of this new data block:
memcpy( padded_block
hash_block_length, text, text_length );
memcpy( hash1, hash_out, hash_code_length * sizeof( unsigned int ) );
digest_hash( padded_block, hash_block_length
text_length, hash1,
hash_code_length, hash_block_operate, hash_block_finalize );
Notice that you're hashing into an internal block called
hash1
, and remember
that HMAC requires you to hash
that
hash. There's a minor implementation
problem here, though. The caller of
digest_hash
must preinitialize the hash
Search WWH ::
Custom Search