1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-24 22:13:52 +01:00

sys/psa_crypto: add aead aes ccm

This commit is contained in:
Lukas-Luger 2025-04-25 13:58:17 +02:00
parent 0a9c351bfa
commit ea04f0b1c4
11 changed files with 717 additions and 62 deletions

View File

@ -62,13 +62,16 @@ extern "C" {
#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_AEAD_AES_256_CCM) || \
IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256) || \
IS_USED(MODULE_PSA_CIPHER_CHACHA20))
#define CONFIG_PSA_MAX_KEY_SIZE 32
#elif (IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || \
IS_USED(MODULE_PSA_AEAD_AES_192_CCM) || \
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_AEAD_AES_128_CCM)) || \
(IS_USED(MODULE_PSA_CIPHER_AES_128_ECB))
#define CONFIG_PSA_MAX_KEY_SIZE 16
#else
@ -124,6 +127,52 @@ extern "C" {
#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \
/* implementation-defined value */
/**
* @brief The length of a tag for an AEAD algorithm, in bytes.
*
* @details This is the size of the tag output from @ref psa_aead_finish().
* If the size of the tag buffer is at least this large, it is guaranteed that
* @ref psa_aead_finish() will not fail due to an insufficient tag buffer size.
*
* See also @ref PSA_AEAD_TAG_MAX_SIZE.
*
* @param key_type The type of the AEAD key.
* @param key_bits The size of the AEAD key in bits.
* @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that
* @ref PSA_ALG_IS_AEAD(@p alg) is true.
*
* @return The tag length for the specified algorithm and key.
* 0 if the AEAD algorithm does not have an identified tag that can be distinguished from
* the rest of the ciphertext.
* 0 if the AEAD algorithm is not recognized or not supported.
*/
#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg) \
(PSA_ALG_IS_AEAD(alg) ? \
(((alg) & 0x003f0000) >> 16) : \
((void) (key_type), (void) (key_bits), 0))
/**
* @brief A sufficient buffer size for storing the tag output by @ref psa_aead_finish(),
* for any of the supported key types and AEAD algorithms.
*
* @details If the size of the tag buffer is at least this large, it is guaranteed that
* @ref psa_aead_finish() will not fail due to an insufficient buffer size.
*
* See also @ref PSA_AEAD_TAG_LENGTH().
*/
#define PSA_AEAD_TAG_MAX_SIZE (16)
/**
* @brief A sufficient buffer size for storing the tag output by @ref psa_aead_finish(),
* for AES key types and CCM algorithms.
*
* @details If the size of the tag buffer is at least this large, it is guaranteed that
* @ref psa_aead_finish() will not fail due to an insufficient buffer size.
*
* See also @ref PSA_AEAD_TAG_LENGTH().
*/
#define PSA_AES_CCM_TAG_MAX_SIZE (16)
/**
* @brief A sufficient plaintext buffer size for @ref psa_aead_decrypt(), in bytes.
*
@ -143,7 +192,9 @@ extern "C" {
* are incompatible.
*/
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \
/* implementation-defined value */
(PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \
((ciphertext_length) > PSA_AEAD_TAG_LENGTH(key_type, 0, alg)) ? \
(ciphertext_length) - PSA_AEAD_TAG_LENGTH(key_type, 0, alg) : 0)
/**
* @brief A sufficient ciphertext buffer size for @ref psa_aead_encrypt(),
@ -158,7 +209,7 @@ extern "C" {
* @param plaintext_length Size of the plaintext in bytes.
*/
#define PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(plaintext_length) \
/* implementation-defined value */
((plaintext_length) + PSA_AEAD_TAG_MAX_SIZE)
/**
* @brief A sufficient ciphertext buffer size for @ref psa_aead_encrypt(), in bytes.
@ -179,7 +230,8 @@ extern "C" {
* are incompatible.
*/
#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext_length) \
/* implementation-defined value */
(PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \
(plaintext_length) + PSA_AEAD_TAG_LENGTH(key_type, 0, alg) : 0)
/**
* @brief A sufficient ciphertext buffer size for @ref psa_aead_finish(),
@ -232,7 +284,13 @@ extern "C" {
* 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters
* are incompatible.
*/
#define PSA_AEAD_NONCE_LENGTH(key_type, alg) /* implementation-defined value */
#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \
((PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) == 16 && \
((PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CCM) || \
(PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CCM))) || \
(key_type == PSA_KEY_TYPE_CHACHA20 && \
PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CHACHA20_POLY1305) ? \
12 : 0)
/**
* @brief A sufficient buffer size for storing the nonce generated by
@ -243,40 +301,7 @@ extern "C" {
*
* See also @ref PSA_AEAD_NONCE_LENGTH().
*/
#define PSA_AEAD_NONCE_MAX_SIZE /* implementation-defined value */
/**
* @brief The length of a tag for an AEAD algorithm, in bytes.
*
* @details This is the size of the tag output from @ref psa_aead_finish().
* If the size of the tag buffer is at least this large, it is guaranteed that
* @ref psa_aead_finish() will not fail due to an insufficient tag buffer size.
*
* See also @ref PSA_AEAD_TAG_MAX_SIZE.
*
* @param key_type The type of the AEAD key.
* @param key_bits The size of the AEAD key in bits.
* @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that
* @ref PSA_ALG_IS_AEAD(@p alg) is true.
*
* @return The tag length for the specified algorithm and key.
* 0 if the AEAD algorithm does not have an identified tag that can be distinguished from
* the rest of the ciphertext.
* 0 if the AEAD algorithm is not recognized or not supported.
*/
#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg) \
/* implementation-defined value */
/**
* @brief A sufficient buffer size for storing the tag output by @ref psa_aead_finish(),
* for any of the supported key types and AEAD algorithms.
*
* @details If the size of the tag buffer is at least this large, it is guaranteed that
* @ref psa_aead_finish() will not fail due to an insufficient buffer size.
*
* See also @ref PSA_AEAD_TAG_LENGTH().
*/
#define PSA_AEAD_TAG_MAX_SIZE /* implementation-defined value */
#define PSA_AEAD_NONCE_MAX_SIZE (13)
/**
* @brief A sufficient output buffer size for @ref psa_aead_update(), for any of the supported key

View File

@ -143,6 +143,75 @@ ifneq (,$(filter psa_cipher_aes_192_cbc_backend_riot,$(USEMODULE)))
USEMODULE += psa_riot_cipher_aes_192_cbc
endif
# AEAD
ifneq (,$(filter psa_aead,$(USEMODULE)))
USEMODULE += psa_key_management
endif
## AES-128-CCM
ifneq (,$(filter psa_aead_aes_128_ccm,$(USEMODULE)))
ifeq (,$(filter psa_aead_aes_128_ccm_custom_backend,$(USEMODULE)))
FEATURES_OPTIONAL += periph_aead_aes_128_ccm
include $(RIOTMAKE)/features_check.inc.mk
# HACK: Due to kconfig migration, may cause problems
ifneq (,$(filter periph_aead_aes_128_ccm,$(FEATURES_USED)))
USEMODULE += psa_aead_aes_128_ccm_backend_periph
else
USEMODULE += psa_aead_aes_128_ccm_backend_cifra
endif
endif
endif
ifneq (,$(filter psa_aead_aes_128_ccm_backend_periph,$(USEMODULE)))
FEATURES_REQUIRED += periph_aead_aes_128_ccm
endif
ifneq (,$(filter psa_aead_aes_128_ccm_backend_tinycrypt,$(USEMODULE)))
USEPKG += tinycrypt
USEMODULE += psa_tinycrypt
USEMODULE += psa_tinycrypt_aes_ccm
endif
## AES-192-CCM
ifneq (,$(filter psa_aead_aes_192_ccm,$(USEMODULE)))
ifeq (,$(filter psa_aead_aes_192_ccm_custom_backend,$(USEMODULE)))
FEATURES_OPTIONAL += periph_aead_aes_192_ccm
include $(RIOTMAKE)/features_check.inc.mk
# HACK: Due to kconfig migration, may cause problems
ifneq (,$(filter periph_aead_aes_192_ccm,$(FEATURES_USED)))
USEMODULE += psa_aead_aes_192_ccm_backend_periph
else
USEMODULE += psa_aead_aes_192_ccm_backend_cifra
endif
endif
endif
ifneq (,$(filter psa_aead_aes_192_ccm_backend_periph,$(USEMODULE)))
FEATURES_REQUIRED += periph_aead_aes_192_ccm
endif
## AES-256-CCM
ifneq (,$(filter psa_aead_aes_256_ccm,$(USEMODULE)))
ifeq (,$(filter psa_aead_aes_256_ccm_custom_backend,$(USEMODULE)))
FEATURES_OPTIONAL += periph_aead_aes_256_ccm
include $(RIOTMAKE)/features_check.inc.mk
# HACK: Due to kconfig migration, may cause problems
ifneq (,$(filter periph_aead_aes_256_ccm,$(FEATURES_USED)))
USEMODULE += psa_aead_aes_256_ccm_backend_periph
else
USEMODULE += psa_aead_aes_256_ccm_backend_cifra
endif
endif
endif
ifneq (,$(filter psa_aead_aes_256_ccm_backend_periph,$(USEMODULE)))
FEATURES_REQUIRED += periph_aead_aes_256_ccm
endif
## Cifra supports all of them
ifneq (,$(filter psa_aead_aes_%_ccm_backend_cifra,$(USEMODULE)))
USEPKG += cifra
USEMODULE += psa_cifra
USEMODULE += psa_cifra_aes_ccm
endif
## ChaCha20
ifneq (,$(filter psa_cipher_chacha20,$(USEMODULE)))
ifeq (,$(filter psa_cipher_chacha20_custom_backend,$(USEMODULE)))

View File

@ -97,6 +97,43 @@ ifneq (,$(filter psa_cipher_chacha20,$(USEMODULE)))
endif
endif
## AEAD
PSEUDOMODULES += psa_aead
PSEUDOMODULES += psa_aead_aes_128_ccm
PSEUDOMODULES += psa_aead_aes_128_ccm_backend_periph
PSEUDOMODULES += psa_aead_aes_128_ccm_backend_cifra
PSEUDOMODULES += psa_aead_aes_128_ccm_backend_tinycrypt
PSEUDOMODULES += psa_aead_aes_128_ccm_custom_backend
# check that one and only one backend has been selected
ifneq (,$(filter psa_aead_aes_128_ccm,$(USEMODULE)))
ifneq (1,$(call backends,psa_aead_aes_128_ccm))
$(error "One (and only one) backend should be selected for psa_aead_aes_128_ccm")
endif
endif
PSEUDOMODULES += psa_aead_aes_192_ccm
PSEUDOMODULES += psa_aead_aes_192_ccm_backend_cifra
PSEUDOMODULES += psa_aead_aes_192_ccm_custom_backend
# check that one and only one backend has been selected
ifneq (,$(filter psa_aead_aes_192_ccm,$(USEMODULE)))
ifneq (1,$(call backends,psa_aead_aes_192_ccm))
$(error "One (and only one) backend should be selected for psa_aead_aes_192_ccm")
endif
endif
PSEUDOMODULES += psa_aead_aes_256_ccm
PSEUDOMODULES += psa_aead_aes_256_ccm_backend_cifra
PSEUDOMODULES += psa_aead_aes_256_ccm_custom_backend
# check that one and only one backend has been selected
ifneq (,$(filter psa_aead_aes_256_ccm,$(USEMODULE)))
ifneq (1,$(call backends,psa_aead_aes_256_ccm))
$(error "One (and only one) backend should be selected for psa_aead_aes_256_ccm")
endif
endif
## Hash
PSEUDOMODULES += psa_hash
PSEUDOMODULES += psa_hash_md5

View File

@ -269,6 +269,25 @@ names in uppercase and add the prefix `CONFIG_MODULE_` to all of them.
- psa_asymmetric_ecc_ed25519_custom_backend
- psa_asymmetric_ecc_ed25519_backend_c25519
### AEAD
- Base: psa_aead
#### AES CCM
- psa_aead_aes_128_ccm
- psa_aead_aes_128_ccm_backend_periph
- psa_aead_aes_128_ccm_backend_cifra
- psa_aead_aes_128_ccm_backend_tinycrypt
@note Be aware that the tinycrypt only allows a nonce size of 13.
- psa_aead_aes_128_ccm_custom_backend
- psa_aead_aes_192_ccm
- psa_aead_aes_192_ccm_backend_cifra
- psa_aead_aes_192_ccm_custom_backend
- psa_aead_aes_256_ccm
- psa_aead_aes_256_ccm_backend_cifra
- psa_aead_aes_256_ccm_custom_backend
### Ciphers
- Base: psa_cipher

View File

@ -0,0 +1,112 @@
/*
* Copyright (C) 2025 TU Dresden
*
* 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.
*/
/**
* @ingroup sys_psa_crypto
* @defgroup sys_psa_crypto_aead PSA Wrapper Functions: AEAD
* @{
*
* @file psa_aead.h
* @brief Function declarations for low level wrapper functions for aead operations.
*
* @author Lukas Luger <lukas.luger@mailbox.tu-dresden.de>
*
*/
#ifndef PSA_AEAD_H
#define PSA_AEAD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "psa/crypto.h"
#include "psa/crypto_contexts.h"
#if IS_USED(MODULE_PSA_AEAD_AES_128_CCM) || defined(DOXYGEN)
/**
* @brief Low level wrapper function to call a driver for an AES 128 CCM encryption.
* See @ref psa_aead_encrypt()
*/
psa_status_t psa_aead_aes_128_ccm_encrypt(const psa_key_attributes_t *attributes,
uint8_t *key_buffer, size_t key_buffer_length,
uint8_t tag_length, const uint8_t *nonce,
size_t nonce_length, const uint8_t *additional_data,
size_t additional_data_length, const uint8_t *plaintext,
size_t plaintext_length, uint8_t *ciphertext,
size_t ciphertext_size, size_t *ciphertext_length);
/**
* @brief Low level wrapper function to call a driver for an AES 128 CCM decryption.
* See @ref psa_aead_decrypt()
*/
psa_status_t psa_aead_aes_128_ccm_decrypt(const psa_key_attributes_t *attributes,
uint8_t *key_buffer, size_t key_buffer_length,
uint8_t tag_length, const uint8_t *nonce,
size_t nonce_length, const uint8_t *additional_data,
size_t additional_data_length, const uint8_t *ciphertext,
size_t ciphertext_length, uint8_t *plaintext,
size_t plaintext_size, size_t *plaintext_length);
#endif /* MODULE_PSA_AEAD_AES_128_CCM */
#if IS_USED(MODULE_PSA_AEAD_AES_192_CCM) || defined(DOXYGEN)
/**
* @brief Low level wrapper function to call a driver for an AES 192 CCM encryption.
* See @ref psa_aead_encrypt()
*/
psa_status_t psa_aead_aes_192_ccm_encrypt(const psa_key_attributes_t *attributes,
uint8_t *key_buffer, size_t key_buffer_length,
uint8_t tag_length, const uint8_t *nonce,
size_t nonce_length, const uint8_t *additional_data,
size_t additional_data_length, const uint8_t *plaintext,
size_t plaintext_length, uint8_t *ciphertext,
size_t ciphertext_size, size_t *ciphertext_length);
/**
* @brief Low level wrapper function to call a driver for an AES 192 CCM decryption.
* See @ref psa_aead_decrypt()
*/
psa_status_t psa_aead_aes_192_ccm_decrypt(const psa_key_attributes_t *attributes,
uint8_t *key_buffer, size_t key_buffer_length,
uint8_t tag_length, const uint8_t *nonce,
size_t nonce_length, const uint8_t *additional_data,
size_t additional_data_length, const uint8_t *ciphertext,
size_t ciphertext_length, uint8_t *plaintext,
size_t plaintext_size, size_t *plaintext_length);
#endif /* MODULE_PSA_AEAD_AES_192_CCM */
#if IS_USED(MODULE_PSA_AEAD_AES_256_CCM) || defined(DOXYGEN)
/**
* @brief Low level wrapper function to call a driver for an AES 256 CCM encryption.
* See @ref psa_aead_encrypt()
*/
psa_status_t psa_aead_aes_256_ccm_encrypt(const psa_key_attributes_t *attributes,
uint8_t *key_buffer, size_t key_buffer_length,
uint8_t tag_length, const uint8_t *nonce,
size_t nonce_length, const uint8_t *additional_data,
size_t additional_data_length, const uint8_t *plaintext,
size_t plaintext_length, uint8_t *ciphertext,
size_t ciphertext_size, size_t *ciphertext_length);
/**
* @brief Low level wrapper function to call a driver for an AES 256 CCM decryption.
* See @ref psa_aead_decrypt()
*/
psa_status_t psa_aead_aes_256_ccm_decrypt(const psa_key_attributes_t *attributes,
uint8_t *key_buffer, size_t key_buffer_length,
uint8_t tag_length, const uint8_t *nonce,
size_t nonce_length, const uint8_t *additional_data,
size_t additional_data_length, const uint8_t *ciphertext,
size_t ciphertext_length, uint8_t *plaintext,
size_t plaintext_size, size_t *plaintext_length);
#endif /* MODULE_PSA_AEAD_AES_256_CCM */
#ifdef __cplusplus
}
#endif
#endif /* PSA_AEAD_H */
/** @} */

