Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys/crypto: Enable support for AES-192, AES-256 #16183

Merged
merged 5 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ PSEUDOMODULES += core_%
PSEUDOMODULES += cortexm_fpu
PSEUDOMODULES += cortexm_svc
PSEUDOMODULES += cpu_check_address
PSEUDOMODULES += crypto_% # crypto_aes or crypto_3des
PSEUDOMODULES += dbgpin
PSEUDOMODULES += devfs_%
PSEUDOMODULES += dhcpv6_%
Expand Down Expand Up @@ -306,6 +305,9 @@ PSEUDOMODULES += skald_eddystone
# define optimized read function of DS18 driver as a pseudo module
PSEUDOMODULES += ds18_optimized

PSEUDOMODULES += crypto_aes_128
leandrolanzieri marked this conversation as resolved.
Show resolved Hide resolved
leandrolanzieri marked this conversation as resolved.
Show resolved Hide resolved
PSEUDOMODULES += crypto_aes_192
PSEUDOMODULES += crypto_aes_256
# By using this pseudomodule, T tables will be precalculated.
PSEUDOMODULES += crypto_aes_precalculated
# This pseudomodule causes a loop in AES to be unrolled (more flash, less CPU)
Expand Down
1 change: 0 additions & 1 deletion pkg/openwsn/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ ifneq (,$(filter openwsn_coap,$(USEMODULE)))
endif

ifneq (,$(filter openwsn_crypto,$(USEMODULE)))
USEMODULE += crypto_3des
USEMODULE += cipher_modes
endif

