Cryptography Reference
In-Depth Information
If this is not quite clear, the code in Listing 9-14 should clarify.
Listing 9-14: “aes.c” aes_ccm_encrypt
#define MAC_LENGTH 8
/**
* This implements 128-bit AES-CCM.
* The IV is the nonce; it should be seven bytes long.
* output must be the input_len + MAC_LENGTH
* bytes, since CCM adds a block-length header
*/
int aes_ccm_encrypt( const unsigned char *input,
int input_len,
unsigned char *output,
void *iv,
const unsigned char *key )
{
unsigned char nonce[ AES_BLOCK_SIZE ];
unsigned char input_block[ AES_BLOCK_SIZE ];
unsigned char mac_block[ AES_BLOCK_SIZE ];
unsigned int next_nonce;
int block_size;
unsigned int header_length_declaration;
// The first input block is a (complicated) standardized header
// This is just for the MAC; not output
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 );
// update the CBC-MAC
memset( mac_block, '\0', AES_BLOCK_SIZE );
xor( input_block, mac_block, AES_BLOCK_SIZE );
aes_block_encrypt( input_block, mac_block, key, 16 );
// Prepare the first nonce
memset( nonce, '\0', AES_BLOCK_SIZE );
nonce[ 0 ] = 0x07; // q hardcode to 8 bytes, so n = 7
memcpy( ( nonce + 1 ), iv, 8 );
while ( input_len )
{
// Increment counter
memcpy( ( void * ) &next_nonce, ( void * ) ( nonce + 12 ),
sizeof( unsigned int ) );
// Preserve byte ordering, although not strictly necessary
next_nonce = ntohl( next_nonce );
next_nonce++;
Search WWH ::




Custom Search