rt-thread/bsp/samd21/sam_d2x_asflib/sam0/drivers/aes/aes.h

716 lines
20 KiB
C
Raw Normal View History

2017-08-30 12:18:28 +08:00
/**
*
* \file
*
* \brief SAM Advanced Encryption Standard driver.
*
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef AES_H_INCLUDED
#define AES_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup asfdoc_sam0_drivers_aes_group SAM Advanced Encryption Standard (AES) Driver
*
* This driver for Atmel&reg; | SMART ARM&reg;-based microcontrollers provides an interface for the configuration
* and management of the device's Advanced Encryption Standard functionality. The following
* driver API modes are covered by this manual:
*
* - Polled APIs
* - Callback APIs
*
* The Advanced Encryption Standard module supports all five confidentiality
* modes of operation for symmetrical key block cipher algorithms (as specified
* in the NIST Special Publication 800-38A Recommendation):
* - Electronic Code Book (ECB)
* - Cipher Block Chaining (CBC)
* - Output Feedback (OFB)
* - Cipher Feedback (CFB)
* - Counter (CTR)
*
* The following peripheral is used by this module:
* - AES (Advanced Encryption Standard)
*
* The following devices can use this module:
* - Atmel | SMART SAM L21
* - Atmel | SMART SAM L22
*
* The outline of this documentation is as follows:
* - \ref asfdoc_sam0_drivers_aes_prerequisites
* - \ref asfdoc_sam0_drivers_aes_module_overview
* - \ref asfdoc_sam0_drivers_aes_special_considerations
* - \ref asfdoc_sam0_drivers_aes_extra_info
* - \ref asfdoc_sam0_drivers_aes_examples
* - \ref asfdoc_sam0_drivers_aes_api_overview
*
*
* \section asfdoc_sam0_drivers_aes_prerequisites Prerequisites
*
* There are no prerequisites for this module.
*
*
* \section asfdoc_sam0_drivers_aes_module_overview Module Overview
*
* The Advanced Encryption Standard (AES) is a specification for the encryption of
* electronic data established by the U.S. National Institute of Standards and
* Technology (NIST) in 2001. It is compliant with the American FIPS
* (Federal Information Processing Standard) Publication 197 specification.
*
* The AES supports all five confidentiality modes of operation for symmetrical
* key block cipher algorithms (as specified in the NIST Special Publication
* 800-38A Recommendation):
* - Electronic Code Book (ECB)
* - Cipher Block Chaining (CBC)
* - Output Feedback (OFB)
* - Cipher Feedback (CFB)
* - Counter (CTR)
*
* Data transfers both to and from the AES module can occur using the peripheral
* DMA controller channels, thus minimizing processor intervention for
* large data buffer transfers.
*
* As soon as the initialization vector, the input data and the key are
* configured, the encryption/decryption process may be started. Once the
* process has completed the encrypted/decrypted data can be read out via
* registers or through DMA channels.
*
* \subsection asfdoc_sam0_drivers_aes_module_overview_en_de Encryption and Decryption
* The AES is capable of using cryptographic keys of 128/192/256 bits to
* encrypt and decrypt data in blocks of 128 bits. In Cipher Feedback Mode (CFB),
* five data sizes are possible (8, 16, 32, 64, or 128 bits).
*
* The input to the encryption processes of the CBC, CFB, and OFB modes includes,
* in addition to the plaintext, a 128-bit data block called the Initialization
* Vector (IV). The Initialization Vector is used in the initial step in the
* encryption of a message and in the corresponding decryption of the message.
*
* There are three encryption/decryption start modes:
* - Manual Mode: Start encryption/decryption manually
* - Auto Start Mode: Once the correct number of input data registers is written,
* processing is automatically started, DMA operation uses this mode
* - Last Output Data Mode (LOD): This mode is used to generate message
* authentication code (MAC) on data in CCM mode of operation
*
* \subsection asfdoc_sam0_drivers_aes_module_overview_hardware_countermeasures Hardware Countermeasures
* The AES module features four types of hardware countermeasures that are
* useful for protecting data against differential power analysis attacks:
* - Type 1: Randomly add one cycle to data processing
* - Type 2: Randomly add one cycle to data processing (other version)
* - Type 3: Add a random number of clock cycles to data processing, subject to
* a maximum of 11/13/15 clock cycles for key sizes of 128/192/256 bits
* - Type 4: Add random spurious power consumption during data processing
*
* \subsection asfdoc_sam0_drivers_aes_module_overview_gcm Galois Counter Mode (GCM)
* GCM is comprised of the AES engine in CTR mode along with a universal hash
* function (GHASH engine) that is defined over a binary Galois field to produce
* a message authentication tag. The GHASH engine processes data packets after the
* AES operation. GCM provides assurance of the confidentiality of data through the
* AES Counter mode of operation for DRAFT 920 encryption. Authenticity of the
* confidential data is assured through the GHASH engine. Refer to the NIST Special
* Publication 800-38D Recommendation for more complete information.
*
* \section asfdoc_sam0_drivers_aes_special_considerations Special Considerations
*
* There are no special considerations for this module.
*
* \section asfdoc_sam0_drivers_aes_extra_info Extra Information
*
* For extra information, see \ref asfdoc_sam0_drivers_aes_extra. This includes:
* - \ref asfdoc_sam0_drivers_aes_extra_acronyms
* - \ref asfdoc_sam0_drivers_aes_extra_dependencies
* - \ref asfdoc_sam0_drivers_aes_extra_errata
* - \ref asfdoc_sam0_drivers_aes_extra_history
*
* \section asfdoc_sam0_drivers_aes_examples Examples
*
* For a list of examples related to this driver, see
* \ref asfdoc_sam0_drivers_aes_exqsg.
*
*
* \section asfdoc_sam0_drivers_aes_api_overview API Overview
* @{
*/
#include <compiler.h>
#include <system.h>
#ifdef __cplusplus
extern "C" {
#endif
/** AES processing mode. */
enum aes_encrypt_mode {
AES_DECRYPTION = 0, /**< Decryption of data will be performed */
AES_ENCRYPTION, /**< Encryption of data will be performed */
};
/** AES cryptographic key size. */
enum aes_key_size {
AES_KEY_SIZE_128 = 0, /**< AES key size is 128-bit */
AES_KEY_SIZE_192, /**< AES key size is 192-bit */
AES_KEY_SIZE_256, /**< AES key size is 256-bit */
};
/** AES start mode. */
enum aes_start_mode {
AES_MANUAL_START = 0, /**< Manual start mode */
AES_AUTO_START, /**< Auto start mode */
};
/** AES operation mode. */
enum aes_operation_mode {
AES_ECB_MODE = 0, /**< Electronic Codebook (ECB) */
AES_CBC_MODE, /**< Cipher Block Chaining (CBC) */
AES_OFB_MODE, /**< Output Feedback (OFB) */
AES_CFB_MODE, /**< Cipher Feedback (CFB) */
AES_CTR_MODE, /**< Counter (CTR) */
AES_CCM_MODE, /**< Counter (CCM) */
AES_GCM_MODE, /**< Galois Counter Mode (GCM) */
};
/** AES Cipher FeedBack (CFB) size. */
enum aes_cfb_size {
AES_CFB_SIZE_128 = 0, /**< Cipher feedback data size is 128-bit */
AES_CFB_SIZE_64, /**< Cipher feedback data size is 64-bit */
AES_CFB_SIZE_32, /**< Cipher feedback data size is 32-bit */
AES_CFB_SIZE_16, /**< Cipher feedback data size is 16-bit */
AES_CFB_SIZE_8, /**< Cipher feedback data size is 8-bit */
};
/** AES countermeasure type */
enum aes_countermeature_type {
AES_COUNTERMEASURE_TYPE_disabled = 0x0, /**< Countermeasure type all disabled */
AES_COUNTERMEASURE_TYPE_1 = 0x01, /**< Countermeasure1 enabled */
AES_COUNTERMEASURE_TYPE_2 = 0x02, /**< Countermeasure2 enabled */
AES_COUNTERMEASURE_TYPE_3 = 0x04, /**< Countermeasure3 enabled */
AES_COUNTERMEASURE_TYPE_4 = 0x08, /**< Countermeasure4 enabled */
AES_COUNTERMEASURE_TYPE_ALL = 0x0F, /**< Countermeasure type all enabled */
};
/**
* \name Module Status Flags
*
* AES status flags, returned by \ref aes_get_status() and cleared by
* \ref aes_clear_status().
*
* @{
*/
/** AES encryption complete.
*/
#define AES_ENCRYPTION_COMPLETE (1UL << 0)
/** AES GF multiplication complete.
*/
#define AES_GF_MULTI_COMPLETE (1UL << 1)
/** @} */
/** AES Configuration structure. */
struct aes_config {
/** AES data mode (decryption or encryption) */
enum aes_encrypt_mode encrypt_mode;
/** AES key size */
enum aes_key_size key_size;
/** Start mode */
enum aes_start_mode start_mode;
/** AES cipher operation mode*/
enum aes_operation_mode opmode;
/** Cipher feedback data size */
enum aes_cfb_size cfb_size;
/** Countermeasure type */
enum aes_countermeature_type ctype;
/** Enable XOR key */
bool enable_xor_key;
/** Enable key generation */
bool enable_key_gen;
/** Last output data mode enable/disable */
bool lod;
};
#if !defined(__DOXYGEN__)
/**
* \brief Device structure.
*/
struct aes_module {
/** AES hardware module. */
Aes *hw;
/** AES cipher operation mode.*/
enum aes_operation_mode opmode;
/** AES key size. */
enum aes_key_size key_size;
/** Cipher feedback data size. */
enum aes_cfb_size cfb_size;
};
#endif
/**
* \name Configuration and Initialization
* @{
*/
void aes_get_config_defaults(struct aes_config *const config);
void aes_set_config(struct aes_module *const module,
Aes *const hw,
struct aes_config *const config);
void aes_init(struct aes_module *const module,
Aes *const hw,
struct aes_config *const config);
/** @} */
/**
* \name Start, Enable, and Write
* @{
*/
/**
* \brief Start a manual encryption/decryption process.
*
* \param[in] module Pointer to the AES software instance struct
*/
static inline void aes_start(struct aes_module *const module)
{
Assert(module);
Assert(module->hw);
module->hw->CTRLB.reg |= AES_CTRLB_START;
}
/**
* \brief Notifies the module that the next input data block
* is the beginning of a new message.
*
* \param[in] module Pointer to the AES software instance struct
*
*/
static inline void aes_set_new_message(struct aes_module *const module)
{
Assert(module);
Assert(module->hw);
module->hw->CTRLB.reg |= AES_CTRLB_NEWMSG;
}
/**
* \brief Clear the indication of the beginning for a new message
*
* \param[in] module Pointer to the AES software instance struct
*
*/
static inline void aes_clear_new_message(struct aes_module *const module)
{
Assert(module);
Assert(module->hw);
module->hw->CTRLB.reg &= ~AES_CTRLB_NEWMSG;
}
void aes_enable(struct aes_module *const module);
void aes_disable(struct aes_module *const module);
void aes_write_key(struct aes_module *const module, const uint32_t *key);
void aes_write_init_vector(struct aes_module *const module, const uint32_t *vector);
void aes_write_input_data(struct aes_module *const module,
const uint32_t *p_input_data_buffer);
void aes_read_output_data(struct aes_module *const module,
uint32_t *p_output_data_buffer);
/**
* \brief Write AES random seed.
*
* \param[in] module Pointer to the AES software instance struct
* \param[in] seed Seed for the random number generator
*/
static inline void aes_write_random_seed(struct aes_module *const module,
uint32_t seed)
{
Assert(module);
Assert(module->hw);
module->hw->RANDSEED.reg = seed;
}
/** @} */
/**
* \name Status Management
* @{
*/
/**
* \brief Retrieves the current module status.
*
* Retrieves the status of the module, giving overall state information.
*
* \param[in] module Pointer to the AES software instance struct
*
* \retval AES_ENCRYPTION_COMPLETE AES encryption complete
* \retval AES_GF_MULTI_COMPLETE AES GF multiplication complete
*/
static inline uint32_t aes_get_status(struct aes_module *const module)
{
/* Sanity check arguments */
Assert(module);
Assert(module->hw);
uint32_t int_flags = module->hw->INTFLAG.reg;
uint32_t status_flags = 0;
if (int_flags & AES_INTFLAG_ENCCMP) {
status_flags |= AES_ENCRYPTION_COMPLETE;
}
if (int_flags & AES_INTFLAG_GFMCMP) {
status_flags |= AES_GF_MULTI_COMPLETE;
}
return status_flags;
}
/**
* \brief Clears a module status flag.
*
* Clears the given status flag of the module.
*
* \param[in] module Pointer to the AES software instance struct
* \param[in] status_flags Bitmask flags to clear
*/
static inline void aes_clear_status(
struct aes_module *const module,
const uint32_t status_flags)
{
/* Sanity check arguments */
Assert(module);
Assert(module->hw);
uint32_t int_flags = 0;
if (status_flags & AES_ENCRYPTION_COMPLETE) {
int_flags |= AES_INTENCLR_ENCCMP;
}
if (status_flags & AES_GF_MULTI_COMPLETE) {
int_flags |= AES_INTENCLR_GFMCMP;
}
/* Clear interrupt flag */
module->hw->INTFLAG.reg = int_flags;
}
/** @} */
/**
* \name Galois Counter Mode
* @{
*/
/**
* \brief Get the AES GCM Hash Value.
*
* \param[in] module Pointer to the AES software instance struct
* \param[in] id Index into the GHASH array (range 0 to 3)
*
* \return The content of the GHASHRx[x = 0...3] value.
*/
static inline uint32_t aes_gcm_read_ghash(struct aes_module *const module, uint32_t id)
{
Assert(module);
Assert(module->hw);
return module->hw->GHASH[id].reg;
}
/**
* \brief Set the AES GCM Hash Value.
*
* \param[in] module Pointer to the AES software instance struct
* \param[in] id Index into the GHASHx array (range 0 to 3)
* \param[in] ghash GCM hash value
*/
static inline void aes_gcm_write_ghash(struct aes_module *const module,
uint32_t id,uint32_t ghash)
{
Assert(module);
Assert(module->hw);
module->hw->GHASH[id].reg = ghash;
}
/**
* \brief Get AES GCM Hash key.
*
* \param[in] module Pointer to the AES software instance struct
* \param[in] id Index into the Hash key array (range 0 to 3)
*
* \return The contents of the HASHKEYx[x = 0...3] specified.
*/
static inline uint32_t aes_gcm_read_hash_key(struct aes_module *const module,
uint32_t id)
{
Assert(module);
Assert(module->hw);
return module->hw->HASHKEY[id].reg;
}
/**
* \brief Set the AES GCM Hash key.
*
* \param[in] module Pointer to the AES software instance struct
* \param[in] id Index into the Hash key array (range 0 to 3)
* \param[in] key GCM Hash key
*/
static inline void aes_gcm_write_hash_key(struct aes_module *const module,
uint32_t id, uint32_t key)
{
Assert(module);
Assert(module->hw);
module->hw->HASHKEY[id].reg = key;
}
/**
* \brief Get the AES GCM cipher length.
*
* \param[in] module Pointer to the AES software instance struct
*
* \return The contents of the HASHKEYx[x = 0...3] specified.
*/
static inline uint32_t aes_gcm_read_cipher_len(struct aes_module *const module)
{
Assert(module);
Assert(module->hw);
return (module->hw->CIPLEN.reg);
}
/**
* \brief Set the AES GCM cipher length.
*
* \param[in] module Pointer to the AES software instance struct
* \param[in] len Cipher length
*/
static inline void aes_gcm_write_cipher_len(struct aes_module *const module,
uint32_t len)
{
Assert(module);
Assert(module->hw);
module->hw->CIPLEN.reg = len;
}
/**
* \brief Set GCM end of input message status.
*
* \param[in] module Pointer to the AES software instance struct
*/
static inline void aes_gcm_set_end_message_status(struct aes_module *const module)
{
Assert(module);
Assert(module->hw);
module->hw->CTRLB.reg |= AES_CTRLB_EOM;
}
/**
* \brief Clear GCM end of input message status.
*
* \param[in] module Pointer to the AES software instance struct
*/
static inline void aes_gcm_clear_end_message_status(struct aes_module *const module)
{
Assert(module);
Assert(module->hw);
module->hw->CTRLB.reg &= ~AES_CTRLB_EOM;
}
/**
* \brief Set GF multiplication of GCM mode.
*
* \param[in] module Pointer to the AES software instance struct
*/
static inline void aes_gcm_set_gf_multiplication(struct aes_module *const module)
{
Assert(module);
Assert(module->hw);
module->hw->CTRLB.reg |= AES_CTRLB_GFMUL;
}
/** @} */
#ifdef __cplusplus
}
#endif
/** @} */
/**
* \page asfdoc_sam0_drivers_aes_extra Extra Information for Advanced Encryption Standard
*
* \section asfdoc_sam0_drivers_aes_extra_acronyms Acronyms
* Below is a table listing the acronyms used in this module, along with their
* intended meanings.
*
* <table>
* <tr>
* <th>Acronym</th>
* <th>Definition</th>
* </tr>
* <tr>
* <td>AAD</td>
* <td>Additional Authenticated Data</td>
* </tr>
* <tr>
* <td>CBC</td>
* <td>Cipher Block Chaining</td>
* </tr>
* <tr>
* <td>CFB</td>
* <td>Cipher Feedback</td>
* </tr>
* <tr>
* <td>CTR</td>
* <td> Counter</td>
* </tr>
* <tr>
* <td>DMA</td>
* <td>Direct Memory Access</td>
* </tr>
* <tr>
* <td>DMAC</td>
* <td>DMA Controller</td>
* </tr>
* <tr>
* <td>ECB</td>
* <td>Electronic Codebook</td>
* </tr>
* <tr>
* <td>GCM</td>
* <td>Galois Counter Mode</td>
* </tr>
* <tr>
* <td>OFB</td>
* <td>Output Feedback</td>
* </tr>
* <tr>
* <td>QSG</td>
* <td>Quick Start Guide</td>
* </tr>
* </table>
*
*
* \section asfdoc_sam0_drivers_aes_extra_dependencies Dependencies
* This driver has the following dependencies:
*
* - None
*
*
* \section asfdoc_sam0_drivers_aes_extra_errata Errata
* There are no errata related to this driver.
*
*
* \section asfdoc_sam0_drivers_aes_extra_history Module History
* An overview of the module history is presented in the table below, with
* details on the enhancements and fixes made to the module since its first
* release. The current version of this corresponds to the newest version in
* the table.
*
* <table>
* <tr>
* <th>Changelog</th>
* </tr>
* <tr>
* <td>Initial release</td>
* </tr>
* </table>
*/
/**
* \page asfdoc_sam0_drivers_aes_exqsg Examples for Advanced Encryption Standard
*
* This is a list of the available Quick Start Guides (QSGs) and example
* applications for \ref asfdoc_sam0_drivers_aes_group. QSGs are simple examples with
* step-by-step instructions to configure and use this driver in a selection of
* use cases. Note that a QSG can be compiled as a standalone application or be
* added to the user application.
*
* - \subpage asfdoc_sam0_aes_basic_use_case
* - \subpage asfdoc_sam0_aes_callback_use_case
* - \subpage asfdoc_sam0_aes_dma_use_case
*
* \page asfdoc_sam0_drivers_aes_document_revision_history Document Revision History
*
* <table>
* <tr>
* <th>Doc. Rev.</td>
* <th>Date</td>
* <th>Comments</td>
* </tr>
* <tr>
* <td>42445B</td>
* <td>12/2015</td>
* <td>Added support for SAM L22</td>
* </tr>
* <tr>
* <td>42445A</td>
* <td>06/2015</td>
* <td>Initial release</td>
* </tr>
* </table>
*
*/
#ifdef __cplusplus
}
#endif
#endif /* AES_H_INCLUDED */