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/psa_crypto: Add generic HMAC implementation #20758

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
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
106 changes: 97 additions & 9 deletions sys/include/psa_crypto/psa/crypto_sizes.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,35 @@
* the features chosen at compile-time. They should not be
* changed manually.
*/
#if (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \
IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) || \
IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \
IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256))
#if (IS_USED(MODULE_PSA_MAC_HMAC_SHA_512) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_512))
#define CONFIG_PSA_MAX_KEY_SIZE 64
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_384) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_384))
#define CONFIG_PSA_MAX_KEY_SIZE 48
#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \
IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) || \
IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_256) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_256) || \
IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256))
#define CONFIG_PSA_MAX_KEY_SIZE 32
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_224) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_224) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_224))
#define CONFIG_PSA_MAX_KEY_SIZE 28
#elif (IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || \
IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1))
#define CONFIG_PSA_MAX_KEY_SIZE 24
#elif (IS_USED(MODULE_PSA_CIPHER_AES_128_CBC)) || \
(IS_USED(MODULE_PSA_CIPHER_AES_128_ECB))
#elif (IS_USED(MODULE_PSA_MAC_HMAC_RIPEMD160) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_1))
#define CONFIG_PSA_MAX_KEY_SIZE 20
#elif (IS_USED(MODULE_PSA_CIPHER_AES_128_CBC) || \
IS_USED(MODULE_PSA_CIPHER_AES_128_ECB) || \
IS_USED(MODULE_PSA_MAC_HMAC_MD2) || \
IS_USED(MODULE_PSA_MAC_HMAC_MD4) || \
IS_USED(MODULE_PSA_MAC_HMAC_MD5))
#define CONFIG_PSA_MAX_KEY_SIZE 16
#else
#define CONFIG_PSA_MAX_KEY_SIZE 0
Expand Down Expand Up @@ -367,7 +385,24 @@
* recognized, return 0. An implementation can return either 0 or the correct size for a
* hash algorithm that it recognizes, but does not support.
*/
#define PSA_HASH_BLOCK_LENGTH(alg) /* implementation-defined value */
#define PSA_HASH_BLOCK_LENGTH(alg) \
( \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 128 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 128 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 128 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 128 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 144 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 136 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 104 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 72 : \
0)

/**
* @brief The size of the output of @ref psa_hash_compute() and @ref psa_hash_finish(), in bytes.
Expand Down Expand Up @@ -439,7 +474,60 @@
*
* See also @ref PSA_MAC_LENGTH().
*/
#define PSA_MAC_MAX_SIZE (PSA_HASH_MAX_SIZE)
#if (IS_USED(MODULE_PSA_MAC_HMAC_SHA_512) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_512))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_512)) /* 64 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_384) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_384))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_384)) /* 48 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_256) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_256))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_256)) /* 32 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_224) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_224) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_224))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_224)) /* 28 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_RIPEMD160) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_1))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA_1)) /* 20 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_MD2) || \
IS_USED(MODULE_PSA_MAC_HMAC_MD4) || \
IS_USED(MODULE_PSA_MAC_HMAC_MD5))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_MD5)) /* 16 */
#else
#define PSA_MAC_MAX_SIZE 0
#endif

/**
* @brief A sufficient buffer size for storing the HMAC hash input. This is usually
the maximum block length of the supported HMAC hash algorithms.
*/
#if (IS_USED(MODULE_PSA_MAC_HMAC_SHA3_224))
#define PSA_HMAC_BLOCK_MAX_SIZE (PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA3_224)) /* 144 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA3_256))
#define PSA_HMAC_BLOCK_MAX_SIZE (PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA3_256)) /* 136 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_384) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_224) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_256))
#define PSA_HMAC_BLOCK_MAX_SIZE (PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_512_256)) /* 128 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA3_384))
#define PSA_HMAC_BLOCK_MAX_SIZE (PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA3_384)) /* 104 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA3_512))
#define PSA_HMAC_BLOCK_MAX_SIZE (PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA3_512)) /* 72 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_MD4) || \
IS_USED(MODULE_PSA_MAC_HMAC_MD5) || \
IS_USED(MODULE_PSA_MAC_HMAC_RIPEMD160) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_1) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_224) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_256))
#define PSA_HMAC_BLOCK_MAX_SIZE (PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_256)) /* 64 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_MD2))
#define PSA_HMAC_BLOCK_MAX_SIZE (PSA_HASH_BLOCK_LENGTH(PSA_ALG_MD2)) /* 16 */
#else
#define PSA_HMAC_BLOCK_MAX_SIZE 0
#endif