View File

@ -155,6 +155,41 @@ psa_status_t psa_algorithm_dispatch_cipher_decrypt( const psa_key_attributes_t *
size_t *output_length);
#endif /* MODULE_PSA_CIPHER */
#if IS_USED(MODULE_PSA_AEAD)
/**
* @brief Dispatch a aead encrypt function to a specific backend.
* See @ref psa_aead_encrypt()
*/
psa_status_t psa_algorithm_dispatch_aead_encrypt( const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const psa_key_slot_t *slot,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length);
/**
* @brief Dispatch a aead decrypt function to a specific backend.
* See @ref psa_aead_decrypt()
*/
psa_status_t psa_algorithm_dispatch_aead_decrypt( const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const psa_key_slot_t *slot,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length);
#endif /* MODULE_PSA_AEAD */
#if IS_USED(MODULE_PSA_MAC)
/**
* @brief Dispatch a mac computation function to a specific backend.

View File

@ -166,6 +166,41 @@ psa_status_t psa_location_dispatch_cipher_decrypt( const psa_key_attributes_t *
size_t *output_length);
#endif /* MODULE_PSA_CIPHER */
#if IS_USED(MODULE_PSA_AEAD)
/**
* @brief Dispatch a aead encrypt function to a specific backend.
* See @ref psa_aead_encrypt()
*/
psa_status_t psa_location_dispatch_aead_encrypt(const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const psa_key_slot_t *slot,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length);
/**
* @brief Dispatch a aead decrypt function to a specific backend.
* See @ref psa_aead_decrypt()
*/
psa_status_t psa_location_dispatch_aead_decrypt(const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const psa_key_slot_t *slot,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length);
#endif /* MODULE_PSA_AEAD */
/**
* @brief Dispatch call of a random number generator to a specific backend.
* See psa_generate_random()

View File

@ -49,6 +49,17 @@ typedef enum {
PSA_STREAM_CIPHER_CHACHA20
} psa_cipher_op_t;
/**
* @brief Enum encoding available aead operations.
*
* @details To be expanded with the development of this implementation.
*/
typedef enum {
PSA_CCM_AES_128,
PSA_CCM_AES_192,
PSA_CCM_AES_256
} psa_aead_op_t;
/**
* @brief Enum encoding available asymmetric key types and sizes.
*
@ -126,6 +137,23 @@ typedef enum {
PSA_INVALID_OPERATION) : \
PSA_INVALID_OPERATION)
/**
* @brief Combine key type and size with a PSA_ALG_CCM algorithm
*
* @param type Key type of type @ref psa_key_type_t
* @param bits Size of the used key of type @ref psa_key_bits_t
*
* @return @ref psa_aead_op_t
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
*/
#define GET_AES_CCM_OPERATION(type, bits) \
((type == PSA_KEY_TYPE_AES) ? \
((bits == 128) ? PSA_CCM_AES_128 : \
(bits == 192) ? PSA_CCM_AES_192 : \
(bits == 256) ? PSA_CCM_AES_256 : \
PSA_INVALID_OPERATION) : \
PSA_INVALID_OPERATION)
/**
* @brief Combine key type and size with a PSA_ALG_CBC_PKCS7 algorithm
*
@ -233,6 +261,20 @@ typedef enum {
(alg == PSA_ALG_XTS) ? GET_XTS_OPERATION(type, bits) : \
PSA_INVALID_OPERATION)
/**
* @brief Map algorithm, key size and type to a specific operation.
*
* @param alg Algorithm of type @ref psa_algorithm_t.
* @param type Key type of type @ref psa_key_type_t
* @param bits Size of the used key of type @ref psa_key_bits_t
*
* @return @ref psa_aead_op_t
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
*/
#define PSA_ENCODE_AEAD_OPERATION(alg, type, bits) \
((PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CCM) ? \
GET_AES_CCM_OPERATION(type, bits) : PSA_INVALID_OPERATION)
#ifdef __cplusplus
}
#endif

