| /****************************************************************************** |
| * drivers/wireless/spirit/lib/spirit_aes.c |
| * |
| * Copyright(c) 2015 STMicroelectronics |
| * Author: VMA division - AMS |
| * Version 3.2.2 08-July-2015 |
| * |
| * 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 description 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); |
| } |