Cryptography Reference
In-Depth Information
next_nonce = htonl( next_nonce );
memcpy( ( void * ) ( nonce + 12 ), ( void * ) &next_nonce,
sizeof( unsigned int ) );
// encrypt the nonce
block_size = ( input_len < AES_BLOCK_SIZE ) ? input_len : AES_BLOCK_SIZE;
aes_block_encrypt( nonce, input_block, key, 16 );
xor( input_block, input, block_size ); // implement CTR
memcpy( output, input_block, block_size );
// update the CBC-MAC
memset( input_block, '\0', AES_BLOCK_SIZE );
memcpy( input_block, input, block_size );
xor( input_block, mac_block, AES_BLOCK_SIZE );
aes_block_encrypt( input_block, mac_block, key, 16 );
// advance to next block
input += block_size;
output += block_size;
input_len -= block_size;
}
// 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 );
return 0;
}
The fi rst section builds the CCM mode header in the input_block :
memset( input_block, '\0', AES_BLOCK_SIZE );
input_block[ 0 ] = 0x1F; // t = mac_length = 8 bytes, q = 8 bytes (so n = 7)
header_length_declaration = htonl( input_len );
memcpy( ( void * ) ( input_block + ( AES_BLOCK_SIZE - sizeof( int ) ) ),
&header_length_declaration, sizeof( unsigned int ) );
memcpy( ( void * ) ( input_block + 1 ), iv, 8 );
As always, the length of the length must be put in network byte order.
The next section updates the CBC-MAC with this header:
memset( mac_block, '\0', AES_BLOCK_SIZE );
xor( input_block, mac_block, AES_BLOCK_SIZE );
aes_block_encrypt( input_block, mac_block, key, 16 );
Search WWH ::




Custom Search