cc2538: Add crypto drivers and examples for AES-CCM and SHA-256
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
This commit is contained in:
parent
c03536f04e
commit
117dc4e5e3
|
@ -49,6 +49,7 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm
|
|||
### CPU-dependent source files
|
||||
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c
|
||||
CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
|
||||
CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ccm.c sha256.c
|
||||
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
|
||||
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
||||
|
|
118
cpu/cc2538/dev/aes.c
Normal file
118
cpu/cc2538/dev/aes.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-aes
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 AES driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "dev/rom-util.h"
|
||||
#include "dev/aes.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
aes_load_key(const void *key, uint8_t key_area)
|
||||
{
|
||||
uint32_t aligned_key[4];
|
||||
|
||||
/* The key address needs to be 4-byte aligned */
|
||||
rom_util_memcpy(aligned_key, key, sizeof(aligned_key));
|
||||
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
/* Configure master control module */
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_KEYSTORE;
|
||||
|
||||
/* Clear any outstanding events */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Configure key store module (area, size): 128-bit key size */
|
||||
REG(AES_KEY_STORE_SIZE) = (REG(AES_KEY_STORE_SIZE) &
|
||||
~AES_KEY_STORE_SIZE_KEY_SIZE_M) |
|
||||
AES_KEY_STORE_SIZE_KEY_SIZE_128;
|
||||
|
||||
/* Enable keys to write (e.g. Key 0) */
|
||||
REG(AES_KEY_STORE_WRITE_AREA) = 0x00000001 << key_area;
|
||||
|
||||
/* Configure DMAC
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
|
||||
/* Base address of the key in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)aligned_key;
|
||||
|
||||
/* Total key length in bytes (e.g. 16 for 1 x 128-bit key) */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = (REG(AES_DMAC_CH0_DMALENGTH) &
|
||||
~AES_DMAC_CH_DMALENGTH_DMALEN_M) |
|
||||
(0x10 << AES_DMAC_CH_DMALENGTH_DMALEN_S);
|
||||
|
||||
/* Wait for operation to complete */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV));
|
||||
|
||||
/* Check for absence of errors in DMA and key store */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) {
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_WR_ERR;
|
||||
return AES_KEYSTORE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
/* Acknowledge the interrupt */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
|
||||
/* Check status, if error return error code */
|
||||
if(!(REG(AES_KEY_STORE_WRITTEN_AREA) & (0x00000001 << key_area))) {
|
||||
return AES_KEYSTORE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/** @} */
|
487
cpu/cc2538/dev/aes.h
Normal file
487
cpu/cc2538/dev/aes.h
Normal file
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-crypto
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-aes cc2538 AES
|
||||
*
|
||||
* Driver for the cc2538 AES modes of the security core
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 AES driver
|
||||
*/
|
||||
#ifndef AES_H_
|
||||
#define AES_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/crypto.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES register offsets
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_CH0_CTRL 0x4008B000 /**< Channel 0 control */
|
||||
#define AES_DMAC_CH0_EXTADDR 0x4008B004 /**< Channel 0 external address */
|
||||
#define AES_DMAC_CH0_DMALENGTH 0x4008B00C /**< Channel 0 DMA length */
|
||||
#define AES_DMAC_STATUS 0x4008B018 /**< DMAC status */
|
||||
#define AES_DMAC_SWRES 0x4008B01C /**< DMAC software reset */
|
||||
#define AES_DMAC_CH1_CTRL 0x4008B020 /**< Channel 1 control */
|
||||
#define AES_DMAC_CH1_EXTADDR 0x4008B024 /**< Channel 1 external address */
|
||||
#define AES_DMAC_CH1_DMALENGTH 0x4008B02C /**< Channel 1 DMA length */
|
||||
#define AES_DMAC_MST_RUNPARAMS 0x4008B078 /**< DMAC master run-time parameters */
|
||||
#define AES_DMAC_PERSR 0x4008B07C /**< DMAC port error raw status */
|
||||
#define AES_DMAC_OPTIONS 0x4008B0F8 /**< DMAC options */
|
||||
#define AES_DMAC_VERSION 0x4008B0FC /**< DMAC version */
|
||||
#define AES_KEY_STORE_WRITE_AREA \
|
||||
0x4008B400 /**< Key store write area */
|
||||
#define AES_KEY_STORE_WRITTEN_AREA \
|
||||
0x4008B404 /**< Key store written area */
|
||||
#define AES_KEY_STORE_SIZE 0x4008B408 /**< Key store size */
|
||||
#define AES_KEY_STORE_READ_AREA 0x4008B40C /**< Key store read area */
|
||||
#define AES_AES_KEY2_0 0x4008B500 /**< AES_KEY2_0 / AES_GHASH_H_IN_0 */
|
||||
#define AES_AES_KEY2_1 0x4008B504 /**< AES_KEY2_1 / AES_GHASH_H_IN_1 */
|
||||
#define AES_AES_KEY2_2 0x4008B508 /**< AES_KEY2_2 / AES_GHASH_H_IN_2 */
|
||||
#define AES_AES_KEY2_3 0x4008B50C /**< AES_KEY2_3 / AES_GHASH_H_IN_3 */
|
||||
#define AES_AES_KEY3_0 0x4008B510 /**< AES_KEY3_0 / AES_KEY2_4 */
|
||||
#define AES_AES_KEY3_1 0x4008B514 /**< AES_KEY3_1 / AES_KEY2_5 */
|
||||
#define AES_AES_KEY3_2 0x4008B518 /**< AES_KEY3_2 / AES_KEY2_6 */
|
||||
#define AES_AES_KEY3_3 0x4008B51C /**< AES_KEY3_3 / AES_KEY2_7 */
|
||||
#define AES_AES_IV_0 0x4008B540 /**< AES initialization vector */
|
||||
#define AES_AES_IV_1 0x4008B544 /**< AES initialization vector */
|
||||
#define AES_AES_IV_2 0x4008B548 /**< AES initialization vector */
|
||||
#define AES_AES_IV_3 0x4008B54C /**< AES initialization vector */
|
||||
#define AES_AES_CTRL 0x4008B550 /**< AES input/output buffer control and mode */
|
||||
#define AES_AES_C_LENGTH_0 0x4008B554 /**< AES crypto length (LSW) */
|
||||
#define AES_AES_C_LENGTH_1 0x4008B558 /**< AES crypto length (MSW) */
|
||||
#define AES_AES_AUTH_LENGTH 0x4008B55C /**< Authentication length */
|
||||
#define AES_AES_DATA_IN_OUT_0 0x4008B560 /**< Data input/output */
|
||||
#define AES_AES_DATA_IN_OUT_1 0x4008B564 /**< Data Input/Output */
|
||||
#define AES_AES_DATA_IN_OUT_2 0x4008B568 /**< Data Input/Output */
|
||||
#define AES_AES_DATA_IN_OUT_3 0x4008B56C /**< Data Input/Output */
|
||||
#define AES_AES_TAG_OUT_0 0x4008B570 /**< TAG */
|
||||
#define AES_AES_TAG_OUT_1 0x4008B574 /**< TAG */
|
||||
#define AES_AES_TAG_OUT_2 0x4008B578 /**< TAG */
|
||||
#define AES_AES_TAG_OUT_3 0x4008B57C /**< TAG */
|
||||
#define AES_HASH_DATA_IN_0 0x4008B600 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_1 0x4008B604 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_2 0x4008B608 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_3 0x4008B60C /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_4 0x4008B610 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_5 0x4008B614 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_6 0x4008B618 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_7 0x4008B61C /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_8 0x4008B620 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_9 0x4008B624 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_10 0x4008B628 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_11 0x4008B62C /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_12 0x4008B630 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_13 0x4008B634 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_14 0x4008B638 /**< HASH data input */
|
||||
#define AES_HASH_DATA_IN_15 0x4008B63C /**< HASH data input */
|
||||
#define AES_HASH_IO_BUF_CTRL 0x4008B640 /**< Input/output buffer control and status */
|
||||
#define AES_HASH_MODE_IN 0x4008B644 /**< Hash mode */
|
||||
#define AES_HASH_LENGTH_IN_L 0x4008B648 /**< Hash length */
|
||||
#define AES_HASH_LENGTH_IN_H 0x4008B64C /**< Hash length */
|
||||
#define AES_HASH_DIGEST_A 0x4008B650 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_B 0x4008B654 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_C 0x4008B658 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_D 0x4008B65C /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_E 0x4008B660 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_F 0x4008B664 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_G 0x4008B668 /**< Hash digest */
|
||||
#define AES_HASH_DIGEST_H 0x4008B66C /**< Hash digest */
|
||||
#define AES_CTRL_ALG_SEL 0x4008B700 /**< Algorithm select */
|
||||
#define AES_CTRL_PROT_EN 0x4008B704 /**< Master PROT privileged access enable */
|
||||
#define AES_CTRL_SW_RESET 0x4008B740 /**< Software reset */
|
||||
#define AES_CTRL_INT_CFG 0x4008B780 /**< Interrupt configuration */
|
||||
#define AES_CTRL_INT_EN 0x4008B784 /**< Interrupt enable */
|
||||
#define AES_CTRL_INT_CLR 0x4008B788 /**< Interrupt clear */
|
||||
#define AES_CTRL_INT_SET 0x4008B78C /**< Interrupt set */
|
||||
#define AES_CTRL_INT_STAT 0x4008B790 /**< Interrupt status */
|
||||
#define AES_CTRL_OPTIONS 0x4008B7F8 /**< Options */
|
||||
#define AES_CTRL_VERSION 0x4008B7FC /**< Version */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_CHx_CTRL registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_CH_CTRL_PRIO 0x00000002 /**< Channel priority 0: Low 1: High */
|
||||
#define AES_DMAC_CH_CTRL_EN 0x00000001 /**< Channel enable */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_CHx_DMALENGTH registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_CH_DMALENGTH_DMALEN_M \
|
||||
0x0000FFFF /**< Channel DMA length in bytes mask */
|
||||
#define AES_DMAC_CH_DMALENGTH_DMALEN_S 0 /**< Channel DMA length in bytes shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_STATUS register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_STATUS_PORT_ERR \
|
||||
0x00020000 /**< AHB port transfer errors */
|
||||
#define AES_DMAC_STATUS_CH1_ACT 0x00000002 /**< Channel 1 active (DMA transfer on-going) */
|
||||
#define AES_DMAC_STATUS_CH0_ACT 0x00000001 /**< Channel 0 active (DMA transfer on-going) */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_SWRES register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_SWRES_SWRES 0x00000001 /**< Software reset enable */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_MST_RUNPARAMS register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_4 \
|
||||
(2 << 12) /**< Maximum burst size: 4 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_8 \
|
||||
(3 << 12) /**< Maximum burst size: 8 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_16 \
|
||||
(4 << 12) /**< Maximum burst size: 16 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_32 \
|
||||
(5 << 12) /**< Maximum burst size: 32 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_64 \
|
||||
(6 << 12) /**< Maximum burst size: 64 bytes */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_M \
|
||||
0x0000F000 /**< Maximum burst size mask */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_S \
|
||||
12 /**< Maximum burst size shift */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_IDLE_EN \
|
||||
0x00000800 /**< Idle insertion between bursts */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_INCR_EN \
|
||||
0x00000400 /**< Fixed-length burst or single transfers */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_LOCK_EN \
|
||||
0x00000200 /**< Locked transfers */
|
||||
#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BIGEND \
|
||||
0x00000100 /**< Big endian AHB master */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_PERSR register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_PERSR_PORT1_AHB_ERROR \
|
||||
0x00001000 /**< AHB bus error */
|
||||
#define AES_DMAC_PERSR_PORT1_CHANNEL \
|
||||
0x00000200 /**< Last serviced channel (0 or 1) */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_OPTIONS register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_M \
|
||||
0x00000F00 /**< Number of channels implemented mask */
|
||||
#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_S \
|
||||
8 /**< Number of channels implemented shift */
|
||||
#define AES_DMAC_OPTIONS_NR_OF_PORTS_M \
|
||||
0x00000007 /**< Number of ports implemented mask */
|
||||
#define AES_DMAC_OPTIONS_NR_OF_PORTS_S 0 /**< Number of ports implemented shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_DMAC_VERSION register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_DMAC_VERSION_HW_MAJOR_VERSION_M \
|
||||
0x0F000000 /**< Major version number mask */
|
||||
#define AES_DMAC_VERSION_HW_MAJOR_VERSION_S \
|
||||
24 /**< Major version number shift */
|
||||
#define AES_DMAC_VERSION_HW_MINOR_VERSION_M \
|
||||
0x00F00000 /**< Minor version number mask */
|
||||
#define AES_DMAC_VERSION_HW_MINOR_VERSION_S \
|
||||
20 /**< Minor version number shift */
|
||||
#define AES_DMAC_VERSION_HW_PATCH_LEVEL_M \
|
||||
0x000F0000 /**< Patch level mask */
|
||||
#define AES_DMAC_VERSION_HW_PATCH_LEVEL_S \
|
||||
16 /**< Patch level shift */
|
||||
#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_M \
|
||||
0x0000FF00 /**< EIP_NUMBER 1's complement mask */
|
||||
#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_S \
|
||||
8 /**< EIP_NUMBER 1's complement shift */
|
||||
#define AES_DMAC_VERSION_EIP_NUMBER_M \
|
||||
0x000000FF /**< DMAC EIP-number mask */
|
||||
#define AES_DMAC_VERSION_EIP_NUMBER_S 0 /**< DMAC EIP-number shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_KEY_STORE_SIZE register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_128 1 /**< Key size: 128 bits */
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_192 2 /**< Key size: 192 bits */
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_256 3 /**< Key size: 256 bits */
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_M \
|
||||
0x00000003 /**< Key size mask */
|
||||
#define AES_KEY_STORE_SIZE_KEY_SIZE_S 0 /**< Key size shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_KEY_STORE_READ_AREA register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_KEY_STORE_READ_AREA_BUSY \
|
||||
0x80000000 /**< Key store operation busy */
|
||||
#define AES_KEY_STORE_READ_AREA_RAM_AREA_M \
|
||||
0x0000000F /**< Key store RAM area select mask */
|
||||
#define AES_KEY_STORE_READ_AREA_RAM_AREA_S \
|
||||
0 /**< Key store RAM area select shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_AES_CTRL register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_AES_CTRL_CONTEXT_READY \
|
||||
0x80000000 /**< Context data registers can be overwritten */
|
||||
#define AES_AES_CTRL_SAVED_CONTEXT_READY \
|
||||
0x40000000 /**< AES auth. TAG and/or IV block(s) available */
|
||||
#define AES_AES_CTRL_SAVE_CONTEXT \
|
||||
0x20000000 /**< Auth. TAG or result IV needs to be stored */
|
||||
#define AES_AES_CTRL_CCM_M_M 0x01C00000 /**< CCM auth. field length mask */
|
||||
#define AES_AES_CTRL_CCM_M_S 22 /**< CCM auth. field length shift */
|
||||
#define AES_AES_CTRL_CCM_L_M 0x00380000 /**< CCM length field width mask */
|
||||
#define AES_AES_CTRL_CCM_L_S 19 /**< CCM length field width shift */
|
||||
#define AES_AES_CTRL_CCM 0x00040000 /**< AES-CCM mode */
|
||||
#define AES_AES_CTRL_GCM 0x00030000 /**< AES-GCM mode */
|
||||
#define AES_AES_CTRL_CBC_MAC 0x00008000 /**< AES-CBC MAC mode */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_32 (0 << 7) /**< CTR counter width: 32 bits */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_64 (1 << 7) /**< CTR counter width: 64 bits */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_96 (2 << 7) /**< CTR counter width: 96 bits */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_128 \
|
||||
(3 << 7) /**< CTR counter width: 128 bits */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_M \
|
||||
0x00000180 /**< CTR counter width mask */
|
||||
#define AES_AES_CTRL_CTR_WIDTH_S 7 /**< CTR counter width shift */
|
||||
#define AES_AES_CTRL_CTR 0x00000040 /**< AES-CTR mode */
|
||||
#define AES_AES_CTRL_CBC 0x00000020 /**< AES-CBC mode */
|
||||
#define AES_AES_CTRL_KEY_SIZE_128 (1 << 3) /**< Key size: 128 bits */
|
||||
#define AES_AES_CTRL_KEY_SIZE_192 (2 << 3) /**< Key size: 192 bits */
|
||||
#define AES_AES_CTRL_KEY_SIZE_256 (3 << 3) /**< Key size: 256 bits */
|
||||
#define AES_AES_CTRL_KEY_SIZE_M 0x00000018 /**< Key size mask */
|
||||
#define AES_AES_CTRL_KEY_SIZE_S 3 /**< Key size shift */
|
||||
#define AES_AES_CTRL_DIRECTION_ENCRYPT \
|
||||
0x00000004 /**< Encrypt */
|
||||
#define AES_AES_CTRL_INPUT_READY \
|
||||
0x00000002 /**< AES input buffer empty */
|
||||
#define AES_AES_CTRL_OUTPUT_READY \
|
||||
0x00000001 /**< AES output block available */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_AES_C_LENGTH_1 register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_AES_C_LENGTH_1_C_LENGTH_M \
|
||||
0x1FFFFFFF /**< Crypto length bits [60:32] mask */
|
||||
#define AES_AES_C_LENGTH_1_C_LENGTH_S 0 /**< Crypto length bits [60:32] shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_HASH_IO_BUF_CTRL register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE \
|
||||
0x00000080 /**< Hash engine message padding required */
|
||||
#define AES_HASH_IO_BUF_CTRL_GET_DIGEST \
|
||||
0x00000040 /**< Hash engine digest requested */
|
||||
#define AES_HASH_IO_BUF_CTRL_PAD_MESSAGE \
|
||||
0x00000020 /**< Last message data in HASH_DATA_IN, apply hash padding */
|
||||
#define AES_HASH_IO_BUF_CTRL_RFD_IN \
|
||||
0x00000004 /**< Hash engine input buffer can accept new data */
|
||||
#define AES_HASH_IO_BUF_CTRL_DATA_IN_AV \
|
||||
0x00000002 /**< Start processing HASH_DATA_IN data */
|
||||
#define AES_HASH_IO_BUF_CTRL_OUTPUT_FULL \
|
||||
0x00000001 /**< Output buffer registers available */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_HASH_MODE_IN register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_HASH_MODE_IN_SHA256_MODE \
|
||||
0x00000008 /**< Hash mode */
|
||||
#define AES_HASH_MODE_IN_NEW_HASH \
|
||||
0x00000001 /**< New hash session */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_ALG_SEL register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_ALG_SEL_TAG 0x80000000 /**< DMA operation includes TAG */
|
||||
#define AES_CTRL_ALG_SEL_HASH 0x00000004 /**< Select hash engine as DMA destination */
|
||||
#define AES_CTRL_ALG_SEL_AES 0x00000002 /**< Select AES engine as DMA source/destination */
|
||||
#define AES_CTRL_ALG_SEL_KEYSTORE \
|
||||
0x00000001 /**< Select Key Store as DMA destination */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_PROT_EN register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_PROT_EN_PROT_EN \
|
||||
0x00000001 /**< m_h_prot[1] asserted for DMA reads towards key store */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_SW_RESET register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_SW_RESET_SW_RESET \
|
||||
0x00000001 /**< Reset master control and key store */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_CFG register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_CFG_LEVEL 0x00000001 /**< Level interrupt type */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_EN register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_EN_DMA_IN_DONE \
|
||||
0x00000002 /**< DMA input done interrupt enabled */
|
||||
#define AES_CTRL_INT_EN_RESULT_AV \
|
||||
0x00000001 /**< Result available interrupt enabled */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_CLR register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_CLR_DMA_BUS_ERR \
|
||||
0x80000000 /**< Clear DMA bus error status */
|
||||
#define AES_CTRL_INT_CLR_KEY_ST_WR_ERR \
|
||||
0x40000000 /**< Clear key store write error status */
|
||||
#define AES_CTRL_INT_CLR_KEY_ST_RD_ERR \
|
||||
0x20000000 /**< Clear key store read error status */
|
||||
#define AES_CTRL_INT_CLR_DMA_IN_DONE \
|
||||
0x00000002 /**< Clear DMA in done interrupt */
|
||||
#define AES_CTRL_INT_CLR_RESULT_AV \
|
||||
0x00000001 /**< Clear result available interrupt */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_SET register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_SET_DMA_IN_DONE \
|
||||
0x00000002 /**< Set DMA data in done interrupt */
|
||||
#define AES_CTRL_INT_SET_RESULT_AV \
|
||||
0x00000001 /**< Set result available interrupt */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_INT_STAT register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_INT_STAT_DMA_BUS_ERR \
|
||||
0x80000000 /**< DMA bus error detected */
|
||||
#define AES_CTRL_INT_STAT_KEY_ST_WR_ERR \
|
||||
0x40000000 /**< Write error detected */
|
||||
#define AES_CTRL_INT_STAT_KEY_ST_RD_ERR \
|
||||
0x20000000 /**< Read error detected */
|
||||
#define AES_CTRL_INT_STAT_DMA_IN_DONE \
|
||||
0x00000002 /**< DMA data in done interrupt status */
|
||||
#define AES_CTRL_INT_STAT_RESULT_AV \
|
||||
0x00000001 /**< Result available interrupt status */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_OPTIONS register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_OPTIONS_TYPE_M 0xFF000000 /**< Device type mask */
|
||||
#define AES_CTRL_OPTIONS_TYPE_S 24 /**< Device type shift */
|
||||
#define AES_CTRL_OPTIONS_AHBINTERFACE \
|
||||
0x00010000 /**< AHB interface available */
|
||||
#define AES_CTRL_OPTIONS_SHA_256 \
|
||||
0x00000100 /**< The HASH core supports SHA-256 */
|
||||
#define AES_CTRL_OPTIONS_AES_CCM \
|
||||
0x00000080 /**< AES-CCM available as single operation */
|
||||
#define AES_CTRL_OPTIONS_AES_GCM \
|
||||
0x00000040 /**< AES-GCM available as single operation */
|
||||
#define AES_CTRL_OPTIONS_AES_256 \
|
||||
0x00000020 /**< AES core supports 256-bit keys */
|
||||
#define AES_CTRL_OPTIONS_AES_128 \
|
||||
0x00000010 /**< AES core supports 128-bit keys */
|
||||
#define AES_CTRL_OPTIONS_HASH 0x00000004 /**< HASH Core available */
|
||||
#define AES_CTRL_OPTIONS_AES 0x00000002 /**< AES core available */
|
||||
#define AES_CTRL_OPTIONS_KEYSTORE \
|
||||
0x00000001 /**< KEY STORE available */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES_CTRL_VERSION register bit fields
|
||||
* @{
|
||||
*/
|
||||
#define AES_CTRL_VERSION_MAJOR_VERSION_M \
|
||||
0x0F000000 /**< Major version number mask */
|
||||
#define AES_CTRL_VERSION_MAJOR_VERSION_S \
|
||||
24 /**< Major version number shift */
|
||||
#define AES_CTRL_VERSION_MINOR_VERSION_M \
|
||||
0x00F00000 /**< Minor version number mask */
|
||||
#define AES_CTRL_VERSION_MINOR_VERSION_S \
|
||||
20 /**< Minor version number shift */
|
||||
#define AES_CTRL_VERSION_PATCH_LEVEL_M \
|
||||
0x000F0000 /**< Patch level mask */
|
||||
#define AES_CTRL_VERSION_PATCH_LEVEL_S 16 /**< Patch level shift */
|
||||
#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_M \
|
||||
0x0000FF00 /**< EIP_NUMBER 1's complement mask */
|
||||
#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_S \
|
||||
8 /**< EIP_NUMBER 1's complement shift */
|
||||
#define AES_CTRL_VERSION_EIP_NUMBER_M \
|
||||
0x000000FF /**< EIP-120t EIP-number mask */
|
||||
#define AES_CTRL_VERSION_EIP_NUMBER_S 0 /**< EIP-120t EIP-number shift */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES drivers return codes
|
||||
* @{
|
||||
*/
|
||||
#define AES_KEYSTORE_READ_ERROR 4
|
||||
#define AES_KEYSTORE_WRITE_ERROR 5
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Writes the key into the Key RAM
|
||||
* \param key Pointer to AES Key
|
||||
* \param key_area Area in Key RAM where to store the key (0 to 7)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES error code
|
||||
*/
|
||||
uint8_t aes_load_key(const void *key, uint8_t key_area);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* AES_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
376
cpu/cc2538/dev/ccm.c
Normal file
376
cpu/cc2538/dev/ccm.c
Normal file
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-ccm
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 AES-CCM driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "dev/rom-util.h"
|
||||
#include "dev/ccm.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_encrypt_start(uint8_t len_len, uint8_t key_area, const void *nonce,
|
||||
const void *adata, uint16_t adata_len, void *pdata,
|
||||
uint16_t pdata_len, uint8_t mic_len)
|
||||
{
|
||||
uint32_t iv[4];
|
||||
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES;
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
REG(AES_KEY_STORE_READ_AREA) = key_area;
|
||||
|
||||
/* Wait until key is loaded to the AES module */
|
||||
while(REG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY);
|
||||
|
||||
/* Check for Key Store read error */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) {
|
||||
/* Clear the Keystore Read error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
|
||||
return AES_KEYSTORE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* Prepare the encryption initialization vector
|
||||
* Flags: L' = L - 1 */
|
||||
((uint8_t *)iv)[0] = len_len - 1;
|
||||
/* Nonce */
|
||||
rom_util_memcpy(&((uint8_t *)iv)[1], nonce, 15 - len_len);
|
||||
/* Initialize counter to 0 */
|
||||
rom_util_memset(&((uint8_t *)iv)[16 - len_len], 0, len_len);
|
||||
|
||||
/* Write initialization vector */
|
||||
REG(AES_AES_IV_0) = iv[0];
|
||||
REG(AES_AES_IV_1) = iv[1];
|
||||
REG(AES_AES_IV_2) = iv[2];
|
||||
REG(AES_AES_IV_3) = iv[3];
|
||||
|
||||
/* Program AES-CCM-128 encryption */
|
||||
REG(AES_AES_CTRL) = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */
|
||||
(((MAX(mic_len, 2) - 2) >> 1) << AES_AES_CTRL_CCM_M_S) | /* M */
|
||||
((len_len - 1) << AES_AES_CTRL_CCM_L_S) | /* L */
|
||||
AES_AES_CTRL_CCM | /* CCM */
|
||||
AES_AES_CTRL_CTR_WIDTH_128 | /* CTR width 128 */
|
||||
AES_AES_CTRL_CTR | /* CTR */
|
||||
AES_AES_CTRL_KEY_SIZE_128 | /* Key = 128 */
|
||||
AES_AES_CTRL_DIRECTION_ENCRYPT; /* Encryption */
|
||||
|
||||
/* Write the length of the crypto block (lo) */
|
||||
REG(AES_AES_C_LENGTH_0) = pdata_len;
|
||||
/* Write the length of the crypto block (hi) */
|
||||
REG(AES_AES_C_LENGTH_1) = 0;
|
||||
|
||||
/* Write the length of the AAD data block (may be non-block size-aligned) */
|
||||
REG(AES_AES_AUTH_LENGTH) = adata_len;
|
||||
|
||||
if(adata_len != 0) {
|
||||
/* Configure DMAC to fetch the AAD data
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the AAD input data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)adata;
|
||||
/* AAD data length in bytes */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = adata_len;
|
||||
|
||||
/* Wait for completion of the AAD data transfer, DMA_IN_DONE */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE));
|
||||
|
||||
/* Check for the absence of error */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear interrupt status */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Enable result available bit in interrupt enable */
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
if(pdata_len != 0) {
|
||||
/* Configure DMAC
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the payload data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pdata;
|
||||
/* Payload data length in bytes */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = pdata_len;
|
||||
|
||||
/* Enable DMA channel 1 */
|
||||
REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the output data buffer */
|
||||
REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)pdata;
|
||||
/* Output data length in bytes */
|
||||
REG(AES_DMAC_CH1_DMALENGTH) = pdata_len;
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_encrypt_check_status(void)
|
||||
{
|
||||
return !!(REG(AES_CTRL_INT_STAT) &
|
||||
(AES_CTRL_INT_STAT_DMA_BUS_ERR | AES_CTRL_INT_STAT_KEY_ST_WR_ERR |
|
||||
AES_CTRL_INT_STAT_KEY_ST_RD_ERR | AES_CTRL_INT_STAT_RESULT_AV));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_encrypt_get_result(void *mic, uint8_t mic_len)
|
||||
{
|
||||
uint32_t tag[4];
|
||||
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) {
|
||||
/* Clear the Key Store Write error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_WR_ERR;
|
||||
return AES_KEYSTORE_WRITE_ERROR;
|
||||
}
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) {
|
||||
/* Clear the Key Store Read error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
|
||||
return AES_KEYSTORE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* Disable the master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
|
||||
/* Read tag
|
||||
* Wait for the context ready bit */
|
||||
while(!(REG(AES_AES_CTRL) & AES_AES_CTRL_SAVED_CONTEXT_READY));
|
||||
|
||||
/* Read the tag registers */
|
||||
tag[0] = REG(AES_AES_TAG_OUT_0);
|
||||
tag[1] = REG(AES_AES_TAG_OUT_1);
|
||||
tag[2] = REG(AES_AES_TAG_OUT_2);
|
||||
tag[3] = REG(AES_AES_TAG_OUT_3);
|
||||
|
||||
/* Clear the interrupt status */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Copy tag to MIC */
|
||||
rom_util_memcpy(mic, tag, mic_len);
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_decrypt_start(uint8_t len_len, uint8_t key_area, const void *nonce,
|
||||
const void *adata, uint16_t adata_len, void *cdata,
|
||||
uint16_t cdata_len, uint8_t mic_len)
|
||||
{
|
||||
uint16_t pdata_len = cdata_len - mic_len;
|
||||
uint32_t iv[4];
|
||||
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES;
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
REG(AES_KEY_STORE_READ_AREA) = key_area;
|
||||
|
||||
/* Wait until key is loaded to the AES module */
|
||||
while(REG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY);
|
||||
|
||||
/* Check for Key Store read error */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) {
|
||||
/* Clear the Keystore Read error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
|
||||
return AES_KEYSTORE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* Prepare the decryption initialization vector
|
||||
* Flags: L' = L - 1 */
|
||||
((uint8_t *)iv)[0] = len_len - 1;
|
||||
/* Nonce */
|
||||
rom_util_memcpy(&((uint8_t *)iv)[1], nonce, 15 - len_len);
|
||||
/* Initialize counter to 0 */
|
||||
rom_util_memset(&((uint8_t *)iv)[16 - len_len], 0, len_len);
|
||||
|
||||
/* Write initialization vector */
|
||||
REG(AES_AES_IV_0) = iv[0];
|
||||
REG(AES_AES_IV_1) = iv[1];
|
||||
REG(AES_AES_IV_2) = iv[2];
|
||||
REG(AES_AES_IV_3) = iv[3];
|
||||
|
||||
/* Program AES-CCM-128 decryption */
|
||||
REG(AES_AES_CTRL) = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */
|
||||
(((MAX(mic_len, 2) - 2) >> 1) << AES_AES_CTRL_CCM_M_S) | /* M */
|
||||
((len_len - 1) << AES_AES_CTRL_CCM_L_S) | /* L */
|
||||
AES_AES_CTRL_CCM | /* CCM */
|
||||
AES_AES_CTRL_CTR_WIDTH_128 | /* CTR width 128 */
|
||||
AES_AES_CTRL_CTR | /* CTR */
|
||||
AES_AES_CTRL_KEY_SIZE_128; /* Key = 128 */
|
||||
|
||||
/* Write the length of the crypto block (lo) */
|
||||
REG(AES_AES_C_LENGTH_0) = pdata_len;
|
||||
/* Write the length of the crypto block (hi) */
|
||||
REG(AES_AES_C_LENGTH_1) = 0;
|
||||
|
||||
/* Write the length of the AAD data block (may be non-block size-aligned) */
|
||||
REG(AES_AES_AUTH_LENGTH) = adata_len;
|
||||
|
||||
if(adata_len != 0) {
|
||||
/* Configure DMAC to fetch the AAD data
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the AAD input data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)adata;
|
||||
/* AAD data length in bytes */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = adata_len;
|
||||
|
||||
/* Wait for completion of the AAD data transfer, DMA_IN_DONE */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE));
|
||||
|
||||
/* Check for the absence of error */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear interrupt status */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Enable result available bit in interrupt enable */
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
if(pdata_len != 0) {
|
||||
/* Configure DMAC
|
||||
* Enable DMA channel 0 */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the payload data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)cdata;
|
||||
/* Payload data length in bytes */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = pdata_len;
|
||||
|
||||
/* Enable DMA channel 1 */
|
||||
REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the output data buffer */
|
||||
REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)cdata;
|
||||
/* Output data length in bytes */
|
||||
REG(AES_DMAC_CH1_DMALENGTH) = pdata_len;
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_decrypt_check_status(void)
|
||||
{
|
||||
/* Check if result is available or some error has occured */
|
||||
return ccm_auth_encrypt_check_status();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ccm_auth_decrypt_get_result(const void *cdata, uint16_t cdata_len,
|
||||
void *mic, uint8_t mic_len)
|
||||
{
|
||||
uint16_t pdata_len = cdata_len - mic_len;
|
||||
uint32_t tag[4];
|
||||
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) {
|
||||
/* Clear the Key Store Write error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_WR_ERR;
|
||||
return AES_KEYSTORE_WRITE_ERROR;
|
||||
}
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) {
|
||||
/* Clear the Key Store Read error bit */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
|
||||
return AES_KEYSTORE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* Disable the master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
|
||||
/* Read tag
|
||||
* Wait for the context ready bit */
|
||||
while(!(REG(AES_AES_CTRL) & AES_AES_CTRL_SAVED_CONTEXT_READY));
|
||||
|
||||
/* Read the tag registers */
|
||||
tag[0] = REG(AES_AES_TAG_OUT_0);
|
||||
tag[1] = REG(AES_AES_TAG_OUT_1);
|
||||
tag[2] = REG(AES_AES_TAG_OUT_2);
|
||||
tag[3] = REG(AES_AES_TAG_OUT_3);
|
||||
|
||||
/* Clear the interrupt status */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Check MIC */
|
||||
if(rom_util_memcmp(tag, &((const uint8_t *)cdata)[pdata_len], mic_len)) {
|
||||
return CCM_AUTHENTICATION_FAILED;
|
||||
}
|
||||
|
||||
/* Copy tag to MIC */
|
||||
rom_util_memcpy(mic, tag, mic_len);
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/** @} */
|
137
cpu/cc2538/dev/ccm.h
Normal file
137
cpu/cc2538/dev/ccm.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-aes
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ccm cc2538 AES-CCM
|
||||
*
|
||||
* Driver for the cc2538 AES-CCM mode of the security core
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 AES-CCM driver
|
||||
*/
|
||||
#ifndef CCM_H_
|
||||
#define CCM_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/aes.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES-CCM driver return codes
|
||||
* @{
|
||||
*/
|
||||
#define CCM_AUTHENTICATION_FAILED 6
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name AES-CCM functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Starts the CCM authentication and encryption operation
|
||||
* \param len_len Number of octets in length field (2, 4 or 8)
|
||||
* \param key_area Area in Key RAM where the key is stored (0 to 7)
|
||||
* \param nonce Pointer to nonce (15 - \p len_len octets)
|
||||
* \param adata Pointer to additional authenticated data, or \c NULL
|
||||
* \param adata_len Length of additional authenticated data in octets, or \c 0
|
||||
* \param pdata Pointer to message to authenticate and encrypt, or \c NULL
|
||||
* \param pdata_len Length of message to authenticate and encrypt in octets, or \c 0
|
||||
* \param mic_len Number of octets in authentication field (even value between 0 and 16)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code
|
||||
*/
|
||||
uint8_t ccm_auth_encrypt_start(uint8_t len_len, uint8_t key_area,
|
||||
const void *nonce, const void *adata,
|
||||
uint16_t adata_len, void *pdata,
|
||||
uint16_t pdata_len, uint8_t mic_len);
|
||||
|
||||
/** \brief Checks the status of the CCM authentication and encryption operation
|
||||
* \retval false Result not yet available, and no error occurred
|
||||
* \retval true Result available, or error occurred
|
||||
*/
|
||||
uint8_t ccm_auth_encrypt_check_status(void);
|
||||
|
||||
/** \brief Gets the result of the CCM authentication and encryption operation
|
||||
* \param mic Pointer to authentication field, or \c NULL
|
||||
* \param mic_len Number of octets in authentication field (even value between 0 and 16)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code
|
||||
* \note This function must be called only after \c ccm_auth_encrypt_start().
|
||||
*/
|
||||
uint8_t ccm_auth_encrypt_get_result(void *mic, uint8_t mic_len);
|
||||
|
||||
/** \brief Starts the CCM authentication checking and decryption operation
|
||||
* \param len_len Number of octets in length field (2, 4 or 8)
|
||||
* \param key_area Area in Key RAM where the key is stored (0 to 7)
|
||||
* \param nonce Pointer to nonce (15 - \p len_len octets)
|
||||
* \param adata Pointer to additional authenticated data, or \c NULL
|
||||
* \param adata_len Length of additional authenticated data in octets, or \c 0
|
||||
* \param cdata Pointer to encrypted and authenticated message
|
||||
* \param cdata_len Length of encrypted and authenticated message in octets
|
||||
* \param mic_len Number of octets in authentication field (even value between 0 and 16)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code
|
||||
*/
|
||||
uint8_t ccm_auth_decrypt_start(uint8_t len_len, uint8_t key_area,
|
||||
const void *nonce, const void *adata,
|
||||
uint16_t adata_len, void *cdata,
|
||||
uint16_t cdata_len, uint8_t mic_len);
|
||||
|
||||
/** \brief Checks the status of the CCM authentication checking and decryption operation
|
||||
* \retval false Result not yet available, and no error occurred
|
||||
* \retval true Result available, or error occurred
|
||||
*/
|
||||
uint8_t ccm_auth_decrypt_check_status(void);
|
||||
|
||||
/** \brief Gets the result of the CCM authentication checking and decryption operation
|
||||
* \param cdata Pointer to encrypted and authenticated message
|
||||
* \param cdata_len Length of encrypted and authenticated message in octets
|
||||
* \param mic Pointer to authentication field, or \c NULL
|
||||
* \param mic_len Number of octets in authentication field (even value between 0 and 16)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code
|
||||
* \note This function must be called only after \c ccm_auth_decrypt_start().
|
||||
*/
|
||||
uint8_t ccm_auth_decrypt_get_result(const void *cdata, uint16_t cdata_len,
|
||||
void *mic, uint8_t mic_len);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* CCM_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
74
cpu/cc2538/dev/crypto.c
Normal file
74
cpu/cc2538/dev/crypto.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-crypto
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 AES/SHA cryptoprocessor driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "dev/sys-ctrl.h"
|
||||
#include "dev/crypto.h"
|
||||
#include "reg.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
crypto_init(void)
|
||||
{
|
||||
volatile int i;
|
||||
|
||||
crypto_enable();
|
||||
|
||||
/* Reset the AES/SHA cryptoprocessor */
|
||||
REG(SYS_CTRL_SRSEC) |= SYS_CTRL_SRSEC_AES;
|
||||
for(i = 0; i < 16; i++);
|
||||
REG(SYS_CTRL_SRSEC) &= ~SYS_CTRL_SRSEC_AES;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
crypto_enable(void)
|
||||
{
|
||||
/* Enable the clock for the AES/SHA cryptoprocessor */
|
||||
REG(SYS_CTRL_RCGCSEC) |= SYS_CTRL_RCGCSEC_AES;
|
||||
REG(SYS_CTRL_SCGCSEC) |= SYS_CTRL_SCGCSEC_AES;
|
||||
REG(SYS_CTRL_DCGCSEC) |= SYS_CTRL_DCGCSEC_AES;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
crypto_disable(void)
|
||||
{
|
||||
/* Gate the clock for the AES/SHA cryptoprocessor */
|
||||
REG(SYS_CTRL_RCGCSEC) &= ~SYS_CTRL_RCGCSEC_AES;
|
||||
REG(SYS_CTRL_SCGCSEC) &= ~SYS_CTRL_SCGCSEC_AES;
|
||||
REG(SYS_CTRL_DCGCSEC) &= ~SYS_CTRL_DCGCSEC_AES;
|
||||
}
|
||||
|
||||
/** @} */
|
81
cpu/cc2538/dev/crypto.h
Normal file
81
cpu/cc2538/dev/crypto.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-crypto cc2538 AES/SHA cryptoprocessor
|
||||
*
|
||||
* Driver for the cc2538 AES/SHA cryptoprocessor
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 AES/SHA cryptoprocessor driver
|
||||
*/
|
||||
#ifndef CRYPTO_H_
|
||||
#define CRYPTO_H_
|
||||
|
||||
#include "contiki.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Crypto drivers return codes
|
||||
* @{
|
||||
*/
|
||||
#define CRYPTO_SUCCESS 0
|
||||
#define CRYPTO_INVALID_PARAM 1
|
||||
#define CRYPTO_NULL_ERROR 2
|
||||
#define CRYPTO_DMA_BUS_ERROR 3
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Crypto functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Enables and resets the AES/SHA cryptoprocessor
|
||||
*/
|
||||
void crypto_init(void);
|
||||
|
||||
/** \brief Enables the AES/SHA cryptoprocessor
|
||||
*/
|
||||
void crypto_enable(void);
|
||||
|
||||
/** \brief Disables the AES/SHA cryptoprocessor
|
||||
* \note Call this function to save power when the cryptoprocessor is unused.
|
||||
*/
|
||||
void crypto_disable(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* CRYPTO_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
344
cpu/cc2538/dev/sha256.c
Normal file
344
cpu/cc2538/dev/sha256.c
Normal file
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-sha256
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 SHA-256 driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "dev/rom-util.h"
|
||||
#include "dev/aes.h"
|
||||
#include "dev/sha256.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define BLOCK_SIZE 64
|
||||
#define OUTPUT_LEN 32
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Starts a new hash session in hardware
|
||||
* \param state Hash state
|
||||
* \param data Pointer to input message
|
||||
* \param hash Destination of the hash (32 bytes)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
*/
|
||||
static uint8_t
|
||||
new_hash(sha256_state_t *state, const void *data, void *hash)
|
||||
{
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
/* Configure master control module and enable DMA path to the SHA-256 engine
|
||||
* + Digest readout */
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_TAG | AES_CTRL_ALG_SEL_HASH;
|
||||
|
||||
/* Clear any outstanding events */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Configure hash engine
|
||||
* Indicate start of a new hash session and SHA-256 */
|
||||
REG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE |
|
||||
AES_HASH_MODE_IN_NEW_HASH;
|
||||
|
||||
/* If the final digest is required (pad the input DMA data), write the
|
||||
* following register */
|
||||
if(state->final_digest) {
|
||||
/* Write length of the message (lo) */
|
||||
REG(AES_HASH_LENGTH_IN_L) = (uint32_t)state->length;
|
||||
/* Write length of the message (hi) */
|
||||
REG(AES_HASH_LENGTH_IN_H) = (uint32_t)(state->length >> 32);
|
||||
/* Pad the DMA-ed data */
|
||||
REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE;
|
||||
}
|
||||
|
||||
/* Enable DMA channel 0 for message data */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data;
|
||||
if(state->final_digest) {
|
||||
/* Input data length in bytes, equal to the message */
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = state->curlen;
|
||||
} else {
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* Enable DMA channel 1 for result digest */
|
||||
REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the digest buffer */
|
||||
REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)hash;
|
||||
/* Length of the result digest */
|
||||
REG(AES_DMAC_CH1_DMALENGTH) = OUTPUT_LEN;
|
||||
|
||||
/* Wait for completion of the operation */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV));
|
||||
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
|
||||
/* Clear the interrupt */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
/* Clear mode */
|
||||
REG(AES_AES_CTRL) = 0x00000000;
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Resumes an already started hash session in hardware
|
||||
* \param state Hash state
|
||||
* \param data Pointer to the input message
|
||||
* \param hash Pointer to the destination of the hash (32 bytes)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
*/
|
||||
static uint8_t
|
||||
resume_hash(sha256_state_t *state, const void *data, void *hash)
|
||||
{
|
||||
/* Workaround for AES registers not retained after PM2 */
|
||||
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
|
||||
REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE |
|
||||
AES_CTRL_INT_EN_RESULT_AV;
|
||||
|
||||
/* Configure master control module and enable the DMA path to the SHA-256
|
||||
* engine */
|
||||
REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_HASH;
|
||||
|
||||
/* Clear any outstanding events */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV;
|
||||
|
||||
/* Configure hash engine
|
||||
* Indicate the start of a resumed hash session and SHA-256 */
|
||||
REG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE;
|
||||
|
||||
/* If the final digest is required (pad the input DMA data) */
|
||||
if(state->final_digest) {
|
||||
/* Write length of the message (lo) */
|
||||
REG(AES_HASH_LENGTH_IN_L) = (uint32_t)state->length;
|
||||
/* Write length of the message (hi) */
|
||||
REG(AES_HASH_LENGTH_IN_H) = (uint32_t)(state->length >> 32);
|
||||
}
|
||||
|
||||
/* Write the initial digest */
|
||||
REG(AES_HASH_DIGEST_A) = (uint32_t)state->state[0];
|
||||
REG(AES_HASH_DIGEST_B) = (uint32_t)state->state[1];
|
||||
REG(AES_HASH_DIGEST_C) = (uint32_t)state->state[2];
|
||||
REG(AES_HASH_DIGEST_D) = (uint32_t)state->state[3];
|
||||
REG(AES_HASH_DIGEST_E) = (uint32_t)state->state[4];
|
||||
REG(AES_HASH_DIGEST_F) = (uint32_t)state->state[5];
|
||||
REG(AES_HASH_DIGEST_G) = (uint32_t)state->state[6];
|
||||
REG(AES_HASH_DIGEST_H) = (uint32_t)state->state[7];
|
||||
|
||||
/* If final digest, pad the DMA-ed data */
|
||||
if(state->final_digest) {
|
||||
REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE;
|
||||
}
|
||||
|
||||
/* Enable DMA channel 0 for message data */
|
||||
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
|
||||
/* Base address of the data in ext. memory */
|
||||
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data;
|
||||
/* Input data length in bytes, equal to the message */
|
||||
if(state->final_digest) {
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = state->curlen;
|
||||
} else {
|
||||
REG(AES_DMAC_CH0_DMALENGTH) = BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* Wait for completion of the operation */
|
||||
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV));
|
||||
|
||||
/* Check for any DMA Bus errors */
|
||||
if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) {
|
||||
/* Clear the DMA error */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR;
|
||||
return CRYPTO_DMA_BUS_ERROR;
|
||||
}
|
||||
|
||||
/* Read digest */
|
||||
((uint32_t *)hash)[0] = REG(AES_HASH_DIGEST_A);
|
||||
((uint32_t *)hash)[1] = REG(AES_HASH_DIGEST_B);
|
||||
((uint32_t *)hash)[2] = REG(AES_HASH_DIGEST_C);
|
||||
((uint32_t *)hash)[3] = REG(AES_HASH_DIGEST_D);
|
||||
((uint32_t *)hash)[4] = REG(AES_HASH_DIGEST_E);
|
||||
((uint32_t *)hash)[5] = REG(AES_HASH_DIGEST_F);
|
||||
((uint32_t *)hash)[6] = REG(AES_HASH_DIGEST_G);
|
||||
((uint32_t *)hash)[7] = REG(AES_HASH_DIGEST_H);
|
||||
|
||||
/* Acknowledge reading of the digest */
|
||||
REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_OUTPUT_FULL;
|
||||
|
||||
/* Clear the interrupt */
|
||||
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
|
||||
AES_CTRL_INT_CLR_RESULT_AV;
|
||||
/* Disable master control / DMA clock */
|
||||
REG(AES_CTRL_ALG_SEL) = 0x00000000;
|
||||
/* Clear mode */
|
||||
REG(AES_AES_CTRL) = 0x00000000;
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
sha256_init(sha256_state_t *state)
|
||||
{
|
||||
if(state == NULL) {
|
||||
return CRYPTO_NULL_ERROR;
|
||||
}
|
||||
|
||||
state->curlen = 0;
|
||||
state->length = 0;
|
||||
state->new_digest = true;
|
||||
state->final_digest = false;
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
sha256_process(sha256_state_t *state, const void *data, uint32_t len)
|
||||
{
|
||||
uint32_t n;
|
||||
uint8_t ret;
|
||||
|
||||
if(state == NULL || data == NULL) {
|
||||
return CRYPTO_NULL_ERROR;
|
||||
}
|
||||
|
||||
if(state->curlen > sizeof(state->buf)) {
|
||||
return CRYPTO_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if(len > 0 && state->new_digest) {
|
||||
if(state->curlen == 0 && len > BLOCK_SIZE) {
|
||||
rom_util_memcpy(state->buf, data, BLOCK_SIZE);
|
||||
ret = new_hash(state, state->buf, state->state);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
state->new_digest = false;
|
||||
state->length += BLOCK_SIZE << 3;
|
||||
data += BLOCK_SIZE;
|
||||
len -= BLOCK_SIZE;
|
||||
} else {
|
||||
n = MIN(len, BLOCK_SIZE - state->curlen);
|
||||
rom_util_memcpy(&state->buf[state->curlen], data, n);
|
||||
state->curlen += n;
|
||||
data += n;
|
||||
len -= n;
|
||||
if(state->curlen == BLOCK_SIZE && len > 0) {
|
||||
ret = new_hash(state, state->buf, state->state);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
state->new_digest = false;
|
||||
state->length += BLOCK_SIZE << 3;
|
||||
state->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(len > 0 && !state->new_digest) {
|
||||
if(state->curlen == 0 && len > BLOCK_SIZE) {
|
||||
rom_util_memcpy(state->buf, data, BLOCK_SIZE);
|
||||
ret = resume_hash(state, state->buf, state->state);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
state->length += BLOCK_SIZE << 3;
|
||||
data += BLOCK_SIZE;
|
||||
len -= BLOCK_SIZE;
|
||||
} else {
|
||||
n = MIN(len, BLOCK_SIZE - state->curlen);
|
||||
rom_util_memcpy(&state->buf[state->curlen], data, n);
|
||||
state->curlen += n;
|
||||
data += n;
|
||||
len -= n;
|
||||
if(state->curlen == BLOCK_SIZE && len > 0) {
|
||||
ret = resume_hash(state, state->buf, state->state);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
state->length += BLOCK_SIZE << 3;
|
||||
state->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
sha256_done(sha256_state_t *state, void *hash)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
if(state == NULL || hash == NULL) {
|
||||
return CRYPTO_NULL_ERROR;
|
||||
}
|
||||
|
||||
if(state->curlen > sizeof(state->buf)) {
|
||||
return CRYPTO_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Increase the length of the message */
|
||||
state->length += state->curlen << 3;
|
||||
state->final_digest = true;
|
||||
if(state->new_digest) {
|
||||
ret = new_hash(state, state->buf, hash);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret = resume_hash(state, state->buf, hash);
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
state->new_digest = false;
|
||||
state->final_digest = false;
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/** @} */
|
103
cpu/cc2538/dev/sha256.h
Normal file
103
cpu/cc2538/dev/sha256.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-crypto
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-sha526 cc2538 SHA-256
|
||||
*
|
||||
* Driver for the cc2538 SHA-256 mode of the security core
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 SHA-256 driver
|
||||
*/
|
||||
#ifndef SHA256_H_
|
||||
#define SHA256_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/crypto.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SHA-256 structures
|
||||
* @{
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t length;
|
||||
uint32_t state[8];
|
||||
uint32_t curlen;
|
||||
uint8_t buf[64];
|
||||
uint8_t new_digest;
|
||||
uint8_t final_digest;
|
||||
} sha256_state_t;
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SHA-256 functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Initializes the hash state
|
||||
* \param state Pointer to hash state to initialize
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
*/
|
||||
uint8_t sha256_init(sha256_state_t *state);
|
||||
|
||||
/** \brief Processes a block of memory through the hash
|
||||
* \param state Pointer to hash state
|
||||
* \param data Pointer to the data to hash
|
||||
* \param len Length of the data to hash in bytes (octets)
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
* \note This function must be called only after \c sha256_init().
|
||||
*/
|
||||
uint8_t sha256_process(sha256_state_t *state, const void *data, uint32_t len);
|
||||
|
||||
/** \brief Terminates hash session to get the digest
|
||||
* \param state Pointer to hash state
|
||||
* \param hash Pointer to hash
|
||||
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code
|
||||
* \note This function must be called only after \c sha256_process().
|
||||
*/
|
||||
uint8_t sha256_done(sha256_state_t *state, void *hash);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* SHA256_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -161,6 +161,34 @@
|
|||
#define SYS_CTRL_SRGPT_GPT0 0x00000001 /**< GPT0 is reset */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_RCGCSEC register bit masks
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CTRL_RCGCSEC_AES 0x00000002 /**< AES clock enable, CPU running */
|
||||
#define SYS_CTRL_RCGCSEC_PKA 0x00000001 /**< PKA clock enable, CPU running */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_SCGCSEC register bit masks
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CTRL_SCGCSEC_AES 0x00000002 /**< AES clock enable, CPU IDLE */
|
||||
#define SYS_CTRL_SCGCSEC_PKA 0x00000001 /**< PKA clock enable, CPU IDLE */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_DCGCSEC register bit masks
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CTRL_DCGCSEC_AES 0x00000002 /**< AES clock enable, PM0 */
|
||||
#define SYS_CTRL_DCGCSEC_PKA 0x00000001 /**< PKA clock enable, PM0 */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_SRSEC register bits
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CTRL_SRSEC_AES 0x00000002 /**< AES is reset */
|
||||
#define SYS_CTRL_SRSEC_PKA 0x00000001 /**< PKA is reset */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SYS_CTRL_PWRDBG register bits
|
||||
* @{
|
||||
*/
|
||||
|
|
6
examples/cc2538dk/crypto/Makefile
Normal file
6
examples/cc2538dk/crypto/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
CONTIKI_PROJECT = ccm-test sha256-test
|
||||
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
CONTIKI = ../../..
|
||||
include $(CONTIKI)/Makefile.include
|
1
examples/cc2538dk/crypto/Makefile.target
Normal file
1
examples/cc2538dk/crypto/Makefile.target
Normal file
|
@ -0,0 +1 @@
|
|||
TARGET = cc2538dk
|
345
examples/cc2538dk/crypto/ccm-test.c
Normal file
345
examples/cc2538dk/crypto/ccm-test.c
Normal file
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-examples
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ccm-test cc2538dk AES-CCM Test Project
|
||||
*
|
||||
* AES-CCM access example for CC2538 on SmartRF06EB.
|
||||
*
|
||||
* This example shows how AES-CCM should be used. The example also verifies
|
||||
* the AES-CCM functionality.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Example demonstrating AES-CCM on the cc2538dk platform
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "sys/rtimer.h"
|
||||
#include "dev/rom-util.h"
|
||||
#include "dev/ccm.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(ccm_test_process, "ccm test process");
|
||||
AUTOSTART_PROCESSES(&ccm_test_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(ccm_test_process, ev, data)
|
||||
{
|
||||
static const char *const str_res[] = {
|
||||
"success",
|
||||
"invalid param",
|
||||
"NULL error",
|
||||
"DMA bus error",
|
||||
"keystore read error",
|
||||
"keystore write error",
|
||||
"authentication failed"
|
||||
};
|
||||
static struct {
|
||||
bool encrypt;
|
||||
uint8_t len_len;
|
||||
uint8_t key[16];
|
||||
uint8_t key_area;
|
||||
uint8_t nonce[13];
|
||||
uint8_t adata[26];
|
||||
uint16_t adata_len;
|
||||
uint8_t mdata[24];
|
||||
uint16_t mdata_len;
|
||||
uint8_t mic[8];
|
||||
uint8_t mic_len;
|
||||
uint8_t expected[24];
|
||||
} vectors[] = {
|
||||
{
|
||||
true, /* encrypt */
|
||||
2, /* len_len */
|
||||
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
|
||||
0, /* key_area */
|
||||
{ 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
|
||||
{}, /* adata */
|
||||
0, /* adata_len */
|
||||
{ 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f }, /* mdata */
|
||||
20, /* mdata_len */
|
||||
{}, /* mic */
|
||||
0, /* mic_len */
|
||||
{ 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0,
|
||||
0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6,
|
||||
0x2c, 0x61, 0x01, 0x4e } /* expected */
|
||||
}, {
|
||||
true, /* encrypt */
|
||||
2, /* len_len */
|
||||
{ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf }, /* key */
|
||||
0, /* key_area */
|
||||
{ 0xac, 0xde, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x05, 0x02 }, /* nonce */
|
||||
{ 0x08, 0xd0, 0x84, 0x21, 0x43, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x48, 0xde, 0xac, 0x02, 0x05, 0x00,
|
||||
0x00, 0x00, 0x55, 0xcf, 0x00, 0x00, 0x51, 0x52,
|
||||
0x53, 0x54 }, /* adata */
|
||||
26, /* adata_len */
|
||||
{}, /* mdata */
|
||||
0, /* mdata_len */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */
|
||||
8, /* mic_len */
|
||||
{ 0x22, 0x3b, 0xc1, 0xec, 0x84, 0x1a, 0xb5, 0x53 } /* expected */
|
||||
}, {
|
||||
true, /* encrypt */
|
||||
2, /* len_len */
|
||||
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
|
||||
0, /* key_area */
|
||||
{ 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
|
||||
{ 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01,
|
||||
0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03 }, /* adata */
|
||||
15, /* adata_len */
|
||||
{ 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f }, /* mdata */
|
||||
20, /* mdata_len */
|
||||
{ 0x00, 0x00, 0x00, 0x00 }, /* mic */
|
||||
4, /* mic_len */
|
||||
{ 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0,
|
||||
0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6,
|
||||
0x2c, 0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09 } /* expected */
|
||||
}, {
|
||||
false, /* decrypt */
|
||||
2, /* len_len */
|
||||
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
|
||||
0, /* key_area */
|
||||
{ 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
|
||||
{}, /* adata */
|
||||
0, /* adata_len */
|
||||
{ 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0,
|
||||
0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6,
|
||||
0x2c, 0x61, 0x01, 0x4e }, /* mdata */
|
||||
20, /* mdata_len */
|
||||
{}, /* mic */
|
||||
0, /* mic_len */
|
||||
{ 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f } /* expected */
|
||||
}, {
|
||||
false, /* decrypt */
|
||||
2, /* len_len */
|
||||
{ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf }, /* key */
|
||||
0, /* key_area */
|
||||
{ 0xac, 0xde, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x05, 0x02 }, /* nonce */
|
||||
{ 0x08, 0xd0, 0x84, 0x21, 0x43, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x48, 0xde, 0xac, 0x02, 0x05, 0x00,
|
||||
0x00, 0x00, 0x55, 0xcf, 0x00, 0x00, 0x51, 0x52,
|
||||
0x53, 0x54 }, /* adata */
|
||||
26, /* adata_len */
|
||||
{ 0x22, 0x3b, 0xc1, 0xec, 0x84, 0x1a, 0xb5, 0x53 }, /* mdata */
|
||||
8, /* mdata_len */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */
|
||||
8, /* mic_len */
|
||||
{} /* expected */
|
||||
}, {
|
||||
false, /* decrypt */
|
||||
2, /* len_len */
|
||||
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
|
||||
0, /* key_area */
|
||||
{ 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
|
||||
{ 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01,
|
||||
0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03 }, /* adata */
|
||||
15, /* adata_len */
|
||||
{ 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0,
|
||||
0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6,
|
||||
0x2c, 0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09 }, /* mdata */
|
||||
24, /* mdata_len */
|
||||
{ 0x00, 0x00, 0x00, 0x00 }, /* mic */
|
||||
4, /* mic_len */
|
||||
{ 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f } /* expected */
|
||||
}
|
||||
};
|
||||
static int i;
|
||||
static uint8_t ret;
|
||||
static rtimer_clock_t time, time2, total_time;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
puts("-----------------------------------------\n"
|
||||
"Initializing cryptoprocessor...");
|
||||
crypto_init();
|
||||
|
||||
for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
|
||||
printf("-----------------------------------------\n"
|
||||
"Test vector #%d: %s\n"
|
||||
"len_len=%d key_area=%d\n"
|
||||
"adata_len=%d mdata_len=%d mic_len=%d\n",
|
||||
i, vectors[i].encrypt ? "encrypt" : "decrypt",
|
||||
vectors[i].len_len, vectors[i].key_area,
|
||||
vectors[i].adata_len, vectors[i].mdata_len, vectors[i].mic_len);
|
||||
|
||||
time = RTIMER_NOW();
|
||||
ret = aes_load_key(vectors[i].key, vectors[i].key_area);
|
||||
time = RTIMER_NOW() - time;
|
||||
total_time = time;
|
||||
printf("aes_load_key(): %s, %lu us\n", str_res[ret],
|
||||
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
|
||||
PROCESS_PAUSE();
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
time = RTIMER_NOW();
|
||||
if(vectors[i].encrypt) {
|
||||
ret = ccm_auth_encrypt_start(vectors[i].len_len, vectors[i].key_area,
|
||||
vectors[i].nonce, vectors[i].adata,
|
||||
vectors[i].adata_len, vectors[i].mdata,
|
||||
vectors[i].mdata_len, vectors[i].mic_len);
|
||||
time2 = RTIMER_NOW();
|
||||
time = time2 - time;
|
||||
total_time += time;
|
||||
if(ret == CRYPTO_SUCCESS) {
|
||||
do {
|
||||
PROCESS_PAUSE();
|
||||
} while(!ccm_auth_encrypt_check_status());
|
||||
time2 = RTIMER_NOW() - time2;
|
||||
total_time += time2;
|
||||
}
|
||||
printf("ccm_auth_encrypt_start(): %s, %lu us\n", str_res[ret],
|
||||
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
PROCESS_PAUSE();
|
||||
continue;
|
||||
}
|
||||
printf("ccm_auth_encrypt_check_status() wait: %lu us\n",
|
||||
(uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND));
|
||||
|
||||
time = RTIMER_NOW();
|
||||
ret = ccm_auth_encrypt_get_result(vectors[i].mic, vectors[i].mic_len);
|
||||
time = RTIMER_NOW() - time;
|
||||
total_time += time;
|
||||
printf("ccm_auth_encrypt_get_result(): %s, %lu us\n", str_res[ret],
|
||||
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
|
||||
PROCESS_PAUSE();
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(rom_util_memcmp(vectors[i].mdata, vectors[i].expected,
|
||||
vectors[i].mdata_len)) {
|
||||
puts("Encrypted message does not match expected one");
|
||||
} else {
|
||||
puts("Encrypted message OK");
|
||||
}
|
||||
|
||||
if(rom_util_memcmp(vectors[i].mic,
|
||||
vectors[i].expected + vectors[i].mdata_len,
|
||||
vectors[i].mic_len)) {
|
||||
puts("MIC does not match expected one");
|
||||
} else {
|
||||
puts("MIC OK");
|
||||
}
|
||||
} else {
|
||||
ret = ccm_auth_decrypt_start(vectors[i].len_len, vectors[i].key_area,
|
||||
vectors[i].nonce, vectors[i].adata,
|
||||
vectors[i].adata_len, vectors[i].mdata,
|
||||
vectors[i].mdata_len, vectors[i].mic_len);
|
||||
time2 = RTIMER_NOW();
|
||||
time = time2 - time;
|
||||
total_time += time;
|
||||
if(ret == CRYPTO_SUCCESS) {
|
||||
do {
|
||||
PROCESS_PAUSE();
|
||||
} while(!ccm_auth_decrypt_check_status());
|
||||
time2 = RTIMER_NOW() - time2;
|
||||
total_time += time2;
|
||||
}
|
||||
printf("ccm_auth_decrypt_start(): %s, %lu us\n", str_res[ret],
|
||||
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
PROCESS_PAUSE();
|
||||
continue;
|
||||
}
|
||||
printf("ccm_auth_decrypt_check_status() wait: %lu us\n",
|
||||
(uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND));
|
||||
|
||||
time = RTIMER_NOW();
|
||||
ret = ccm_auth_decrypt_get_result(vectors[i].mdata, vectors[i].mdata_len,
|
||||
vectors[i].mic, vectors[i].mic_len);
|
||||
time = RTIMER_NOW() - time;
|
||||
total_time += time;
|
||||
printf("ccm_auth_decrypt_get_result(): %s, %lu us\n", str_res[ret],
|
||||
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
|
||||
PROCESS_PAUSE();
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(rom_util_memcmp(vectors[i].mdata, vectors[i].expected,
|
||||
vectors[i].mdata_len - vectors[i].mic_len)) {
|
||||
puts("Decrypted message does not match expected one");
|
||||
} else {
|
||||
puts("Decrypted message OK");
|
||||
}
|
||||
}
|
||||
|
||||
printf("Total duration: %lu us\n",
|
||||
(uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND));
|
||||
}
|
||||
|
||||
puts("-----------------------------------------\n"
|
||||
"Disabling cryptoprocessor...");
|
||||
crypto_disable();
|
||||
|
||||
puts("Done!");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
260
examples/cc2538dk/crypto/sha256-test.c
Normal file
260
examples/cc2538dk/crypto/sha256-test.c
Normal file
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-examples
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-sha256-test cc2538dk SHA-256 Test Project
|
||||
*
|
||||
* SHA-256 access example for CC2538 on SmartRF06EB.
|
||||
*
|
||||
* This example shows how SHA-256 should be used. The example also verifies
|
||||
* the SHA-256 functionality.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Example demonstrating SHA-256 on the cc2538dk platform
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "sys/rtimer.h"
|
||||
#include "dev/rom-util.h"
|
||||
#include "dev/sha256.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(sha256_test_process, "sha256 test process");
|
||||
AUTOSTART_PROCESSES(&sha256_test_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(sha256_test_process, ev, data)
|
||||
{
|
||||
static const char *const str_res[] = {
|
||||
"success",
|
||||
"invalid param",
|
||||
"NULL error",
|
||||
"DMA bus error"
|
||||
};
|
||||
static const struct {
|
||||
const char *data[3];
|
||||
uint8_t sha256[32];
|
||||
} vectors[] = {
|
||||
{ /* Simple */
|
||||
{
|
||||
"abc",
|
||||
NULL,
|
||||
NULL
|
||||
}, {
|
||||
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
|
||||
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
|
||||
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
|
||||
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
|
||||
}
|
||||
}, { /* Simple */
|
||||
{
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
NULL,
|
||||
NULL,
|
||||
}, {
|
||||
0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
|
||||
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
|
||||
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
|
||||
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
|
||||
}
|
||||
}, { /* Message of length 130 */
|
||||
{
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklabcd"
|
||||
"efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn",
|
||||
NULL,
|
||||
NULL
|
||||
}, {
|
||||
0x15, 0xd2, 0x3e, 0xea, 0x57, 0xb3, 0xd4, 0x61,
|
||||
0xbf, 0x38, 0x91, 0x12, 0xab, 0x4c, 0x43, 0xce,
|
||||
0x85, 0xe1, 0x68, 0x23, 0x8a, 0xaa, 0x54, 0x8e,
|
||||
0xc8, 0x6f, 0x0c, 0x9d, 0x65, 0xf9, 0xb9, 0x23
|
||||
}
|
||||
}, { /* Message of length 128 */
|
||||
{
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklabcd"
|
||||
"efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl",
|
||||
NULL,
|
||||
NULL
|
||||
}, {
|
||||
0xf8, 0xa3, 0xf2, 0x26, 0xfc, 0x42, 0x10, 0xe9,
|
||||
0x0d, 0x13, 0x0c, 0x7f, 0x41, 0xf2, 0xbe, 0x66,
|
||||
0x45, 0x53, 0x85, 0xd2, 0x92, 0x0a, 0xda, 0x78,
|
||||
0x15, 0xf8, 0xf7, 0x95, 0xd9, 0x44, 0x90, 0x5f
|
||||
}
|
||||
}, { /* Message of length 64 */
|
||||
{
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl",
|
||||
NULL,
|
||||
NULL
|
||||
}, {
|
||||
0x2f, 0xcd, 0x5a, 0x0d, 0x60, 0xe4, 0xc9, 0x41,
|
||||
0x38, 0x1f, 0xcc, 0x4e, 0x00, 0xa4, 0xbf, 0x8b,
|
||||
0xe4, 0x22, 0xc3, 0xdd, 0xfa, 0xfb, 0x93, 0xc8,
|
||||
0x09, 0xe8, 0xd1, 0xe2, 0xbf, 0xff, 0xae, 0x8e
|
||||
}
|
||||
}, { /* Message of length 66 */
|
||||
{
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn",
|
||||
NULL,
|
||||
NULL
|
||||
}, {
|
||||
0x92, 0x90, 0x1c, 0x85, 0x82, 0xe3, 0x1c, 0x05,
|
||||
0x69, 0xb5, 0x36, 0x26, 0x9c, 0xe2, 0x2c, 0xc8,
|
||||
0x30, 0x8b, 0xa4, 0x17, 0xab, 0x36, 0xc1, 0xbb,
|
||||
0xaf, 0x08, 0x4f, 0xf5, 0x8b, 0x18, 0xdc, 0x6a
|
||||
}
|
||||
}, {
|
||||
{
|
||||
"abcdbcdecdefde",
|
||||
"fgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
NULL
|
||||
}, {
|
||||
0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
|
||||
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
|
||||
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
|
||||
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
|
||||
}
|
||||
}, {
|
||||
{
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl",
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl",
|
||||
NULL
|
||||
}, {
|
||||
0xf8, 0xa3, 0xf2, 0x26, 0xfc, 0x42, 0x10, 0xe9,
|
||||
0x0d, 0x13, 0x0c, 0x7f, 0x41, 0xf2, 0xbe, 0x66,
|
||||
0x45, 0x53, 0x85, 0xd2, 0x92, 0x0a, 0xda, 0x78,
|
||||
0x15, 0xf8, 0xf7, 0x95, 0xd9, 0x44, 0x90, 0x5f
|
||||
}
|
||||
}, {
|
||||
{
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh",
|
||||
"ijkl",
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl"
|
||||
}, {
|
||||
0xf8, 0xa3, 0xf2, 0x26, 0xfc, 0x42, 0x10, 0xe9,
|
||||
0x0d, 0x13, 0x0c, 0x7f, 0x41, 0xf2, 0xbe, 0x66,
|
||||
0x45, 0x53, 0x85, 0xd2, 0x92, 0x0a, 0xda, 0x78,
|
||||
0x15, 0xf8, 0xf7, 0x95, 0xd9, 0x44, 0x90, 0x5f
|
||||
}
|
||||
}
|
||||
};
|
||||
static sha256_state_t state;
|
||||
static uint8_t sha256[32];
|
||||
static int i, j;
|
||||
static uint8_t ret;
|
||||
static rtimer_clock_t total_time;
|
||||
rtimer_clock_t time;
|
||||
size_t len;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
puts("-----------------------------------------\n"
|
||||
"Initializing cryptoprocessor...");
|
||||
crypto_init();
|
||||
|
||||
for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
|
||||
printf("-----------------------------------------\n"
|
||||
"Test vector #%d:\n", i);
|
||||
|
||||
time = RTIMER_NOW();
|
||||
ret = sha256_init(&state);
|
||||
time = RTIMER_NOW() - time;
|
||||
total_time = time;
|
||||
printf("sha256_init(): %s, %lu us\n", str_res[ret],
|
||||
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
|
||||
PROCESS_PAUSE();
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(j = 0; j < sizeof(vectors[i].data) / sizeof(vectors[i].data[0]) &&
|
||||
vectors[i].data[j] != NULL; j++) {
|
||||
len = strlen(vectors[i].data[j]);
|
||||
printf("Buffer #%d (length: %u):\n", j, len);
|
||||
time = RTIMER_NOW();
|
||||
ret = sha256_process(&state, vectors[i].data[j], len);
|
||||
time = RTIMER_NOW() - time;
|
||||
total_time += time;
|
||||
printf("sha256_process(): %s, %lu us\n", str_res[ret],
|
||||
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
|
||||
PROCESS_PAUSE();
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
time = RTIMER_NOW();
|
||||
ret = sha256_done(&state, sha256);
|
||||
time = RTIMER_NOW() - time;
|
||||
total_time += time;
|
||||
printf("sha256_done(): %s, %lu us\n", str_res[ret],
|
||||
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
|
||||
PROCESS_PAUSE();
|
||||
if(ret != CRYPTO_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(rom_util_memcmp(sha256, vectors[i].sha256, sizeof(sha256))) {
|
||||
puts("Computed SHA-256 hash does not match expected hash");
|
||||
} else {
|
||||
puts("Computed SHA-256 hash OK");
|
||||
}
|
||||
printf("Total duration: %lu us\n",
|
||||
(uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND));
|
||||
}
|
||||
|
||||
puts("-----------------------------------------\n"
|
||||
"Disabling cryptoprocessor...");
|
||||
crypto_disable();
|
||||
|
||||
puts("Done!");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -29,6 +29,7 @@ In terms of hardware support, the following drivers have been implemented:
|
|||
* Low Power Modes
|
||||
* General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development.
|
||||
* ADC
|
||||
* Cryptoprocessor (AES-CCM-128, SHA-256)
|
||||
* SmartRF06 EB and BB peripherals
|
||||
* LEDs
|
||||
* Buttons
|
||||
|
|
|
@ -44,6 +44,7 @@ In terms of hardware support, the following drivers have been implemented:
|
|||
* Low Power Modes
|
||||
* General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development.
|
||||
* ADC
|
||||
* Cryptoprocessor (AES-CCM-128, SHA-256)
|
||||
* LEDs
|
||||
* Buttons
|
||||
* Internal/external 2.4GHz antenna switch controllable by SW.
|
||||
|
|
Loading…
Reference in a new issue