Cryptography Reference
In-Depth Information
Listing 9-13: aes_cbc_mac
#define MAC_LENGTH 8
void aes_cbc_mac( const unsigned char *key,
int key_length,
const unsigned char *text,
int text_length,
unsigned char *mac )
{
unsigned char input_block[ AES_BLOCK_SIZE ];
unsigned char mac_block[ AES_BLOCK_SIZE ];
memset( mac_block, '\0', AES_BLOCK_SIZE );
while ( text_length >= AES_BLOCK_SIZE )
{
memcpy( input_block, text, AES_BLOCK_SIZE );
xor( input_block, mac_block, AES_BLOCK_SIZE );
aes_block_encrypt( input_block, mac_block, key, key_length );
text += AES_BLOCK_SIZE;
text_length -= AES_BLOCK_SIZE;
}
memcpy( mac, mac_block, MAC_LENGTH );
}
If you compare Listing 9-13 to Listing 2-42, you see that the only difference
here — besides different variable names — is that the output is copied to the
same mac_block over and over again. The mac output pointer can't be used for
this purpose because it's not guaranteed to be the same length as an AES block;
if you need fewer bytes of MAC, you discard the least-signifi cant bytes of the
fi nal AES block. Of course, if you need a longer MAC, you must use a different
MAC function; the output of the CBC-MAC is bounded by the block size of the
underlying block cipher. The process is illustrated in Figure 9-2.
input block 1
input block 2
input block 3
...
input block n
AES Encrypt
MAC
Figure 9-2: CBC-MAC
Search WWH ::




Custom Search