From 5dc8cfa8f1818aac205411dafce2db01817b990e Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 27 Apr 2018 14:45:49 +0100 Subject: [PATCH 1/8] CCM*: Add public API Interface for CCM* (described in IEEE Std 802.15.4.). --- include/mbedtls/ccm.h | 76 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 8585ce5e7..24e13dd80 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -102,7 +102,6 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); /** * \brief This function encrypts a buffer using CCM. * - * * \note The tag is written to a separate buffer. To concatenate * the \p tag with the \p output, as done in RFC-3610: * Counter with CBC-MAC (CCM), use @@ -132,6 +131,45 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, const unsigned char *input, unsigned char *output, unsigned char *tag, size_t tag_len ); +/** + * \brief This function encrypts a buffer using CCM*. + * + * \note The tag is written to a separate buffer. To concatenate + * the \p tag with the \p output, as done in RFC-3610: + * Counter with CBC-MAC (CCM), use + * \p tag = \p output + \p length, and make sure that the + * output buffer is at least \p length + \p tag_len wide. + * + * \note When using this function in a variable tag length context, + * the tag length has to be encoded into the \p iv passed to + * this function. + * + * \param ctx The CCM context to use for encryption. + * \param length The length of the input data in Bytes. + * \param iv Initialization vector (nonce). + * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param add The additional data field. + * \param add_len The length of additional data in Bytes. + * Must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. + * \param output The buffer holding the output data. + * Must be at least \p length Bytes wide. + * \param tag The buffer holding the tag. + * \param tag_len The length of the tag to generate in Bytes: + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing 0 as \p tag_len means that the message is no + * longer authenticated. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_star_encrypt_and_tag( mbedtls_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 ); + /** * \brief This function performs a CCM authenticated decryption of a * buffer. @@ -160,6 +198,42 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, const unsigned char *input, unsigned char *output, const unsigned char *tag, size_t tag_len ); +/** + * \brief This function performs a CCM* authenticated decryption of a + * buffer. + * + * \note When using this function in a variable tag length context, + * the tag length has to be decoded from \p iv and passed to + * this function as \p tag_len. (\p tag needs to be adjusted + * accordingly.) + * + * \param ctx The CCM context to use for decryption. + * \param length The length of the input data in Bytes. + * \param iv Initialization vector. + * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param add The additional data field. + * \param add_len The length of additional data in Bytes. + * Must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. + * \param output The buffer holding the output data. + * Must be at least \p length Bytes wide. + * \param tag The buffer holding the tag. + * \param tag_len The length of the tag in Bytes. + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing 0 as \p tag_len means that the message is no + * longer authenticated. + * + * \return \c 0 on success. This indicates that the message is + * authentic. + * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. + * \return A cipher-specific error code on calculation failure. + */ +int mbedtls_ccm_star_auth_decrypt( mbedtls_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 ); #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) /** From b5734a28d9bc49e8dd6c385694f1002017f608dc Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 14 May 2018 14:31:49 +0100 Subject: [PATCH 2/8] CCM*: Add implementation --- library/ccm.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/library/ccm.c b/library/ccm.c index cf6520935..b195a7165 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -154,7 +154,13 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, * 'length' checked later (when writing it to the first block) */ if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); + { + /* + * Loosen the requirements to enable support for CCM* (IEEE 802.15.4) + */ + if( tag_len != 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + } /* Also implies q is within bounds */ if( iv_len < 7 || iv_len > 13 ) @@ -302,7 +308,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, /* * Authenticated encryption */ -int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, +int mbedtls_ccm_star_encrypt_and_tag( mbedtls_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, @@ -312,10 +318,23 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, add, add_len, input, output, tag, tag_len ) ); } +int mbedtls_ccm_encrypt_and_tag( mbedtls_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 ) +{ + if( tag_len == 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add, + add_len, input, output, tag, tag_len ) ); +} + /* * Authenticated decryption */ -int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, +int mbedtls_ccm_star_auth_decrypt( mbedtls_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, @@ -346,6 +365,18 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, return( 0 ); } +int mbedtls_ccm_auth_decrypt( mbedtls_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 ) +{ + if( tag_len == 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add, + add_len, input, output, tag, tag_len ) ); +} #endif /* !MBEDTLS_CCM_ALT */ #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) From 95ab93d41733d468f72ea29cecd2d73055626027 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 14 May 2018 14:32:41 +0100 Subject: [PATCH 3/8] CCM*: Add minimal tests --- tests/suites/test_suite_ccm.data | 9 ++++++ tests/suites/test_suite_ccm.function | 41 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data index 90ba42d83..ac66812cc 100644 --- a/tests/suites/test_suite_ccm.data +++ b/tests/suites/test_suite_ccm.data @@ -41,6 +41,15 @@ ccm_lengths:5:10:65281:8:MBEDTLS_ERR_CCM_BAD_INPUT CCM lengths #8 msg too long for this IV length (2^16, q = 2) ccm_lengths:65536:13:5:8:MBEDTLS_ERR_CCM_BAD_INPUT +CCM lengths #9 tag length 0 +ccm_lengths:5:10:5:0:MBEDTLS_ERR_CCM_BAD_INPUT + +CCM* fixed tag lengths #1 all OK +ccm_star_lengths:5:10:5:8:0 + +CCM* fixed tag lengths #2 all OK - tag length 0 +ccm_star_lengths:5:10:5:0:0 + CCM encrypt and tag RFC 3610 #1 depends_on:MBEDTLS_AES_C mbedtls_ccm_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"00000003020100A0A1A2A3A4A5":"0001020304050607":"588C979A61C663D2F066D0C2C0F989806D5F6B61DAC38417E8D12CFDF926E0" diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function index 2f5c77c2c..6d685438e 100644 --- a/tests/suites/test_suite_ccm.function +++ b/tests/suites/test_suite_ccm.function @@ -74,6 +74,47 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_AES_C */ +void ccm_star_lengths( int msg_len, int iv_len, int add_len, int tag_len, + int res ) +{ + mbedtls_ccm_context ctx; + unsigned char key[16]; + unsigned char msg[10]; + unsigned char iv[14]; + unsigned char add[10]; + unsigned char out[10]; + unsigned char tag[18]; + int decrypt_ret; + + mbedtls_ccm_init( &ctx ); + + memset( key, 0, sizeof( key ) ); + memset( msg, 0, sizeof( msg ) ); + memset( iv, 0, sizeof( iv ) ); + memset( add, 0, sizeof( add ) ); + memset( out, 0, sizeof( out ) ); + memset( tag, 0, sizeof( tag ) ); + + TEST_ASSERT( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, + key, 8 * sizeof( key ) ) == 0 ); + + TEST_ASSERT( mbedtls_ccm_star_encrypt_and_tag( &ctx, msg_len, iv, iv_len, + add, add_len, msg, out, tag, tag_len ) == res ); + + decrypt_ret = mbedtls_ccm_star_auth_decrypt( &ctx, msg_len, iv, iv_len, add, + add_len, msg, out, tag, tag_len ); + + if( res == 0 && tag_len != 0 ) + TEST_ASSERT( decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED ); + else + TEST_ASSERT( decrypt_ret == res ); + +exit: + mbedtls_ccm_free( &ctx ); +} +/* END_CASE */ + /* BEGIN_CASE */ void mbedtls_ccm_encrypt_and_tag( int cipher_id, char *key_hex, char *msg_hex, From 6b4bd3dcc4caa2d555eb087e97e3692e7ce59bfe Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 29 May 2018 11:30:26 +0100 Subject: [PATCH 4/8] CCM*: Improve documentation --- include/mbedtls/ccm.h | 44 +++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 24e13dd80..4881db7e1 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -14,6 +14,18 @@ *
  • Nonce - A unique value that is assigned to the payload and the * associated data.
  • * + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + * + * Definition of CCM*: + * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks + * Integer representation is fixed most-significant-octet-first order and + * the representation of octets is most-significant-bit-first order. This is + * consistent with RFC 3610. */ /* * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved @@ -111,15 +123,17 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * \param ctx The CCM context to use for encryption. * \param length The length of the input data in Bytes. * \param iv Initialization vector (nonce). - * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. * \param add The additional data field. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. * \param input The buffer holding the input data. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the tag. - * \param tag_len The length of the tag to generate in Bytes: + * \param tag The buffer holding the authentication field. + * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * * \return \c 0 on success. @@ -147,15 +161,17 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param ctx The CCM context to use for encryption. * \param length The length of the input data in Bytes. * \param iv Initialization vector (nonce). - * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. * \param add The additional data field. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. * \param input The buffer holding the input data. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the tag. - * \param tag_len The length of the tag to generate in Bytes: + * \param tag The buffer holding the authentication field. + * \param tag_len The length of the authentication field to generate in Bytes: * 0, 4, 6, 8, 10, 12, 14 or 16. * * \warning Passing 0 as \p tag_len means that the message is no @@ -177,15 +193,17 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param ctx The CCM context to use for decryption. * \param length The length of the input data in Bytes. * \param iv Initialization vector. - * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. * \param add The additional data field. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. * \param input The buffer holding the input data. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the tag. - * \param tag_len The length of the tag in Bytes. + * \param tag The buffer holding the authentication field. + * \param tag_len The length of the authentication field in Bytes. * 4, 6, 8, 10, 12, 14 or 16. * * \return \c 0 on success. This indicates that the message is authentic. @@ -210,15 +228,17 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * \param ctx The CCM context to use for decryption. * \param length The length of the input data in Bytes. * \param iv Initialization vector. - * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. * \param add The additional data field. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. * \param input The buffer holding the input data. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the tag. - * \param tag_len The length of the tag in Bytes. + * \param tag The buffer holding the authentication field. + * \param tag_len The length of the authentication field in Bytes. * 0, 4, 6, 8, 10, 12, 14 or 16. * * \warning Passing 0 as \p tag_len means that the message is no From 997e85c049c122357387e4c077d1045b8142e819 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 29 May 2018 11:33:45 +0100 Subject: [PATCH 5/8] CCM*: Remove nested if --- library/ccm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/library/ccm.c b/library/ccm.c index b195a7165..32f8bb098 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -152,14 +152,12 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, * Check length requirements: SP800-38C A.1 * Additional requirement: a < 2^16 - 2^8 to simplify the code. * 'length' checked later (when writing it to the first block) + * + * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4). */ - if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) + if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 ) { - /* - * Loosen the requirements to enable support for CCM* (IEEE 802.15.4) - */ - if( tag_len != 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); + return( MBEDTLS_ERR_CCM_BAD_INPUT ); } /* Also implies q is within bounds */ From 143b319773c74740b8d3a4010fabd64859168c6d Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 30 May 2018 13:57:29 +0100 Subject: [PATCH 6/8] CCM*: Make documentation consistent --- include/mbedtls/ccm.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 4881db7e1..5d727e7cc 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -192,7 +192,7 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * * \param ctx The CCM context to use for decryption. * \param length The length of the input data in Bytes. - * \param iv Initialization vector. + * \param iv Initialization vector (nonce). * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. @@ -227,7 +227,7 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * * \param ctx The CCM context to use for decryption. * \param length The length of the input data in Bytes. - * \param iv Initialization vector. + * \param iv Initialization vector (nonce). * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. @@ -244,8 +244,7 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * \warning Passing 0 as \p tag_len means that the message is no * longer authenticated. * - * \return \c 0 on success. This indicates that the message is - * authentic. + * \return \c 0 on success. * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. * \return A cipher-specific error code on calculation failure. */ From 4c579391b14f2af25fa8987e3966375474d8301f Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 30 May 2018 13:58:38 +0100 Subject: [PATCH 7/8] CCM*: Remove superfluous braces --- library/ccm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/ccm.c b/library/ccm.c index 32f8bb098..804eaf80f 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -156,9 +156,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4). */ if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 ) - { return( MBEDTLS_ERR_CCM_BAD_INPUT ); - } /* Also implies q is within bounds */ if( iv_len < 7 || iv_len > 13 ) From 0daf4caaf8ffb4fc82aa0f43a2a53a0739d40a4d Mon Sep 17 00:00:00 2001 From: Darryl Green Date: Tue, 29 May 2018 14:12:26 +0100 Subject: [PATCH 8/8] Add test vectors for CCM* --- tests/suites/test_suite_ccm.data | 24 +++++ tests/suites/test_suite_ccm.function | 137 +++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data index ac66812cc..cad40d59c 100644 --- a/tests/suites/test_suite_ccm.data +++ b/tests/suites/test_suite_ccm.data @@ -50,6 +50,30 @@ ccm_star_lengths:5:10:5:8:0 CCM* fixed tag lengths #2 all OK - tag length 0 ccm_star_lengths:5:10:5:0:0 +CCM* encrypt and tag #1 +depends_on:MBEDTLS_AES_C +mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"":"ACDE480000000001":"00000005":2:"08D0842143010000000048DEAC020500000055CF000051525354":"223BC1EC841AB553":0 + +CCM* encrypt and tag #2 +depends_on:MBEDTLS_AES_C +mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"61626364":"ACDE480000000001":"00000005":4:"69DC842143020000000048DEAC010000000048DEAC0405000000":"D43E022B":0 + +CCM* encrypt and tag #3 +depends_on:MBEDTLS_AES_C +mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"CE":"ACDE480000000001":"00000005":6:"2BDC842143020000000048DEACFFFF010000000048DEAC060500000001":"D84FDE529061F9C6F1":0 + +CCM* auth decrypt tag #1 +depends_on:MBEDTLS_AES_C +mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"223BC1EC841AB553":"ACDE480000000001":"00000005":2:"08D0842143010000000048DEAC020500000055CF000051525354":"":0 + +CCM* auth decrypt tag #2 +depends_on:MBEDTLS_AES_C +mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"D43E022B":"ACDE480000000001":"00000005":4:"69DC842143020000000048DEAC010000000048DEAC0405000000":"61626364":0 + +CCM* auth decrypt tag #3 +depends_on:MBEDTLS_AES_C +mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"D84FDE529061F9C6F1":"ACDE480000000001":"00000005":6:"2BDC842143020000000048DEACFFFF010000000048DEAC060500000001":"CE":0 + CCM encrypt and tag RFC 3610 #1 depends_on:MBEDTLS_AES_C mbedtls_ccm_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"00000003020100A0A1A2A3A4A5":"0001020304050607":"588C979A61C663D2F066D0C2C0F989806D5F6B61DAC38417E8D12CFDF926E0" diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function index 6d685438e..58c856985 100644 --- a/tests/suites/test_suite_ccm.function +++ b/tests/suites/test_suite_ccm.function @@ -228,3 +228,140 @@ exit: mbedtls_ccm_free( &ctx ); } /* END_CASE */ + +/* BEGIN_CASE */ +void mbedtls_ccm_star_encrypt_and_tag( int cipher_id, + char *key_hex, char *msg_hex, + char *source_address_hex, char *frame_counter_hex, + int sec_level, char *add_hex, + char *result_hex, int output_ret ) +{ + unsigned char key[32]; + unsigned char msg[50]; + unsigned char iv[13]; + unsigned char add[32]; + unsigned char result[50]; + unsigned char source_address[8]; + unsigned char frame_counter[4]; + mbedtls_ccm_context ctx; + size_t i, key_len, msg_len, iv_len, add_len, result_len, source_address_len, frame_counter_len, tag_len; + int ret; + + mbedtls_ccm_init( &ctx ); + + memset( key, 0x00, sizeof( key ) ); + memset( msg, 0x00, sizeof( msg ) ); + memset( iv, 0x00, sizeof( iv ) ); + memset( add, 0x00, sizeof( add ) ); + memset( result, 0x00, sizeof( result ) ); + memset( source_address, 0x00, sizeof( source_address ) ); + memset( frame_counter, 0x00, sizeof( frame_counter ) ); + + key_len = unhexify( key, key_hex ); + msg_len = unhexify( msg, msg_hex ); + add_len = unhexify( add, add_hex ); + result_len = unhexify( result, result_hex ); + source_address_len = unhexify( source_address, source_address_hex ); + frame_counter_len = unhexify( frame_counter, frame_counter_hex ); + + if( sec_level % 4 == 0) + tag_len = 0; + else + tag_len = 1 << ( sec_level % 4 + 1); + + for( i = 0; i < source_address_len; i++ ) + iv[i] = source_address[i]; + + for( i = 0; i < frame_counter_len; i++ ) + iv[source_address_len + i] = frame_counter[i]; + + iv[source_address_len + frame_counter_len] = sec_level; + iv_len = sizeof( iv ); + + TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 ); + + ret = mbedtls_ccm_star_encrypt_and_tag( &ctx, msg_len, iv, iv_len, + add, add_len, msg, msg, msg + msg_len, tag_len ); + + TEST_ASSERT( ret == output_ret ); + + TEST_ASSERT( memcmp( msg, result, result_len ) == 0 ); + + /* Check we didn't write past the end */ + TEST_ASSERT( msg[result_len] == 0 && msg[result_len + 1] == 0 ); + +exit: + mbedtls_ccm_free( &ctx ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void mbedtls_ccm_star_auth_decrypt( int cipher_id, + char *key_hex, char *msg_hex, + char *source_address_hex, char *frame_counter_hex, + int sec_level, char *add_hex, + char *result_hex, int output_ret ) +{ + unsigned char key[32]; + unsigned char msg[50]; + unsigned char iv[13]; + unsigned char add[32]; + unsigned char tag[16]; + unsigned char result[50]; + unsigned char source_address[8]; + unsigned char frame_counter[4]; + mbedtls_ccm_context ctx; + size_t i, key_len, msg_len, iv_len, add_len, tag_len, result_len, source_address_len, frame_counter_len; + int ret; + + mbedtls_ccm_init( &ctx ); + + memset( key, 0x00, sizeof( key ) ); + memset( msg, 0x00, sizeof( msg ) ); + memset( iv, 0x00, sizeof( iv ) ); + memset( add, 0x00, sizeof( add ) ); + memset( result, 0x00, sizeof( result ) ); + memset( source_address, 0x00, sizeof( source_address ) ); + memset( frame_counter, 0x00, sizeof( frame_counter ) ); + memset( tag, 0x00, sizeof( tag ) ); + + key_len = unhexify( key, key_hex ); + msg_len = unhexify( msg, msg_hex ); + add_len = unhexify( add, add_hex ); + result_len = unhexify( result, result_hex ); + source_address_len = unhexify( source_address, source_address_hex ); + frame_counter_len = unhexify( frame_counter, frame_counter_hex ); + + if( sec_level % 4 == 0) + tag_len = 0; + else + tag_len = 1 << ( sec_level % 4 + 1); + + for( i = 0; i < source_address_len; i++ ) + iv[i] = source_address[i]; + + for( i = 0; i < frame_counter_len; i++ ) + iv[source_address_len + i] = frame_counter[i]; + + iv[source_address_len + frame_counter_len] = sec_level; + iv_len = sizeof( iv ); + + msg_len -= tag_len; + memcpy( tag, msg + msg_len, tag_len ); + + TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 ); + + ret = mbedtls_ccm_star_auth_decrypt( &ctx, msg_len, iv, iv_len, + add, add_len, msg, msg, msg + msg_len, tag_len ); + + TEST_ASSERT( ret == output_ret ); + + TEST_ASSERT( memcmp( msg, result, result_len ) == 0 ); + + /* Check we didn't write past the end (where the original tag is) */ + TEST_ASSERT( memcmp( msg + msg_len, tag, tag_len ) == 0 ); + +exit: + mbedtls_ccm_free( &ctx ); +} +/* END_CASE */