363 lines
11 KiB
C
363 lines
11 KiB
C
/******************************************************************************
|
|
* drivers/wireless/spirit/lib/spirit_aes.c
|
|
* Configuration and management of SPIRIT AES Engine.
|
|
*
|
|
* Copyright(c) 2015 STMicroelectronics
|
|
* Author: VMA division - AMS
|
|
* Version 3.2.2 08-July-2015
|
|
*
|
|
* Adapted for NuttX by:
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
*
|
|
* 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. Neither the name of STMicroelectronics nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
|
*
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
* Included Files
|
|
******************************************************************************/
|
|
|
|
#include <assert.h>
|
|
|
|
#include "spirit_aes.h"
|
|
#include "spirit_spi.h"
|
|
|
|
/******************************************************************************
|
|
* Public Functions
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_enable
|
|
*
|
|
* Description:
|
|
* Enables or Disables the AES engine.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate new state for AES engine.
|
|
* This parameter can be: S_ENABLE or S_DISABLE.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_enable(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Modifies the register value */
|
|
|
|
ret = spirit_reg_read(spirit, ANA_FUNC_CONF0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= AES_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= ~AES_MASK;
|
|
}
|
|
|
|
/* Write to the ANA_FUNC_CONF0 register to enable or disable the AES
|
|
* engine
|
|
*/
|
|
|
|
ret = spirit_reg_write(spirit, ANA_FUNC_CONF0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_write_datain
|
|
*
|
|
* Description:
|
|
* Writes the data to encrypt or decrypt, or the encryption key for the
|
|
* derive decryption key operation into the AES_DATA_IN registers.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* buffer - Pointer to the user data buffer. The first byte of the array
|
|
* must be the MSB byte and it will be put in the AES_DATA_IN[0]
|
|
* register, while the last one must be the LSB and it will be
|
|
* put in the AES_DATA_IN[buflen-1] register. If data to write
|
|
* are less than 16 bytes the remaining AES_DATA_IN registers
|
|
* will be filled with bytes equal to 0.
|
|
* buflen - Length of data in bytes.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_write_datain(FAR struct spirit_library_s *spirit,
|
|
FAR const uint8_t *buffer, uint8_t buflen)
|
|
{
|
|
uint8_t datain[16];
|
|
uint8_t i;
|
|
|
|
/* Verifies that there are no more than 16 bytes */
|
|
|
|
(buflen > 16) ? (buflen = 16) : buflen;
|
|
|
|
/* Fill the datain with the data buffer, using padding */
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
if (i < (16 - buflen))
|
|
{
|
|
datain[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
datain[i] = buffer[15 - i];
|
|
}
|
|
}
|
|
|
|
/* Writes the AES_DATA_IN registers */
|
|
|
|
return spirit_reg_write(spirit, AES_DATA_IN_15_BASE, datain, 16);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_read_dataout
|
|
*
|
|
* Description:
|
|
* Returns the encrypted or decrypted data or the decription key from the
|
|
* AES_DATA_OUT register.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* buffer - pointer to the user data buffer. The AES_DATA_OUT[0]
|
|
* register value will be put as first element of the buffer
|
|
* (MSB), while the AES_DAT_OUT[buflen-1] register value will be
|
|
* put as last element of the buffer (LSB).
|
|
* buflen - Length of data to read in bytes.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_read_dataout(FAR struct spirit_library_s *spirit,
|
|
FAR uint8_t *buffer, uint8_t buflen)
|
|
{
|
|
uint8_t dataout[16];
|
|
uint8_t address;
|
|
int ret;
|
|
|
|
/* Verifies that there are no more than 16 bytes */
|
|
|
|
if (buflen > 16)
|
|
{
|
|
buflen = 16;
|
|
}
|
|
|
|
/* Evaluates the address of AES_DATA_OUT from which start to read */
|
|
|
|
address = AES_DATA_OUT_15_BASE + 16 - buflen;
|
|
|
|
/* Reads the exact number of AES_DATA_OUT registers */
|
|
|
|
ret = spirit_reg_read(spirit, address, dataout, buflen);
|
|
if (ret >= 0)
|
|
{
|
|
int i;
|
|
|
|
/* Copy in the user buffer the read values changing the order */
|
|
|
|
for (i = buflen - 1; i >= 0; i--)
|
|
{
|
|
*buffer++ = dataout[i];
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_write_key
|
|
*
|
|
* Description:
|
|
* Writes the encryption key into the AES_KEY_IN register.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* key - Pointer to the buffer of 4 words containing the AES key.
|
|
* The first byte of the buffer must be the most significant byte
|
|
* AES_KEY_0 of the AES key. The last byte of the buffer must be
|
|
* the less significant byte AES_KEY_15 of the AES key.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_write_key(FAR struct spirit_library_s *spirit,
|
|
FAR const uint8_t *key)
|
|
{
|
|
uint8_t tmp[16];
|
|
int i;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
tmp[15 - i] = key[i];
|
|
}
|
|
|
|
/* Write to the AES_DATA_IN registers */
|
|
|
|
return spirit_reg_write(spirit, AES_KEY_IN_15_BASE, tmp, 16);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_read_key
|
|
*
|
|
* Description:
|
|
* Returns the encryption/decryption key from the AES_KEY_IN register.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* key - Pointer to the buffer of 4 words (16 bytes) containing the AES
|
|
* key. The first byte of the buffer shall be the most
|
|
* significant byte AES_KEY_0 of the AES key.
|
|
* The last byte of the buffer shall be the less significant byte
|
|
* AES_KEY_15 of the AES key. This parameter is an uint8_t*.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_read_key(FAR struct spirit_library_s *spirit, FAR uint8_t *key)
|
|
{
|
|
uint8_t tmp[16];
|
|
int ret;
|
|
int i;
|
|
|
|
/* Reads the AES_DATA_IN registers */
|
|
|
|
ret = spirit_reg_read(spirit, AES_KEY_IN_15_BASE, tmp, 16);
|
|
if (ret >= 0)
|
|
{
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
key[i] = tmp[15 - i];
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_enc2deckey
|
|
*
|
|
* Description:
|
|
* Derives the decryption key from a given encryption key.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_enc2deckey(FAR struct spirit_library_s *spirit)
|
|
{
|
|
/* Sends the COMMAND_AES_KEY command */
|
|
|
|
return spirit_command(spirit, COMMAND_AES_KEY);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_encrypt
|
|
*
|
|
* Description:
|
|
* Executes the encryption operation.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_encrypt(FAR struct spirit_library_s *spirit)
|
|
{
|
|
/* Sends the COMMAND_AES_ENC command */
|
|
|
|
return spirit_command(spirit, COMMAND_AES_ENC);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_decrypt
|
|
*
|
|
* Description:
|
|
* Executes the decryption operation.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_decrypt(FAR struct spirit_library_s *spirit)
|
|
{
|
|
/* Sends the COMMAND_AES_DEC command */
|
|
|
|
return spirit_command(spirit, COMMAND_AES_DEC);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_aes_derivekey_decrypt
|
|
*
|
|
* Description:
|
|
* Executes the key derivation and the decryption operation.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_aes_derivekey_decrypt(FAR struct spirit_library_s *spirit)
|
|
{
|
|
/* Sends the COMMAND_AES_KEY_DEC command */
|
|
|
|
return spirit_command(spirit, COMMAND_AES_KEY_DEC);
|
|
}
|