/**
* @brief The block size of a block cipher.
Expand Down Expand Up @@ -802,7 +890,7 @@
#define PSA_KEY_EXPORT_ECC_KEY_MAX_SIZE(key_type, key_bits) \
(size_t)\
(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 32 : \
(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_SECP_R1 ? PSA_BITS_TO_BYTES(key_bits) : \

Check warning on line 893 in sys/include/psa_crypto/psa/crypto_sizes.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
0))

/**
Expand Down Expand Up @@ -842,7 +930,7 @@
* Unspecified if the parameters are not valid.
*/
#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \
(PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type) ? PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) : \

Check warning on line 933 in sys/include/psa_crypto/psa/crypto_sizes.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
(PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_KEY_MAX_SIZE(key_type, key_bits) : \
0))

Expand Down
10 changes: 6 additions & 4 deletions sys/include/psa_crypto/psa/crypto_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,14 @@ static inline struct psa_hash_operation_s psa_hash_operation_init(void)
#define PSA_MAC_OPERATION_INIT { 0 }

/**
* @brief Structure storing a MAC operation context
*
* @note Not yet implemented
* @brief Structure storing a MAC operation context.
*/
struct psa_mac_operation_s {
int dummy; /**< Not yet implemented */
psa_algorithm_t alg; /**< Operation algorithm*/
#if IS_USED(MODULE_PSA_RIOT_MAC_HMAC_GENERIC)
psa_hash_operation_t hash; /**< Hash context*/
uint8_t block[PSA_HMAC_BLOCK_MAX_SIZE]; /**< Block buffer*/
#endif
};

/**
Expand Down
82 changes: 68 additions & 14 deletions sys/psa_crypto/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -334,28 +334,82 @@ ifneq (,$(filter psa_mac,$(USEMODULE)))
USEMODULE += psa_key_management
endif

# HMAC MD5
ifneq (,$(filter psa_mac_hmac_md5,$(USEMODULE)))
ifeq (,$(filter psa_mac_hmac_md5_custom_backend,$(USEMODULE)))
USEMODULE += psa_mac_hmac_md5_backend_generic
endif
endif

ifneq (,$(filter psa_mac_hmac_md5_backend_generic,$(USEMODULE)))
USEMODULE += psa_hash
USEMODULE += psa_hash_md5
USEMODULE += psa_riot_mac_hmac_generic
endif

# HMAC SHA-1
ifneq (,$(filter psa_mac_hmac_sha_1,$(USEMODULE)))
ifeq (,$(filter psa_mac_hmac_sha_1_custom_backend,$(USEMODULE)))
USEMODULE += psa_mac_hmac_sha_1_backend_generic
endif
endif

ifneq (,$(filter psa_mac_hmac_sha_1_backend_generic,$(USEMODULE)))
USEMODULE += psa_hash
USEMODULE += psa_hash_sha_1
USEMODULE += psa_riot_mac_hmac_generic
endif

# HMAC SHA-224
ifneq (,$(filter psa_mac_hmac_sha_224,$(USEMODULE)))
ifeq (,$(filter psa_mac_hmac_sha_224_custom_backend,$(USEMODULE)))
USEMODULE += psa_mac_hmac_sha_224_backend_generic
endif
endif

ifneq (,$(filter psa_mac_hmac_sha_224_backend_generic,$(USEMODULE)))
USEMODULE += psa_hash
USEMODULE += psa_hash_sha_224
USEMODULE += psa_riot_mac_hmac_generic
endif

## HMAC SHA-256
ifneq (,$(filter psa_mac_hmac_sha_256,$(USEMODULE)))
ifeq (,$(filter psa_mac_hmac_sha_256_custom_backend,$(USEMODULE)))
FEATURES_OPTIONAL += periph_hmac_sha_256
include $(RIOTMAKE)/features_check.inc.mk
# HACK: Due to kconfig migration, may cause problems
ifneq (,$(filter periph_hmac_sha_256,$(FEATURES_USED)))
USEMODULE += psa_mac_hmac_sha_256_backend_periph
else
USEMODULE += psa_mac_hmac_sha_256_backend_riot
endif
USEMODULE += psa_mac_hmac_sha_256_backend_generic
endif
endif

ifneq (,$(filter psa_mac_hmac_sha_256_backend_periph,$(USEMODULE)))
FEATURES_REQUIRED += periph_hmac_sha_256
ifneq (,$(filter psa_mac_hmac_sha_256_backend_generic,$(USEMODULE)))
USEMODULE += psa_hash
USEMODULE += psa_hash_sha_256
USEMODULE += psa_riot_mac_hmac_generic
endif

ifneq (,$(filter psa_mac_hmac_sha_256_backend_riot,$(USEMODULE)))
USEMODULE += hashes
USEMODULE += psa_riot_hashes
USEMODULE += psa_riot_hashes_hmac_sha256
# HMAC SHA-384
ifneq (,$(filter psa_mac_hmac_sha_384,$(USEMODULE)))
ifeq (,$(filter psa_mac_hmac_sha_384_custom_backend,$(USEMODULE)))
USEMODULE += psa_mac_hmac_sha_384_backend_generic
endif
endif

ifneq (,$(filter psa_mac_hmac_sha_384_backend_generic,$(USEMODULE)))
USEMODULE += psa_hash
USEMODULE += psa_hash_sha_384
USEMODULE += psa_riot_mac_hmac_generic
endif

# HMAC SHA-512
ifneq (,$(filter psa_mac_hmac_sha_512,$(USEMODULE)))
ifeq (,$(filter psa_mac_hmac_sha_512_custom_backend,$(USEMODULE)))
USEMODULE += psa_mac_hmac_sha_512_backend_generic
endif
endif

ifneq (,$(filter psa_mac_hmac_sha_512_backend_generic,$(USEMODULE)))
USEMODULE += psa_hash
USEMODULE += psa_hash_sha_512
USEMODULE += psa_riot_mac_hmac_generic
endif

# Secure Elements
Expand Down
60 changes: 58 additions & 2 deletions sys/psa_crypto/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,41 @@ PSEUDOMODULES += psa_key_management

## MAC
PSEUDOMODULES += psa_mac
PSEUDOMODULES += psa_mac_hmac_md5
PSEUDOMODULES += psa_mac_hmac_md5_backend_generic
PSEUDOMODULES += psa_mac_hmac_md5_custom_backend

# check that one and only one backend has been selected
ifneq (,$(filter psa_mac_hmac_md5,$(USEMODULE)))
ifneq (1,$(call backends,psa_mac_hmac_md5))
$(error "One (and only one) backend should be selected for psa_mac_hmac_md5")
endif
endif

PSEUDOMODULES += psa_mac_hmac_sha_1
PSEUDOMODULES += psa_mac_hmac_sha_1_backend_generic
PSEUDOMODULES += psa_mac_hmac_sha_1_custom_backend

# check that one and only one backend has been selected
ifneq (,$(filter psa_mac_hmac_sha_1,$(USEMODULE)))
ifneq (1,$(call backends,psa_mac_hmac_sha_1))
$(error "One (and only one) backend should be selected for psa_mac_hmac_sha_1")
endif
endif

PSEUDOMODULES += psa_mac_hmac_sha_224
PSEUDOMODULES += psa_mac_hmac_sha_224_backend_generic
PSEUDOMODULES += psa_mac_hmac_sha_224_custom_backend

# check that one and only one backend has been selected
ifneq (,$(filter psa_mac_hmac_sha_224,$(USEMODULE)))
ifneq (1,$(call backends,psa_mac_hmac_sha_224))
$(error "One (and only one) backend should be selected for psa_mac_hmac_sha_224")
endif
endif

PSEUDOMODULES += psa_mac_hmac_sha_256
PSEUDOMODULES += psa_mac_hmac_sha_256_backend_periph
PSEUDOMODULES += psa_mac_hmac_sha_256_backend_riot
PSEUDOMODULES += psa_mac_hmac_sha_256_backend_generic
PSEUDOMODULES += psa_mac_hmac_sha_256_custom_backend

# check that one and only one backend has been selected
Expand All @@ -199,6 +231,30 @@ ifneq (,$(filter psa_mac_hmac_sha_256,$(USEMODULE)))
endif
endif

PSEUDOMODULES += psa_mac_hmac_sha_384
PSEUDOMODULES += psa_mac_hmac_sha_384_backend_generic
PSEUDOMODULES += psa_mac_hmac_sha_384_custom_backend

# check that one and only one backend has been selected
ifneq (,$(filter psa_mac_hmac_sha_384,$(USEMODULE)))
ifneq (1,$(call backends,psa_mac_hmac_sha_384))
$(error "One (and only one) backend should be selected for psa_mac_hmac_sha_384")
endif
endif

PSEUDOMODULES += psa_mac_hmac_sha_512
PSEUDOMODULES += psa_mac_hmac_sha_512_backend_generic
PSEUDOMODULES += psa_mac_hmac_sha_512_custom_backend

# check that one and only one backend has been selected
ifneq (,$(filter psa_mac_hmac_sha_512,$(USEMODULE)))
ifneq (1,$(call backends,psa_mac_hmac_sha_512))
$(error "One (and only one) backend should be selected for psa_mac_hmac_sha_512")
endif
endif

PSEUDOMODULES += psa_riot_mac_hmac_generic

## Secure Elements
PSEUDOMODULES += psa_secure_element
PSEUDOMODULES += psa_secure_element_config
Expand Down
43 changes: 41 additions & 2 deletions sys/psa_crypto/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,35 @@
* ### MAC
* - Base: psa_mac
*
* #### HMAC MD5
* - psa_mac_hmac_md5
* - psa_mac_hmac_md5_custom_backend
* - psa_mac_hmac_md5_backend_generic
*
* #### HMAC SHA 1
* - psa_mac_hmac_sha_1
* - psa_mac_hmac_sha_1_custom_backend
* - psa_mac_hmac_sha_1_backend_generic
*
* #### HMAC SHA 224
* - psa_mac_hmac_sha_224
* - psa_mac_hmac_sha_224_custom_backend
* - psa_mac_hmac_sha_224_backend_generic
*
* #### HMAC SHA 256
* - psa_mac_hmac_sha_256
* - psa_mac_hmac_sha_256_backend_periph
* - psa_mac_hmac_sha_256_custom_backend
* - psa_mac_hmac_sha_256_backend_riot
* - psa_mac_hmac_sha_256_backend_generic
*
* #### HMAC SHA 384
* - psa_mac_hmac_sha_384
* - psa_mac_hmac_sha_384_custom_backend
* - psa_mac_hmac_sha_384_backend_generic
*
* #### HMAC SHA 512
* - psa_mac_hmac_sha_512
* - psa_mac_hmac_sha_512_custom_backend
* - psa_mac_hmac_sha_512_backend_generic
*
* ### Secure Elements
* Base:
Expand All @@ -361,6 +385,21 @@
* Currently uses the [RIOT Random Module](#sys_random) as a backend.
* See the documentation for configuration options.
*
* Generic HMAC implementation
* ===
Wer-Wolf marked this conversation as resolved.
Show resolved Hide resolved
* RIOT features a generic HMAC implementation which works with all hash algorithms supported
* by the PSA crypto API. This minimizes the amount of work necessary to add support for new
* HMAC algorithms.
*
* The following steps are required to add support for a new HMAC algorithm:
*
* 1. Add support for the hash algorithm to the PSA crypto library.
* 2. Extend `PSA_MAC_MAX_SIZE` and `PSA_HMAC_BLOCK_MAX_SIZE` to take new algorithm into account.
* 3. Update `CONFIG_PSA_MAX_KEY_SIZE` in `crypto_sizes.h` to be big enough for the new algorithm.
* 4. Update `sys/psa_crypto/Makefile.dep` (usually just copy from an existing HMAC algorithm).
* 5. Update `sys/psa_crypto/Makefile.include` the same way.
* 6. Document the new modules and extend any HMAC unit tests.
*
* Secure Elements {#secure-elements}
* ===
*
Expand Down
Loading
Loading