Merge with updated master.
This commit is contained in:
commit
41f9ca08e2
507 changed files with 63538 additions and 42206 deletions
|
@ -51,7 +51,6 @@ typedef uint32_t u32_t;
|
|||
typedef int32_t s32_t;
|
||||
|
||||
#define CC_CONF_REGISTER_ARGS 1
|
||||
#define CC_CONF_FASTCALL __fastcall__
|
||||
|
||||
#define ARCH_DOESNT_NEED_ALIGNED_STRUCTS 1
|
||||
|
||||
|
|
|
@ -66,9 +66,13 @@ high-level configuration macros may be set:
|
|||
- Default: 0
|
||||
- Purpose: Enable UDP support and initialize resolver process on startup.
|
||||
|
||||
- WITH_80COL
|
||||
- Default: 0
|
||||
- Purpose: Enable 80 column screen.
|
||||
|
||||
- WITH_GUI
|
||||
- Default: 0
|
||||
- Purpose: Initialize the the CTK process on startup.
|
||||
- Purpose: Initialize the CTK process on startup.
|
||||
|
||||
- WITH_MOUSE
|
||||
- Default: 0
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if LOG_CONF_ENABLED
|
||||
static char * CC_FASTCALL
|
||||
static char *
|
||||
ipaddrtoa(uip_ipaddr_t *ipaddr, char *buffer)
|
||||
{
|
||||
char *ptr = buffer;
|
||||
|
@ -59,7 +59,7 @@ ipaddrtoa(uip_ipaddr_t *ipaddr, char *buffer)
|
|||
}
|
||||
#endif /* LOG_CONF_ENABLED */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
struct ethernet_config * CC_FASTCALL
|
||||
struct ethernet_config *
|
||||
config_read(char *filename)
|
||||
{
|
||||
static struct {
|
||||
|
|
|
@ -35,6 +35,6 @@
|
|||
#ifndef CONFIG_H_
|
||||
#define CONFIG_H_
|
||||
|
||||
struct ethernet_config * CC_FASTCALL config_read(char *filename);
|
||||
struct ethernet_config * config_read(char *filename);
|
||||
|
||||
#endif /* CONFIG_H_ */
|
||||
|
|
|
@ -58,7 +58,7 @@ struct {
|
|||
} *module;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void CC_FASTCALL
|
||||
void
|
||||
ethernet_init(struct ethernet_config *config)
|
||||
{
|
||||
static const char signature[4] = {0x65, 0x74, 0x68, 0x01};
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#ifndef ETHERNET_H_
|
||||
#define ETHERNET_H_
|
||||
|
||||
void CC_FASTCALL ethernet_init(struct ethernet_config *config);
|
||||
void ethernet_init(struct ethernet_config *config);
|
||||
uint16_t ethernet_poll(void);
|
||||
void ethernet_send(void);
|
||||
void ethernet_exit(void);
|
||||
|
|
|
@ -139,10 +139,10 @@ ifndef NOAVRSIZE
|
|||
avr-size -C --mcu=$(MCU) $@
|
||||
endif
|
||||
|
||||
%.hex: %.out
|
||||
%.hex: %.$(TARGET)
|
||||
$(OBJCOPY) $^ -j .text -j .data -O ihex $@
|
||||
|
||||
%.ihex: %.out
|
||||
%.ihex: %.$(TARGET)
|
||||
$(OBJCOPY) $^ -O ihex $@
|
||||
|
||||
# Add a namelist to the kernel
|
||||
|
@ -160,7 +160,7 @@ endif
|
|||
#%.hex: %.elf
|
||||
# $(OBJCOPY) -R .eeprom -R .fuse -R .signature $^ -O ihex $@
|
||||
|
||||
%.eep: %.out
|
||||
%.eep: %.$(TARGET)
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 -O ihex $^ $@
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
/* MCUSR is a deprecated name but older avr-libc versions may define it */
|
||||
#if !defined (MCUCSR)
|
||||
# if defined (MCUSR)
|
||||
# warning *** MCUCSR not defined, using MCUSR instead ***
|
||||
# define MCUCSR MCUSR
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -751,7 +751,8 @@ HAL_RF230_ISR()
|
|||
#endif
|
||||
#endif
|
||||
|
||||
} else if (interrupt_source & HAL_TRX_END_MASK){
|
||||
}
|
||||
if (interrupt_source & HAL_TRX_END_MASK){
|
||||
INTERRUPTDEBUG(11);
|
||||
|
||||
state = hal_subregister_read(SR_TRX_STATUS);
|
||||
|
@ -778,16 +779,20 @@ HAL_RF230_ISR()
|
|||
|
||||
}
|
||||
|
||||
} else if (interrupt_source & HAL_TRX_UR_MASK){
|
||||
}
|
||||
if (interrupt_source & HAL_TRX_UR_MASK){
|
||||
INTERRUPTDEBUG(13);
|
||||
;
|
||||
} else if (interrupt_source & HAL_PLL_UNLOCK_MASK){
|
||||
}
|
||||
if (interrupt_source & HAL_PLL_UNLOCK_MASK){
|
||||
INTERRUPTDEBUG(14);
|
||||
;
|
||||
} else if (interrupt_source & HAL_PLL_LOCK_MASK){
|
||||
}
|
||||
if (interrupt_source & HAL_PLL_LOCK_MASK){
|
||||
INTERRUPTDEBUG(15);
|
||||
;
|
||||
} else if (interrupt_source & HAL_BAT_LOW_MASK){
|
||||
}
|
||||
if (interrupt_source & HAL_BAT_LOW_MASK){
|
||||
/* Disable BAT_LOW interrupt to prevent endless interrupts. The interrupt */
|
||||
/* will continously be asserted while the supply voltage is less than the */
|
||||
/* user-defined voltage threshold. */
|
||||
|
@ -796,9 +801,6 @@ HAL_RF230_ISR()
|
|||
hal_register_write(RG_IRQ_MASK, trx_isr_mask);
|
||||
INTERRUPTDEBUG(16);
|
||||
;
|
||||
} else {
|
||||
INTERRUPTDEBUG(99);
|
||||
;
|
||||
}
|
||||
}
|
||||
#endif /* defined(__AVR_ATmega128RFA1__) */
|
||||
|
|
|
@ -237,6 +237,8 @@ typedef enum{
|
|||
PROCESS(rf230_process, "RF230 driver");
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
int rf230_interrupt(void);
|
||||
|
||||
static int rf230_on(void);
|
||||
static int rf230_off(void);
|
||||
|
||||
|
@ -552,7 +554,19 @@ rf230_is_ready_to_send() {
|
|||
static void
|
||||
flushrx(void)
|
||||
{
|
||||
/* Clear the length field to allow buffering of the next packet */
|
||||
rxframe[rxframe_head].length=0;
|
||||
rxframe_head++;
|
||||
if (rxframe_head >= RF230_CONF_RX_BUFFERS) {
|
||||
rxframe_head=0;
|
||||
}
|
||||
/* If another packet has been buffered, schedule another receive poll */
|
||||
if (rxframe[rxframe_head].length) {
|
||||
rf230_interrupt();
|
||||
}
|
||||
else {
|
||||
rf230_pending = 0;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
@ -1434,6 +1448,7 @@ rf230_read(void *buf, unsigned short bufsize)
|
|||
#if RADIOALWAYSON && DEBUGFLOWSIZE
|
||||
if (RF230_receive_on==0) {if (debugflow[debugflowsize-1]!='z') DEBUGFLOW('z');} //cxmac calls with radio off?
|
||||
#endif
|
||||
flushrx();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1476,19 +1491,8 @@ rf230_read(void *buf, unsigned short bufsize)
|
|||
memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN);
|
||||
rf230_last_correlation = rxframe[rxframe_head].lqi;
|
||||
|
||||
/* Clear the length field to allow buffering of the next packet */
|
||||
rxframe[rxframe_head].length=0;
|
||||
rxframe_head++;
|
||||
if (rxframe_head >= RF230_CONF_RX_BUFFERS) {
|
||||
rxframe_head=0;
|
||||
}
|
||||
/* If another packet has been buffered, schedule another receive poll */
|
||||
if (rxframe[rxframe_head].length) {
|
||||
rf230_interrupt();
|
||||
}
|
||||
else {
|
||||
rf230_pending = 0;
|
||||
}
|
||||
/* Prepare to receive another packet */
|
||||
flushrx();
|
||||
|
||||
/* Point to the checksum */
|
||||
framep+=len-AUX_LEN;
|
||||
|
|
|
@ -67,7 +67,6 @@
|
|||
/* MCUSR is a deprecated name but older avr-libc versions may define it */
|
||||
#if !defined (MCUCSR)
|
||||
# if defined (MCUSR)
|
||||
# warning *** MCUCSR not defined, using MCUSR instead ***
|
||||
# define MCUCSR MCUSR
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#endif
|
||||
|
||||
#define CC_CONF_FUNCTION_POINTER_ARGS 1
|
||||
#define CC_CONF_FASTCALL
|
||||
#define CC_CONF_VA_ARGS 1
|
||||
#define CC_CONF_UNSIGNED_CHAR_BUGS 0
|
||||
#define CC_CONF_REGISTER_ARGS 0
|
||||
|
|
|
@ -22,6 +22,10 @@ LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch
|
|||
OBJCOPY_FLAGS += -O binary --gap-fill 0xff
|
||||
OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb
|
||||
|
||||
ifdef WERROR
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
### Are we building with code size optimisations?
|
||||
ifeq ($(SMALL),1)
|
||||
CFLAGS += -Os
|
||||
|
@ -51,6 +55,8 @@ 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 += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c
|
||||
CONTIKI_CPU_SOURCEFILES += ecc-curve.c
|
||||
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
||||
CONTIKI_CPU_SOURCEFILES += i2c.c cc2538-temp-sensor.c vdd3-sensor.c
|
||||
|
|
1064
cpu/cc2538/dev/bignum-driver.c
Normal file
1064
cpu/cc2538/dev/bignum-driver.c
Normal file
File diff suppressed because it is too large
Load diff
462
cpu/cc2538/dev/bignum-driver.h
Normal file
462
cpu/cc2538/dev/bignum-driver.h
Normal file
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Authors: Andreas Dröscher <contiki@anticat.ch>
|
||||
* Hu Luo
|
||||
* Hossein Shafagh <shafagh@inf.ethz.ch>
|
||||
*
|
||||
* 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-pka
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-bignum cc2538 BigNum math function driver
|
||||
*
|
||||
* Driver for the cc2538 BigNum math functions of the PKC engine
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 BigNum driver
|
||||
*
|
||||
* bignum_subtract_start bignum_subtract_get_result (subtraction)
|
||||
* bignum_add_start bignum_add_get_result (addition)
|
||||
* bignum_mod_start bignum_mod_get_result (modulo)
|
||||
* bignum_exp_mod_start bignum_exp_mod_get_result (modular exponentiation operation)
|
||||
* bignum_inv_mod_start bignum_inv_mod_get_result (inverse modulo operation)
|
||||
* bignum_mul_start bignum_mul_get_result (multiplication)
|
||||
* bignum_divide_start bignum_divide_get_result (division)
|
||||
* bignum_cmp_start bignum_cmp_get_result (comparison)
|
||||
*/
|
||||
#ifndef BIGNUM_DRIVER_H_
|
||||
#define BIGNUM_DRIVER_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "pka.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Starts the big number modulus operation.
|
||||
*
|
||||
* \param number Pointer to the big number on which modulo operation
|
||||
* needs to be carried out.
|
||||
* \param number_size Size of the big number \sa number in 32-bit word.
|
||||
* \param modulus Pointer to the divisor.
|
||||
* \param modulus_size Size of the divisor \sa modulus.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the modulo operation on the big num \sa number
|
||||
* using the divisor \sa modulus. The PKA RAM location where the result
|
||||
* will be available is stored in \sa result_vector.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t bignum_mod_start(const uint32_t *number,
|
||||
const uint8_t number_size,
|
||||
const uint32_t *modulus,
|
||||
const uint8_t modulus_size,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of the big number modulus operation.
|
||||
*
|
||||
* \param buffer Pointer to buffer where the result needs to
|
||||
* be stored.
|
||||
* \param buffer_size Size of the provided buffer in 32 bit size word.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function \sa PKABigNumModStart().
|
||||
*
|
||||
* This function gets the result of the big number modulus operation which was
|
||||
* previously started using the function \sa PKABigNumModStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_BUF_UNDERFLOW if the \e size is less than the length
|
||||
* of the result.
|
||||
*/
|
||||
uint8_t bignum_mod_get_result(uint32_t *buffer,
|
||||
const uint8_t buffer_size,
|
||||
const uint32_t result_vector);
|
||||
|
||||
/** \brief Starts the comparison of two big numbers.
|
||||
*
|
||||
* \param number1 Pointer to the first big number.
|
||||
* \param number2 Pointer to the second big number.
|
||||
* \param size Size of the big number in 32 bit size word.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the comparison of two big numbers pointed by
|
||||
* \e number1 and \e number2.
|
||||
* Note this function expects the size of the two big numbers equal.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t bignum_cmp_start(const uint32_t *number1,
|
||||
const uint32_t *number2,
|
||||
uint8_t size,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of the comparison operation of two big numbers.
|
||||
*
|
||||
* This function provides the results of the comparison of two big numbers
|
||||
* which was started using the \sa PKABigNumCmpStart().
|
||||
*
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the operation is in progress.
|
||||
* \retval PKA_STATUS_SUCCESS if the two big numbers are equal.
|
||||
* \retval PKA_STATUS_A_GR_B if the first number is greater than the second.
|
||||
* \retval PKA_STATUS_A_LT_B if the first number is less than the second.
|
||||
*/
|
||||
uint8_t bignum_cmp_get_result(void);
|
||||
|
||||
/** \brief Starts the big number inverse modulo operation.
|
||||
*
|
||||
* \param number Pointer to the buffer containing the big number
|
||||
* (dividend).
|
||||
* \param number_size Size of the \e number in 32 bit word.
|
||||
* \param modulus Pointer to the buffer containing the modulus.
|
||||
* \param modulus_size Size of the modulus in 32 bit word.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the the inverse modulo operation on \e number
|
||||
* using the divisor \e modulus.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t bignum_inv_mod_start(const uint32_t *number,
|
||||
const uint8_t number_size,
|
||||
const uint32_t *modulus,
|
||||
const uint8_t modulus_size,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of the big number inverse modulo operation.
|
||||
*
|
||||
* \param buffer Pointer to buffer where the result needs to be
|
||||
* stored.
|
||||
* \param buffer_size Size of the provided buffer in 32 bit size
|
||||
* word.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function \sa PKABigNumInvModStart().
|
||||
*
|
||||
* This function gets the result of the big number inverse modulo operation
|
||||
* previously started using the function \sa PKABigNumInvModStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if the operation is successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less
|
||||
* then the result.
|
||||
*/
|
||||
uint8_t bignum_inv_mod_get_result(uint32_t *buffer,
|
||||
const uint8_t buffer_size,
|
||||
const uint32_t result_vector);
|
||||
|
||||
/** \brief Starts the big number multiplication.
|
||||
*
|
||||
* \param multiplicand Pointer to the buffer containing the big
|
||||
* number multiplicand.
|
||||
* \param multiplicand_size Size of the multiplicand in 32-bit word.
|
||||
* \param multiplier Pointer to the buffer containing the big
|
||||
* number multiplier.
|
||||
* \param multiplier_size Size of the multiplier in 32-bit word.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the multiplication of the two big numbers.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t bignum_mul_start(const uint32_t *multiplicand,
|
||||
const uint8_t multiplicand_size,
|
||||
const uint32_t *multiplier,
|
||||
const uint8_t multiplier_size,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the results of the big number multiplication.
|
||||
*
|
||||
* \param buffer Pointer to buffer where the result needs to be stored.
|
||||
* \param buffer_size Address of the variable containing the length of the
|
||||
* buffer. After the operation, the actual length of the resultant is
|
||||
* stored at this address.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function \sa PKABigNumMultiplyStart().
|
||||
*
|
||||
* This function gets the result of the multiplication of two big numbers
|
||||
* operation previously started using the function \sa
|
||||
* PKABigNumMultiplyStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if the operation is successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_FAILURE if the operation is not successful.
|
||||
* \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less
|
||||
* then the length of the result.
|
||||
*/
|
||||
uint8_t bignum_mul_get_result(uint32_t *buffer,
|
||||
uint32_t *buffer_size,
|
||||
const uint32_t result_vector);
|
||||
|
||||
/** \brief Starts the addition of two big number.
|
||||
*
|
||||
* \param number1 Pointer to the buffer containing the first big mumber.
|
||||
* \param number1_size Size of the first big number in 32-bit word.
|
||||
* \param number2 Pointer to the buffer containing the second big number.
|
||||
* \param number2_size Size of the second big number in 32-bit word.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the addition of the two big numbers.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t bignum_add_start(const uint32_t *number1,
|
||||
const uint8_t number1_size,
|
||||
const uint32_t *number2,
|
||||
const uint8_t number2_size,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of the addition operation on two big number.
|
||||
*
|
||||
* \param buffer Pointer to buffer where the result
|
||||
* needs to be stored.
|
||||
* \param buffer_size Address of the variable containing the length of
|
||||
* the buffer. After the operation the actual length of the
|
||||
* resultant is stored at this address.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function \sa PKABigNumAddStart().
|
||||
*
|
||||
* This function gets the result of the addition operation on two big numbers,
|
||||
* previously started using the function \sa PKABigNumAddStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if the operation is successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_FAILURE if the operation is not successful.
|
||||
* \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less
|
||||
* then the length of the result.
|
||||
*/
|
||||
uint8_t bignum_add_get_result(uint32_t *buffer,
|
||||
uint32_t *buffer_size,
|
||||
const uint32_t result_vector);
|
||||
|
||||
/** \brief Starts the substract of two big number.
|
||||
*
|
||||
* \param number1 Pointer to the buffer containing the first big mumber.
|
||||
* \param number1_size Size of the first big number in 32-bit word.
|
||||
* \param number2 Pointer to the buffer containing the second big number.
|
||||
* \param number2_size Size of the second big number in 32-bit word.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the substraction of the two big numbers.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t bignum_subtract_start(const uint32_t *number1,
|
||||
const uint8_t number1_size,
|
||||
const uint32_t *number2,
|
||||
const uint8_t number2_size,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of big number subtract.
|
||||
*
|
||||
* \param buffer Pointer to store the result of subtraction.
|
||||
* \param buffer_size Address of the variable containing the length of the
|
||||
* buffer. After the operation, the actual length of the resultant is
|
||||
* stored at this address.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function PKABigNumSubtractStart().
|
||||
*
|
||||
* This function gets the result of PKABigNumSubtractStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if the operation is successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_FAILURE if the operation is not successful.
|
||||
*/
|
||||
uint8_t bignum_subtract_get_result(uint32_t *buffer,
|
||||
uint32_t *buffer_size,
|
||||
const uint32_t result_vector);
|
||||
|
||||
/** \brief Starts the big number moduluar Exponentiation operation.
|
||||
*
|
||||
* \param number Pointer to the Exponent on which moduluar Exponentiation operation
|
||||
* needs to be carried out.
|
||||
* \param number_size Size of the the Exponent number number in 32-bit word.
|
||||
* \param modulus Pointer to the divisor.
|
||||
* \param modulus_size Size of the divisor modulus.
|
||||
* \param base Pointer to the Base.
|
||||
* \param base_size Size of the divisor base.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the moduluar Exponentiation operation on the base num base
|
||||
* using the Exponent number and the Modulus num modulus. The PKA RAM location where the result
|
||||
* will be available is stored in \sa result_vector.
|
||||
* IMPORTANT = Modulus and Based should have buffers of the same length!
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t bignum_exp_mod_start(const uint32_t *number,
|
||||
const uint8_t number_size,
|
||||
const uint32_t *modulus,
|
||||
const uint8_t modulus_size,
|
||||
const uint32_t *base,
|
||||
const uint8_t base_size,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of the big number modulus operation result.
|
||||
*
|
||||
* \param buffer Pointer to buffer where the result needs to
|
||||
* be stored.
|
||||
* \param buffer_size Size of the provided buffer in 32 bit size word.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function \sa PKABigNumExpModStart().
|
||||
*
|
||||
* This function gets the result of the big number modulus operation which was
|
||||
* previously started using the function \sa PKABigNumExpModStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_BUF_UNDERFLOW if the \e size is less than the length
|
||||
* of the result.
|
||||
*
|
||||
* \note
|
||||
* - 0 < number_size <= Max_Len
|
||||
* - 1 < modulus_size <=Max_Len
|
||||
* - modulus must be odd and modulus > 232
|
||||
* - base < modulus
|
||||
*/
|
||||
uint8_t bignum_exp_mod_get_result(uint32_t *buffer,
|
||||
const uint8_t buffer_size,
|
||||
const uint32_t result_vector);
|
||||
|
||||
/** \brief Starts the big number Divide.
|
||||
*
|
||||
* \param dividend Pointer to the buffer containing the big
|
||||
* number dividend.
|
||||
* \param dividend_size Size of the dividend in 32-bit word.
|
||||
* \param divisor Pointer to the buffer containing the big
|
||||
* number divisor.
|
||||
* \param divisor_size Size of the divisor in 32-bit word.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the divide of the two big numbers.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t bignum_divide_start(const uint32_t *dividend,
|
||||
const uint8_t dividend_size,
|
||||
const uint32_t *divisor,
|
||||
const uint8_t divisor_size,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the results of the big number Divide.
|
||||
*
|
||||
* \param buffer Pointer to buffer where the result needs to be stored.
|
||||
* \param buffer_size Address of the variable containing the length of the
|
||||
* buffer. After the operation, the actual length of the resultant is
|
||||
* stored at this address.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function \sa PKABigNumMultiplyStart().
|
||||
*
|
||||
* This function gets the result of the Divide of two big numbers
|
||||
* operation previously started using the function \sa
|
||||
* PKABigNumDivideStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if the operation is successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_FAILURE if the operation is not successful.
|
||||
* \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less
|
||||
* then the length of the result.
|
||||
*/
|
||||
uint8_t bignum_divide_get_result(uint32_t *buffer,
|
||||
uint32_t *buffer_size,
|
||||
const uint32_t result_vector);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* BIGNUM_DRIVER_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
200
cpu/cc2538/dev/ecc-algorithm.c
Normal file
200
cpu/cc2538/dev/ecc-algorithm.c
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Andreas Dröscher <contiki@anticat.ch>
|
||||
*
|
||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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 c2538-ecc-algo
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 ECC Algorithms
|
||||
*/
|
||||
#include <contiki.h>
|
||||
#include <process.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ecc-algorithm.h"
|
||||
#include "ecc-driver.h"
|
||||
#include "pka.h"
|
||||
|
||||
#define CHECK_RESULT(...) \
|
||||
state->result = __VA_ARGS__; \
|
||||
if(state->result) { \
|
||||
printf("Line: %u Error: %u\n", __LINE__, (unsigned int)state->result); \
|
||||
PT_EXIT(&state->pt); \
|
||||
}
|
||||
|
||||
PT_THREAD(ecc_compare(ecc_compare_state_t *state)) {
|
||||
PT_BEGIN(&state->pt);
|
||||
|
||||
CHECK_RESULT(bignum_cmp_start(state->a, state->b, state->size, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
state->result = bignum_cmp_get_result();
|
||||
|
||||
PT_END(&state->pt);
|
||||
}
|
||||
|
||||
PT_THREAD(ecc_multiply(ecc_multiply_state_t *state)) {
|
||||
PT_BEGIN(&state->pt);
|
||||
|
||||
CHECK_RESULT(ecc_mul_start(state->secret, &state->point_in, state->curve_info, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(ecc_mul_get_result(&state->point_out, state->rv));
|
||||
|
||||
PT_END(&state->pt);
|
||||
}
|
||||
|
||||
PT_THREAD(ecc_dsa_sign(ecc_dsa_sign_state_t *state)) {
|
||||
/* Executed Every Time */
|
||||
uint8_t size = state->curve_info->size;
|
||||
const uint32_t *ord = state->curve_info->n;
|
||||
|
||||
ec_point_t point;
|
||||
memcpy(point.x, state->curve_info->x, sizeof(point.x));
|
||||
memcpy(point.y, state->curve_info->y, sizeof(point.y));
|
||||
|
||||
PT_BEGIN(&state->pt);
|
||||
|
||||
/* Invert k_e mod n */
|
||||
CHECK_RESULT(bignum_inv_mod_start(state->k_e, size, ord, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(bignum_inv_mod_get_result(state->k_e_inv, size, state->rv));
|
||||
|
||||
/* Calculate Point R = K_e * GeneratorPoint */
|
||||
CHECK_RESULT(ecc_mul_start(state->k_e, &point, state->curve_info, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(ecc_mul_get_result(&state->point_r, state->rv));
|
||||
|
||||
/* Calculate signature using big math functions
|
||||
* d*r (r is the x coordinate of PointR) */
|
||||
CHECK_RESULT(bignum_mul_start(state->secret, size, state->point_r.x, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
state->len = 24;
|
||||
CHECK_RESULT(bignum_mul_get_result(state->signature_s, &state->len, state->rv));
|
||||
|
||||
/* d*r mod n */
|
||||
CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv));
|
||||
|
||||
/* hash + d*r */
|
||||
CHECK_RESULT(bignum_add_start(state->hash, size, state->signature_s, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
state->len = 24;
|
||||
CHECK_RESULT(bignum_add_get_result(state->signature_s, &state->len, state->rv));
|
||||
|
||||
/* hash + d*r mod n */
|
||||
CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv));
|
||||
|
||||
/* k_e_inv * (hash + d*r) */
|
||||
CHECK_RESULT(bignum_mul_start(state->k_e_inv, size, state->signature_s, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
state->len = 24;
|
||||
CHECK_RESULT(bignum_mul_get_result(state->signature_s, &state->len, state->rv));
|
||||
|
||||
/* k_e_inv * (hash + d*r) mod n */
|
||||
CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv));
|
||||
|
||||
PT_END(&state->pt);
|
||||
}
|
||||
|
||||
PT_THREAD(ecc_dsa_verify(ecc_dsa_verify_state_t *state)) {
|
||||
/* Executed Every Time */
|
||||
uint8_t size = state->curve_info->size;
|
||||
const uint32_t *ord = state->curve_info->n;
|
||||
|
||||
ec_point_t point;
|
||||
memcpy(point.x, state->curve_info->x, sizeof(point.x));
|
||||
memcpy(point.y, state->curve_info->y, sizeof(point.y));
|
||||
|
||||
PT_BEGIN(&state->pt);
|
||||
|
||||
/* Invert s mod n */
|
||||
CHECK_RESULT(bignum_inv_mod_start(state->signature_s, size, ord, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(bignum_inv_mod_get_result(state->s_inv, size, state->rv));
|
||||
|
||||
/* Calculate u1 = s_inv * hash */
|
||||
CHECK_RESULT(bignum_mul_start(state->s_inv, size, state->hash, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
state->len = 24;
|
||||
CHECK_RESULT(bignum_mul_get_result(state->u1, &state->len, state->rv));
|
||||
|
||||
/* Calculate u1 = s_inv * hash mod n */
|
||||
CHECK_RESULT(bignum_mod_start(state->u1, state->len, ord, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(bignum_mod_get_result(state->u1, size, state->rv));
|
||||
|
||||
/* Calculate u2 = s_inv * r */
|
||||
CHECK_RESULT(bignum_mul_start(state->s_inv, size, state->signature_r, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
state->len = 24;
|
||||
CHECK_RESULT(bignum_mul_get_result(state->u2, &state->len, state->rv));
|
||||
|
||||
/* Calculate u2 = s_inv * r mod n */
|
||||
CHECK_RESULT(bignum_mod_start(state->u2, state->len, ord, size, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(bignum_mod_get_result(state->u2, size, state->rv));
|
||||
|
||||
/* Calculate p1 = u1 * A */
|
||||
CHECK_RESULT(ecc_mul_start(state->u1, &point, state->curve_info, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(ecc_mul_get_result(&state->p1, state->rv));
|
||||
|
||||
/* Calculate p2 = u1 * B */
|
||||
CHECK_RESULT(ecc_mul_start(state->u2, &state->public, state->curve_info, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(ecc_mul_get_result(&state->p2, state->rv));
|
||||
|
||||
/* Calculate P = p1 + p2 */
|
||||
CHECK_RESULT(ecc_add_start(&state->p1, &state->p2, state->curve_info, &state->rv, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
CHECK_RESULT(ecc_add_get_result(&state->p1, state->rv));
|
||||
|
||||
/* Verify Result */
|
||||
CHECK_RESULT(bignum_cmp_start(state->signature_r, state->p1.x, size, state->process));
|
||||
PT_WAIT_UNTIL(&state->pt, pka_check_status());
|
||||
state->result = bignum_cmp_get_result();
|
||||
if((state->result == PKA_STATUS_A_GR_B) || (state->result == PKA_STATUS_A_LT_B)) {
|
||||
state->result = PKA_STATUS_SIGNATURE_INVALID;
|
||||
}
|
||||
|
||||
PT_END(&state->pt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
178
cpu/cc2538/dev/ecc-algorithm.h
Normal file
178
cpu/cc2538/dev/ecc-algorithm.h
Normal file
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Andreas Dröscher <contiki@anticat.ch>
|
||||
*
|
||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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-ecc
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ecc-algo cc2538 ECC Algorithms
|
||||
*
|
||||
* This is a implementation of ECDH, ECDSA sign and ECDSA verify. It
|
||||
* uses ecc-driver to communicate with the PKA. It uses continuations
|
||||
* to free the main CPU / thread while the PKA is calculating.
|
||||
*
|
||||
* \note
|
||||
* Only one request can be processed at a time.
|
||||
* Maximal supported key length is 384bit (12 words).
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 ECC Algorithms
|
||||
*/
|
||||
#ifndef ECC_ALGORITHM_H_
|
||||
#define ECC_ALGORITHM_H_
|
||||
|
||||
#include "bignum-driver.h"
|
||||
#include "ecc-driver.h"
|
||||
|
||||
typedef struct {
|
||||
/* Containers for the State */
|
||||
struct pt pt;
|
||||
struct process *process;
|
||||
|
||||
/* Input Variables */
|
||||
uint32_t a[12]; /**< Left Number */
|
||||
uint32_t b[12]; /**< Right Number */
|
||||
uint8_t size; /**< Length of a and b */
|
||||
|
||||
/* Output Variables */
|
||||
uint8_t result; /**< Result Code */
|
||||
} ecc_compare_state_t;
|
||||
|
||||
/**
|
||||
* \brief Do a compare of two big numbers
|
||||
*
|
||||
* This function can be used for ECDH as well as
|
||||
* Calculating a Public Key for ECDSA
|
||||
*/
|
||||
PT_THREAD(ecc_compare(ecc_compare_state_t *state));
|
||||
|
||||
typedef struct {
|
||||
/* Containers for the State */
|
||||
struct pt pt;
|
||||
struct process *process;
|
||||
|
||||
/* Input Variables */
|
||||
ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */
|
||||
ec_point_t point_in; /**< Generator Point */
|
||||
uint32_t secret[12]; /**< Secret */
|
||||
|
||||
/* Variables Holding intermediate data (initialized/used internally) */
|
||||
uint32_t rv; /**< Address of Next Result in PKA SRAM */
|
||||
|
||||
/* Output Variables */
|
||||
uint8_t result; /**< Result Code */
|
||||
ec_point_t point_out; /**< Generated Point */
|
||||
} ecc_multiply_state_t;
|
||||
|
||||
/**
|
||||
* \brief Do a Multiplication on a EC
|
||||
*
|
||||
* This function can be used for ECDH as well as
|
||||
* Calculating a Public Key for ECDSA
|
||||
*/
|
||||
PT_THREAD(ecc_multiply(ecc_multiply_state_t *state));
|
||||
|
||||
typedef struct {
|
||||
/* Containers for the State */
|
||||
struct pt pt;
|
||||
struct process *process;
|
||||
|
||||
/* Input Variables */
|
||||
ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */
|
||||
uint32_t secret[12]; /**< Secret Key */
|
||||
uint32_t k_e[12]; /**< Ephemeral Key */
|
||||
uint32_t hash[12]; /**< Hash to be signed */
|
||||
|
||||
/* Variables Holding intermediate data (initialized/used internally) */
|
||||
uint32_t rv; /**< Address of Next Result in PKA SRAM */
|
||||
uint32_t k_e_inv[12]; /**< Inverted ephemeral Key */
|
||||
uint32_t len; /**< Length of intermediate Result */
|
||||
|
||||
/* Output Variables */
|
||||
uint8_t result; /**< Result Code */
|
||||
ec_point_t point_r; /**< Signature R (x coordinate) */
|
||||
uint32_t signature_s[24]; /**< Signature S */
|
||||
} ecc_dsa_sign_state_t;
|
||||
|
||||
/**
|
||||
* \brief Sign a Hash
|
||||
*
|
||||
* This function has to be called several times until the
|
||||
* pt state is EXIT
|
||||
* If the result code is 0 (SUCCESS) the signature can be
|
||||
* read from point_r and signature_s
|
||||
*/
|
||||
PT_THREAD(ecc_dsa_sign(ecc_dsa_sign_state_t *state));
|
||||
|
||||
typedef struct {
|
||||
/* Containers for the State */
|
||||
struct pt pt;
|
||||
struct process *process;
|
||||
|
||||
/* Input Variables */
|
||||
ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */
|
||||
uint32_t signature_r[12]; /**< Signature R */
|
||||
uint32_t signature_s[12]; /**< Signature S */
|
||||
uint32_t hash[12]; /**< Hash to be signed */
|
||||
ec_point_t public; /**< Signature R (x coordinate) */
|
||||
|
||||
/* Variables Holding intermediate data (initialized/used internally) */
|
||||
uint32_t rv; /**< Address of Next Result in PKA SRAM */
|
||||
uint32_t s_inv[12]; /**< Inverted ephemeral Key */
|
||||
uint32_t u1[24]; /**< Intermediate result */
|
||||
uint32_t u2[24]; /**< Intermediate result */
|
||||
ec_point_t p1; /**< Intermediate result */
|
||||
ec_point_t p2; /**< Intermediate result */
|
||||
uint32_t len; /**< Length of intermediate Result */
|
||||
|
||||
/* Output Variables */
|
||||
uint8_t result; /**< Result Code */
|
||||
} ecc_dsa_verify_state_t;
|
||||
|
||||
/**
|
||||
* \brief Verify Signature
|
||||
*
|
||||
* This function has to be called several times until the
|
||||
* pt state is EXIT
|
||||
* If the result code is 0 (SUCCESS) the verification
|
||||
* was success full.
|
||||
* \note some error codes signal internal errors
|
||||
* and others signal falls signatures.
|
||||
*/
|
||||
PT_THREAD(ecc_dsa_verify(ecc_dsa_verify_state_t *state));
|
||||
|
||||
#endif /* ECC_ALGORITHM_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
91
cpu/cc2538/dev/ecc-curve.c
Normal file
91
cpu/cc2538/dev/ecc-curve.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Andreas Dröscher <contiki@anticat.ch>
|
||||
*
|
||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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 c2538-ecc-curves
|
||||
* @{
|
||||
*/
|
||||
#include <contiki.h>
|
||||
#include <ecc-driver.h>
|
||||
|
||||
/* [NIST P-256, X9.62 prime256v1] */
|
||||
static const uint32_t nist_p_256_p[8] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF };
|
||||
static const uint32_t nist_p_256_n[8] = { 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF };
|
||||
static const uint32_t nist_p_256_a[8] = { 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF };
|
||||
static const uint32_t nist_p_256_b[8] = { 0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0,
|
||||
0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8 };
|
||||
static const uint32_t nist_p_256_x[8] = { 0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81,
|
||||
0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2 };
|
||||
static const uint32_t nist_p_256_y[8] = { 0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357,
|
||||
0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2 };
|
||||
|
||||
ecc_curve_info_t nist_p_256 = {
|
||||
.name = "NIST P-256",
|
||||
.size = 8,
|
||||
.prime = nist_p_256_p,
|
||||
.n = nist_p_256_n,
|
||||
.a = nist_p_256_a,
|
||||
.b = nist_p_256_b,
|
||||
.x = nist_p_256_x,
|
||||
.y = nist_p_256_y
|
||||
};
|
||||
|
||||
/* [NIST P-192, X9.62 prime192v1] */
|
||||
static const uint32_t nist_p_192_p[6] = { 0xffffffff, 0xffffffff, 0xfffffffe, 0xffffffff,
|
||||
0xffffffff, 0xffffffff };
|
||||
static const uint32_t nist_p_192_a[6] = { 0xfffffffc, 0xffffffff, 0xfffffffe, 0xffffffff,
|
||||
0xffffffff, 0xffffffff };
|
||||
static const uint32_t nist_p_192_b[6] = { 0xc146b9b1, 0xfeb8deec, 0x72243049, 0x0fa7e9ab,
|
||||
0xe59c80e7, 0x64210519 };
|
||||
static const uint32_t nist_p_192_x[6] = { 0x82ff1012, 0xf4ff0afd, 0x43a18800, 0x7cbf20eb,
|
||||
0xb03090f6, 0x188da80e };
|
||||
static const uint32_t nist_p_192_y[6] = { 0x1e794811, 0x73f977a1, 0x6b24cdd5, 0x631011ed,
|
||||
0xffc8da78, 0x07192b95 };
|
||||
static const uint32_t nist_p_192_n[6] = { 0xb4d22831, 0x146bc9b1, 0x99def836, 0xffffffff,
|
||||
0xffffffff, 0xffffffff };
|
||||
|
||||
ecc_curve_info_t nist_p_192 = {
|
||||
.name = "NIST P-192",
|
||||
.size = 6,
|
||||
.prime = nist_p_192_p,
|
||||
.n = nist_p_192_n,
|
||||
.a = nist_p_192_a,
|
||||
.b = nist_p_192_b,
|
||||
.x = nist_p_192_x,
|
||||
.y = nist_p_192_y
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
65
cpu/cc2538/dev/ecc-curve.h
Normal file
65
cpu/cc2538/dev/ecc-curve.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2014 Andreas Dröscher <contiki@anticat.ch>
|
||||
*
|
||||
* 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-ecc
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ecc-curves cc2538 NIST curves
|
||||
*
|
||||
* NIST curves for various key sizes
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* NIST curves for various key sizes
|
||||
*/
|
||||
#ifndef ECC_CURVE_H_
|
||||
#define ECC_CURVE_H_
|
||||
|
||||
/*
|
||||
* NIST P-256, X9.62 prime256v1
|
||||
*/
|
||||
ecc_curve_info_t nist_p_256;
|
||||
|
||||
/*
|
||||
* NIST P-192, X9.62 prime192v1
|
||||
*/
|
||||
ecc_curve_info_t nist_p_192;
|
||||
|
||||
#endif /* CURVE_INFO_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
559
cpu/cc2538/dev/ecc-driver.c
Normal file
559
cpu/cc2538/dev/ecc-driver.c
Normal file
|
@ -0,0 +1,559 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2014 Andreas Dröscher <contiki@anticat.ch>
|
||||
*
|
||||
* 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-ecc
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 ECC driver
|
||||
*/
|
||||
#include "ecc-driver.h"
|
||||
#include "reg.h"
|
||||
#include "dev/nvic.h"
|
||||
|
||||
#define ASSERT(IF) if(!(IF)) { return PKA_STATUS_INVALID_PARAM; }
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ecc_mul_start(uint32_t *scalar, ec_point_t *ec_point,
|
||||
ecc_curve_info_t *curve, uint32_t *result_vector,
|
||||
struct process *process)
|
||||
{
|
||||
|
||||
uint8_t extraBuf;
|
||||
uint32_t offset;
|
||||
int i;
|
||||
|
||||
/* Check for the arguments. */
|
||||
ASSERT(NULL != scalar);
|
||||
ASSERT(NULL != ec_point);
|
||||
ASSERT(NULL != ec_point->x);
|
||||
ASSERT(NULL != ec_point->y);
|
||||
ASSERT(NULL != curve);
|
||||
ASSERT(curve->size <= PKA_MAX_CURVE_SIZE);
|
||||
ASSERT(NULL != result_vector);
|
||||
|
||||
offset = 0;
|
||||
|
||||
/* Make sure no PKA operation is in progress. */
|
||||
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
|
||||
return PKA_STATUS_OPERATION_INPRG;
|
||||
}
|
||||
|
||||
/* Calculate the extra buffer requirement. */
|
||||
extraBuf = 2 + curve->size % 2;
|
||||
|
||||
/* Update the A ptr with the offset address of the PKA RAM location
|
||||
* where the scalar will be stored. */
|
||||
REG(PKA_APTR) = offset >> 2;
|
||||
|
||||
/* Load the scalar in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = *scalar++;
|
||||
}
|
||||
|
||||
/* Determine the offset for the next data. */
|
||||
offset += 4 * (i + (curve->size % 2));
|
||||
|
||||
/* Update the B ptr with the offset address of the PKA RAM location
|
||||
* where the curve parameters will be stored. */
|
||||
REG(PKA_BPTR) = offset >> 2;
|
||||
|
||||
/* Write curve parameter 'p' as 1st part of vector B immediately
|
||||
* following vector A at PKA RAM */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i];
|
||||
}
|
||||
|
||||
/* Determine the offset for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Copy curve parameter 'a' in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i];
|
||||
}
|
||||
|
||||
/* Determine the offset for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Copy curve parameter 'b' in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->b[i];
|
||||
}
|
||||
|
||||
/* Determine the offset for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Update the C ptr with the offset address of the PKA RAM location
|
||||
* where the x, y will be stored. */
|
||||
REG(PKA_CPTR) = offset >> 2;
|
||||
|
||||
/* Write elliptic curve point.x co-ordinate value. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point->x[i];
|
||||
}
|
||||
|
||||
/* Determine the offset for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Write elliptic curve point.y co-ordinate value. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point->y[i];
|
||||
}
|
||||
|
||||
/* Determine the offset for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Update the result location. */
|
||||
*result_vector = PKA_RAM_BASE + offset;
|
||||
|
||||
/* Load D ptr with the result location in PKA RAM. */
|
||||
REG(PKA_DPTR) = offset >> 2;
|
||||
|
||||
/* Load length registers. */
|
||||
REG(PKA_ALENGTH) = curve->size;
|
||||
REG(PKA_BLENGTH) = curve->size;
|
||||
|
||||
/* set the PKA function to ECC-MULT and start the operation. */
|
||||
REG(PKA_FUNCTION) = 0x0000D000;
|
||||
|
||||
/* Enable Interrupt */
|
||||
if(process != NULL) {
|
||||
pka_register_process_notification(process);
|
||||
nvic_interrupt_unpend(NVIC_INT_PKA);
|
||||
nvic_interrupt_enable(NVIC_INT_PKA);
|
||||
}
|
||||
|
||||
return PKA_STATUS_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ecc_mul_get_result(ec_point_t *ec_point,
|
||||
uint32_t result_vector)
|
||||
{
|
||||
int i;
|
||||
uint32_t addr;
|
||||
uint32_t regMSWVal;
|
||||
uint32_t len;
|
||||
|
||||
/* Check for the arguments. */
|
||||
ASSERT(NULL != ec_point);
|
||||
ASSERT(NULL != ec_point->x);
|
||||
ASSERT(NULL != ec_point->y);
|
||||
ASSERT(result_vector > PKA_RAM_BASE);
|
||||
ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE));
|
||||
|
||||
/* Verify that the operation is completed. */
|
||||
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
|
||||
return PKA_STATUS_OPERATION_INPRG;
|
||||
}
|
||||
|
||||
/* Disable Interrupt */
|
||||
nvic_interrupt_disable(NVIC_INT_PKA);
|
||||
pka_register_process_notification(NULL);
|
||||
|
||||
if(REG(PKA_SHIFT) == 0x00000000) {
|
||||
/* Get the MSW register value. */
|
||||
regMSWVal = REG(PKA_MSW);
|
||||
|
||||
/* Check to make sure that the result vector is not all zeroes. */
|
||||
if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) {
|
||||
return PKA_STATUS_RESULT_0;
|
||||
}
|
||||
|
||||
/* Get the length of the result */
|
||||
len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1)
|
||||
- ((result_vector - PKA_RAM_BASE) >> 2);
|
||||
|
||||
addr = result_vector;
|
||||
|
||||
/* copy the x co-ordinate value of the result from vector D into
|
||||
* the \e ec_point. */
|
||||
for(i = 0; i < len; i++) {
|
||||
ec_point->x[i] = REG(addr + 4 * i);
|
||||
}
|
||||
|
||||
addr += 4 * (i + 2 + len % 2);
|
||||
|
||||
/* copy the y co-ordinate value of the result from vector D into
|
||||
* the \e ec_point. */
|
||||
for(i = 0; i < len; i++) {
|
||||
ec_point->y[i] = REG(addr + 4 * i);
|
||||
}
|
||||
|
||||
return PKA_STATUS_SUCCESS;
|
||||
} else {
|
||||
return PKA_STATUS_FAILURE;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ecc_mul_gen_pt_start(uint32_t *scalar, ecc_curve_info_t *curve,
|
||||
uint32_t *result_vector, struct process *process)
|
||||
{
|
||||
uint8_t extraBuf;
|
||||
uint32_t offset;
|
||||
int i;
|
||||
|
||||
/* check for the arguments. */
|
||||
ASSERT(NULL != scalar);
|
||||
ASSERT(NULL != curve);
|
||||
ASSERT(curve->size <= PKA_MAX_CURVE_SIZE);
|
||||
ASSERT(NULL != result_vector);
|
||||
|
||||
offset = 0;
|
||||
|
||||
/* Make sure no operation is in progress. */
|
||||
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
|
||||
return PKA_STATUS_OPERATION_INPRG;
|
||||
}
|
||||
|
||||
/* Calculate the extra buffer requirement. */
|
||||
extraBuf = 2 + curve->size % 2;
|
||||
|
||||
/* Update the A ptr with the offset address of the PKA RAM location
|
||||
* where the scalar will be stored. */
|
||||
REG(PKA_APTR) = offset >> 2;
|
||||
|
||||
/* Load the scalar in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = *scalar++;
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + (curve->size % 2));
|
||||
|
||||
/* Update the B ptr with the offset address of the PKA RAM location
|
||||
* where the curve parameters will be stored. */
|
||||
REG(PKA_BPTR) = offset >> 2;
|
||||
|
||||
/* Write curve parameter 'p' as 1st part of vector B. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Write curve parameter 'a' in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* write curve parameter 'b' in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->b[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Update the C ptr with the offset address of the PKA RAM location
|
||||
* where the x, y will be stored. */
|
||||
REG(PKA_CPTR) = offset >> 2;
|
||||
|
||||
/* Write x co-ordinate value of the Generator point in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->x[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Write y co-ordinate value of the Generator point in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->y[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Update the result location. */
|
||||
*result_vector = PKA_RAM_BASE + offset;
|
||||
|
||||
/* Load D ptr with the result location in PKA RAM. */
|
||||
REG(PKA_DPTR) = offset >> 2;
|
||||
|
||||
/* Load length registers. */
|
||||
REG(PKA_ALENGTH) = curve->size;
|
||||
REG(PKA_BLENGTH) = curve->size;
|
||||
|
||||
/* Set the PKA function to ECC-MULT and start the operation. */
|
||||
REG(PKA_FUNCTION) = 0x0000D000;
|
||||
|
||||
/* Enable Interrupt */
|
||||
if(process != NULL) {
|
||||
pka_register_process_notification(process);
|
||||
nvic_interrupt_unpend(NVIC_INT_PKA);
|
||||
nvic_interrupt_enable(NVIC_INT_PKA);
|
||||
}
|
||||
|
||||
return PKA_STATUS_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ecc_mul_gen_pt_get_result(ec_point_t *ec_point,
|
||||
uint32_t result_vector)
|
||||
{
|
||||
|
||||
int i;
|
||||
uint32_t regMSWVal;
|
||||
uint32_t addr;
|
||||
uint32_t len;
|
||||
|
||||
/* Check for the arguments. */
|
||||
ASSERT(NULL != ec_point);
|
||||
ASSERT(NULL != ec_point->x);
|
||||
ASSERT(NULL != ec_point->y);
|
||||
ASSERT(result_vector > PKA_RAM_BASE);
|
||||
ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE));
|
||||
|
||||
/* Verify that the operation is completed. */
|
||||
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
|
||||
return PKA_STATUS_OPERATION_INPRG;
|
||||
}
|
||||
|
||||
/* Disable Interrupt */
|
||||
nvic_interrupt_disable(NVIC_INT_PKA);
|
||||
pka_register_process_notification(NULL);
|
||||
|
||||
if(REG(PKA_SHIFT) == 0x00000000) {
|
||||
/* Get the MSW register value. */
|
||||
regMSWVal = REG(PKA_MSW);
|
||||
|
||||
/* Check to make sure that the result vector is not all zeroes. */
|
||||
if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) {
|
||||
return PKA_STATUS_RESULT_0;
|
||||
}
|
||||
|
||||
/* Get the length of the result. */
|
||||
len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1)
|
||||
- ((result_vector - PKA_RAM_BASE) >> 2);
|
||||
|
||||
addr = result_vector;
|
||||
|
||||
/* Copy the x co-ordinate value of the result from vector D into the
|
||||
* EC point. */
|
||||
for(i = 0; i < len; i++) {
|
||||
ec_point->x[i] = REG(addr + 4 * i);
|
||||
}
|
||||
|
||||
addr += 4 * (i + 2 + len % 2);
|
||||
|
||||
/* Copy the y co-ordinate value of the result from vector D into the
|
||||
* EC point. */
|
||||
for(i = 0; i < len; i++) {
|
||||
ec_point->y[i] = REG(addr + 4 * i);
|
||||
}
|
||||
|
||||
return PKA_STATUS_SUCCESS;
|
||||
} else {
|
||||
return PKA_STATUS_FAILURE;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ecc_add_start(ec_point_t *ec_point1, ec_point_t *ec_point2,
|
||||
ecc_curve_info_t *curve, uint32_t *result_vector,
|
||||
struct process *process)
|
||||
{
|
||||
|
||||
uint8_t extraBuf;
|
||||
uint32_t offset;
|
||||
int i;
|
||||
|
||||
/* Check for the arguments. */
|
||||
ASSERT(NULL != ec_point1);
|
||||
ASSERT(NULL != ec_point1->x);
|
||||
ASSERT(NULL != ec_point1->y);
|
||||
ASSERT(NULL != ec_point2);
|
||||
ASSERT(NULL != ec_point2->x);
|
||||
ASSERT(NULL != ec_point2->y);
|
||||
ASSERT(NULL != curve);
|
||||
ASSERT(NULL != result_vector);
|
||||
|
||||
offset = 0;
|
||||
|
||||
/* Make sure no operation is in progress. */
|
||||
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
|
||||
return PKA_STATUS_OPERATION_INPRG;
|
||||
}
|
||||
|
||||
/* Calculate the extra buffer requirement. */
|
||||
extraBuf = 2 + curve->size % 2;
|
||||
|
||||
/* Update the A ptr with the offset address of the PKA RAM location
|
||||
* where the first ecPt will be stored. */
|
||||
REG(PKA_APTR) = offset >> 2;
|
||||
|
||||
/* Load the x co-ordinate value of the first EC point in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point1->x[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Load the y co-ordinate value of the first EC point in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point1->y[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Update the B ptr with the offset address of the PKA RAM location
|
||||
* where the curve parameters will be stored. */
|
||||
REG(PKA_BPTR) = offset >> 2;
|
||||
|
||||
/* Write curve parameter 'p' as 1st part of vector B */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Write curve parameter 'a'. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Update the C ptr with the offset address of the PKA RAM location
|
||||
* where the ecPt2 will be stored. */
|
||||
REG(PKA_CPTR) = offset >> 2;
|
||||
|
||||
/* Load the x co-ordinate value of the second EC point in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point2->x[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Load the y co-ordinate value of the second EC point in PKA RAM. */
|
||||
for(i = 0; i < curve->size; i++) {
|
||||
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point2->y[i];
|
||||
}
|
||||
|
||||
/* Determine the offset in PKA RAM for the next data. */
|
||||
offset += 4 * (i + extraBuf);
|
||||
|
||||
/* Copy the result vector location. */
|
||||
*result_vector = PKA_RAM_BASE + offset;
|
||||
|
||||
/* Load D ptr with the result location in PKA RAM. */
|
||||
REG(PKA_DPTR) = offset >> 2;
|
||||
|
||||
/* Load length registers. */
|
||||
REG(PKA_BLENGTH) = curve->size;
|
||||
|
||||
/* Set the PKA Function to ECC-ADD and start the operation. */
|
||||
REG(PKA_FUNCTION) = 0x0000B000;
|
||||
|
||||
/* Enable Interrupt */
|
||||
if(process != NULL) {
|
||||
pka_register_process_notification(process);
|
||||
nvic_interrupt_unpend(NVIC_INT_PKA);
|
||||
nvic_interrupt_enable(NVIC_INT_PKA);
|
||||
}
|
||||
|
||||
return PKA_STATUS_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
ecc_add_get_result(ec_point_t *ec_point, uint32_t result_vector)
|
||||
{
|
||||
uint32_t regMSWVal;
|
||||
uint32_t addr;
|
||||
int i;
|
||||
uint32_t len;
|
||||
|
||||
/* Check for the arguments. */
|
||||
ASSERT(NULL != ec_point);
|
||||
ASSERT(NULL != ec_point->x);
|
||||
ASSERT(NULL != ec_point->y);
|
||||
ASSERT(result_vector > PKA_RAM_BASE);
|
||||
ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE));
|
||||
|
||||
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
|
||||
return PKA_STATUS_OPERATION_INPRG;
|
||||
}
|
||||
|
||||
/* Disable Interrupt */
|
||||
nvic_interrupt_disable(NVIC_INT_PKA);
|
||||
pka_register_process_notification(NULL);
|
||||
|
||||
if(REG(PKA_SHIFT) == 0x00000000) {
|
||||
/* Get the MSW register value. */
|
||||
regMSWVal = REG(PKA_MSW);
|
||||
|
||||
/* Check to make sure that the result vector is not all zeroes. */
|
||||
if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) {
|
||||
return PKA_STATUS_RESULT_0;
|
||||
}
|
||||
|
||||
/* Get the length of the result. */
|
||||
len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1)
|
||||
- ((result_vector - PKA_RAM_BASE) >> 2);
|
||||
|
||||
addr = result_vector;
|
||||
|
||||
/* Copy the x co-ordinate value of result from vector D into the
|
||||
* the output EC Point. */
|
||||
for(i = 0; i < len; i++) {
|
||||
ec_point->x[i] = REG(addr + 4 * i);
|
||||
}
|
||||
|
||||
addr += 4 * (i + 2 + len % 2);
|
||||
|
||||
/* Copy the y co-ordinate value of result from vector D into the
|
||||
* the output EC Point. */
|
||||
for(i = 0; i < len; i++) {
|
||||
ec_point->y[i] = REG(addr + 4 * i);
|
||||
}
|
||||
|
||||
return PKA_STATUS_SUCCESS;
|
||||
} else {
|
||||
return PKA_STATUS_FAILURE;
|
||||
}
|
||||
}
|
||||
/** @} */
|
227
cpu/cc2538/dev/ecc-driver.h
Normal file
227
cpu/cc2538/dev/ecc-driver.h
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2014 Andreas Dröscher <contiki@anticat.ch>
|
||||
*
|
||||
* 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-pka
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ecc cc2538 ECC driver
|
||||
*
|
||||
* Driver for the cc2538 ECC mode of the PKC engine
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 ECC driver
|
||||
*/
|
||||
#ifndef ECC_DRIVER_H_
|
||||
#define ECC_DRIVER_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "pka.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name ECC structures
|
||||
* @{
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name; /**< Name of the curve. */
|
||||
const uint8_t size; /**< Size of the curve in 32-bit word. */
|
||||
const uint32_t *prime; /**< The prime that defines the field of the curve. */
|
||||
const uint32_t *n; /**< Order of the curve. */
|
||||
const uint32_t *a; /**< Co-efficient a of the equation. */
|
||||
const uint32_t *b; /**< co-efficient b of the equation. */
|
||||
const uint32_t *x; /**< x co-ordinate value of the generator point. */
|
||||
const uint32_t *y; /**< y co-ordinate value of the generator point. */
|
||||
} ecc_curve_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t x[12]; /**< Pointer to value of the x co-ordinate. */
|
||||
uint32_t y[12]; /**< Pointer to value of the y co-ordinate. */
|
||||
} ec_point_t;
|
||||
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name ECC functions
|
||||
* \note Not all sequencer functions are implemented in this driver
|
||||
* look at the CC2538 manual for a complete list.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Starts ECC Multiplication.
|
||||
*
|
||||
* \param scalar Pointer to the buffer containing the scalar
|
||||
* value to be multiplied.
|
||||
* \param ec_point Pointer to the structure containing the
|
||||
* elliptic curve point to be multiplied. The point should be
|
||||
* on the given curve.
|
||||
* \param curve Pointer to the structure containing the curve
|
||||
* info.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the Elliptical curve cryptography (ECC) point
|
||||
* multiplication operation on the EC point and the scalar value.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t ecc_mul_start(uint32_t *scalar,
|
||||
ec_point_t *ec_point,
|
||||
ecc_curve_info_t *curve,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of ECC Multiplication
|
||||
*
|
||||
* \param ec_point Pointer to the structure where the resultant EC
|
||||
* point will be stored. The callee is responsible to allocate the
|
||||
* space for the ec point structure and the x and y co-ordinate as well.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function \sa PKAECCMultiplyStart().
|
||||
*
|
||||
* This function gets the result of ecc point multiplication operation on the
|
||||
* ec point and the scalar value, previously started using the function
|
||||
* \sa PKAECCMultiplyStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if the operation is successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_FAILURE if the operation is not successful.
|
||||
*/
|
||||
uint8_t ecc_mul_get_result(ec_point_t *ec_point,
|
||||
uint32_t result_vector);
|
||||
|
||||
/** \brief Starts the ECC Multiplication with Generator point.
|
||||
*
|
||||
* \param scalar Pointer to the buffer containing the
|
||||
* scalar value.
|
||||
* \param curve Pointer to the structure containing the curve
|
||||
* info.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the ecc point multiplication operation of the
|
||||
* scalar value with the well known generator point of the given curve.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t ecc_mul_gen_pt_start(uint32_t *scalar,
|
||||
ecc_curve_info_t *curve,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of ECC Multiplication with Generator point.
|
||||
*
|
||||
* \param ec_point Pointer to the structure where the resultant EC
|
||||
* point will be stored. The callee is responsible to allocate the
|
||||
* space for the ec point structure and the x and y co-ordinate as well.
|
||||
* \param result_vector Address of the result location which
|
||||
* was provided by the start function \sa PKAECCMultGenPtStart().
|
||||
*
|
||||
* This function gets the result of ecc point multiplication operation on the
|
||||
* scalar point and the known generator point on the curve, previously started
|
||||
* using the function \sa PKAECCMultGenPtStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if the operation is successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_FAILURE if the operation is not successful.
|
||||
*/
|
||||
uint8_t ecc_mul_gen_pt_get_result(ec_point_t *ec_point,
|
||||
uint32_t result_vector);
|
||||
|
||||
/** \brief Starts the ECC Addition.
|
||||
*
|
||||
* \param ec_point1 Pointer to the structure containing the first
|
||||
* ecc point.
|
||||
* \param ec_point2 Pointer to the structure containing the
|
||||
* second ecc point.
|
||||
* \param curve Pointer to the structure containing the curve
|
||||
* info.
|
||||
* \param result_vector Pointer to the result vector location
|
||||
* which will be set by this function.
|
||||
* \param process Process to be polled upon completion of the
|
||||
* operation, or \c NULL
|
||||
*
|
||||
* This function starts the ecc point addition operation on the
|
||||
* two given ec points and generates the resultant ecc point.
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
|
||||
* some other operation.
|
||||
*/
|
||||
uint8_t ecc_add_start(ec_point_t *ec_point1, ec_point_t *ec_point2,
|
||||
ecc_curve_info_t *curve,
|
||||
uint32_t *result_vector,
|
||||
struct process *process);
|
||||
|
||||
/** \brief Gets the result of the ECC Addition
|
||||
*
|
||||
* \param ptOutEcPt Pointer to the structure where the resultant
|
||||
* point will be stored. The callee is responsible to allocate memory,
|
||||
* for the ec point structure including the memory for x and y
|
||||
* co-ordinate values.
|
||||
* \param ui32ResultLoc Address of the result location which
|
||||
* was provided by the function \sa PKAECCAddStart().
|
||||
*
|
||||
* This function gets the result of ecc point addition operation on the
|
||||
* on the two given ec points, previously started using the function \sa
|
||||
* PKAECCAddStart().
|
||||
*
|
||||
* \retval PKA_STATUS_SUCCESS if the operation is successful.
|
||||
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
|
||||
* the operation.
|
||||
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
|
||||
* \retval PKA_STATUS_FAILURE if the operation is not successful.
|
||||
*/
|
||||
uint8_t ecc_add_get_result(ec_point_t *ptOutEcPt, uint32_t ui32ResultLoc);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* ECC_DRIVER_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
128
cpu/cc2538/dev/pka.c
Normal file
128
cpu/cc2538/dev/pka.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2014 Andreas Dröscher <contiki@anticat.ch>
|
||||
*
|
||||
* 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-pka
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the cc2538 PKA engine driver
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "sys/energest.h"
|
||||
#include "dev/pka.h"
|
||||
#include "dev/sys-ctrl.h"
|
||||
#include "dev/nvic.h"
|
||||
#include "lpm.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static volatile struct process *notification_process = NULL;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief The PKA engine ISR
|
||||
*
|
||||
* This is the interrupt service routine for the PKA engine.
|
||||
*
|
||||
* This ISR is called at worst from PM0, so lpm_exit() does not need
|
||||
* to be called.
|
||||
*/
|
||||
void
|
||||
pka_isr(void)
|
||||
{
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
|
||||
nvic_interrupt_unpend(NVIC_INT_PKA);
|
||||
nvic_interrupt_disable(NVIC_INT_PKA);
|
||||
|
||||
if(notification_process != NULL) {
|
||||
process_poll((struct process *)notification_process);
|
||||
notification_process = NULL;
|
||||
}
|
||||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
permit_pm1(void)
|
||||
{
|
||||
return (REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) == 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
pka_init(void)
|
||||
{
|
||||
volatile int i;
|
||||
|
||||
lpm_register_peripheral(permit_pm1);
|
||||
|
||||
pka_enable();
|
||||
|
||||
/* Reset the PKA engine */
|
||||
REG(SYS_CTRL_SRSEC) |= SYS_CTRL_SRSEC_PKA;
|
||||
for(i = 0; i < 16; i++) {
|
||||
REG(SYS_CTRL_SRSEC) &= ~SYS_CTRL_SRSEC_PKA;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
pka_enable(void)
|
||||
{
|
||||
/* Enable the clock for the PKA engine */
|
||||
REG(SYS_CTRL_RCGCSEC) |= SYS_CTRL_RCGCSEC_PKA;
|
||||
REG(SYS_CTRL_SCGCSEC) |= SYS_CTRL_SCGCSEC_PKA;
|
||||
REG(SYS_CTRL_DCGCSEC) |= SYS_CTRL_DCGCSEC_PKA;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
pka_disable(void)
|
||||
{
|
||||
/* Gate the clock for the PKA engine */
|
||||
REG(SYS_CTRL_RCGCSEC) &= ~SYS_CTRL_RCGCSEC_PKA;
|
||||
REG(SYS_CTRL_SCGCSEC) &= ~SYS_CTRL_SCGCSEC_PKA;
|
||||
REG(SYS_CTRL_DCGCSEC) &= ~SYS_CTRL_DCGCSEC_PKA;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
pka_check_status(void)
|
||||
{
|
||||
return (REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) == 0;
|
||||
}
|
||||
void
|
||||
pka_register_process_notification(struct process *p)
|
||||
{
|
||||
notification_process = p;
|
||||
}
|
||||
/** @} */
|
871
cpu/cc2538/dev/pka.h
Normal file
871
cpu/cc2538/dev/pka.h
Normal file
|
@ -0,0 +1,871 @@
|
|||
/*
|
||||
* Original file:
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Port to Contiki:
|
||||
* Copyright (c) 2014 Andreas Dröscher <contiki@anticat.ch>
|
||||
*
|
||||
* 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-pka cc2538 PKA engine
|
||||
*
|
||||
* Driver for the cc2538 PKA engine
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 PKA engine driver
|
||||
*/
|
||||
#ifndef PKA_H_
|
||||
#define PKA_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA memory
|
||||
* @{
|
||||
*/
|
||||
#define PKA_RAM_BASE 0x44006000 /**< PKA Memory Address */
|
||||
#define PKA_RAM_SIZE 0x800 /**< PKA Memory Size */
|
||||
#define PKA_MAX_CURVE_SIZE 12 /**< Define for the maximum curve
|
||||
size supported by the PKA module
|
||||
in 32 bit word. */
|
||||
#define PKA_MAX_LEN 12 /**< Define for the maximum length of
|
||||
the big number supported by the
|
||||
PKA module in 32 bit word. */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA register offsets
|
||||
* @{
|
||||
*/
|
||||
#define PKA_APTR 0x44004000 /**< PKA vector A address During
|
||||
execution of basic PKCP
|
||||
operations, this register is
|
||||
double buffered and can be
|
||||
written with a new value for the
|
||||
next operation; when not
|
||||
written, the value remains
|
||||
intact. During the execution of
|
||||
sequencer-controlled complex
|
||||
operations, this register may
|
||||
not be written and its value is
|
||||
undefined at the conclusion of
|
||||
the operation. The driver
|
||||
software cannot rely on the
|
||||
written value to remain intact. */
|
||||
#define PKA_BPTR 0x44004004 /**< PKA vector B address During
|
||||
execution of basic PKCP
|
||||
operations, this register is
|
||||
double buffered and can be
|
||||
written with a new value for the
|
||||
next operation; when not
|
||||
written, the value remains
|
||||
intact. During the execution of
|
||||
sequencer-controlled complex
|
||||
operations, this register may
|
||||
not be written and its value is
|
||||
undefined at the conclusion of
|
||||
the operation. The driver
|
||||
software cannot rely on the
|
||||
written value to remain intact. */
|
||||
#define PKA_CPTR 0x44004008 /**< PKA vector C address During
|
||||
execution of basic PKCP
|
||||
operations, this register is
|
||||
double buffered and can be
|
||||
written with a new value for the
|
||||
next operation; when not
|
||||
written, the value remains
|
||||
intact. During the execution of
|
||||
sequencer-controlled complex
|
||||
operations, this register may
|
||||
not be written and its value is
|
||||
undefined at the conclusion of
|
||||
the operation. The driver
|
||||
software cannot rely on the
|
||||
written value to remain intact. */
|
||||
#define PKA_DPTR 0x4400400C /**< PKA vector D address During
|
||||
execution of basic PKCP
|
||||
operations, this register is
|
||||
double buffered and can be
|
||||
written with a new value for the
|
||||
next operation; when not
|
||||
written, the value remains
|
||||
intact. During the execution of
|
||||
sequencer-controlled complex
|
||||
operations, this register may
|
||||
not be written and its value is
|
||||
undefined at the conclusion of
|
||||
the operation. The driver
|
||||
software cannot rely on the
|
||||
written value to remain intact. */
|
||||
#define PKA_ALENGTH 0x44004010 /**< PKA vector A length During
|
||||
execution of basic PKCP
|
||||
operations, this register is
|
||||
double buffered and can be
|
||||
written with a new value for the
|
||||
next operation; when not
|
||||
written, the value remains
|
||||
intact. During the execution of
|
||||
sequencer-controlled complex
|
||||
operations, this register may
|
||||
not be written and its value is
|
||||
undefined at the conclusion of
|
||||
the operation. The driver
|
||||
software cannot rely on the
|
||||
written value to remain intact. */
|
||||
#define PKA_BLENGTH 0x44004014 /**< PKA vector B length During
|
||||
execution of basic PKCP
|
||||
operations, this register is
|
||||
double buffered and can be
|
||||
written with a new value for the
|
||||
next operation; when not
|
||||
written, the value remains
|
||||
intact. During the execution of
|
||||
sequencer-controlled complex
|
||||
operations, this register may
|
||||
not be written and its value is
|
||||
undefined at the conclusion of
|
||||
the operation. The driver
|
||||
software cannot rely on the
|
||||
written value to remain intact. */
|
||||
#define PKA_SHIFT 0x44004018 /**< PKA bit shift value For basic
|
||||
PKCP operations, modifying the
|
||||
contents of this register is
|
||||
made impossible while the
|
||||
operation is being performed.
|
||||
For the ExpMod-variable and
|
||||
ExpMod-CRT operations, this
|
||||
register is used to indicate the
|
||||
number of odd powers to use
|
||||
(directly as a value in the
|
||||
range 1-16). For the ModInv and
|
||||
ECC operations, this register is
|
||||
used to hold a completion code. */
|
||||
#define PKA_FUNCTION 0x4400401C /**< PKA function This register
|
||||
contains the control bits to
|
||||
start basic PKCP as well as
|
||||
complex sequencer operations.
|
||||
The run bit can be used to poll
|
||||
for the completion of the
|
||||
operation. Modifying bits [11:0]
|
||||
is made impossible during the
|
||||
execution of a basic PKCP
|
||||
operation. During the execution
|
||||
of sequencer-controlled complex
|
||||
operations, this register is
|
||||
modified; the run and stall
|
||||
result bits are set to zero at
|
||||
the conclusion, but other bits
|
||||
are undefined. Attention:
|
||||
Continuously reading this
|
||||
register to poll the run bit is
|
||||
not allowed when executing
|
||||
complex sequencer operations
|
||||
(the sequencer cannot access the
|
||||
PKCP when this is done). Leave
|
||||
at least one sysclk cycle
|
||||
between poll operations. */
|
||||
#define PKA_COMPARE 0x44004020 /**< PKA compare result This
|
||||
register provides the result of
|
||||
a basic PKCP compare operation.
|
||||
It is updated when the run bit
|
||||
in the PKA_FUNCTION register is
|
||||
reset at the end of that
|
||||
operation. Status after a
|
||||
complex sequencer operation is
|
||||
unknown */
|
||||
#define PKA_MSW 0x44004024 /**< PKA most-significant-word of
|
||||
result vector This register
|
||||
indicates the (word) address in
|
||||
the PKA RAM where the most
|
||||
significant nonzero 32-bit word
|
||||
of the result is stored. Should
|
||||
be ignored for modulo
|
||||
operations. For basic PKCP
|
||||
operations, this register is
|
||||
updated when the run bit in the
|
||||
PKA_FUNCTION register is reset
|
||||
at the end of the operation. For
|
||||
the complex-sequencer controlled
|
||||
operations, updating of the
|
||||
final value matching the actual
|
||||
result is done near the end of
|
||||
the operation; note that the
|
||||
result is only meaningful if no
|
||||
errors were detected and that
|
||||
for ECC operations, the PKA_MSW
|
||||
register will provide
|
||||
information for the x-coordinate
|
||||
of the result point only. */
|
||||
#define PKA_DIVMSW 0x44004028 /**< PKA most-significant-word of
|
||||
divide remainder This register
|
||||
indicates the (32-bit word)
|
||||
address in the PKA RAM where the
|
||||
most significant nonzero 32-bit
|
||||
word of the remainder result for
|
||||
the basic divide and modulo
|
||||
operations is stored. Bits [4:0]
|
||||
are loaded with the bit number
|
||||
of the most-significant nonzero
|
||||
bit in the most-significant
|
||||
nonzero word when MS one control
|
||||
bit is set. For divide, modulo,
|
||||
and MS one reporting, this
|
||||
register is updated when the RUN
|
||||
bit in the PKA_FUNCTION register
|
||||
is reset at the end of the
|
||||
operation. For the complex
|
||||
sequencer controlled operations,
|
||||
updating of bits [4:0] of this
|
||||
register with the
|
||||
most-significant bit location of
|
||||
the actual result is done near
|
||||
the end of the operation. The
|
||||
result is meaningful only if no
|
||||
errors were detected and that
|
||||
for ECC operations; the
|
||||
PKA_DIVMSW register provides
|
||||
information for the x-coordinate
|
||||
of the result point only. */
|
||||
#define PKA_SEQ_CTRL 0x440040C8 /**< PKA sequencer control and
|
||||
status register The sequencer is
|
||||
interfaced with the outside
|
||||
world through a single control
|
||||
and status register. With the
|
||||
exception of bit [31], the
|
||||
actual use of bits in the
|
||||
separate sub-fields of this
|
||||
register is determined by the
|
||||
sequencer firmware. This
|
||||
register need only be accessed
|
||||
when the sequencer program is
|
||||
stored in RAM. The reset value
|
||||
of the RESTE bit depends upon
|
||||
the option chosen for sequencer
|
||||
program storage. */
|
||||
#define PKA_OPTIONS 0x440040F4 /**< PKA hardware options register
|
||||
This register provides the host
|
||||
with a means to determine the
|
||||
hardware configuration
|
||||
implemented in this PKA engine,
|
||||
focused on options that have an
|
||||
effect on software interacting
|
||||
with the module. Note: (32 x
|
||||
(1st LNME nr. of PEs + 1st LNME
|
||||
FIFO RAM depth - 10)) equals the
|
||||
maximum modulus vector length
|
||||
(in bits) that can be handled by
|
||||
the modular exponentiation and
|
||||
ECC operations executed on a PKA
|
||||
engine that includes an LNME. */
|
||||
#define PKA_SW_REV 0x440040F8 /**< PKA firmware revision and
|
||||
capabilities register This
|
||||
register allows the host access
|
||||
to the internal firmware
|
||||
revision number of the PKA
|
||||
Engine for software driver
|
||||
matching and diagnostic
|
||||
purposes. This register also
|
||||
contains a field that encodes
|
||||
the capabilities of the embedded
|
||||
firmware. The PKA_SW_REV
|
||||
register is written by the
|
||||
firmware within a few clock
|
||||
cycles after starting up that
|
||||
firmware. The hardware reset
|
||||
value is zero, indicating that
|
||||
the information has not been
|
||||
written yet. */
|
||||
#define PKA_REVISION 0x440040FC /**< PKA hardware revision register
|
||||
This register allows the host
|
||||
access to the hardware revision
|
||||
number of the PKA engine for
|
||||
software driver matching and
|
||||
diagnostic purposes. It is
|
||||
always located at the highest
|
||||
address in the access space of
|
||||
the module and contains an
|
||||
encoding of the EIP number (with
|
||||
its complement as signature) for
|
||||
recognition of the hardware
|
||||
module. */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_APTR register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_APTR_APTR_M 0x000007FF /**< This register specifies the
|
||||
location of vector A within the
|
||||
PKA RAM. Vectors are identified
|
||||
through the location of their
|
||||
least-significant 32-bit word.
|
||||
Note that bit [0] must be zero
|
||||
to ensure that the vector starts
|
||||
at an 8-byte boundary. */
|
||||
#define PKA_APTR_APTR_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_BPTR register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_BPTR_BPTR_M 0x000007FF /**< This register specifies the
|
||||
location of vector B within the
|
||||
PKA RAM. Vectors are identified
|
||||
through the location of their
|
||||
least-significant 32-bit word.
|
||||
Note that bit [0] must be zero
|
||||
to ensure that the vector starts
|
||||
at an 8-byte boundary. */
|
||||
#define PKA_BPTR_BPTR_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_CPTR register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_CPTR_CPTR_M 0x000007FF /**< This register specifies the
|
||||
location of vector C within the
|
||||
PKA RAM. Vectors are identified
|
||||
through the location of their
|
||||
least-significant 32-bit word.
|
||||
Note that bit [0] must be zero
|
||||
to ensure that the vector starts
|
||||
at an 8-byte boundary. */
|
||||
#define PKA_CPTR_CPTR_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_DPTR register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_DPTR_DPTR_M 0x000007FF /**< This register specifies the
|
||||
location of vector D within the
|
||||
PKA RAM. Vectors are identified
|
||||
through the location of their
|
||||
least-significant 32-bit word.
|
||||
Note that bit [0] must be zero
|
||||
to ensure that the vector starts
|
||||
at an 8-byte boundary. */
|
||||
#define PKA_DPTR_DPTR_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_ALENGTH register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_ALENGTH_ALENGTH_M 0x000001FF /**< This register specifies the
|
||||
length (in 32-bit words) of
|
||||
Vector A. */
|
||||
#define PKA_ALENGTH_ALENGTH_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_BLENGTH register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_BLENGTH_BLENGTH_M 0x000001FF /**< This register specifies the
|
||||
length (in 32-bit words) of
|
||||
Vector B. */
|
||||
#define PKA_BLENGTH_BLENGTH_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_SHIFT register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_SHIFT_NUM_BITS_TO_SHIFT_M \
|
||||
0x0000001F /**< This register specifies the
|
||||
number of bits to shift the
|
||||
input vector (in the range 0-31)
|
||||
during a Rshift or Lshift
|
||||
operation. */
|
||||
|
||||
#define PKA_SHIFT_NUM_BITS_TO_SHIFT_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_FUNCTION register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_FUNCTION_STALL_RESULT \
|
||||
0x01000000 /**< When written with a 1b,
|
||||
updating of the PKA_COMPARE,
|
||||
PKA_MSW and PKA_DIVMSW
|
||||
registers, as well as resetting
|
||||
the run bit is stalled beyond
|
||||
the point that a running
|
||||
operation is actually finished.
|
||||
Use this to allow software
|
||||
enough time to read results from
|
||||
a previous operation when the
|
||||
newly started operation is known
|
||||
to take only a short amount of
|
||||
time. If a result is waiting,
|
||||
the result registers is updated
|
||||
and the run bit is reset in the
|
||||
clock cycle following writing
|
||||
the stall result bit back to 0b.
|
||||
The Stall result function may
|
||||
only be used for basic PKCP
|
||||
operations. */
|
||||
|
||||
#define PKA_FUNCTION_STALL_RESULT_M \
|
||||
0x01000000
|
||||
#define PKA_FUNCTION_STALL_RESULT_S 24
|
||||
#define PKA_FUNCTION_RUN 0x00008000 /**< The host sets this bit to
|
||||
instruct the PKA module to begin
|
||||
processing the basic PKCP or
|
||||
complex sequencer operation.
|
||||
This bit is reset low
|
||||
automatically when the operation
|
||||
is complete. The complement of
|
||||
this bit is output as
|
||||
interrupts[1]. After a reset,
|
||||
the run bit is always set to 1b.
|
||||
Depending on the option, program
|
||||
ROM or program RAM, the
|
||||
following applies: Program ROM -
|
||||
The first sequencer instruction
|
||||
sets the bit to 0b. This is done
|
||||
immediately after the hardware
|
||||
reset is released. Program RAM -
|
||||
The sequencer must set the bit
|
||||
to 0b. As a valid firmware may
|
||||
not have been loaded, the
|
||||
sequencer is held in software
|
||||
reset after the hardware reset
|
||||
is released (the reset bit in
|
||||
PKA_SEQ_CRTL is set to 1b).
|
||||
After the FW image is loaded and
|
||||
the Reset bit is cleared, the
|
||||
sequencer starts to execute the
|
||||
FW. The first instruction clears
|
||||
the run bit. In both cases a few
|
||||
clock cycles are needed before
|
||||
the first instruction is
|
||||
executed and the run bit state
|
||||
has been propagated. */
|
||||
#define PKA_FUNCTION_RUN_M 0x00008000
|
||||
#define PKA_FUNCTION_RUN_S 15
|
||||
#define PKA_FUNCTION_SEQUENCER_OPERATIONS_M \
|
||||
0x00007000 /**< These bits select the complex
|
||||
sequencer operation to perform:
|
||||
000b: None 001b: ExpMod-CRT
|
||||
010b: ExpMod-ACT4 (compatible
|
||||
with EIP2315) 011b: ECC-ADD (if
|
||||
available in firmware, otherwise
|
||||
reserved) 100b: ExpMod-ACT2
|
||||
(compatible with EIP2316) 101b:
|
||||
ECC-MUL (if available in
|
||||
firmware, otherwise reserved)
|
||||
110b: ExpMod-variable 111b:
|
||||
ModInv (if available in
|
||||
firmware, otherwise reserved)
|
||||
The encoding of these operations
|
||||
is determined by sequencer
|
||||
firmware. */
|
||||
|
||||
#define PKA_FUNCTION_SEQUENCER_OPERATIONS_S 12
|
||||
#define PKA_FUNCTION_COPY 0x00000800 /**< Perform copy operation */
|
||||
#define PKA_FUNCTION_COPY_M 0x00000800
|
||||
#define PKA_FUNCTION_COPY_S 11
|
||||
#define PKA_FUNCTION_COMPARE 0x00000400 /**< Perform compare operation */
|
||||
#define PKA_FUNCTION_COMPARE_M 0x00000400
|
||||
#define PKA_FUNCTION_COMPARE_S 10
|
||||
#define PKA_FUNCTION_MODULO 0x00000200 /**< Perform modulo operation */
|
||||
#define PKA_FUNCTION_MODULO_M 0x00000200
|
||||
#define PKA_FUNCTION_MODULO_S 9
|
||||
#define PKA_FUNCTION_DIVIDE 0x00000100 /**< Perform divide operation */
|
||||
#define PKA_FUNCTION_DIVIDE_M 0x00000100
|
||||
#define PKA_FUNCTION_DIVIDE_S 8
|
||||
#define PKA_FUNCTION_LSHIFT 0x00000080 /**< Perform left shift operation */
|
||||
#define PKA_FUNCTION_LSHIFT_M 0x00000080
|
||||
#define PKA_FUNCTION_LSHIFT_S 7
|
||||
#define PKA_FUNCTION_RSHIFT 0x00000040 /**< Perform right shift operation */
|
||||
#define PKA_FUNCTION_RSHIFT_M 0x00000040
|
||||
#define PKA_FUNCTION_RSHIFT_S 6
|
||||
#define PKA_FUNCTION_SUBTRACT 0x00000020 /**< Perform subtract operation */
|
||||
#define PKA_FUNCTION_SUBTRACT_M 0x00000020
|
||||
#define PKA_FUNCTION_SUBTRACT_S 5
|
||||
#define PKA_FUNCTION_ADD 0x00000010 /**< Perform add operation */
|
||||
#define PKA_FUNCTION_ADD_M 0x00000010
|
||||
#define PKA_FUNCTION_ADD_S 4
|
||||
#define PKA_FUNCTION_MS_ONE 0x00000008 /**< Loads the location of the Most
|
||||
Significant one bit within the
|
||||
result word indicated in the
|
||||
PKA_MSW register into bits [4:0]
|
||||
of the PKA_DIVMSW register - can
|
||||
only be used with basic PKCP
|
||||
operations, except for Divide,
|
||||
Modulo and Compare. */
|
||||
#define PKA_FUNCTION_MS_ONE_M 0x00000008
|
||||
#define PKA_FUNCTION_MS_ONE_S 3
|
||||
#define PKA_FUNCTION_ADDSUB 0x00000002 /**< Perform combined add/subtract
|
||||
operation */
|
||||
#define PKA_FUNCTION_ADDSUB_M 0x00000002
|
||||
#define PKA_FUNCTION_ADDSUB_S 1
|
||||
#define PKA_FUNCTION_MULTIPLY 0x00000001 /**< Perform multiply operation */
|
||||
#define PKA_FUNCTION_MULTIPLY_M 0x00000001
|
||||
#define PKA_FUNCTION_MULTIPLY_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_COMPARE register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_COMPARE_A_GREATER_THAN_B \
|
||||
0x00000004 /**< Vector_A is greater than
|
||||
Vector_B */
|
||||
|
||||
#define PKA_COMPARE_A_GREATER_THAN_B_M \
|
||||
0x00000004
|
||||
#define PKA_COMPARE_A_GREATER_THAN_B_S 2
|
||||
#define PKA_COMPARE_A_LESS_THAN_B \
|
||||
0x00000002 /**< Vector_A is less than Vector_B */
|
||||
|
||||
#define PKA_COMPARE_A_LESS_THAN_B_M \
|
||||
0x00000002
|
||||
#define PKA_COMPARE_A_LESS_THAN_B_S 1
|
||||
#define PKA_COMPARE_A_EQUALS_B 0x00000001 /**< Vector_A is equal to Vector_B */
|
||||
#define PKA_COMPARE_A_EQUALS_B_M \
|
||||
0x00000001
|
||||
#define PKA_COMPARE_A_EQUALS_B_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_MSW register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_MSW_RESULT_IS_ZERO 0x00008000 /**< The result vector is all
|
||||
zeroes, ignore the address
|
||||
returned in bits [10:0] */
|
||||
#define PKA_MSW_RESULT_IS_ZERO_M \
|
||||
0x00008000
|
||||
#define PKA_MSW_RESULT_IS_ZERO_S 15
|
||||
#define PKA_MSW_MSW_ADDRESS_M 0x000007FF /**< Address of the most-significant
|
||||
nonzero 32-bit word of the
|
||||
result vector in PKA RAM */
|
||||
#define PKA_MSW_MSW_ADDRESS_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_DIVMSW register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_DIVMSW_RESULT_IS_ZERO \
|
||||
0x00008000 /**< The result vector is all
|
||||
zeroes, ignore the address
|
||||
returned in bits [10:0] */
|
||||
|
||||
#define PKA_DIVMSW_RESULT_IS_ZERO_M \
|
||||
0x00008000
|
||||
#define PKA_DIVMSW_RESULT_IS_ZERO_S 15
|
||||
#define PKA_DIVMSW_MSW_ADDRESS_M \
|
||||
0x000007FF /**< Address of the most significant
|
||||
nonzero 32-bit word of the
|
||||
remainder result vector in PKA
|
||||
RAM */
|
||||
|
||||
#define PKA_DIVMSW_MSW_ADDRESS_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_SEQ_CTRL register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_SEQ_CTRL_RESET 0x80000000 /**< Option program ROM: Reset value
|
||||
= 0. Read/Write, reset value 0b
|
||||
(ZERO). Writing 1b resets the
|
||||
sequencer, write to 0b to
|
||||
restart operations again. As the
|
||||
reset value is 0b, the sequencer
|
||||
will automatically start
|
||||
operations executing from
|
||||
program ROM. This bit should
|
||||
always be written with zero and
|
||||
ignored when reading this
|
||||
register. Option Program RAM:
|
||||
Reset value =1. Read/Write,
|
||||
reset value 1b (ONE). When 1b,
|
||||
the sequencer is held in a reset
|
||||
state and the PKA_PROGRAM area
|
||||
is accessible for loading the
|
||||
sequencer program (while the
|
||||
PKA_DATA_RAM is inaccessible),
|
||||
write to 0b to (re)start
|
||||
sequencer operations and disable
|
||||
PKA_PROGRAM area accessibility
|
||||
(also enables the PKA_DATA_RAM
|
||||
accesses). Resetting the
|
||||
sequencer (in order to load
|
||||
other firmware) should only be
|
||||
done when the PKA Engine is not
|
||||
performing any operations (i.e.
|
||||
the run bit in the PKA_FUNCTION
|
||||
register should be zero). */
|
||||
#define PKA_SEQ_CTRL_RESET_M 0x80000000
|
||||
#define PKA_SEQ_CTRL_RESET_S 31
|
||||
#define PKA_SEQ_CTRL_SEQUENCER_STATUS_M \
|
||||
0x0000FF00 /**< These read-only bits can be
|
||||
used by the sequencer to
|
||||
communicate status to the
|
||||
outside world. Bit [8] is also
|
||||
used as sequencer interrupt,
|
||||
with the complement of this bit
|
||||
ORed into the run bit in
|
||||
PKA_FUNCTION. This field should
|
||||
always be written with zeroes
|
||||
and ignored when reading this
|
||||
register. */
|
||||
|
||||
#define PKA_SEQ_CTRL_SEQUENCER_STATUS_S 8
|
||||
#define PKA_SEQ_CTRL_SW_CONTROL_STATUS_M \
|
||||
0x000000FF /**< These bits can be used by
|
||||
software to trigger sequencer
|
||||
operations. External logic can
|
||||
set these bits by writing 1b,
|
||||
cannot reset them by writing 0b.
|
||||
The sequencer can reset these
|
||||
bits by writing 0b, cannot set
|
||||
them by writing 1b. Setting the
|
||||
run bit in PKA_FUNCTION together
|
||||
with a nonzero sequencer
|
||||
operations field automatically
|
||||
sets bit [0] here. This field
|
||||
should always be written with
|
||||
zeroes and ignored when reading
|
||||
this register. */
|
||||
|
||||
#define PKA_SEQ_CTRL_SW_CONTROL_STATUS_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_OPTIONS register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_OPTIONS_FIRST_LNME_FIFO_DEPTH_M \
|
||||
0xFF000000 /**< Number of words in the first
|
||||
LNME's FIFO RAM Should be
|
||||
ignored if LNME configuration is
|
||||
0. The contents of this field
|
||||
indicate the actual depth as
|
||||
selected by the LNME FIFO RAM
|
||||
size strap input, fifo_size_sel.
|
||||
Note: Reset value is undefined */
|
||||
|
||||
#define PKA_OPTIONS_FIRST_LNME_FIFO_DEPTH_S 24
|
||||
#define PKA_OPTIONS_FIRST_LNME_NR_OF_PES_M \
|
||||
0x003F0000 /**< Number of processing elements
|
||||
in the pipeline of the first
|
||||
LNME Should be ignored if LNME
|
||||
configuration is 0. Note: Reset
|
||||
value is undefined. */
|
||||
|
||||
#define PKA_OPTIONS_FIRST_LNME_NR_OF_PES_S 16
|
||||
#define PKA_OPTIONS_MMM3A 0x00001000 /**< Reserved for a future
|
||||
functional extension to the LNME
|
||||
Always 0b */
|
||||
#define PKA_OPTIONS_MMM3A_M 0x00001000
|
||||
#define PKA_OPTIONS_MMM3A_S 12
|
||||
#define PKA_OPTIONS_INT_MASKING 0x00000800 /**< Value 0b indicates that the
|
||||
main interrupt output (bit [1]
|
||||
of the interrupts output bus) is
|
||||
the direct complement of the run
|
||||
bit in the PKA_CONTROL register,
|
||||
value 1b indicates that
|
||||
interrupt masking logic is
|
||||
present for this output. Note:
|
||||
Reset value is undefined */
|
||||
#define PKA_OPTIONS_INT_MASKING_M \
|
||||
0x00000800
|
||||
#define PKA_OPTIONS_INT_MASKING_S 11
|
||||
#define PKA_OPTIONS_PROTECTION_OPTION_M \
|
||||
0x00000700 /**< Value 0 indicates no additional
|
||||
protection against side channel
|
||||
attacks, value 1 indicates the
|
||||
SCAP option, value 3 indicates
|
||||
the PROT option; other values
|
||||
are reserved. Note: Reset value
|
||||
is undefined */
|
||||
|
||||
#define PKA_OPTIONS_PROTECTION_OPTION_S 8
|
||||
#define PKA_OPTIONS_PROGRAM_RAM 0x00000080 /**< Value 1b indicates sequencer
|
||||
program storage in RAM, value 0b
|
||||
in ROM. Note: Reset value is
|
||||
undefined */
|
||||
#define PKA_OPTIONS_PROGRAM_RAM_M \
|
||||
0x00000080
|
||||
#define PKA_OPTIONS_PROGRAM_RAM_S 7
|
||||
#define PKA_OPTIONS_SEQUENCER_CONFIGURATION_M \
|
||||
0x00000060 /**< Value 1 indicates a standard
|
||||
sequencer; other values are
|
||||
reserved. */
|
||||
|
||||
#define PKA_OPTIONS_SEQUENCER_CONFIGURATION_S 5
|
||||
#define PKA_OPTIONS_LNME_CONFIGURATION_M \
|
||||
0x0000001C /**< Value 0 indicates NO LNME,
|
||||
value 1 indicates one standard
|
||||
LNME (with alpha = 32, beta =
|
||||
8); other values reserved. Note:
|
||||
Reset value is undefined */
|
||||
|
||||
#define PKA_OPTIONS_LNME_CONFIGURATION_S 2
|
||||
#define PKA_OPTIONS_PKCP_CONFIGURATION_M \
|
||||
0x00000003 /**< Value 1 indicates a PKCP with a
|
||||
16x16 multiplier, value 2
|
||||
indicates a PKCP with a 32x32
|
||||
multiplier, other values
|
||||
reserved. Note: Reset value is
|
||||
undefined. */
|
||||
|
||||
#define PKA_OPTIONS_PKCP_CONFIGURATION_S 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_SW_REV register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_SW_REV_FW_CAPABILITIES_M \
|
||||
0xF0000000 /**< 4-bit binary encoding for the
|
||||
functionality implemented in the
|
||||
firmware. Value 0 indicates
|
||||
basic ModExp with/without CRT.
|
||||
Value 1 adds Modular Inversion,
|
||||
value 2 adds Modular Inversion
|
||||
and ECC operations. Values 3-15
|
||||
are reserved. */
|
||||
|
||||
#define PKA_SW_REV_FW_CAPABILITIES_S 28
|
||||
#define PKA_SW_REV_MAJOR_FW_REVISION_M \
|
||||
0x0F000000 /**< 4-bit binary encoding of the
|
||||
major firmware revision number */
|
||||
|
||||
#define PKA_SW_REV_MAJOR_FW_REVISION_S 24
|
||||
#define PKA_SW_REV_MINOR_FW_REVISION_M \
|
||||
0x00F00000 /**< 4-bit binary encoding of the
|
||||
minor firmware revision number */
|
||||
|
||||
#define PKA_SW_REV_MINOR_FW_REVISION_S 20
|
||||
#define PKA_SW_REV_FW_PATCH_LEVEL_M \
|
||||
0x000F0000 /**< 4-bit binary encoding of the
|
||||
firmware patch level, initial
|
||||
release will carry value zero
|
||||
Patches are used to remove bugs
|
||||
without changing the
|
||||
functionality or interface of a
|
||||
module. */
|
||||
|
||||
#define PKA_SW_REV_FW_PATCH_LEVEL_S 16
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA_REVISION register registers bit fields
|
||||
* @{
|
||||
*/
|
||||
#define PKA_REVISION_MAJOR_HW_REVISION_M \
|
||||
0x0F000000 /**< 4-bit binary encoding of the
|
||||
major hardware revision number */
|
||||
|
||||
#define PKA_REVISION_MAJOR_HW_REVISION_S 24
|
||||
#define PKA_REVISION_MINOR_HW_REVISION_M \
|
||||
0x00F00000 /**< 4-bit binary encoding of the
|
||||
minor hardware revision number */
|
||||
|
||||
#define PKA_REVISION_MINOR_HW_REVISION_S 20
|
||||
#define PKA_REVISION_HW_PATCH_LEVEL_M \
|
||||
0x000F0000 /**< 4-bit binary encoding of the
|
||||
hardware patch level, initial
|
||||
release will carry value zero
|
||||
Patches are used to remove bugs
|
||||
without changing the
|
||||
functionality or interface of a
|
||||
module. */
|
||||
|
||||
#define PKA_REVISION_HW_PATCH_LEVEL_S 16
|
||||
#define PKA_REVISION_COMPLEMENT_OF_BASIC_EIP_NUMBER_M \
|
||||
0x0000FF00 /**< Bit-by-bit logic complement of
|
||||
bits [7:0], EIP-28 gives 0xE3 */
|
||||
|
||||
#define PKA_REVISION_COMPLEMENT_OF_BASIC_EIP_NUMBER_S 8
|
||||
#define PKA_REVISION_BASIC_EIP_NUMBER_M \
|
||||
0x000000FF /**< 8-bit binary encoding of the
|
||||
EIP number, EIP-28 gives 0x1C */
|
||||
|
||||
#define PKA_REVISION_BASIC_EIP_NUMBER_S 0
|
||||
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA driver return codes
|
||||
* @{
|
||||
*/
|
||||
#define PKA_STATUS_SUCCESS 0 /**< Success */
|
||||
#define PKA_STATUS_FAILURE 1 /**< Failure */
|
||||
#define PKA_STATUS_INVALID_PARAM 2 /**< Invalid parameter */
|
||||
#define PKA_STATUS_BUF_UNDERFLOW 3 /**< Buffer underflow */
|
||||
#define PKA_STATUS_RESULT_0 4 /**< Result is all zeros */
|
||||
#define PKA_STATUS_A_GR_B 5 /**< Big number compare return status if
|
||||
the first big num is greater than
|
||||
the second. */
|
||||
#define PKA_STATUS_A_LT_B 6 /**< Big number compare return status if
|
||||
the first big num is less than the
|
||||
second. */
|
||||
#define PKA_STATUS_OPERATION_INPRG 7 /**< PKA operation is in progress. */
|
||||
#define PKA_STATUS_OPERATION_NOT_INPRG 8 /**< No PKA operation is in progress. */
|
||||
#define PKA_STATUS_SIGNATURE_INVALID 9 /**< Signature is invalid. */
|
||||
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name PKA functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Enables and resets the PKA engine
|
||||
*/
|
||||
void pka_init(void);
|
||||
|
||||
/** \brief Enables the PKA engine
|
||||
*/
|
||||
void pka_enable(void);
|
||||
|
||||
/** \brief Disables the PKA engine
|
||||
* \note Call this function to save power when the engine is unused.
|
||||
*/
|
||||
void pka_disable(void);
|
||||
|
||||
/** \brief Checks the status of the PKA engine operation
|
||||
* \retval false Result not yet available, and no error occurred
|
||||
* \retval true Result available, or error occurred
|
||||
*/
|
||||
uint8_t pka_check_status(void);
|
||||
|
||||
/** \brief Registers a process to be notified of the completion of a PKA
|
||||
* operation
|
||||
* \param p Process to be polled upon IRQ
|
||||
* \note This function is only supposed to be called by the PKA drivers.
|
||||
*/
|
||||
void pka_register_process_notification(struct process *p);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* PKA_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -101,7 +101,7 @@ static uint8_t max_pm;
|
|||
#ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||
#else
|
||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 3
|
||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 4
|
||||
#endif
|
||||
|
||||
static lpm_periph_permit_pm1_func_t
|
||||
|
@ -128,8 +128,7 @@ periph_permit_pm1(void)
|
|||
static void
|
||||
enter_pm0(void)
|
||||
{
|
||||
ENERGEST_OFF(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_ON(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
|
||||
|
||||
/* We are only interested in IRQ energest while idle or in LPM */
|
||||
ENERGEST_IRQ_RESTORE(irq_energest);
|
||||
|
@ -147,8 +146,7 @@ enter_pm0(void)
|
|||
/* Remember IRQ energest for next pass */
|
||||
ENERGEST_IRQ_SAVE(irq_energest);
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
@ -238,8 +236,7 @@ lpm_exit()
|
|||
/* Remember IRQ energest for next pass */
|
||||
ENERGEST_IRQ_SAVE(irq_energest);
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -312,8 +309,7 @@ lpm_enter()
|
|||
|
||||
/* We are only interested in IRQ energest while idle or in LPM */
|
||||
ENERGEST_IRQ_RESTORE(irq_energest);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_ON(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
|
||||
|
||||
/* Remember the current time so we can keep stats when we wake up */
|
||||
if(LPM_CONF_STATS) {
|
||||
|
@ -339,8 +335,7 @@ lpm_enter()
|
|||
|
||||
/* Remember IRQ energest for next pass */
|
||||
ENERGEST_IRQ_SAVE(irq_energest);
|
||||
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
} else {
|
||||
/* All clear. Assert WFI and drop to PM1/2. This is now un-interruptible */
|
||||
assert_wfi();
|
||||
|
|
|
@ -68,6 +68,7 @@ void usb_isr(void) WEAK_ALIAS(default_handler);
|
|||
void uart0_isr(void) WEAK_ALIAS(default_handler);
|
||||
void uart1_isr(void) WEAK_ALIAS(default_handler);
|
||||
void crypto_isr(void);
|
||||
void pka_isr(void);
|
||||
|
||||
/* Boot Loader Backdoor selection */
|
||||
#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR
|
||||
|
@ -271,7 +272,7 @@ void(*const vectors[])(void) =
|
|||
cc2538_rf_rx_tx_isr, /* 157 RFCORE RX/TX */
|
||||
cc2538_rf_err_isr, /* 158 RFCORE Error */
|
||||
crypto_isr, /* 159 AES */
|
||||
default_handler, /* 160 PKA */
|
||||
pka_isr, /* 160 PKA */
|
||||
rtimer_isr, /* 161 SM Timer */
|
||||
default_handler, /* 162 MACTimer */
|
||||
};
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#endif
|
||||
|
||||
#define CC_CONF_FUNCTION_POINTER_ARGS 1
|
||||
#define CC_CONF_FASTCALL
|
||||
#define CC_CONF_VA_ARGS 1
|
||||
#define CC_CONF_UNSIGNED_CHAR_BUGS 0
|
||||
#define CC_CONF_REGISTER_ARGS 0
|
||||
|
|
|
@ -41,6 +41,10 @@ LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch
|
|||
OBJCOPY_FLAGS += -O binary --gap-fill 0xff
|
||||
OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb
|
||||
|
||||
ifdef WERROR
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
### Are we building with code size optimisations?
|
||||
ifeq ($(SMALL),1)
|
||||
CFLAGS += -Os
|
||||
|
|
|
@ -120,31 +120,35 @@ clock_init(void)
|
|||
((TIMER_CFG_B_ONE_SHOT >> 8) & 0xFF) | GPT_TBMR_TBPWMIE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
update_clock_variable(void)
|
||||
{
|
||||
uint32_t aon_rtc_secs_now;
|
||||
uint32_t aon_rtc_secs_now2;
|
||||
uint16_t aon_rtc_ticks_now;
|
||||
|
||||
do {
|
||||
aon_rtc_secs_now = HWREG(AON_RTC_BASE + AON_RTC_O_SEC);
|
||||
aon_rtc_ticks_now = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) >> 16;
|
||||
aon_rtc_secs_now2 = HWREG(AON_RTC_BASE + AON_RTC_O_SEC);
|
||||
} while(aon_rtc_secs_now != aon_rtc_secs_now2);
|
||||
|
||||
/* Convert AON RTC ticks to clock tick counter */
|
||||
count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CCIF clock_time_t
|
||||
clock_time(void)
|
||||
{
|
||||
update_clock_variable();
|
||||
|
||||
return (clock_time_t)(count & 0xFFFFFFFF);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
clock_update(void)
|
||||
{
|
||||
bool interrupts_disabled;
|
||||
uint32_t aon_rtc_secs_now;
|
||||
uint16_t aon_rtc_ticks_now;
|
||||
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
aon_rtc_secs_now = HWREG(AON_RTC_BASE + AON_RTC_O_SEC);
|
||||
aon_rtc_ticks_now = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) >> 16;
|
||||
|
||||
/* Convert AON RTC ticks to clock tick counter */
|
||||
count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9);
|
||||
|
||||
/* Re-enable interrupts */
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
update_clock_variable();
|
||||
|
||||
if(etimer_pending()) {
|
||||
etimer_request_poll();
|
||||
|
|
|
@ -42,8 +42,61 @@
|
|||
* \file
|
||||
* Implementation of the CC13xx/CC26xx watchdog driver.
|
||||
*/
|
||||
#include "watchdog.h"
|
||||
#include "contiki.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef CONTIKI_WATCHDOG_CONF_TIMER_TOP
|
||||
#define CONTIKI_WATCHDOG_TIMER_TOP CONTIKI_WATCHDOG_CONF_TIMER_TOP
|
||||
#else
|
||||
#define CONTIKI_WATCHDOG_TIMER_TOP 0xFFFFF
|
||||
#endif
|
||||
|
||||
#ifdef CONTIKI_WATCHDOG_CONF_LOCK_CONFIG
|
||||
#define CONTIKI_WATCHDOG_LOCK_CONFIG CONTIKI_WATCHDOG_CONF_LOCK_CONFIG
|
||||
#else
|
||||
#define CONTIKI_WATCHDOG_LOCK_CONFIG 1
|
||||
#endif
|
||||
|
||||
#define LOCK_INTERRUPTS_DISABLED 0x01
|
||||
#define LOCK_REGISTERS_UNLOCKED 0x02
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint32_t
|
||||
unlock_config(void)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
bool int_status;
|
||||
|
||||
if(CONTIKI_WATCHDOG_LOCK_CONFIG) {
|
||||
int_status = ti_lib_int_master_disable();
|
||||
|
||||
if(ti_lib_watchdog_lock_state()) {
|
||||
ret |= LOCK_REGISTERS_UNLOCKED;
|
||||
ti_lib_watchdog_unlock();
|
||||
}
|
||||
|
||||
ret |= (int_status) ? (0) : (LOCK_INTERRUPTS_DISABLED);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
lock_config(uint32_t status)
|
||||
{
|
||||
if(CONTIKI_WATCHDOG_LOCK_CONFIG) {
|
||||
|
||||
if(status & LOCK_REGISTERS_UNLOCKED) {
|
||||
ti_lib_watchdog_lock();
|
||||
}
|
||||
if(status & LOCK_INTERRUPTS_DISABLED) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initialises the CC26xx WDT
|
||||
|
@ -54,7 +107,8 @@
|
|||
void
|
||||
watchdog_init(void)
|
||||
{
|
||||
ti_lib_watchdog_reload_set(0xFFFFF);
|
||||
ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP);
|
||||
lock_config(LOCK_REGISTERS_UNLOCKED);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -63,7 +117,12 @@ watchdog_init(void)
|
|||
void
|
||||
watchdog_start(void)
|
||||
{
|
||||
uint32_t lock_status = unlock_config();
|
||||
|
||||
watchdog_periodic();
|
||||
ti_lib_watchdog_reset_enable();
|
||||
|
||||
lock_config(lock_status);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -72,9 +131,23 @@ watchdog_start(void)
|
|||
void
|
||||
watchdog_periodic(void)
|
||||
{
|
||||
ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP);
|
||||
ti_lib_watchdog_int_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Stops the WDT such that it won't timeout and cause MCU reset
|
||||
*/
|
||||
void
|
||||
watchdog_stop(void)
|
||||
{
|
||||
uint32_t lock_status = unlock_config();
|
||||
|
||||
ti_lib_watchdog_reset_disable();
|
||||
|
||||
lock_config(lock_status);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Manually trigger a WDT reboot
|
||||
*/
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* Prototype of a function in clock.c. Called every time the handler fires */
|
||||
void clock_update(void);
|
||||
|
||||
static rtimer_clock_t last_isr_time;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define COMPARE_INCREMENT (RTIMER_SECOND / CLOCK_SECOND)
|
||||
#define MULTIPLE_512_MASK 0xFFFFFE00
|
||||
|
@ -130,6 +132,12 @@ soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks)
|
|||
ti_lib_aon_rtc_channel_enable(channel);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rtimer_clock_t
|
||||
soc_rtc_last_isr_time(void)
|
||||
{
|
||||
return last_isr_time;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* The AON RTC interrupt handler */
|
||||
void
|
||||
soc_rtc_isr(void)
|
||||
|
@ -138,6 +146,8 @@ soc_rtc_isr(void)
|
|||
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
|
||||
last_isr_time = RTIMER_NOW();
|
||||
|
||||
now = ti_lib_aon_rtc_current_compare_value_get();
|
||||
|
||||
/* Adjust the s/w tick counter irrespective of which event trigger this */
|
||||
|
|
|
@ -92,6 +92,8 @@ rtimer_clock_t soc_rtc_get_next_trigger(void);
|
|||
* instead use Contiki's timer-related libraries
|
||||
*/
|
||||
void soc_rtc_schedule_one_shot(uint32_t channel, uint32_t t);
|
||||
|
||||
rtimer_clock_t soc_rtc_last_isr_time(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* SOC_RTC_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 63ed52888467ea7d403b0c743852162395232c9e
|
||||
Subproject commit 6bdb6da3fa9682303799e5c3b1f755398e87fc99
|
|
@ -1 +1 @@
|
|||
Subproject commit 0e82b18bf2c69fb0a40af4d2496db2a3dc721cec
|
||||
Subproject commit 0270b50ac750f8f3348a98f900a470e7a65ffce8
|
|
@ -84,7 +84,7 @@ void
|
|||
lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
|
||||
{
|
||||
lpm_registered_module_t *module;
|
||||
int i, j;
|
||||
int i;
|
||||
uint32_t io_cfg = (IOC_STD_INPUT & ~IOC_IOPULL_M) | io_pull |
|
||||
wake_on;
|
||||
|
||||
|
@ -109,18 +109,6 @@ lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
|
|||
|
||||
watchdog_periodic();
|
||||
|
||||
/* fade away....... */
|
||||
j = 1000;
|
||||
|
||||
for(i = j; i > 0; --i) {
|
||||
leds_on(LEDS_ALL);
|
||||
clock_delay_usec(i);
|
||||
leds_off(LEDS_ALL);
|
||||
clock_delay_usec(j - i);
|
||||
}
|
||||
|
||||
leds_off(LEDS_ALL);
|
||||
|
||||
/* Notify all modules that we're shutting down */
|
||||
for(module = list_head(modules_list); module != NULL;
|
||||
module = module->next) {
|
||||
|
@ -130,8 +118,10 @@ lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
|
|||
}
|
||||
|
||||
/* Configure the wakeup trigger */
|
||||
ti_lib_gpio_dir_mode_set((1 << wakeup_pin), GPIO_DIR_MODE_IN);
|
||||
ti_lib_ioc_port_configure_set(wakeup_pin, IOC_PORT_GPIO, io_cfg);
|
||||
if(wakeup_pin != IOID_UNUSED) {
|
||||
ti_lib_gpio_dir_mode_set((1 << wakeup_pin), GPIO_DIR_MODE_IN);
|
||||
ti_lib_ioc_port_configure_set(wakeup_pin, IOC_PORT_GPIO, io_cfg);
|
||||
}
|
||||
|
||||
/* Freeze I/O latches in AON */
|
||||
ti_lib_aon_ioc_freeze_enable();
|
||||
|
@ -202,8 +192,7 @@ wake_up(void)
|
|||
|
||||
/* Remember IRQ energest for next pass */
|
||||
ENERGEST_IRQ_SAVE(irq_energest);
|
||||
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
|
||||
/* Sync so that we get the latest values before adjusting recharge settings */
|
||||
ti_lib_sys_ctrl_aon_sync();
|
||||
|
@ -292,7 +281,7 @@ lpm_drop()
|
|||
|
||||
if(next_event) {
|
||||
next_event = next_event - clock_time();
|
||||
soc_rtc_schedule_one_shot(AON_RTC_CH1, RTIMER_NOW() +
|
||||
soc_rtc_schedule_one_shot(AON_RTC_CH1, soc_rtc_last_isr_time() +
|
||||
(next_event * (RTIMER_SECOND / CLOCK_SECOND)));
|
||||
}
|
||||
|
||||
|
@ -396,8 +385,7 @@ lpm_drop()
|
|||
|
||||
/* We are only interested in IRQ energest while idle or in LPM */
|
||||
ENERGEST_IRQ_RESTORE(irq_energest);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_ON(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
|
||||
|
||||
/* Sync the AON interface to ensure all writes have gone through. */
|
||||
ti_lib_sys_ctrl_aon_sync();
|
||||
|
@ -429,8 +417,7 @@ lpm_drop()
|
|||
void
|
||||
lpm_sleep(void)
|
||||
{
|
||||
ENERGEST_OFF(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_ON(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
|
||||
|
||||
/* We are only interested in IRQ energest while idle or in LPM */
|
||||
ENERGEST_IRQ_RESTORE(irq_energest);
|
||||
|
@ -443,8 +430,7 @@ lpm_sleep(void)
|
|||
/* Remember IRQ energest for next pass */
|
||||
ENERGEST_IRQ_SAVE(irq_energest);
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -805,7 +805,7 @@ transmit(unsigned short transmit_len)
|
|||
cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN];
|
||||
|
||||
/* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */
|
||||
rf_core_cmd_done_en();
|
||||
rf_core_cmd_done_en(true);
|
||||
|
||||
ret = rf_core_send_cmd((uint32_t)&cmd, &cmd_status);
|
||||
|
||||
|
@ -853,6 +853,11 @@ transmit(unsigned short transmit_len)
|
|||
*/
|
||||
rf_core_cmd_done_dis();
|
||||
|
||||
|
||||
if(was_off) {
|
||||
off();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -1101,8 +1106,12 @@ off(void)
|
|||
|
||||
while(transmitting());
|
||||
|
||||
/* stopping the rx explicitly results in lower sleep-mode power usage */
|
||||
rx_off();
|
||||
rf_core_power_down();
|
||||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
|
||||
|
||||
/* Switch HF clock source to the RCOSC to preserve power */
|
||||
oscillators_switch_to_hf_rc();
|
||||
|
||||
|
@ -1212,6 +1221,12 @@ set_value(radio_param_t param, radio_value_t value)
|
|||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if(cmd->channel == (uint8_t)value) {
|
||||
/* We already have that very same channel configured.
|
||||
* Nothing to do here. */
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
|
||||
cmd->channel = (uint8_t)value;
|
||||
break;
|
||||
case RADIO_PARAM_PAN_ID:
|
||||
|
|
|
@ -687,7 +687,7 @@ transmit(unsigned short transmit_len)
|
|||
rx_off_prop();
|
||||
|
||||
/* Enable the LAST_COMMAND_DONE interrupt to wake us up */
|
||||
rf_core_cmd_done_en();
|
||||
rf_core_cmd_done_en(false);
|
||||
|
||||
ret = rf_core_send_cmd((uint32_t)cmd_tx_adv, &cmd_status);
|
||||
|
||||
|
@ -968,6 +968,7 @@ off(void)
|
|||
return RF_CORE_CMD_OK;
|
||||
}
|
||||
|
||||
rx_off_prop();
|
||||
rf_core_power_down();
|
||||
|
||||
/* Switch HF clock source to the RCOSC to preserve power */
|
||||
|
|
|
@ -201,6 +201,28 @@ rf_core_wait_cmd_done(void *cmd)
|
|||
== RF_CORE_RADIO_OP_STATUS_DONE_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
fs_powerdown(void)
|
||||
{
|
||||
rfc_CMD_FS_POWERDOWN_t cmd;
|
||||
uint32_t cmd_status;
|
||||
|
||||
rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_FS_POWERDOWN);
|
||||
|
||||
if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) {
|
||||
PRINTF("fs_powerdown: CMDSTA=0x%08lx\n", cmd_status);
|
||||
return RF_CORE_CMD_ERROR;
|
||||
}
|
||||
|
||||
if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) {
|
||||
PRINTF("fs_powerdown: CMDSTA=0x%08lx, status=0x%04x\n",
|
||||
cmd_status, cmd.status);
|
||||
return RF_CORE_CMD_ERROR;
|
||||
}
|
||||
|
||||
return RF_CORE_CMD_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rf_core_power_up()
|
||||
{
|
||||
|
@ -256,6 +278,9 @@ rf_core_power_down()
|
|||
if(rf_core_is_accessible()) {
|
||||
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
|
||||
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0;
|
||||
|
||||
/* need to send FS_POWERDOWN or analog components will use power */
|
||||
fs_powerdown();
|
||||
}
|
||||
|
||||
/* Shut down the RFCORE clock domain in the MCU VD */
|
||||
|
@ -378,11 +403,12 @@ rf_core_setup_interrupts()
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rf_core_cmd_done_en()
|
||||
rf_core_cmd_done_en(bool fg)
|
||||
{
|
||||
uint32_t irq = fg ? IRQ_LAST_FG_COMMAND_DONE : IRQ_LAST_COMMAND_DONE;
|
||||
|
||||
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ENABLED_IRQS;
|
||||
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS +
|
||||
IRQ_LAST_COMMAND_DONE;
|
||||
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS | irq;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -331,17 +331,19 @@ uint8_t rf_core_boot(void);
|
|||
void rf_core_setup_interrupts(void);
|
||||
|
||||
/**
|
||||
* \brief Enable the LAST_CMD_DONE interrupt.
|
||||
* \brief Enable interrupt on command done.
|
||||
* \param fg set true to enable irq on foreground command done and false for
|
||||
* background commands or if not in ieee mode.
|
||||
*
|
||||
* This is used within TX routines in order to be able to sleep the CM3 and
|
||||
* wake up after TX has finished
|
||||
*
|
||||
* \sa rf_core_cmd_done_dis()
|
||||
*/
|
||||
void rf_core_cmd_done_en(void);
|
||||
void rf_core_cmd_done_en(bool fg);
|
||||
|
||||
/**
|
||||
* \brief Disable the LAST_CMD_DONE interrupt.
|
||||
* \brief Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
|
||||
*
|
||||
* This is used within TX routines after TX has completed
|
||||
*
|
||||
|
|
|
@ -90,6 +90,12 @@ clock_seconds(void)
|
|||
return seconds;
|
||||
}
|
||||
|
||||
void
|
||||
clock_set_seconds(unsigned long sec)
|
||||
{
|
||||
seconds = sec;
|
||||
}
|
||||
|
||||
void
|
||||
clock_wait(clock_time_t t)
|
||||
{
|
||||
|
|
|
@ -325,6 +325,17 @@ static const int XTAL32_EN = 0;
|
|||
#define pack_XTAL_CNTL(ctune4pf, ctune, ftune, ibias) \
|
||||
(*CRM_XTAL_CNTL = ((ctune4pf << 25) | (ctune << 21) | ( ftune << 16) | (ibias << 8) | 0x52))
|
||||
|
||||
#define soft_reset() \
|
||||
__asm__ __volatile__ ( \
|
||||
"ldr r0, [%[sw]] \n\t" \
|
||||
"str r0, [%[sw]] \n\t" \
|
||||
: /* out */ \
|
||||
: /* in */ \
|
||||
[sw] "l" (CRM_SW_RST) \
|
||||
: /* clobber list */ \
|
||||
"r0", "memory" \
|
||||
);
|
||||
|
||||
#endif /* REG_NO_COMPAT */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -78,5 +78,6 @@ extern nvmErr_t (*nvm_write)(nvmInterface_t nvmInterface, nvmType_t nvmType ,voi
|
|||
/* SST flash has 32 sectors 4096 bytes each */
|
||||
/* bit 0 is the first sector, bit 31 is the last */
|
||||
extern nvmErr_t (*nvm_erase)(nvmInterface_t nvmInterface, nvmType_t nvmType ,uint32_t sectorBitfield);
|
||||
extern nvmErr_t (*nvm_verify)(nvmInterface_t nvmInterface, nvmType_t nvmType, void *pSrc, uint32_t address, uint32_t numBytes);
|
||||
extern void(*nvm_setsvar)(uint32_t zero_for_awesome);
|
||||
#endif //NVM_H
|
||||
|
|
|
@ -51,6 +51,10 @@ nvmErr_t (*nvm_erase)
|
|||
(nvmInterface_t nvmInterface, nvmType_t nvmType ,uint32_t sectorBitfield)
|
||||
= (void*) 0x00006e05;
|
||||
|
||||
nvmErr_t (*nvm_verify)
|
||||
(nvmInterface_t nvmInterface, nvmType_t nvmType, void *pSrc, uint32_t address, uint32_t numBytes)
|
||||
= (void*) 0x00006f85;
|
||||
|
||||
void(*nvm_setsvar)
|
||||
(uint32_t zero_for_awesome)
|
||||
= (void *)0x00007085;
|
||||
|
|
|
@ -35,10 +35,17 @@ endif
|
|||
CONTIKI_CPU_DIRS = $(CONTIKI_CPU_FAM_DIR) . dev
|
||||
|
||||
MSP430 = msp430.c flash.c clock.c leds.c leds-arch.c \
|
||||
watchdog.c lpm.c mtarch.c rtimer-arch.c
|
||||
watchdog.c lpm.c rtimer-arch.c
|
||||
UIPDRIVERS = me.c me_tabs.c slip.c crc16.c
|
||||
ELFLOADER = elfloader.c elfloader-msp430.c symtab.c
|
||||
|
||||
ifndef CPU_HAS_MSP430X
|
||||
# include mtarch.c only in the non-large memory model case, because
|
||||
# the current implementation assumes 16-bit addresses (function pointers
|
||||
# stored as "unsigned short").
|
||||
MSP430 += mtarch.c
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_MEMORY_MODEL),large)
|
||||
ELFLOADER = elfloader-msp430x.c symtab.c
|
||||
endif
|
||||
|
|
|
@ -45,6 +45,8 @@ ISR(TIMERB1, cc2420_timerb1_interrupt)
|
|||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
/* always read TBIV to clear IFG */
|
||||
tbiv = TBIV;
|
||||
/* read and discard tbiv to avoid "variable set but not used" warning */
|
||||
(void)tbiv;
|
||||
if(CC2420_SFD_IS_1) {
|
||||
cc2420_sfd_counter++;
|
||||
cc2420_sfd_start_time = TBCCR1;
|
||||
|
|
|
@ -44,6 +44,8 @@ ISR(TIMERB1, cc2520_timerb1_interrupt)
|
|||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
/* always read TBIV to clear IFG */
|
||||
tbiv = TBIV;
|
||||
/* read and discard tbiv to avoid "variable set but not used" warning */
|
||||
(void)tbiv;
|
||||
if(CC2520_SFD_IS_1) {
|
||||
cc2520_sfd_counter++;
|
||||
cc2520_sfd_start_time = TBCCR1;
|
||||
|
|
|
@ -32,8 +32,12 @@
|
|||
#include "contiki.h"
|
||||
#include "dev/watchdog.h"
|
||||
|
||||
/* dco_required set to 1 will cause the CPU not to go into
|
||||
* sleep modes where the DCO clock stopped */
|
||||
int msp430_dco_required;
|
||||
|
||||
#if defined(__MSP430__) && defined(__GNUC__)
|
||||
#define asmv(arg) __asm__ __volatile__(arg)
|
||||
#define asmv(arg) __asm__ __volatile__ (arg)
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -42,8 +46,8 @@ void *
|
|||
w_memcpy(void *out, const void *in, size_t n)
|
||||
{
|
||||
uint8_t *src, *dest;
|
||||
src = (uint8_t *) in;
|
||||
dest = (uint8_t *) out;
|
||||
src = (uint8_t *)in;
|
||||
dest = (uint8_t *)out;
|
||||
while(n-- > 0) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
@ -56,7 +60,7 @@ void *
|
|||
w_memset(void *out, int value, size_t n)
|
||||
{
|
||||
uint8_t *dest;
|
||||
dest = (uint8_t *) out;
|
||||
dest = (uint8_t *)out;
|
||||
while(n-- > 0) {
|
||||
*dest++ = value & 0xff;
|
||||
}
|
||||
|
@ -152,10 +156,30 @@ init_ports(void)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* msp430-ld may align _end incorrectly. Workaround in cpu_init. */
|
||||
#if defined(__MSP430__) && defined(__GNUC__)
|
||||
extern int _end; /* Not in sys/unistd.h */
|
||||
extern int _end; /* Not in sys/unistd.h */
|
||||
static char *cur_break = (char *)&_end;
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* add/remove_lpm_req - for requiring a specific LPM mode. currently Contiki */
|
||||
/* jumps to LPM3 to save power, but DMA will not work if DCO is not clocked */
|
||||
/* so some modules might need to enter their LPM requirements */
|
||||
/* NOTE: currently only works with LPM1 (e.g. DCO) requirements. */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
msp430_add_lpm_req(int req)
|
||||
{
|
||||
if(req <= MSP430_REQUIRE_LPM1) {
|
||||
msp430_dco_required++;
|
||||
}
|
||||
}
|
||||
void
|
||||
msp430_remove_lpm_req(int req)
|
||||
{
|
||||
if(req <= MSP430_REQUIRE_LPM1) {
|
||||
msp430_dco_required--;
|
||||
}
|
||||
}
|
||||
void
|
||||
msp430_cpu_init(void)
|
||||
{
|
||||
|
@ -164,7 +188,7 @@ msp430_cpu_init(void)
|
|||
init_ports();
|
||||
/* set DCO to a reasonable default value (8MHz) */
|
||||
msp430_init_dco();
|
||||
/* calibrate the DCO step-by-step */
|
||||
/* calibrate the DCO step-by-step */
|
||||
msp430_sync_dco();
|
||||
eint();
|
||||
#if defined(__MSP430__) && defined(__GNUC__)
|
||||
|
@ -172,6 +196,7 @@ msp430_cpu_init(void)
|
|||
cur_break++;
|
||||
}
|
||||
#endif
|
||||
msp430_dco_required = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -191,7 +216,7 @@ splhigh_(void)
|
|||
asmv("mov r2, %0" : "=r" (sr));
|
||||
asmv("bic %0, r2" : : "i" (GIE));
|
||||
#endif
|
||||
return sr & GIE; /* Ignore other sr bits. */
|
||||
return sr & GIE; /* Ignore other sr bits. */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
@ -209,7 +234,8 @@ splhigh_(void)
|
|||
/* } */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
int __low_level_init(void)
|
||||
int
|
||||
__low_level_init(void)
|
||||
{
|
||||
/* turn off watchdog so that C-init will run */
|
||||
WDTCTL = WDTPW + WDTHOLD;
|
||||
|
@ -224,7 +250,8 @@ int __low_level_init(void)
|
|||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
msp430_sync_dco(void) {
|
||||
msp430_sync_dco(void)
|
||||
{
|
||||
uint16_t oldcapture;
|
||||
int16_t diff;
|
||||
/* DELTA_2 assumes an ACLK of 32768 Hz */
|
||||
|
@ -260,7 +287,7 @@ msp430_sync_dco(void) {
|
|||
if(DCOCTL == 0x00) { /* Did DCO roll over? */
|
||||
BCSCTL1++;
|
||||
}
|
||||
/* -> Select next higher RSEL */
|
||||
/* -> Select next higher RSEL */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,11 @@ static volatile uint8_t transmitting;
|
|||
#define TX_WITH_INTERRUPT 1
|
||||
#endif /* UART0_CONF_TX_WITH_INTERRUPT */
|
||||
|
||||
#ifdef UART0_CONF_RX_WITH_DMA
|
||||
#define RX_WITH_DMA UART0_CONF_RX_WITH_DMA
|
||||
#else /* UART0_CONF_RX_WITH_DMA */
|
||||
#define RX_WITH_DMA 1
|
||||
#endif /* UART0_CONF_RX_WITH_DMA */
|
||||
|
||||
#if TX_WITH_INTERRUPT
|
||||
#define TXBUFSIZE 64
|
||||
|
@ -59,6 +64,30 @@ static struct ringbuf txbuf;
|
|||
static uint8_t txbuf_data[TXBUFSIZE];
|
||||
#endif /* TX_WITH_INTERRUPT */
|
||||
|
||||
#if RX_WITH_DMA
|
||||
#define RXBUFSIZE 128
|
||||
|
||||
static uint8_t rxbuf[RXBUFSIZE];
|
||||
static uint16_t last_size;
|
||||
static struct ctimer rxdma_timer;
|
||||
|
||||
static void
|
||||
handle_rxdma_timer(void *ptr)
|
||||
{
|
||||
uint16_t size;
|
||||
size = DMA0SZ; /* Note: loop requires that size is less or eq to RXBUFSIZE */
|
||||
while(last_size != size) {
|
||||
uart0_input_handler((unsigned char)rxbuf[RXBUFSIZE - last_size]);
|
||||
last_size--;
|
||||
if(last_size == 0) {
|
||||
last_size = RXBUFSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
ctimer_reset(&rxdma_timer);
|
||||
}
|
||||
#endif /* RX_WITH_DMA */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
uart0_active(void)
|
||||
|
@ -69,6 +98,9 @@ uart0_active(void)
|
|||
void
|
||||
uart0_set_input(int (*input)(unsigned char c))
|
||||
{
|
||||
#if RX_WITH_DMA /* This needs to be called after ctimer process is started */
|
||||
ctimer_set(&rxdma_timer, CLOCK_SECOND / 64, handle_rxdma_timer, NULL);
|
||||
#endif
|
||||
uart0_input_handler = input;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -100,7 +132,7 @@ uart0_writeb(unsigned char c)
|
|||
#endif /* TX_WITH_INTERRUPT */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if ! NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */
|
||||
#if !NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */
|
||||
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -135,8 +167,24 @@ uart0_init(unsigned long ubr)
|
|||
ringbuf_init(&txbuf, txbuf_data, sizeof(txbuf_data));
|
||||
IE2 |= UCA0TXIE; /* Enable UCA0 TX interrupt */
|
||||
#endif /* TX_WITH_INTERRUPT */
|
||||
|
||||
#if RX_WITH_DMA
|
||||
IE2 &= ~UCA0RXIE; /* disable USART0 RX interrupt */
|
||||
/* UART0_RX trigger */
|
||||
DMACTL0 = DMA0TSEL_3;
|
||||
|
||||
/* source address = UCA0RXBUF */
|
||||
DMA0SA = (unsigned int)&UCA0RXBUF;
|
||||
DMA0DA = (unsigned int)&rxbuf;
|
||||
DMA0SZ = RXBUFSIZE;
|
||||
last_size = RXBUFSIZE;
|
||||
DMA0CTL = DMADT_4 + DMASBDB + DMADSTINCR_3 + DMAEN + DMAREQ;
|
||||
|
||||
msp430_add_lpm_req(MSP430_REQUIRE_LPM1);
|
||||
#endif /* RX_WITH_DMA */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if !RX_WITH_DMA
|
||||
ISR(USCIAB0RX, uart0_rx_interrupt)
|
||||
{
|
||||
uint8_t c;
|
||||
|
@ -148,18 +196,19 @@ ISR(USCIAB0RX, uart0_rx_interrupt)
|
|||
c = UCA0RXBUF;
|
||||
if(uart0_input_handler != NULL) {
|
||||
if(uart0_input_handler(c)) {
|
||||
LPM4_EXIT;
|
||||
LPM4_EXIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||
}
|
||||
#endif /* !RX_WITH_DMA */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if TX_WITH_INTERRUPT
|
||||
ISR(USCIAB0TX, uart0_tx_interrupt)
|
||||
{
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
if((IFG2 & UCA0TXIFG)){
|
||||
if((IFG2 & UCA0TXIFG)) {
|
||||
|
||||
if(ringbuf_elements(&txbuf) == 0) {
|
||||
transmitting = 0;
|
||||
|
|
|
@ -14,10 +14,10 @@ NM ?= nm
|
|||
OBJCOPY ?= objcopy
|
||||
STRIP ?= strip
|
||||
ifdef WERROR
|
||||
CFLAGSWERROR=-Werror -pedantic -std=c99 -Werror
|
||||
CFLAGSWERROR=-Werror
|
||||
endif
|
||||
CFLAGSNO = -Wall -g -I/usr/local/include $(CFLAGSWERROR)
|
||||
CFLAGS += $(CFLAGSNO) -O
|
||||
CFLAGS += $(CFLAGSNO)
|
||||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
AROPTS = -r
|
||||
|
@ -25,7 +25,7 @@ LDFLAGS += -Wl,-flat_namespace
|
|||
CFLAGS += -DHAVE_SNPRINTF=1 -U__ASSERT_USE_STDERR
|
||||
else
|
||||
ifeq ($(HOST_OS),Linux)
|
||||
LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic
|
||||
LDFLAGS += -Wl,-Map=contiki-$(TARGET).map,-export-dynamic
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
210
cpu/native/net/linuxradio-drv.c
Normal file
210
cpu/native/net/linuxradio-drv.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Google
|
||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
||||
*
|
||||
* Author: Vladimir Pouzanov <farcaller@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#if defined(linux) && NETSTACK_CONF_WITH_IPV6
|
||||
|
||||
#include "linuxradio-drv.h"
|
||||
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/netstack.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/sockios.h>
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
|
||||
static int sockfd = -1;
|
||||
static char *sockbuf;
|
||||
static int buflen;
|
||||
|
||||
#define MAX_PACKET_SIZE 256
|
||||
|
||||
static int
|
||||
init(void)
|
||||
{
|
||||
sockbuf = malloc(MAX_PACKET_SIZE);
|
||||
if(sockbuf == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
prepare(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
if(payload_len > MAX_PACKET_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(sockbuf, payload, payload_len);
|
||||
buflen = payload_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
transmit(unsigned short transmit_len)
|
||||
{
|
||||
int sent = 0;
|
||||
sent = send(sockfd, sockbuf, buflen, 0);
|
||||
if(sent < 0) {
|
||||
perror("linuxradio send()");
|
||||
return RADIO_TX_ERR;
|
||||
}
|
||||
buflen = 0;
|
||||
return RADIO_TX_OK;
|
||||
}
|
||||
static int
|
||||
my_send(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if(prepare(payload, payload_len)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = transmit(payload_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static int
|
||||
my_read(void *buf, unsigned short buf_len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
channel_clear(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static int
|
||||
receiving_packet(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
pending_packet(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
set_fd(fd_set *rset, fd_set *wset)
|
||||
{
|
||||
FD_SET(sockfd, rset);
|
||||
return 1;
|
||||
}
|
||||
static void
|
||||
handle_fd(fd_set *rset, fd_set *wset)
|
||||
{
|
||||
if(FD_ISSET(sockfd, rset)) {
|
||||
int bytes = read(sockfd, sockbuf, MAX_PACKET_SIZE);
|
||||
buflen = bytes;
|
||||
memcpy(packetbuf_dataptr(), sockbuf, bytes);
|
||||
packetbuf_set_datalen(bytes);
|
||||
NETSTACK_RDC.input();
|
||||
}
|
||||
}
|
||||
|
||||
static const struct select_callback linuxradio_sock_callback = { set_fd, handle_fd };
|
||||
|
||||
static int
|
||||
on(void)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int err;
|
||||
struct sockaddr_ll sll;
|
||||
|
||||
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154));
|
||||
if(sockfd < 0) {
|
||||
perror("linuxradio socket()");
|
||||
return 0;
|
||||
} else {
|
||||
strncpy((char *)ifr.ifr_name, NETSTACK_CONF_LINUXRADIO_DEV, IFNAMSIZ);
|
||||
err = ioctl(sockfd, SIOCGIFINDEX, &ifr);
|
||||
if(err == -1) {
|
||||
perror("linuxradio ioctl()");
|
||||
return 0;
|
||||
}
|
||||
sll.sll_family = AF_PACKET;
|
||||
sll.sll_ifindex = ifr.ifr_ifindex;
|
||||
sll.sll_protocol = htons(ETH_P_IEEE802154);
|
||||
|
||||
if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
|
||||
perror("linuxradio bind()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
select_set_callback(sockfd, &linuxradio_sock_callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
static int
|
||||
off(void)
|
||||
{
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
return 1;
|
||||
}
|
||||
const struct radio_driver linuxradio_driver =
|
||||
{
|
||||
init,
|
||||
prepare,
|
||||
transmit,
|
||||
my_send,
|
||||
my_read,
|
||||
channel_clear,
|
||||
receiving_packet,
|
||||
pending_packet,
|
||||
on,
|
||||
off,
|
||||
};
|
||||
|
||||
#endif
|
43
cpu/native/net/linuxradio-drv.h
Normal file
43
cpu/native/net/linuxradio-drv.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Google
|
||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
||||
*
|
||||
* Author: Vladimir Pouzanov <farcaller@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUXRADIO_DRV_H__
|
||||
#define __LINUXRADIO_DRV_H__
|
||||
|
||||
#include "dev/radio.h"
|
||||
|
||||
extern const struct radio_driver linuxradio_driver;
|
||||
|
||||
#endif
|
|
@ -93,8 +93,11 @@ static void
|
|||
remove_route(void)
|
||||
{
|
||||
char buf[1024];
|
||||
int ret;
|
||||
|
||||
snprintf(buf, sizeof(buf), "route delete -net 172.18.0.0");
|
||||
system(buf);
|
||||
ret = system(buf);
|
||||
fprintf(stderr, "ret %d\n", ret);
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
|
||||
}
|
||||
|
@ -103,7 +106,8 @@ void
|
|||
tapdev_init(void)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
int ret;
|
||||
|
||||
fd = open(DEVTAP, O_RDWR);
|
||||
if(fd == -1) {
|
||||
perror("tapdev: tapdev_init: open");
|
||||
|
@ -123,7 +127,8 @@ tapdev_init(void)
|
|||
#endif /* Linux */
|
||||
|
||||
snprintf(buf, sizeof(buf), "ifconfig tap0 inet 172.18.0.1/16");
|
||||
system(buf);
|
||||
ret = system(buf);
|
||||
fprintf(stderr, "ret %d\n", ret);
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
#ifdef linux
|
||||
/* route add for linux */
|
||||
|
@ -132,8 +137,9 @@ tapdev_init(void)
|
|||
/* route add for freebsd */
|
||||
snprintf(buf, sizeof(buf), "route add -net 172.18.0.0/16 -iface tap0");
|
||||
#endif /* linux */
|
||||
|
||||
system(buf);
|
||||
|
||||
ret = system(buf);
|
||||
fprintf(stderr, "ret %d\n", ret);
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
atexit(remove_route);
|
||||
|
||||
|
|
|
@ -331,7 +331,10 @@ tapdev_init(void)
|
|||
*/
|
||||
/* freebsd */
|
||||
snprintf(buf, sizeof(buf), "ifconfig tap0 up");
|
||||
system(buf);
|
||||
if(system(buf) == -1) {
|
||||
perror("tapdev: system: ifconfig");
|
||||
return;
|
||||
}
|
||||
printf("%s\n", buf);
|
||||
|
||||
/* */
|
||||
|
|
|
@ -192,7 +192,7 @@ uint8_t wfall_send(const uip_lladdr_t *lladdr);
|
|||
static uip_ipaddr_t last_sender;
|
||||
#endif
|
||||
|
||||
static void
|
||||
static int
|
||||
output(void)
|
||||
{
|
||||
#if FALLBACK_HAS_ETHERNET_HEADERS&&0
|
||||
|
@ -203,8 +203,8 @@ output(void)
|
|||
}
|
||||
uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
|
||||
#endif
|
||||
PRINTF("FUT: %u\n", uip_len);
|
||||
wfall_send(0);
|
||||
PRINTF("FUT: %u\n", uip_len);
|
||||
return wfall_send(0);
|
||||
}
|
||||
|
||||
const struct uip_fallback_interface rpl_interface = {
|
||||
|
|
|
@ -127,7 +127,7 @@ else
|
|||
STRIP = $(CROSS_COMPILE)strip
|
||||
|
||||
ifdef WERROR
|
||||
CFLAGSWERROR ?= -Werror -pedantic -std=c99 -Werror
|
||||
CFLAGSWERROR ?= -Werror
|
||||
endif
|
||||
|
||||
CFLAGSNO ?= -Wall -g $(CFLAGSWERROR)
|
||||
|
|
|
@ -102,12 +102,10 @@ ifeq ($(STM32W_CPUREV), CC)
|
|||
LD-EXT=-stm32w108CC
|
||||
RAM_SIZE = 2*8192
|
||||
FLASH_SIZE = 2*128*1024
|
||||
${warning "using stm32w108CC specific ld file"}
|
||||
else ifeq ($(STM32W_CPUREV), xB)
|
||||
LD-EXT=-stm32w108xB
|
||||
RAM_SIZE = 8192
|
||||
FLASH_SIZE = 128*1024
|
||||
${warning "using stm32w108xB specific ld file"}
|
||||
else
|
||||
${error "Bad STM32W_CPUREV value or no STM32W_CPUREV value specified. Cpu revision should be specified. Please read cpu/stm32w108/README.txt for more details."}
|
||||
endif
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
|
||||
#if RDC_CONF_DEBUG_LED
|
||||
#define LED_RDC RDC_CONF_DEBUG_LED
|
||||
#undef LED_ACTIVITY
|
||||
#define LED_ACTIVITY 1
|
||||
#else
|
||||
#define LED_RDC 0
|
||||
|
@ -117,6 +118,7 @@
|
|||
#endif /* LED_ACTIVITY */
|
||||
|
||||
#if RDC_CONF_HARDWARE_CSMA
|
||||
#undef MAC_RETRIES
|
||||
#define MAC_RETRIES 0
|
||||
#endif /* RDC_CONF_HARDWARE_CSMA */
|
||||
|
||||
|
@ -169,6 +171,7 @@ const RadioTransmitConfig radioTransmitConfig = {
|
|||
TRUE /* appendCrc; */
|
||||
};
|
||||
|
||||
#undef MAC_RETRIES
|
||||
#define MAC_RETRIES 0
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue