aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorTheodore Ateba <tf.ateba@gmail.com>2018-06-12 12:27:26 +0000
committerTheodore Ateba <tf.ateba@gmail.com>2018-06-12 12:27:26 +0000
commitf61f6596c18d45b73854b52c304ed9431342980b (patch)
tree3e1f840792a43ce4fae825b9d867f15c0a52f741 /os/hal
parent93c2ed5ca1af342b694fe83b0fa5778d1579fc75 (diff)
downloadChibiOS-f61f6596c18d45b73854b52c304ed9431342980b.tar.gz
ChibiOS-f61f6596c18d45b73854b52c304ed9431342980b.tar.bz2
ChibiOS-f61f6596c18d45b73854b52c304ed9431342980b.zip
AVR: Add Crypto driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12089 110e8d01-0319-4d1e-a829-52ad28d1bb01
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/ports/AVR/XMEGA/LLD/CRYPv1/driver.mk9
-rw-r--r--os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.c342
-rw-r--r--os/hal/ports/AVR/XMEGA/LLD/CRYPv1/hal_crypto_lld.h176
3 files changed, 527 insertions, 0 deletions
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 */
+
+/** @} */