35 #if !defined(POLARSSL_CONFIG_FILE) 38 #include POLARSSL_CONFIG_FILE 41 #if defined(POLARSSL_CCM_C) 46 static void polarssl_zeroize(
void *v,
size_t n ) {
47 volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
57 const unsigned char *key,
unsigned int keysize )
67 if( cipher_info == NULL )
103 #define UPDATE_CBC_MAC \ 104 for( i = 0; i < 16; i++ ) \ 107 if( ( ret = cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ 115 #define CTR_CRYPT( dst, src, len ) \ 116 if( ( ret = cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ 119 for( i = 0; i < len; i++ ) \ 120 dst[i] = src[i] ^ b[i]; 125 static int ccm_auth_crypt(
ccm_context *ctx,
int mode,
size_t length,
126 const unsigned char *iv,
size_t iv_len,
127 const unsigned char *add,
size_t add_len,
128 const unsigned char *input,
unsigned char *output,
129 unsigned char *tag,
size_t tag_len )
133 unsigned char q = 16 - 1 - iv_len;
134 size_t len_left, olen;
137 unsigned char ctr[16];
138 const unsigned char *src;
146 if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
150 if( iv_len < 7 || iv_len > 13 )
153 if( add_len > 0xFF00 )
169 b[0] |= ( add_len > 0 ) << 6;
170 b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
173 memcpy( b + 1, iv, iv_len );
175 for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
176 b[15-i] = (
unsigned char)( len_left & 0xFF );
197 b[0] = (
unsigned char)( ( add_len >> 8 ) & 0xFF );
198 b[1] = (
unsigned char)( ( add_len ) & 0xFF );
200 use_len = len_left < 16 - 2 ? len_left : 16 - 2;
201 memcpy( b + 2, src, use_len );
207 while( len_left > 0 )
209 use_len = len_left > 16 ? 16 : len_left;
212 memcpy( b, src, use_len );
231 memcpy( ctr + 1, iv, iv_len );
232 memset( ctr + 1 + iv_len, 0, q );
245 while( len_left > 0 )
247 unsigned char use_len = len_left > 16 ? 16 : len_left;
249 if( mode == CCM_ENCRYPT )
252 memcpy( b, src, use_len );
256 CTR_CRYPT( dst, src, use_len );
258 if( mode == CCM_DECRYPT )
261 memcpy( b, dst, use_len );
273 for( i = 0; i < q; i++ )
274 if( ++ctr[15-i] != 0 )
281 for( i = 0; i < q; i++ )
284 CTR_CRYPT( y, y, 16 );
285 memcpy( tag, y, tag_len );
294 const unsigned char *iv,
size_t iv_len,
295 const unsigned char *add,
size_t add_len,
296 const unsigned char *input,
unsigned char *output,
297 unsigned char *tag,
size_t tag_len )
299 return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
300 add, add_len, input, output, tag, tag_len ) );
307 const unsigned char *iv,
size_t iv_len,
308 const unsigned char *add,
size_t add_len,
309 const unsigned char *input,
unsigned char *output,
310 const unsigned char *tag,
size_t tag_len )
313 unsigned char check_tag[16];
317 if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
318 iv, iv_len, add, add_len,
319 input, output, check_tag, tag_len ) ) != 0 )
325 for( diff = 0, i = 0; i < tag_len; i++ )
326 diff |= tag[i] ^ check_tag[i];
330 polarssl_zeroize( output, length );
338 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) 340 #if defined(POLARSSL_PLATFORM_C) 344 #define polarssl_printf printf 356 static const unsigned char key[] = {
357 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
358 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
361 static const unsigned char iv[] = {
362 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
363 0x18, 0x19, 0x1a, 0x1b
366 static const unsigned char ad[] = {
367 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
368 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
369 0x10, 0x11, 0x12, 0x13
372 static const unsigned char msg[] = {
373 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
374 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
375 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
378 static const size_t iv_len [NB_TESTS] = { 7, 8, 12 };
379 static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
380 static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
381 static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
383 static const unsigned char res[NB_TESTS][32] = {
384 { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
385 { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
386 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
387 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
388 { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
389 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
390 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
391 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
397 unsigned char out[32];
409 for( i = 0; i < NB_TESTS; i++ )
415 iv, iv_len[i], ad, add_len[i],
417 out + msg_len[i], tag_len[i] );
420 memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 )
429 iv, iv_len[i], ad, add_len[i],
431 res[i] + msg_len[i], tag_len[i] );
434 memcmp( out, msg, msg_len[i] ) != 0 )
#define POLARSSL_ERR_CCM_BAD_INPUT
Bad input parameters to function.
void cipher_init(cipher_context_t *ctx)
Initialize a cipher_context (as NONE)
Configuration options (set of defines)
int ccm_auth_decrypt(ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, const unsigned char *tag, size_t tag_len)
CCM buffer authenticated decryption.
int ccm_init(ccm_context *ctx, cipher_id_t cipher, const unsigned char *key, unsigned int keysize)
CCM initialization (encryption and decryption)
int ccm_self_test(int verbose)
Checkup routine.
void cipher_free(cipher_context_t *ctx)
Free and clear the cipher-specific context of ctx.
int cipher_init_ctx(cipher_context_t *ctx, const cipher_info_t *cipher_info)
Initialises and fills the cipher context structure with the appropriate values.
int cipher_setkey(cipher_context_t *ctx, const unsigned char *key, int key_length, const operation_t operation)
Set the key to use with the given context.
void ccm_free(ccm_context *ctx)
Free a CCM context and underlying cipher sub-context.
int ccm_encrypt_and_tag(ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, unsigned char *tag, size_t tag_len)
CCM buffer encryption.
cipher_context_t cipher_ctx
unsigned int block_size
block size, in bytes
#define POLARSSL_ERR_CCM_AUTH_FAILED
Authenticated decryption failed.
const cipher_info_t * cipher_info_from_values(const cipher_id_t cipher_id, int key_length, const cipher_mode_t mode)
Returns the cipher information structure associated with the given cipher id, key size and mode...
Counter with CBC-MAC (CCM) for 128-bit block ciphers.