From 8372286591920b4ab33fee3d412cd751682efbf5 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Thu, 9 Apr 2020 15:57:57 +0200 Subject: [PATCH 1/2] sys/crypto/modes/ccm: accept input_len=0 CCM may be used on messages with no plaintext data. --- sys/crypto/modes/ccm.c | 6 ++++++ sys/include/crypto/modes/ccm.h | 11 +++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/sys/crypto/modes/ccm.c b/sys/crypto/modes/ccm.c index 3f5a428820..322a568fd3 100644 --- a/sys/crypto/modes/ccm.c +++ b/sys/crypto/modes/ccm.c @@ -43,6 +43,12 @@ static int ccm_compute_cbc_mac(cipher_t *cipher, const uint8_t iv[16], block_size = cipher_get_block_size(cipher); memmove(mac, iv, 16); offset = 0; + + /* no input message */ + if(length == 0) { + return 0; + } + do { uint8_t block_size_input = (length - offset > block_size) ? block_size : length - offset; diff --git a/sys/include/crypto/modes/ccm.h b/sys/include/crypto/modes/ccm.h index 4c81593ae7..9900b8407e 100644 --- a/sys/include/crypto/modes/ccm.h +++ b/sys/include/crypto/modes/ccm.h @@ -57,10 +57,12 @@ extern "C" { * @param nonce_len Length of the nonce in octets * (maximum: 15-length_encoding) * @param input pointer to input data to encrypt - * @param input_len length of the input data, max 2^32 + * @param input_len length of the input data, [0, 2^32] * @param output pointer to allocated memory for encrypted data. It * has to be of size data_len + mac_length. - * @return Length of encrypted data on a successful encryption + * + * @return Length of encrypted data on a successful encryption, + * can be 0 if input_len=0 (no plaintext) * @return A negative error code if something went wrong */ int cipher_encrypt_ccm(cipher_t *cipher, @@ -85,11 +87,12 @@ int cipher_encrypt_ccm(cipher_t *cipher, * @param nonce_len Length of the nonce in octets * (maximum: 15-length_encoding) * @param input pointer to input data to decrypt - * @param input_len length of the input data, max 2^32 + * @param input_len length of the input data, [0, 2^32] * @param output pointer to allocated memory for decrypted data. It * has to be of size data_len - mac_length. * - * @return Length of the decrypted data on a successful decryption + * @return Length of the decrypted data on a successful decryption, + * can be 0 if only auth_data and MAC is present. * @return A negative error code if something went wrong */ int cipher_decrypt_ccm(cipher_t *cipher, From 7a39e2e875ca0617e5b2b193983a79eb2112280d Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Thu, 9 Apr 2020 16:10:07 +0200 Subject: [PATCH 2/2] tests/sys_crypto/tests-crypto-modes-ccm: add test for input_len=0 --- tests/sys_crypto/tests-crypto-modes-ccm.c | 30 ++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/sys_crypto/tests-crypto-modes-ccm.c b/tests/sys_crypto/tests-crypto-modes-ccm.c index 70b6afcbbc..bd8f32ec1b 100644 --- a/tests/sys_crypto/tests-crypto-modes-ccm.c +++ b/tests/sys_crypto/tests-crypto-modes-ccm.c @@ -826,6 +826,32 @@ static const size_t TEST_NIST_3_EXPECTED_LEN = 52; /* Tests from Project Wycheproof */ /* See https://github.com/google/wycheproof/blob/master/testvectors/aes_ccm_test.json */ +/* tcId" : 1 */ +static const uint8_t TEST_WYCHEPROOF_1_KEY[] = { + 0xbe, 0xdc, 0xfb, 0x5a, 0x01, 0x1e, 0xbc, 0x84, + 0x60, 0x0f, 0xcb, 0x29, 0x6c, 0x15, 0xaf, 0x0d +}; +static const size_t TEST_WYCHEPROOF_1_KEY_LEN = 16; +static const uint8_t TEST_WYCHEPROOF_1_NONCE[] = { + 0x43, 0x8a, 0x54, 0x7a, 0x94, 0xea, 0x88, 0xdc, + 0xe4, 0x6c, 0x6c, 0x85 +}; +static const size_t TEST_WYCHEPROOF_1_NONCE_LEN = 12; +static const size_t TEST_WYCHEPROOF_1_MAC_LEN = 16; +static const uint8_t TEST_WYCHEPROOF_1_INPUT[] = { + /* PLAINTEXT */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static const size_t TEST_WYCHEPROOF_1_INPUT_LEN = 0; +static const size_t TEST_WYCHEPROOF_1_ADATA_LEN = 0; +static const uint8_t TEST_WYCHEPROOF_1_EXPECTED[] = { + /* MAC */ + 0x25, 0xd1, 0xa3, 0x84, 0x95, 0xa7, 0xde, 0xa4, + 0x5b, 0xda, 0x04, 0x97, 0x05, 0x62, 0x7d, 0x10 +}; +static const size_t TEST_WYCHEPROOF_1_EXPECTED_LEN = 16; + +/* tcId" : 28 */ static const uint8_t TEST_WYCHEPROOF_28_KEY[] = { 0x20, 0xbb, 0xf7, 0x4c, 0x1e, 0x63, 0x98, 0x2c, 0x47, 0x2c, 0x47, 0x43, 0x56, 0x9e, 0x4c, 0x84, @@ -1113,7 +1139,7 @@ static void test_decrypt_op(const uint8_t *key, uint8_t key_len, len = cipher_decrypt_ccm(&cipher, adata, adata_len, mac_length, len_encoding, nonce, nonce_len, encrypted, encrypted_len, data); - TEST_ASSERT_MESSAGE(len > 0, "Decryption failed"); + TEST_ASSERT_MESSAGE(len >= 0, "Decryption failed"); TEST_ASSERT_EQUAL_INT(output_expected_len, len); cmp = compare(output_expected, data, len); @@ -1168,6 +1194,7 @@ static void test_crypto_modes_ccm_encrypt(void) do_test_encrypt_op(NIST_2); do_test_encrypt_op(NIST_3); + do_test_encrypt_op(WYCHEPROOF_1); do_test_encrypt_op(WYCHEPROOF_28); do_test_encrypt_op(MANUAL_01); @@ -1220,6 +1247,7 @@ static void test_crypto_modes_ccm_decrypt(void) do_test_decrypt_op(NIST_2); do_test_decrypt_op(NIST_3); + do_test_decrypt_op(WYCHEPROOF_1); do_test_decrypt_op(WYCHEPROOF_28); do_test_decrypt_op(MANUAL_01);