diff --git a/include/polarssl/ccm.h b/include/polarssl/ccm.h index b794cd895..24405e431 100644 --- a/include/polarssl/ccm.h +++ b/include/polarssl/ccm.h @@ -36,6 +36,34 @@ extern "C" { #endif +/** + * \brief CCM context structure + */ +typedef struct { + cipher_context_t cipher_ctx; /*!< cipher context used */ +} +ccm_context; + +/** + * \brief CCM initialization (encryption and decryption) + * + * \param ctx CCM context to be initialized + * \param cipher cipher to use (a 128-bit block cipher) + * \param key encryption key + * \param keysize key size in bits (must be acceptable by the cipher) + * + * \return 0 if successful, or a cipher specific error code + */ +int ccm_init( ccm_context *ctx, cipher_id_t cipher, + const unsigned char *key, unsigned int keysize ); + +/** + * \brief Free a CCM context and underlying cipher sub-context + * + * \param ctx CCM context to free + */ +void ccm_free( ccm_context *ctx ); + #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) /** * \brief Checkup routine diff --git a/library/ccm.c b/library/ccm.c index b4ba3d5d0..453edfb13 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -42,6 +42,45 @@ #include "polarssl/ccm.h" +/* + * Initialize context + */ +int ccm_init( ccm_context *ctx, cipher_id_t cipher, + const unsigned char *key, unsigned int keysize ) +{ + int ret; + const cipher_info_t *cipher_info; + + memset( ctx, 0, sizeof( ccm_context ) ); + + cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB ); + if( cipher_info == NULL ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize, + POLARSSL_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Free context + */ +void ccm_free( ccm_context *ctx ) +{ + (void) cipher_free_ctx( &ctx->cipher_ctx ); + memset( ctx, 0, sizeof( ccm_context ) ); +} + #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data index 223e28a7e..61ae8319f 100644 --- a/tests/suites/test_suite_ccm.data +++ b/tests/suites/test_suite_ccm.data @@ -1,2 +1,18 @@ CCM self test ccm_self_test: + +CCM init #1 AES-128: OK +depends_on:POLARSSL_AES_C +ccm_init:POLARSSL_CIPHER_ID_AES:128:0 + +CCM init #2 CAMELLIA-256: OK +depends_on:POLARSSL_CAMELLIA_C +ccm_init:POLARSSL_CIPHER_ID_CAMELLIA:256:0 + +CCM init #3 AES-224: bad key size +depends_on:POLARSSL_AES_C +ccm_init:POLARSSL_CIPHER_ID_AES:224:POLARSSL_ERR_CCM_BAD_INPUT + +CCM init #4 BLOWFISH-128: bad block size +depends_on:POLARSSL_BLOWFISH_C +ccm_init:POLARSSL_CIPHER_ID_BLOWFISH:128:POLARSSL_ERR_CCM_BAD_INPUT diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function index 487d1c590..7137a6029 100644 --- a/tests/suites/test_suite_ccm.function +++ b/tests/suites/test_suite_ccm.function @@ -13,3 +13,20 @@ void ccm_self_test( ) TEST_ASSERT( ccm_self_test( 0 ) == 0 ); } /* END_CASE */ + +/* BEGIN_CASE */ +void ccm_init( int cipher_id, int key_size, int result ) +{ + ccm_context ctx; + unsigned char key[32]; + int ret; + + memset( key, 0x2A, sizeof( key ) ); + TEST_ASSERT( (unsigned) key_size <= 8 * sizeof( key ) ); + + ret = ccm_init( &ctx, cipher_id, key, key_size ); + TEST_ASSERT( ret == result ); + + ccm_free( &ctx ); +} +/* END_CASE */