From 5e59649fda6c76543f126b1fa5bc82302d69eff7 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 31 Aug 2022 08:50:33 +0200 Subject: [PATCH 1/4] hashes_cmac: rename to hashes_aes128_cmac --- sys/hashes/{cmac.c => aes128_cmac.c} | 42 ++++++------- sys/include/hashes/aes128_cmac.h | 88 ++++++++++++++++++++++++++++ sys/include/hashes/cmac.h | 39 ++++++------ 3 files changed, 132 insertions(+), 37 deletions(-) rename sys/hashes/{cmac.c => aes128_cmac.c} (59%) create mode 100644 sys/include/hashes/aes128_cmac.h diff --git a/sys/hashes/cmac.c b/sys/hashes/aes128_cmac.c similarity index 59% rename from sys/hashes/cmac.c rename to sys/hashes/aes128_cmac.c index 27cc57975c..209b40da4a 100644 --- a/sys/hashes/cmac.c +++ b/sys/hashes/aes128_cmac.c @@ -7,11 +7,11 @@ */ /** - * @ingroup sys_hashes_cmac + * @ingroup sys_hashes_aes128_cmac * @{ * * @file - * @brief AES_CMAC implementation + * @brief AES128_CMAC implementation * * @author José Ignacio Alamos * @@ -23,7 +23,7 @@ #include #include "crypto/ciphers.h" -#include "hashes/cmac.h" +#include "hashes/aes128_cmac.h" #define MIN(a, b) a < b ? a : b @@ -42,17 +42,19 @@ static void _leftshift(uint8_t *x, uint8_t *y) y[15] = x[15] << 1; } -int cmac_init(cmac_context_t *ctx, const uint8_t *key, uint8_t key_size) +int aes128_cmac_init(aes128_cmac_context_t *ctx, + const uint8_t *key, uint8_t key_size) { - if (key_size != CMAC_BLOCK_SIZE) { + if (key_size != AES128_CMAC_BLOCK_SIZE) { return CIPHER_ERR_INVALID_KEY_SIZE; } - memset(ctx, 0, sizeof(cmac_context_t)); - return cipher_init(&(ctx->aes_ctx), CIPHER_AES, key, key_size); + memset(ctx, 0, sizeof(aes128_cmac_context_t)); + return cipher_init(&(ctx->aes128_ctx), CIPHER_AES, key, key_size); } -void cmac_update(cmac_context_t *ctx, const void *data, size_t len) +void aes128_cmac_update(aes128_cmac_context_t *ctx, + const void *data, size_t len) { uint8_t d[16]; @@ -61,29 +63,29 @@ void cmac_update(cmac_context_t *ctx, const void *data, size_t len) if (ctx->M_n == 16) { ctx->M_n = 0; _xor128(ctx->M_last, ctx->X); - cipher_encrypt(&ctx->aes_ctx, ctx->X, d); - memcpy(ctx->X, d, CMAC_BLOCK_SIZE); + cipher_encrypt(&ctx->aes128_ctx, ctx->X, d); + memcpy(ctx->X, d, AES128_CMAC_BLOCK_SIZE); } - c = MIN(CMAC_BLOCK_SIZE - ctx->M_n, len); + c = MIN(AES128_CMAC_BLOCK_SIZE - ctx->M_n, len); memcpy(ctx->M_last + ctx->M_n, data, c); ctx->M_n += c; len -= c; data = (void *) (((uint8_t *) data) + c); - if (ctx->M_n < CMAC_BLOCK_SIZE) { + if (ctx->M_n < AES128_CMAC_BLOCK_SIZE) { break; } } } -void cmac_final(cmac_context_t *ctx, void *digest) +void aes128_cmac_final(aes128_cmac_context_t *ctx, void *digest) { /* Generate subkeys */ - uint8_t K[CMAC_BLOCK_SIZE]; - uint8_t L[CMAC_BLOCK_SIZE]; + uint8_t K[AES128_CMAC_BLOCK_SIZE]; + uint8_t L[AES128_CMAC_BLOCK_SIZE]; - memset(K, 0, CMAC_BLOCK_SIZE); - cipher_encrypt(&ctx->aes_ctx, K, L); + memset(K, 0, AES128_CMAC_BLOCK_SIZE); + cipher_encrypt(&ctx->aes128_ctx, K, L); if (L[0] & 0x80) { _leftshift(L, K); @@ -103,11 +105,11 @@ void cmac_final(cmac_context_t *ctx, void *digest) _leftshift(K, K); } /* Padding */ - memset(ctx->M_last + ctx->M_n, 0, CMAC_BLOCK_SIZE - ctx->M_n); + memset(ctx->M_last + ctx->M_n, 0, AES128_CMAC_BLOCK_SIZE - ctx->M_n); ctx->M_last[ctx->M_n] = 0x80; } _xor128(K, ctx->M_last); _xor128(ctx->M_last, ctx->X); - cipher_encrypt(&ctx->aes_ctx, ctx->X, L); - memcpy(digest, L, CMAC_BLOCK_SIZE); + cipher_encrypt(&ctx->aes128_ctx, ctx->X, L); + memcpy(digest, L, AES128_CMAC_BLOCK_SIZE); } diff --git a/sys/include/hashes/aes128_cmac.h b/sys/include/hashes/aes128_cmac.h new file mode 100644 index 0000000000..a32614e101 --- /dev/null +++ b/sys/include/hashes/aes128_cmac.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 Fundación Inria Chile + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup sys_hashes_aes128_cmac AES128_CMAC + * @ingroup sys_hashes_keyed + * @brief Implementation of the AES128 CMAC hashing function + + * @{ + * + * @file + * @brief AES128_CMAC interface definition + * + * @author José Ignacio Alamos + */ + +#ifndef HASHES_AES128_CMAC_H +#define HASHES_AES128_CMAC_H + +#include +#include "crypto/ciphers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Length of AES128_CMAC block in bytes + */ +#define AES128_CMAC_BLOCK_SIZE 16 + +/** + * @brief AES128_CMAC calculation context + */ +typedef struct { + /** AES128 context */ + cipher_t aes128_ctx; + /** auxiliary array for CMAC calculations **/ + uint8_t X[AES128_CMAC_BLOCK_SIZE]; + /** current last block **/ + uint8_t M_last[AES128_CMAC_BLOCK_SIZE]; + /** last byte in last block */ + uint32_t M_n; +} aes128_cmac_context_t; + +/** + * @brief Initialize AES128 CMAC message digest context + * + * @param[in] ctx Pointer to the AES128 CMAC context to initialize + * @param[in] key Key to be set + * @param[in] key_size Size of the key + * + * @return CIPHER_INIT_SUCCESS if the initialization was successful. + * CIPHER_ERR_INVALID_KEY_SIZE if the key size is not valid. + */ +int aes128_cmac_init(aes128_cmac_context_t *ctx, + const uint8_t *key, uint8_t key_size); + +/** + * @brief Update the AES128 CMAC context with a portion of the message being + * hashed + * + * @param[in] ctx Pointer to the AES128 CMAC context to update + * @param[in] data Input data + * @param[in] len Length of @p data + */ +void aes128_cmac_update(aes128_cmac_context_t *ctx, + const void *data, size_t len); + +/** + * @brief Finalizes the CMAC message digest + * + * @param[in] ctx Pointer to the AES128 CMAC context + * @param[out] digest Result location + */ +void aes128_cmac_final(aes128_cmac_context_t *ctx, void *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* HASHES_AES128_CMAC_H */ +/** @} */ diff --git a/sys/include/hashes/cmac.h b/sys/include/hashes/cmac.h index cfa6518c26..fbae5634f2 100644 --- a/sys/include/hashes/cmac.h +++ b/sys/include/hashes/cmac.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Fundación Inria Chile + * Copyright (C) 2022 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -10,6 +11,8 @@ * @defgroup sys_hashes_cmac AES_CMAC * @ingroup sys_hashes_keyed * @brief Implementation of the AES CMAC hashing function + * @deprecated Will be removed after the 2023.01 release. Please use + * @ref sys_hashes_aes128_cmac instead. * @{ * @@ -17,13 +20,13 @@ * @brief AES_CMAC interface definition * * @author José Ignacio Alamos + * @author Martine S. Lenders */ #ifndef HASHES_CMAC_H #define HASHES_CMAC_H -#include -#include "crypto/ciphers.h" +#include "hashes/aes128_cmac.h" #ifdef __cplusplus extern "C" { @@ -32,21 +35,12 @@ extern "C" { /** * @brief Length of AES_CMAC block in bytes */ -#define CMAC_BLOCK_SIZE 16 +#define CMAC_BLOCK_SIZE AES128_CMAC_BLOCK_SIZE /** - * @brief AES_CMAC calculation context + * @brief CMAC calculation context */ -typedef struct { - /** AES128 context */ - cipher_t aes_ctx; - /** auxiliary array for CMAC calculations **/ - uint8_t X[CMAC_BLOCK_SIZE]; - /** current last block **/ - uint8_t M_last[CMAC_BLOCK_SIZE]; - /** last byte in last block */ - uint32_t M_n; -} cmac_context_t; +typedef aes128_cmac_context_t cmac_context_t; /** * @brief Initialize CMAC message digest context @@ -58,7 +52,11 @@ typedef struct { * @return CIPHER_INIT_SUCCESS if the initialization was successful. * CIPHER_ERR_INVALID_KEY_SIZE if the key size is not valid. */ -int cmac_init(cmac_context_t *ctx, const uint8_t *key, uint8_t key_size); +static inline int cmac_init(cmac_context_t *ctx, + const uint8_t *key, uint8_t key_size) +{ + return aes128_cmac_init(ctx, key, key_size); +} /** * @brief Update the CMAC context with a portion of the message being hashed @@ -67,7 +65,11 @@ int cmac_init(cmac_context_t *ctx, const uint8_t *key, uint8_t key_size); * @param[in] data Input data * @param[in] len Length of @p data */ -void cmac_update(cmac_context_t *ctx, const void *data, size_t len); +static inline void cmac_update(cmac_context_t *ctx, + const void *data, size_t len) +{ + aes128_cmac_update(ctx, data, len); +} /** * @brief Finalizes the CMAC message digest @@ -75,7 +77,10 @@ void cmac_update(cmac_context_t *ctx, const void *data, size_t len); * @param[in] ctx Pointer to the CMAC context * @param[out] digest Result location */ -void cmac_final(cmac_context_t *ctx, void *digest); +static inline void cmac_final(cmac_context_t *ctx, void *digest) +{ + aes128_cmac_final(ctx, digest); +} #ifdef __cplusplus } From aead6d201085063af2b89303fa451f2b9edb5831 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 31 Aug 2022 08:53:00 +0200 Subject: [PATCH 2/4] gnrc_lorawan: use aes128_cmac_.* instead of cmac_.* --- .../link_layer/lorawan/gnrc_lorawan_crypto.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c index 7cc67af245..738d810942 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c @@ -16,7 +16,7 @@ #include #include -#include "hashes/cmac.h" +#include "hashes/aes128_cmac.h" #include "crypto/ciphers.h" #include "net/gnrc/lorawan.h" @@ -31,7 +31,7 @@ #define APP_SKEY_B0_START (0x1) #define NWK_SKEY_B0_START (0x2) -static cmac_context_t CmacContext; +static aes128_cmac_context_t CmacContext; static uint8_t digest[LORAMAC_APPKEY_LEN]; static cipher_t AesContext; @@ -48,9 +48,9 @@ typedef struct __attribute__((packed)) { void gnrc_lorawan_calculate_join_mic(const uint8_t *buf, size_t len, const uint8_t *key, le_uint32_t *out) { - cmac_init(&CmacContext, key, LORAMAC_APPKEY_LEN); - cmac_update(&CmacContext, buf, len); - cmac_final(&CmacContext, digest); + aes128_cmac_init(&CmacContext, key, LORAMAC_APPKEY_LEN); + aes128_cmac_update(&CmacContext, buf, len); + aes128_cmac_final(&CmacContext, digest); memcpy(out, digest, sizeof(le_uint32_t)); } @@ -73,12 +73,12 @@ void gnrc_lorawan_calculate_mic(const le_uint32_t *dev_addr, uint32_t fcnt, block.len = iolist_size(frame); - cmac_init(&CmacContext, nwkskey, LORAMAC_APPKEY_LEN); - cmac_update(&CmacContext, &block, sizeof(block)); + aes128_cmac_init(&CmacContext, nwkskey, LORAMAC_APPKEY_LEN); + aes128_cmac_update(&CmacContext, &block, sizeof(block)); for (iolist_t *io = frame; io != NULL; io = io->iol_next) { - cmac_update(&CmacContext, io->iol_base, io->iol_len); + aes128_cmac_update(&CmacContext, io->iol_base, io->iol_len); } - cmac_final(&CmacContext, digest); + aes128_cmac_final(&CmacContext, digest); memcpy(out, digest, sizeof(le_uint32_t)); } From 27e68787c50bdfde75a87c7676437352adcc428b Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 31 Aug 2022 08:55:56 +0200 Subject: [PATCH 3/4] tests: rename cmac to aes128_cmac --- ...shes-cmac.c => tests-hashes-aes128_cmac.c} | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) rename tests/unittests/tests-hashes/{tests-hashes-cmac.c => tests-hashes-aes128_cmac.c} (83%) diff --git a/tests/unittests/tests-hashes/tests-hashes-cmac.c b/tests/unittests/tests-hashes/tests-hashes-aes128_cmac.c similarity index 83% rename from tests/unittests/tests-hashes/tests-hashes-cmac.c rename to tests/unittests/tests-hashes/tests-hashes-aes128_cmac.c index feb3765bfa..01b9a5addd 100644 --- a/tests/unittests/tests-hashes/tests-hashes-cmac.c +++ b/tests/unittests/tests-hashes/tests-hashes-aes128_cmac.c @@ -11,7 +11,7 @@ * @{ * * @file - * @brief Test cases for the AES-CMAC hash implementation + * @brief Test cases for the AES128-CMAC hash implementation * * @author José Ignacio Alamos * @@ -23,10 +23,10 @@ #include "tests-hashes.h" #include "embUnit/embUnit.h" -#include "hashes/cmac.h" +#include "hashes/aes128_cmac.h" #include "crypto/ciphers.h" -static const uint8_t CMAC_KEY[16] = { +static const uint8_t AES128_CMAC_KEY[16] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; @@ -78,11 +78,11 @@ static const uint8_t TEST_3_EXP[16] = { static int calc_and_compare_hash(const uint8_t *hash, size_t size, const uint8_t *expected) { uint8_t digest[16]; - cmac_context_t ctx; + aes128_cmac_context_t ctx; - cmac_init(&ctx, CMAC_KEY, 16); - cmac_update(&ctx, hash, size); - cmac_final(&ctx, digest); + aes128_cmac_init(&ctx, AES128_CMAC_KEY, 16); + aes128_cmac_update(&ctx, hash, size); + aes128_cmac_final(&ctx, digest); return memcmp(digest, expected, 16); } @@ -96,10 +96,12 @@ static void test_hashes_cmac(void) static void test_hashes_cmac_keysize(void) { - cmac_context_t ctx; + aes128_cmac_context_t ctx; - TEST_ASSERT_EQUAL_INT(cmac_init(&ctx, CMAC_KEY, 15), CIPHER_ERR_INVALID_KEY_SIZE); - TEST_ASSERT_EQUAL_INT(cmac_init(&ctx, CMAC_KEY, 16), CIPHER_INIT_SUCCESS); + TEST_ASSERT_EQUAL_INT(aes128_cmac_init(&ctx, AES128_CMAC_KEY, 15), + CIPHER_ERR_INVALID_KEY_SIZE); + TEST_ASSERT_EQUAL_INT(aes128_cmac_init(&ctx, AES128_CMAC_KEY, 16), + CIPHER_INIT_SUCCESS); } Test *tests_hashes_cmac_tests(void) From 84e3ace6e38b147906616fa6a620d03215312cbf Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 31 Aug 2022 10:42:44 +0200 Subject: [PATCH 4/4] gnrc_lorawan_crypto: fix Vera++ errors --- sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c index 738d810942..9cb5ae015c 100644 --- a/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c +++ b/sys/net/gnrc/link_layer/lorawan/gnrc_lorawan_crypto.c @@ -35,7 +35,7 @@ static aes128_cmac_context_t CmacContext; static uint8_t digest[LORAMAC_APPKEY_LEN]; static cipher_t AesContext; -typedef struct __attribute__((packed)) { +typedef struct __attribute__((packed)) { uint8_t fb; uint32_t u8_pad; uint8_t dir;