AVR: Add Crypto driver.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12089 110e8d01-0319-4d1e-a829-52ad28d1bb01
This commit is contained in:
Theodore Ateba 2018-06-12 12:27:26 +00:00
parent 93c2ed5ca1
commit f61f6596c1
3 changed files with 527 additions and 0 deletions

View File

@ -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

View File

@ -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 */
/** @} */

View File

@ -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 */
/** @} */