From f61f6596c18d45b73854b52c304ed9431342980b Mon Sep 17 00:00:00 2001 From: Theodore Ateba Date: Tue, 12 Jun 2018 12:27:26 +0000 Subject: AVR: Add Crypto driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12089 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- os/hal/ports/AVR/XMEGA/LLD/CRYPv1/driver.mk | 9 + os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.c | 342 +++++++++++++++++++++ os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.h | 176 +++++++++++ 3 files changed, 527 insertions(+) create mode 100644 os/hal/ports/AVR/XMEGA/LLD/CRYPv1/driver.mk create mode 100644 os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.c create mode 100644 os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.h (limited to 'os/hal') diff --git a/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/driver.mk b/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/driver.mk new file mode 100644 index 000000000..170b0d87d --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_CRY TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.c +endif +else +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.c +endif + +PLATFORMINC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/CRYPv1 diff --git a/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.c b/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.c new file mode 100644 index 000000000..99dbcabce --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.c @@ -0,0 +1,342 @@ +/* + ChibiOS - Copyright (C) 2016..2018 Theodore Ateba + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_crypto_lld.c + * @brief AVR cryptographic subsystem low level driver source. + * + * @addtogroup CRYPTO + * @{ + */ + +#include "hal.h" + +#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief CRY1 driver identifier.*/ +#if AVR_CRY_USE_CRY1 || defined(__DOXYGEN__) +CRYDriver CRYD1; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Enabable the AES auto start feature. + */ +static void aes_lld_enable_auto_start(void) { + AES.CTRL |= (1 << AES_AUTO_bp); +} + +/** + * @brief Disable the AES auto start feature. + */ +static void aes_lld_disable_auto_start(void) { + AES.CTRL &= ~(1 << AES_AUTO_bp); +} + +/** + * @brief Software reset of the AES crypto module. + */ +void aes_lld_reset(void) { + AES.CTRL |= (1 << AES_RESET_bp); +} + +/** + * @brief Set the AES module to Encrypt data. + */ +static void aes_lld_set_mode_encrypt(void) { + AES.CTRL &= ~(1 << AES_DECRYPT_bp); +} + +/** + * @brief Set the AES module to decrypt data. + */ +static void aes_lld_set_mode_decrypt(void) { + AES.CTRL |= (1 << AES_DECRYPT_bp); +} + +/** + * @brief Enable the XOR feature in the AES module. + */ +static void aes_lld_enable_xor(void) { + AES.CTRL |= (1 << AES_XOR_bp); +} + +/** + * @brief Enable the XOR feature in the AES module. + */ +static void aes_lld_disable_xor(void) { + AES.CTRL &= ~(1 << AES_XOR_bp); +} + +/** + * @brief Start the Encryption/Decryption procedure. + */ +static void aes_lld_start(void) { + AES.CTRL |= (1 << AES_START_bp); +} + +/** + * @brief Stop the Encryption/Decryption procedure. + */ +static void aes_lld_stop(void) { + AES.CTRL &= ~(1 << AES_START_bp); +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level crypto driver initialization. + * + * @notapi + */ +void cry_lld_init(void) { + +#if AVR_CRY_USE_CRY1 || defined(__DOXYGEN__) + aes_lld_reset(); // Reset the AES module. + aes_lld_stop(); // Stop the AES module. + CRYD1.config = NULL; + CRYD1.state = CRY_STOP; +#endif +} + +/** + * @brief Configures and activates the crypto peripheral. + * + * @param[in] cryp pointer to the @p CRYDriver object + * + * @notapi + */ +void cry_lld_start(CRYDriver *cryp) { + + if (cryp->state == CRY_STOP) { + if (cryp->config->xorf) { + aes_lld_enable_xor(); + } + else { + aes_lld_disable_xor(); + } + + if (cryp->config->autof) { + aes_lld_enable_auto_start(); + } + else { + aes_lld_disable_auto_start(); + } + } + aes_lld_reset(); +} + +/** + * @brief Deactivates the crypto peripheral. + * + * @param[in] cryp pointer to the @p CRYDriver object + * + * @notapi + */ +void cry_lld_stop(CRYDriver *cryp) { + + if (cryp->state == CRY_READY) { + aes_lld_stop(); // Stop the AES module. + } +} + +/** + * @brief Initializes the transient key for a specific algorithm. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] algorithm the algorithm identifier + * @param[in] size key size in bytes + * @param[in] keyp pointer to the key data + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the specified algorithm is unknown or + * unsupported. + * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid. + * + * @notapi + */ +cryerror_t cry_lld_loadkey(CRYDriver *cryp, + cryalgorithm_t algorithm, + size_t size, + const uint8_t *keyp) { + + uint8_t i; + + (void)cryp; + (void)size; + + if (size != AES_BLOCK_SIZE) { + return CRY_ERR_INV_KEY_SIZE; // invalid size error code. + } + + if (algorithm == cry_algo_aes) { + // Load the Key into the AES key memory. + for (i = 0; i < AES_BLOCK_SIZE; i++) { + AES.KEY = keyp[i]; + } + } + + if (algorithm == cry_algo_des) { + } + + return CRY_NOERROR; +} + +/** + * @brief Encryption of a single block using AES. + * @note The implementation of this function must guarantee that it can + * be called from any context. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is + * the transient key, other values are keys stored + * in an unspecified way + * @param[in] src source buffer containing the input plaintext + * @param[out] dest destination buffer for the output cyphertext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp, + crykey_t key_id, + const uint8_t *src, + uint8_t *dest) { + uint8_t i; + + (void)cryp; + (void)key_id; + + // Load the Data into the AES state memory. + for (i = 0; i < AES_BLOCK_SIZE; i++) { + AES.STATE = src[i]; + } + + // Set the AES encryption mode. + aes_lld_set_mode_encrypt(); + + // Start the AES. + aes_lld_start(); + + // Wait the Encryption to finish or an error to occurs. + do{ + } + while ((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm)) == 0); + + // Check error. + if((AES.STATUS & AES_ERROR_bm) == 0) { + // Store the result of the encryption + for(i = 0; i < AES_BLOCK_SIZE; i++) { + dest[i] = AES.STATE; + } + } + else { + return CRY_ERR_ENCRYP; + } + + return CRY_NOERROR; +} + +/** + * @brief Decryption of a single block using AES. + * @note The implementation of this function must guarantee that it can + * be called from any context. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is + * the transient key, other values are keys stored + * in an unspecified way + * @param[in] src source buffer containing the input cyphertext + * @param[out] dest destination buffer for the output plaintext + * @return the operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp, + crykey_t key_id, + const uint8_t *src, + uint8_t *dest) { + + uint8_t i; + + (void)cryp; + (void)key_id; + + // Load data into AES state memory. + for (i = 0; i < AES_BLOCK_SIZE; i++) { + AES.STATE = src[i]; + } + + // Set the AES decryption mode. + aes_lld_set_mode_decrypt(); + + // Start the AES. + aes_lld_start(); + + // Wait the Encryption to finish or an error to occurs. + do { + } + while ((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm)) == 0); + + // Check if not error. + if ((AES.STATUS & AES_ERROR_bm) == 0) { + // Store the result. + for (i = 0; i < AES_BLOCK_SIZE; i++) { + dest[i] = AES.STATE; + } + } + else { + return CRY_ERR_DECRYP; + } + + return CRY_NOERROR; +} + +#endif /* HAL_USE_CRY == TRUE */ + +/** @} */ diff --git a/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.h b/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.h new file mode 100644 index 000000000..8029e06de --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.h @@ -0,0 +1,176 @@ +/* + ChibiOS - Copyright (C) 2016..2018 Theodore Ateba + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_crypto_lld.h + * @brief AVR cryptographic subsystem low level driver header. + * + * @addtogroup CRYPTO + * @{ + */ + +#ifndef HAL_CRYPTO_LLD_H +#define HAL_CRYPTO_LLD_H + +#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) + +/*==========================================================================*/ +/* Driver constants. */ +/*==========================================================================*/ + +/** + * @name Driver capability switches + * @{ + */ +#define CRY_LLD_SUPPORTS_AES TRUE +#define CRY_LLD_SUPPORTS_AES_ECB FALSE +#define CRY_LLD_SUPPORTS_AES_CBC FALSE +#define CRY_LLD_SUPPORTS_AES_CFB FALSE +#define CRY_LLD_SUPPORTS_AES_CTR FALSE +#define CRY_LLD_SUPPORTS_AES_GCM FALSE +#define CRY_LLD_SUPPORTS_DES FALSE +#define CRY_LLD_SUPPORTS_DES_ECB FALSE +#define CRY_LLD_SUPPORTS_DES_CBC FALSE +#define CRY_LLD_SUPPORTS_SHA1 FALSE +#define CRY_LLD_SUPPORTS_SHA256 FALSE +#define CRY_LLD_SUPPORTS_SHA512 FALSE +#define CRY_LLD_SUPPORTS_HMAC_SHA256 FALSE +#define CRY_LLD_SUPPORTS_HMAC_SHA512 FALSE +#define CRY_LLD_SUPPORTS_TRNG FALSE +/** @} */ + +/** + * @brief Size of one block data, always 128-bits (16 bytes). + */ +#define AES_BLOCK_SIZE 16 + +/*==========================================================================*/ +/* Driver pre-compile time settings. */ +/*==========================================================================*/ + +/** + * @name AVR configuration options + * @{ + */ +/** + * @brief CRY1 driver enable switch. + * @details If set to @p TRUE the support for CRY1 is included. + * @note The default is @p FALSE. + */ +#if !defined(AVR_CRY_USE_CRY1) || defined(__DOXYGEN__) +#define AVR_CRY_USE_CRY1 FALSE +#endif +/** @} */ + +/*==========================================================================*/ +/* Derived constants and error checks. */ +/*==========================================================================*/ + +/*==========================================================================*/ +/* Driver data structures and types. */ +/*==========================================================================*/ + +/** + * @brief CRY key identifier type. + */ +typedef uint16_t crykey_t; + +/** + * @brief Type of a structure representing an CRY driver. + */ +typedef struct CRYDriver CRYDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + bool autof; // Auto start feature + bool xorf; // XOR feature +} CRYConfig; + +/** + * @brief Structure representing an CRY driver. + */ +struct CRYDriver { + /** + * @brief Driver state. + */ + crystate_t state; + /** + * @brief Current configuration data. + */ + const CRYConfig *config; + /** + * @brief Algorithm type of transient key. + */ + cryalgorithm_t key0_type; + /** + * @brief Size of transient key. + */ + size_t key0_size; +#if (HAL_CRY_USE_FALLBACK == TRUE) || defined(__DOXYGEN__) + /** + * @brief Key buffer for the fall-back implementation. + */ + uint8_t key0_buffer[HAL_CRY_MAX_KEY_SIZE]; +#endif +#if defined(CRY_DRIVER_EXT_FIELDS) + CRY_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ +}; + +/*==========================================================================*/ +/* Driver macros. */ +/*==========================================================================*/ + +/*==========================================================================*/ +/* External declarations. */ +/*==========================================================================*/ + +#if (AVR_CRY_USE_CRY1 == TRUE) && !defined(__DOXYGEN__) +extern CRYDriver CRYD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void cry_lld_init(void); + void cry_lld_start(CRYDriver *cryp); + void cry_lld_stop(CRYDriver *cryp); + cryerror_t cry_lld_loadkey(CRYDriver *cryp, + cryalgorithm_t algorithm, + size_t size, + const uint8_t *keyp); + cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp, + crykey_t key_id, + const uint8_t *src, + uint8_t *dest); + cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp, + crykey_t key_id, + const uint8_t *src, + uint8_t *dest); + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_CRY == TRUE */ + +#endif /* HAL_CRYPTO_LLD_H */ + +/** @} */ -- cgit v1.2.3