Expand Down
6 changes: 3 additions & 3 deletions pkg/openwsn/contrib/cryptoengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ owerror_t cryptoengine_aes_ccms_enc(uint8_t *a, uint8_t len_a, uint8_t *m,
int ret, len;
uint8_t tmp_buff[MAX_MESSAGE_LEN + CCM_MAC_MAX_LEN];

ret = cipher_init(&cipher, CIPHER_AES_128, key, CCM_BLOCK_SIZE);
ret = cipher_init(&cipher, CIPHER_AES, key, CCM_BLOCK_SIZE);

if (ret != 1) {
return E_FAIL;
Expand All @@ -64,7 +64,7 @@ owerror_t cryptoengine_aes_ccms_dec(uint8_t *a, uint8_t len_a, uint8_t *m,
int ret, len;
uint8_t tmp_buff[MAX_MESSAGE_LEN];

ret = cipher_init(&cipher, CIPHER_AES_128, key, CCM_BLOCK_SIZE);
ret = cipher_init(&cipher, CIPHER_AES, key, CCM_BLOCK_SIZE);

if (ret != 1) {
return E_FAIL;
Expand All @@ -88,7 +88,7 @@ owerror_t cryptoengine_aes_ecb_enc(uint8_t *buffer, uint8_t *key)
cipher_t cipher;
int ret, len;

ret = cipher_init(&cipher, CIPHER_AES_128, key, CCM_BLOCK_SIZE);
ret = cipher_init(&cipher, CIPHER_AES, key, CCM_BLOCK_SIZE);

if (ret != 1) {
return E_FAIL;
Expand Down
2 changes: 1 addition & 1 deletion pkg/semtech-loramac/Makefile.dep
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
USEMODULE += random
USEMODULE += hashes
USEMODULE += crypto_aes
USEMODULE += crypto_aes_128

USEMODULE += semtech_loramac_contrib
USEMODULE += semtech_loramac_mac
Expand Down
14 changes: 9 additions & 5 deletions sys/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,29 @@ ifneq (,$(filter i2c_scan,$(USEMODULE)))
endif

ifneq (,$(filter prng_fortuna,$(USEMODULE)))
USEMODULE += crypto_aes
USEMODULE += crypto_aes_128
endif

ifneq (,$(filter crypto_aes_%,$(USEMODULE)))
USEMODULE += crypto_aes
ifneq (,$(filter crypto_%,$(USEMODULE)))
USEMODULE += crypto
endif

ifneq (,$(filter crypto_%,$(USEMODULE)))
ifneq (,$(filter cipher_modes,$(USEMODULE)))
USEMODULE += crypto
endif

ifneq (,$(filter crypto,$(USEMODULE)))
DEFAULT_MODULE += crypto_aes_128
endif

ifneq (,$(filter sys_bus_%,$(USEMODULE)))
USEMODULE += sys_bus
USEMODULE += core_msg_bus
endif

ifneq (,$(filter ieee802154_security,$(USEMODULE)))
USEMODULE += crypto
USEMODULE += crypto_aes
USEMODULE += crypto_aes_128
USEMODULE += cipher_modes
endif

Expand Down
33 changes: 12 additions & 21 deletions sys/crypto/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,23 @@
# directory for more details.
#

menu "Crypto"

config MODULE_CRYPTO
bool "Common cryptographic functionalities"
menuconfig MODULE_CRYPTO
bool "Crypto"
depends on TEST_KCONFIG

choice
bool "Crypto block ciphers API implementation"
optional
depends on TEST_KCONFIG
help
The common Crypto block ciphers API has multiple implementations. Choose
one of the following.
if MODULE_CRYPTO

config MODULE_CRYPTO_AES
bool "AES"
select MODULE_CRYPTO
menu "Crypto AES options"

config MODULE_CRYPTO_3DES
bool "3DES (deprecated)"
select MODULE_CRYPTO
config MODULE_CRYPTO_AES_128
bool "AES-128"
default y

endchoice
config MODULE_CRYPTO_AES_192
bool "AES-192"

menu "Crypto AES options"
depends on MODULE_CRYPTO_AES
config MODULE_CRYPTO_AES_256
bool "AES-256"

config MODULE_CRYPTO_AES_PRECALCULATED
bool "Pre-calculate T tables"
Expand All @@ -44,4 +35,4 @@ endmenu # Crypto AES options

rsource "modes/Kconfig"

endmenu # Crypto
endif # Crypto
45 changes: 39 additions & 6 deletions sys/crypto/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@
#include <stdint.h>
#include "crypto/aes.h"
#include "crypto/ciphers.h"
#include "kernel_defines.h"

#if !IS_USED(MODULE_CRYPTO_AES_128) && !IS_USED(MODULE_CRYPTO_AES_192) && \
!IS_USED(MODULE_CRYPTO_AES_256)
#error "sys/crypto/aes: No aes module used."
#endif

/**
* @brief AES key size used
*/
#if IS_USED(MODULE_CRYPTO_AES_128) && !IS_USED(MODULE_CRYPTO_AES_192) && \
!IS_USED(MODULE_CRYPTO_AES_256)
# define AES_KEY_SIZE(ctx) AES_KEY_SIZE_128
#elif !IS_USED(MODULE_CRYPTO_AES_128) && IS_USED(MODULE_CRYPTO_AES_192) && \
!IS_USED(MODULE_CRYPTO_AES_256)
# define AES_KEY_SIZE(ctx) AES_KEY_SIZE_192
#elif !IS_USED(MODULE_CRYPTO_AES_128) && !IS_USED(MODULE_CRYPTO_AES_192) && \
IS_USED(MODULE_CRYPTO_AES_256)
# define AES_KEY_SIZE(ctx) AES_KEY_SIZE_256
#else
# define AES_KEY_SIZE(ctx) ctx->key_size
#endif

/**
* Interface to the aes cipher
Expand All @@ -49,7 +71,9 @@ static const cipher_interface_t aes_interface = {
aes_encrypt,
aes_decrypt
};

const cipher_id_t CIPHER_AES_128 = &aes_interface;
const cipher_id_t CIPHER_AES = &aes_interface;
leandrolanzieri marked this conversation as resolved.
Show resolved Hide resolved

static const u32 Te0[256] = {
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
Expand Down Expand Up @@ -794,19 +818,26 @@ static const u32 rcon[] = {
0x1B000000, 0x36000000,
};


int aes_init(cipher_context_t *context, const uint8_t *key, uint8_t keySize)
{
uint8_t i;

/* This implementation only supports a single key size (defined in AES_KEY_SIZE) */
if (keySize != AES_KEY_SIZE) {
if (keySize != AES_KEY_SIZE_128 && keySize != AES_KEY_SIZE_192 &&
keySize != AES_KEY_SIZE_256) {
return CIPHER_ERR_INVALID_KEY_SIZE;
}

if ((keySize == AES_KEY_SIZE_128 && !IS_USED(MODULE_CRYPTO_AES_128)) ||
(keySize == AES_KEY_SIZE_192 && !IS_USED(MODULE_CRYPTO_AES_192)) ||
(keySize == AES_KEY_SIZE_256 && !IS_USED(MODULE_CRYPTO_AES_256))) {
return CIPHER_ERR_INVALID_KEY_SIZE;
}

context->key_size = keySize;

/* Make sure that context is large enough. If this is not the case,
you should build with -DAES */
if (CIPHER_MAX_CONTEXT_SIZE < AES_KEY_SIZE) {
if (CIPHER_MAX_CONTEXT_SIZE < keySize) {
return CIPHER_ERR_BAD_CONTEXT_SIZE;
}

Expand Down Expand Up @@ -1036,13 +1067,14 @@ int aes_encrypt(const cipher_context_t *context, const uint8_t *plainBlock,
const AES_KEY *key = &aeskey;

res = aes_set_encrypt_key((unsigned char *)context->context,
AES_KEY_SIZE * 8, &aeskey);
AES_KEY_SIZE(context) * 8, &aeskey);
if (res < 0) {
return res;
}

const u32 *rk;
u32 s0, s1, s2, s3, t0, t1, t2, t3;

#ifndef MODULE_CRYPTO_AES_UNROLL
int r;
#endif /* ?MODULE_CRYPTO_AES_UNROLL */
Expand Down Expand Up @@ -1304,14 +1336,15 @@ int aes_decrypt(const cipher_context_t *context, const uint8_t *cipherBlock,
const AES_KEY *key = &aeskey;

res = aes_set_decrypt_key((unsigned char *)context->context,
AES_KEY_SIZE * 8, &aeskey);
AES_KEY_SIZE(context) * 8, &aeskey);

if (res < 0) {
return res;
}

const u32 *rk;
u32 s0, s1, s2, s3, t0, t1, t2, t3;

#ifndef MODULE_CRYPTO_AES_UNROLL
int r;
#endif /* ?MODULE_CRYPTO_AES_UNROLL */
Expand Down
9 changes: 4 additions & 5 deletions sys/crypto/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@
* @section ciphers Ciphers
*
* RIOT supports the following block ciphers:
* * AES-128
* * 3DES (deprecated)
* * AES-128, AES-192, AES-256
* * NULL
*
* You can use them directly by adding `crypto_aes` or `crypto_3des` to your
* USEMODULE-List.
* You can use them directly by adding `crypto_aes_128`, `crypto_aes_192` or
* `crypto_aes_256` to your USEMODULE-List.
* While you can use the ciphers functions directly, you should resort to
* the generic API for block ciphers whenever possible.
*
Expand All @@ -37,7 +36,7 @@
* plain_text[AES_BLOCK_SIZE] = {0},
* cipher_text[AES_BLOCK_SIZE] = {0};
*
* if (cipher_init(&cipher, CIPHER_AES_128, key, AES_KEY_SIZE) < 0)
* if (cipher_init(&cipher, CIPHER_AES, key, AES_KEY_SIZE) < 0)
* printf("Cipher init failed!\n");
*
* if (cipher_encrypt(&cipher, plain_text, cipher_text) < 0)
Expand Down
2 changes: 1 addition & 1 deletion sys/hashes/cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ int cmac_init(cmac_context_t *ctx, const uint8_t *key, uint8_t key_size)
}

memset(ctx, 0, sizeof(cmac_context_t));
return cipher_init(&(ctx->aes_ctx), CIPHER_AES_128, key, key_size);
return cipher_init(&(ctx->aes_ctx), CIPHER_AES, key, key_size);
}

void cmac_update(cmac_context_t *ctx, const void *data, size_t len)
Expand Down
24 changes: 19 additions & 5 deletions sys/include/crypto/aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
* @file
* @brief Headers for the implementation of the AES cipher-algorithm
*
* The default key size is 128 bits. To use a different key size add
* USEMODULE += crypto_aes_192 and/or USEMODULE += crypto_aes_256 to
* your Makefile.
*
* If only one key size is needed and that key size is not 128 bits, the 128 bit
* key size can be disabled with DISABLE_MODULE += crypto_aes_128 as an
* optimization.
*
* @author Freie Universitaet Berlin, Computer Systems & Telematics
* @author Nicolai Schmittberger <[email protected]>
* @author Fabrice Bellard
Expand Down Expand Up @@ -46,20 +54,26 @@ typedef uint8_t u8;

#define AES_MAXNR 14
#define AES_BLOCK_SIZE 16
#define AES_KEY_SIZE 16

/**
* @name AES key sizes
* @{
*/
leandrolanzieri marked this conversation as resolved.
Show resolved Hide resolved
#define AES_KEY_SIZE_128 16
#define AES_KEY_SIZE_192 24
#define AES_KEY_SIZE_256 32
/** @} */

/**
* @brief AES key
* @see cipher_context_t
*/
struct aes_key_st {
typedef struct aes_key_st {
/** @cond INTERNAL */
uint32_t rd_key[4 * (AES_MAXNR + 1)];
int rounds;
/** @endcond */
};

typedef struct aes_key_st AES_KEY;
} AES_KEY;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not?

Suggested change
} AES_KEY;
} aes_key_t;


/**
* @brief the cipher_context_t-struct adapted for AES
Expand Down
Loading