Cryptography Reference
In-Depth Information
at each step and, if the least-signifi cant bit of X is a 1, X is additionally XORed
with the fi eld polynomial 0xE1
2 120 . The value of this polynomial is signifi cant,
in the number-theoretic sense, but you can just treat it as a magic constant that
you must use to maintain compatibility with other implementations.
The GHASH routine, illustrated in Figure 9-4, takes as input a key that
the specifi cation calls H . It computes a variable-length MAC from its input by
GF-multiplying each input block by H and XORing all of the resulting blocks
to each other. If the last block is not block-length aligned, it's padded with 0's,
and there's a single “pseudo-block” trailer that includes the 64-bit length of the
input itself.
input
MAC
H
gcm_multiply
Figure 9-4: GHASH MAC algorithm
A standalone GHASH implementation is shown in Listing 9-17.
Listing 9-17: “aes.c” ghash
static void ghash( unsigned char *H,
unsigned char *X,
int X_len,
unsigned char *Y ) // Y is the output value
{
unsigned char X_block[ AES_BLOCK_SIZE ];
unsigned int input_len;
int process_len;
memset( Y, '\0', AES_BLOCK_SIZE );
input_len = htonl( X_len << 3 ); // remember this for final block
while ( X_len )
{
process_len = ( X_len < AES_BLOCK_SIZE ) ? X_len : AES_BLOCK_SIZE;
memset( X_block, '\0', AES_BLOCK_SIZE );
memcpy( X_block, X, process_len );
xor( X_block, Y, AES_BLOCK_SIZE );
gf_multiply( X_block, H, Y );
X += process_len;
X_len -= process_len;
}
 
Search WWH ::




Custom Search