View File

@ -71,6 +71,13 @@ static inline int constant_time_memcmp(const uint8_t *a, const uint8_t *b, size_
}
#endif /* MODULE_PSA_HASH */
#if IS_USED(MODULE_PSA_KEY_MANAGEMENT)
static psa_status_t psa_get_and_lock_key_slot_with_policy(psa_key_id_t id,
psa_key_slot_t **p_slot,
psa_key_usage_t usage,
psa_algorithm_t alg);
#endif /* MODULE_PSA_KEY_MANAGEMENT */
const char *psa_status_to_humanly_readable(psa_status_t status)
{
switch (status) {
@ -116,6 +123,8 @@ const char *psa_status_to_humanly_readable(psa_status_t status)
return "PSA_ERROR_INSUFFICIENT_DATA";
case PSA_ERROR_INVALID_HANDLE:
return "PSA_ERROR_INVALID_HANDLE";
case PSA_SUCCESS:
return "PSA_SUCCESS";
default:
return "Error value not recognized";
}
@ -143,6 +152,98 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
return PSA_ERROR_NOT_SUPPORTED;
}
/**
* @brief aead encrypt and decrypt function
*
* See @ref psa_aead_encrypt(...)
* See @ref psa_aead_decrypt(...)
*
* @param direction Whether to encrypt or decrypt, see @ref psa_encrypt_or_decrypt_t
* @return @ref psa_status_t
*/
static psa_status_t psa_aead_encrypt_decrypt( psa_key_id_t key,
psa_algorithm_t alg,
const uint8_t * nonce,
size_t nonce_length,
const uint8_t * additional_data,
size_t additional_data_length,
const uint8_t * input,
size_t input_length,
uint8_t * output,
size_t output_size,
size_t * output_length,
psa_encrypt_or_decrypt_t direction)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
if (!lib_initialized) {
return PSA_ERROR_BAD_STATE;
}
if ((additional_data_length != 0 && !additional_data) || !nonce) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) != PSA_ALG_CCM) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (!PSA_ALG_IS_AEAD(alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (nonce_length > PSA_AEAD_NONCE_MAX_SIZE) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (direction == PSA_CRYPTO_DRIVER_DECRYPT && (!input || input_length == 0)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (direction == PSA_CRYPTO_DRIVER_ENCRYPT && (!output || output_size == 0)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_key_usage_t usage = (direction == PSA_CRYPTO_DRIVER_ENCRYPT ?
PSA_KEY_USAGE_ENCRYPT :
PSA_KEY_USAGE_DECRYPT);
status = psa_get_and_lock_key_slot_with_policy(key, &slot, usage, alg);
if (status != PSA_SUCCESS) {
unlock_status = psa_unlock_key_slot(slot);
if (unlock_status != PSA_SUCCESS) {
status = unlock_status;
}
return status;
}
if (direction == PSA_CRYPTO_DRIVER_ENCRYPT) {
if (output_size < PSA_AEAD_ENCRYPT_OUTPUT_SIZE(slot->attr.type, alg, input_length)) {
unlock_status = psa_unlock_key_slot(slot);
return PSA_ERROR_BUFFER_TOO_SMALL;
}
status = psa_location_dispatch_aead_encrypt(&slot->attr, alg, slot, nonce, nonce_length,
additional_data, additional_data_length,
input, input_length, output,
output_size, output_length);
}
else {
if (output_size < PSA_AEAD_DECRYPT_OUTPUT_SIZE(slot->attr.type, alg, input_length)) {
unlock_status = psa_unlock_key_slot(slot);
return PSA_ERROR_BUFFER_TOO_SMALL;
}
status = psa_location_dispatch_aead_decrypt(&slot->attr, alg, slot, nonce, nonce_length,
additional_data, additional_data_length,
input, input_length, output,
output_size, output_length);
}
unlock_status = psa_unlock_key_slot(slot);
return ((status == PSA_SUCCESS) ? unlock_status : status);
}
psa_status_t psa_aead_decrypt( psa_key_id_t key,
psa_algorithm_t alg,
const uint8_t *nonce,
@ -155,18 +256,10 @@ psa_status_t psa_aead_decrypt( psa_key_id_t key,
size_t plaintext_size,
size_t *plaintext_length)
{
(void)key;
(void)alg;
(void)nonce;
(void)nonce_length;
(void)additional_data;
(void)additional_data_length;
(void)ciphertext;
(void)ciphertext_length;
(void)plaintext;
(void)plaintext_size;
(void)plaintext_length;
return PSA_ERROR_NOT_SUPPORTED;
return psa_aead_encrypt_decrypt(key, alg, nonce, nonce_length, additional_data,
additional_data_length, ciphertext, ciphertext_length,
plaintext, plaintext_size, plaintext_length,
PSA_CRYPTO_DRIVER_DECRYPT);
}
psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
@ -191,18 +284,10 @@ psa_status_t psa_aead_encrypt( psa_key_id_t key,
size_t ciphertext_size,
size_t *ciphertext_length)
{
(void)key;
(void)alg;
(void)nonce;
(void)nonce_length;
(void)additional_data;
(void)additional_data_length;
(void)plaintext;
(void)plaintext_length;
(void)ciphertext;
(void)ciphertext_size;
(void)ciphertext_length;
return PSA_ERROR_NOT_SUPPORTED;
return psa_aead_encrypt_decrypt(key, alg, nonce, nonce_length, additional_data,
additional_data_length, plaintext, plaintext_length,
ciphertext, ciphertext_size, ciphertext_length,
PSA_CRYPTO_DRIVER_ENCRYPT);
}
psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,

View File

@ -38,6 +38,10 @@
#include "psa_ciphers.h"
#endif
#if IS_USED(MODULE_PSA_AEAD)
#include "psa_aead.h"
#endif
#if IS_USED(MODULE_PSA_KEY_MANAGEMENT)
#include "psa_crypto_operation_encoder.h"
#endif
@ -729,6 +733,152 @@ psa_status_t psa_algorithm_dispatch_cipher_decrypt( const psa_key_attributes_t *
}
#endif /* MODULE_PSA_CIPHER */
#if IS_USED(MODULE_PSA_AEAD)
psa_status_t psa_algorithm_dispatch_aead_encrypt( const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const psa_key_slot_t *slot,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length)
{
psa_aead_op_t op = PSA_ENCODE_AEAD_OPERATION(alg, attributes->type, attributes->bits);
uint8_t *key_data = NULL;
size_t *key_bytes = NULL;
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
if (attributes->type != PSA_KEY_TYPE_AES) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (op == PSA_INVALID_OPERATION) {
return PSA_ERROR_INVALID_ARGUMENT;
}
uint8_t tag_len = PSA_AEAD_TAG_LENGTH(attributes->type, attributes->bits, alg);
switch (op) {
#if IS_USED(MODULE_PSA_AEAD_AES_128_CCM)
case PSA_CCM_AES_128:
return psa_aead_aes_128_ccm_encrypt(attributes, key_data, *key_bytes, tag_len,
nonce, nonce_length, additional_data,
additional_data_length, plaintext,
plaintext_length, ciphertext,
ciphertext_size, ciphertext_length);
#endif
#if IS_USED(MODULE_PSA_AEAD_AES_192_CCM)
case PSA_CCM_AES_192:
return psa_aead_aes_192_ccm_encrypt(attributes, key_data, *key_bytes, tag_len,
nonce, nonce_length, additional_data,
additional_data_length, plaintext,
plaintext_length, ciphertext,
ciphertext_size, ciphertext_length);
#endif
#if IS_USED(MODULE_PSA_AEAD_AES_256_CCM)
case PSA_CCM_AES_256:
return psa_aead_aes_256_ccm_encrypt(attributes, key_data, *key_bytes, tag_len,
nonce, nonce_length, additional_data,
additional_data_length, plaintext,
plaintext_length, ciphertext,
ciphertext_size, ciphertext_length);
#endif
default:
(void)attributes;
(void)alg;
(void)slot;
(void)nonce;
(void)nonce_length;
(void)additional_data;
(void)additional_data_length;
(void)plaintext;
(void)plaintext_length;
(void)ciphertext;
(void)ciphertext_size;
(void)ciphertext_length;
return PSA_ERROR_NOT_SUPPORTED;
}
}
psa_status_t psa_algorithm_dispatch_aead_decrypt( const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const psa_key_slot_t *slot,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length)
{
psa_aead_op_t op = PSA_ENCODE_AEAD_OPERATION(alg, attributes->type, attributes->bits);
uint8_t *key_data = NULL;
size_t *key_bytes = NULL;
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
if (attributes->type != PSA_KEY_TYPE_AES) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (op == PSA_INVALID_OPERATION) {
return PSA_ERROR_INVALID_ARGUMENT;
}
uint8_t tag_len = PSA_AEAD_TAG_LENGTH(attributes->type, attributes->bits, alg);
switch (op) {
#if IS_USED(MODULE_PSA_AEAD_AES_128_CCM)
case PSA_CCM_AES_128:
return psa_aead_aes_128_ccm_decrypt(attributes, key_data, *key_bytes, tag_len,
nonce, nonce_length, additional_data,
additional_data_length, ciphertext,
ciphertext_length, plaintext,
plaintext_size, plaintext_length);
#endif
#if IS_USED(MODULE_PSA_AEAD_AES_192_CCM)
case PSA_CCM_AES_192:
return psa_aead_aes_192_ccm_decrypt(attributes, key_data, *key_bytes, tag_len,
nonce, nonce_length, additional_data,
additional_data_length, ciphertext,
ciphertext_length, plaintext,
plaintext_size, plaintext_length);
#endif
#if IS_USED(MODULE_PSA_AEAD_AES_256_CCM)
case PSA_CCM_AES_256:
return psa_aead_aes_256_ccm_decrypt(attributes, key_data, *key_bytes, tag_len,
nonce, nonce_length, additional_data,
additional_data_length, ciphertext,
ciphertext_length, plaintext,
plaintext_size, plaintext_length);
#endif
default:
(void)attributes;
(void)alg;
(void)slot;
(void)nonce;
(void)nonce_length;
(void)additional_data;
(void)additional_data_length;
(void)ciphertext;
(void)ciphertext_length;
(void)plaintext;
(void)plaintext_size;
(void)plaintext_length;
return PSA_ERROR_NOT_SUPPORTED;
}
}
#endif /* MODULE_PSA_AEAD */
#if IS_USED(MODULE_PSA_MAC)
psa_status_t psa_algorithm_dispatch_mac_compute(const psa_key_attributes_t *attributes,
psa_algorithm_t alg,

View File

@ -329,6 +329,52 @@ psa_status_t psa_location_dispatch_cipher_decrypt( const psa_key_attributes_t *
#endif /* MODULE_PSA_CIPHER */
#if IS_USED(MODULE_PSA_AEAD)
psa_status_t psa_location_dispatch_aead_encrypt(const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const psa_key_slot_t *slot,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length)
{
/* TODO: implement MODULE_PSA_SECURE_ELEMENT support */
return psa_algorithm_dispatch_aead_encrypt(attributes, alg, slot, nonce,
nonce_length, additional_data,
additional_data_length, plaintext,
plaintext_length, ciphertext,
ciphertext_size, ciphertext_length);
}
psa_status_t psa_location_dispatch_aead_decrypt(const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const psa_key_slot_t *slot,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length)
{
/* TODO: implement MODULE_PSA_SECURE_ELEMENT support */
return psa_algorithm_dispatch_aead_decrypt( attributes, alg, slot, nonce, nonce_length,
additional_data, additional_data_length,
ciphertext, ciphertext_length, plaintext,
plaintext_size, plaintext_length);
}
#endif /* MODULE_PSA_AEAD */
#if IS_USED(MODULE_PSA_ASYMMETRIC)
psa_status_t psa_location_dispatch_sign_hash( const psa_key_attributes_t *attributes,
psa_algorithm_t alg,