2 * NIST SP800-38C compliant CCM implementation
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
26 * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
27 * RFC 3610 "Counter with CBC-MAC (CCM)"
30 * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
33 #if !defined(MBEDTLS_CONFIG_FILE)
34 #include "mbedtls/config.h"
36 #include MBEDTLS_CONFIG_FILE
39 #if defined(MBEDTLS_CCM_C)
41 #include "mbedtls/ccm.h"
45 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
46 #if defined(MBEDTLS_PLATFORM_C)
47 #include "mbedtls/platform.h"
50 #define mbedtls_printf printf
51 #endif /* MBEDTLS_PLATFORM_C */
52 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
54 #if !defined(MBEDTLS_CCM_ALT)
56 /* Implementation that should never be optimized out by the compiler */
57 static void mbedtls_zeroize( void *v
, size_t n
) {
58 volatile unsigned char *p
= (unsigned char*)v
; while( n
-- ) *p
++ = 0;
67 void mbedtls_ccm_init( mbedtls_ccm_context
*ctx
)
69 memset( ctx
, 0, sizeof( mbedtls_ccm_context
) );
72 int mbedtls_ccm_setkey( mbedtls_ccm_context
*ctx
,
73 mbedtls_cipher_id_t cipher
,
74 const unsigned char *key
,
75 unsigned int keybits
)
78 const mbedtls_cipher_info_t
*cipher_info
;
80 cipher_info
= mbedtls_cipher_info_from_values( cipher
, keybits
, MBEDTLS_MODE_ECB
);
81 if( cipher_info
== NULL
)
82 return( MBEDTLS_ERR_CCM_BAD_INPUT
);
84 if( cipher_info
->block_size
!= 16 )
85 return( MBEDTLS_ERR_CCM_BAD_INPUT
);
87 mbedtls_cipher_free( &ctx
->cipher_ctx
);
89 if( ( ret
= mbedtls_cipher_setup( &ctx
->cipher_ctx
, cipher_info
) ) != 0 )
92 if( ( ret
= mbedtls_cipher_setkey( &ctx
->cipher_ctx
, key
, keybits
,
93 MBEDTLS_ENCRYPT
) ) != 0 )
104 void mbedtls_ccm_free( mbedtls_ccm_context
*ctx
)
106 mbedtls_cipher_free( &ctx
->cipher_ctx
);
107 mbedtls_zeroize( ctx
, sizeof( mbedtls_ccm_context
) );
111 * Macros for common operations.
112 * Results in smaller compiled code than static inline functions.
116 * Update the CBC-MAC state in y using a block in b
117 * (Always using b as the source helps the compiler optimise a bit better.)
119 #define UPDATE_CBC_MAC \
120 for( i = 0; i < 16; i++ ) \
123 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
127 * Encrypt or decrypt a partial block with CTR
128 * Warning: using b for temporary storage! src and dst must not be b!
129 * This avoids allocating one more 16 bytes buffer while allowing src == dst.
131 #define CTR_CRYPT( dst, src, len ) \
132 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \
135 for( i = 0; i < len; i++ ) \
136 dst[i] = src[i] ^ b[i];
139 * Authenticated encryption or decryption
141 static int ccm_auth_crypt( mbedtls_ccm_context
*ctx
, int mode
, size_t length
,
142 const unsigned char *iv
, size_t iv_len
,
143 const unsigned char *add
, size_t add_len
,
144 const unsigned char *input
, unsigned char *output
,
145 unsigned char *tag
, size_t tag_len
)
150 size_t len_left
, olen
;
153 unsigned char ctr
[16];
154 const unsigned char *src
;
158 * Check length requirements: SP800-38C A.1
159 * Additional requirement: a < 2^16 - 2^8 to simplify the code.
160 * 'length' checked later (when writing it to the first block)
162 if( tag_len
< 4 || tag_len
> 16 || tag_len
% 2 != 0 )
163 return( MBEDTLS_ERR_CCM_BAD_INPUT
);
165 /* Also implies q is within bounds */
166 if( iv_len
< 7 || iv_len
> 13 )
167 return( MBEDTLS_ERR_CCM_BAD_INPUT
);
169 if( add_len
> 0xFF00 )
170 return( MBEDTLS_ERR_CCM_BAD_INPUT
);
172 q
= 16 - 1 - (unsigned char) iv_len
;
177 * 1 .. iv_len nonce (aka iv)
178 * iv_len+1 .. 15 length
180 * With flags as (bits):
187 b
[0] |= ( add_len
> 0 ) << 6;
188 b
[0] |= ( ( tag_len
- 2 ) / 2 ) << 3;
191 memcpy( b
+ 1, iv
, iv_len
);
193 for( i
= 0, len_left
= length
; i
< q
; i
++, len_left
>>= 8 )
194 b
[15-i
] = (unsigned char)( len_left
& 0xFF );
197 return( MBEDTLS_ERR_CCM_BAD_INPUT
);
200 /* Start CBC-MAC with first block */
205 * If there is additional data, update CBC-MAC with
206 * add_len, add, 0 (padding to a block boundary)
215 b
[0] = (unsigned char)( ( add_len
>> 8 ) & 0xFF );
216 b
[1] = (unsigned char)( ( add_len
) & 0xFF );
218 use_len
= len_left
< 16 - 2 ? len_left
: 16 - 2;
219 memcpy( b
+ 2, src
, use_len
);
225 while( len_left
> 0 )
227 use_len
= len_left
> 16 ? 16 : len_left
;
230 memcpy( b
, src
, use_len
);
239 * Prepare counter block for encryption:
241 * 1 .. iv_len nonce (aka iv)
242 * iv_len+1 .. 15 counter (initially 1)
244 * With flags as (bits):
249 memcpy( ctr
+ 1, iv
, iv_len
);
250 memset( ctr
+ 1 + iv_len
, 0, q
);
254 * Authenticate and {en,de}crypt the message.
256 * The only difference between encryption and decryption is
257 * the respective order of authentication and {en,de}cryption.
263 while( len_left
> 0 )
265 size_t use_len
= len_left
> 16 ? 16 : len_left
;
267 if( mode
== CCM_ENCRYPT
)
270 memcpy( b
, src
, use_len
);
274 CTR_CRYPT( dst
, src
, use_len
);
276 if( mode
== CCM_DECRYPT
)
279 memcpy( b
, dst
, use_len
);
289 * No need to check for overflow thanks to the length check above.
291 for( i
= 0; i
< q
; i
++ )
292 if( ++ctr
[15-i
] != 0 )
297 * Authentication: reset counter and crypt/mask internal tag
299 for( i
= 0; i
< q
; i
++ )
302 CTR_CRYPT( y
, y
, 16 );
303 memcpy( tag
, y
, tag_len
);
309 * Authenticated encryption
311 int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context
*ctx
, size_t length
,
312 const unsigned char *iv
, size_t iv_len
,
313 const unsigned char *add
, size_t add_len
,
314 const unsigned char *input
, unsigned char *output
,
315 unsigned char *tag
, size_t tag_len
)
317 return( ccm_auth_crypt( ctx
, CCM_ENCRYPT
, length
, iv
, iv_len
,
318 add
, add_len
, input
, output
, tag
, tag_len
) );
322 * Authenticated decryption
324 int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context
*ctx
, size_t length
,
325 const unsigned char *iv
, size_t iv_len
,
326 const unsigned char *add
, size_t add_len
,
327 const unsigned char *input
, unsigned char *output
,
328 const unsigned char *tag
, size_t tag_len
)
331 unsigned char check_tag
[16];
335 if( ( ret
= ccm_auth_crypt( ctx
, CCM_DECRYPT
, length
,
336 iv
, iv_len
, add
, add_len
,
337 input
, output
, check_tag
, tag_len
) ) != 0 )
342 /* Check tag in "constant-time" */
343 for( diff
= 0, i
= 0; i
< tag_len
; i
++ )
344 diff
|= tag
[i
] ^ check_tag
[i
];
348 mbedtls_zeroize( output
, length
);
349 return( MBEDTLS_ERR_CCM_AUTH_FAILED
);
355 #endif /* !MBEDTLS_CCM_ALT */
357 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
359 * Examples 1 to 3 from SP800-38C Appendix C
363 #define CCM_SELFTEST_PT_MAX_LEN 24
364 #define CCM_SELFTEST_CT_MAX_LEN 32
366 * The data is the same for all tests, only the used length changes
368 static const unsigned char key
[] = {
369 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
370 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
373 static const unsigned char iv
[] = {
374 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
375 0x18, 0x19, 0x1a, 0x1b
378 static const unsigned char ad
[] = {
379 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
380 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
381 0x10, 0x11, 0x12, 0x13
384 static const unsigned char msg
[CCM_SELFTEST_PT_MAX_LEN
] = {
385 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
386 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
387 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
390 static const size_t iv_len
[NB_TESTS
] = { 7, 8, 12 };
391 static const size_t add_len
[NB_TESTS
] = { 8, 16, 20 };
392 static const size_t msg_len
[NB_TESTS
] = { 4, 16, 24 };
393 static const size_t tag_len
[NB_TESTS
] = { 4, 6, 8 };
395 static const unsigned char res
[NB_TESTS
][CCM_SELFTEST_CT_MAX_LEN
] = {
396 { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
397 { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
398 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
399 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
400 { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
401 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
402 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
403 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
406 int mbedtls_ccm_self_test( int verbose
)
408 mbedtls_ccm_context ctx
;
410 * Some hardware accelerators require the input and output buffers
411 * would be in RAM, because the flash is not accessible.
412 * Use buffers on the stack to hold the test vectors data.
414 unsigned char plaintext
[CCM_SELFTEST_PT_MAX_LEN
];
415 unsigned char ciphertext
[CCM_SELFTEST_CT_MAX_LEN
];
419 mbedtls_ccm_init( &ctx
);
421 if( mbedtls_ccm_setkey( &ctx
, MBEDTLS_CIPHER_ID_AES
, key
, 8 * sizeof key
) != 0 )
424 mbedtls_printf( " CCM: setup failed" );
429 for( i
= 0; i
< NB_TESTS
; i
++ )
432 mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i
+ 1 );
434 memset( plaintext
, 0, CCM_SELFTEST_PT_MAX_LEN
);
435 memset( ciphertext
, 0, CCM_SELFTEST_CT_MAX_LEN
);
436 memcpy( plaintext
, msg
, msg_len
[i
] );
438 ret
= mbedtls_ccm_encrypt_and_tag( &ctx
, msg_len
[i
],
439 iv
, iv_len
[i
], ad
, add_len
[i
],
440 plaintext
, ciphertext
,
441 ciphertext
+ msg_len
[i
], tag_len
[i
] );
444 memcmp( ciphertext
, res
[i
], msg_len
[i
] + tag_len
[i
] ) != 0 )
447 mbedtls_printf( "failed\n" );
451 memset( plaintext
, 0, CCM_SELFTEST_PT_MAX_LEN
);
453 ret
= mbedtls_ccm_auth_decrypt( &ctx
, msg_len
[i
],
454 iv
, iv_len
[i
], ad
, add_len
[i
],
455 ciphertext
, plaintext
,
456 ciphertext
+ msg_len
[i
], tag_len
[i
] );
459 memcmp( plaintext
, msg
, msg_len
[i
] ) != 0 )
462 mbedtls_printf( "failed\n" );
468 mbedtls_printf( "passed\n" );
471 mbedtls_ccm_free( &ctx
);
474 mbedtls_printf( "\n" );
479 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
481 #endif /* MBEDTLS_CCM_C */