Cryptography Reference
In-Depth Information
This is followed by a single loop through the input data that simultaneously
performs the CTR-mode encryption and updates the CBC-MAC. This enables the
encrypt-and-authenticate process to pass over the data only one time. Because CTR
mode encryption encrypts the counter, and CBC-MAC encrypts the input itself,
it's necessary to invoke aes_block_encrypt twice inside the loop. If you want
to be hyper-effi cient, you can modify aes_block_encrypt to accept two inputs
and generate two outputs; you can then reuse the key schedule computation.
The order of things in the main loop of Listing 9-14 is only slightly different
than those of Listings 9-12 and 9-13 (you may want to compare them before
continuing). Because AES-CCM wants the fi rst counter block to have the value
of 1, the counter is initialized outside the loop and then incremented at the top
instead of after encryption.
Finally, the MAC itself is encrypted in CTR mode with the 0 counter and output:
// Regenerate the first nonce
memset( nonce, '\0', AES_BLOCK_SIZE );
nonce[ 0 ] = 0x07; // q hardcode to 8 bytes
memcpy( ( nonce + 1 ), iv, 8 );
// encrypt the header and output it
aes_block_encrypt( nonce, input_block, key, AES_BLOCK_SIZE );
// MAC is the CBC-mac XOR'ed with S0
xor( mac_block, input_block, MAC_LENGTH );
memcpy( output, mac_block, MAC_LENGTH );
Although counter-mode makes a reversible cipher from any block cipher, you
do still need a special decrypt routine for AES-CCM. The encryption routine
generates the output and appends a MAC, so the decryption routine must be
aware of the MAC and not output it. For robustness, the decryption routine
should probably verify the MAC as well. However, the bulk of the routine is
the same as the encryption routine, so it makes sense to combine them into one
common routine and just pass in a fl ag indicating which operation is taking
place: encrypt or decrypt.
Rename aes_ccm_encrypt to aes_ccm_process and add a decrypt fl ag to it
as shown in Listing 9-15.
Listing 9-15: “aes.c” aes_ccm_process common routine for encrypt and decrypt
int aes_ccm_ process ( const unsigned char *input,
int input_len,
unsigned char *output,
void *iv,
const unsigned char *key,
int decrypt )
{
 
Search WWH ::




Custom Search