cc2538: Add PKA drivers, ECC algorithms and examples
This commit is contained in:
parent
f9ed78a327
commit
d631270af4
19 changed files with 4307 additions and 2 deletions
|
@ -51,6 +51,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
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
6
examples/cc2538dk/pka/Makefile
Normal file
6
examples/cc2538dk/pka/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
CONTIKI_PROJECT = ecc-ecdh ecc-sign ecc-verify
|
||||
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
CONTIKI = ../../..
|
||||
include $(CONTIKI)/Makefile.include
|
188
examples/cc2538dk/pka/ecc-ecdh.c
Normal file
188
examples/cc2538dk/pka/ecc-ecdh.c
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* 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-examples
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ecdh-test cc2538dk ECDH Test Project
|
||||
*
|
||||
* ECDH example for CC2538 on SmartRF06EB.
|
||||
*
|
||||
* This example shows how ECDH should be used. The example also verifies
|
||||
* the ECDH functionality.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Example demonstrating ECDH on the cc2538dk platform
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "ecc-algorithm.h"
|
||||
#include "ecc-curve.h"
|
||||
#include "random.h"
|
||||
#include "rtimer.h"
|
||||
#include "pt.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void
|
||||
ecc_set_random(uint32_t *secret)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 8; ++i) {
|
||||
secret[i] = (uint32_t)random_rand() | (uint32_t)random_rand() << 16;
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS(ecdh_test, "ecdh test");
|
||||
AUTOSTART_PROCESSES(&ecdh_test);
|
||||
|
||||
PROCESS_THREAD(ecdh_test, ev, data) {
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/*
|
||||
* Variable for Time Measurement
|
||||
*/
|
||||
static rtimer_clock_t time;
|
||||
|
||||
/*
|
||||
* Activate Engine
|
||||
*/
|
||||
puts("-----------------------------------------\n"
|
||||
"Initializing pka...");
|
||||
pka_init();
|
||||
|
||||
/*
|
||||
* Generate secrets make sure they are valid (smaller as order)
|
||||
*/
|
||||
static ecc_compare_state_t state = {
|
||||
.process = &ecdh_test,
|
||||
.size = 8,
|
||||
};
|
||||
memcpy(state.b, nist_p_256.n, sizeof(uint32_t) * 8);
|
||||
static uint32_t secret_a[8];
|
||||
do {
|
||||
ecc_set_random(secret_a);
|
||||
memcpy(state.a, secret_a, sizeof(uint32_t) * 8);
|
||||
PT_SPAWN(&(ecdh_test.pt), &(state.pt), ecc_compare(&state));
|
||||
} while(state.result != PKA_STATUS_A_LT_B);
|
||||
|
||||
static uint32_t secret_b[8];
|
||||
ecc_set_random(secret_b);
|
||||
do {
|
||||
ecc_set_random(secret_b);
|
||||
memcpy(state.a, secret_b, sizeof(uint32_t) * 8);
|
||||
PT_SPAWN(&(ecdh_test.pt), &(state.pt), ecc_compare(&state));
|
||||
} while(state.result != PKA_STATUS_A_LT_B);
|
||||
|
||||
/*
|
||||
* Prepare Points
|
||||
*/
|
||||
static ecc_multiply_state_t side_a = {
|
||||
.process = &ecdh_test,
|
||||
.curve_info = &nist_p_256,
|
||||
};
|
||||
memcpy(side_a.point_in.x, nist_p_256.x, sizeof(uint32_t) * 8);
|
||||
memcpy(side_a.point_in.y, nist_p_256.y, sizeof(uint32_t) * 8);
|
||||
memcpy(side_a.secret, secret_a, sizeof(secret_a));
|
||||
|
||||
static ecc_multiply_state_t side_b = {
|
||||
.process = &ecdh_test,
|
||||
.curve_info = &nist_p_256,
|
||||
};
|
||||
memcpy(side_b.point_in.x, nist_p_256.x, sizeof(uint32_t) * 8);
|
||||
memcpy(side_b.point_in.y, nist_p_256.y, sizeof(uint32_t) * 8);
|
||||
memcpy(side_b.secret, secret_b, sizeof(secret_b));
|
||||
|
||||
/*
|
||||
* Round 1
|
||||
*/
|
||||
time = RTIMER_NOW();
|
||||
PT_SPAWN(&(ecdh_test.pt), &(side_a.pt), ecc_multiply(&side_a));
|
||||
time = RTIMER_NOW() - time;
|
||||
printf("Round 1, Side a: %i, %lu ms\n", (unsigned)side_a.result,
|
||||
(uint32_t)((uint64_t)time * 1000 / RTIMER_SECOND));
|
||||
|
||||
time = RTIMER_NOW();
|
||||
PT_SPAWN(&(ecdh_test.pt), &(side_b.pt), ecc_multiply(&side_b));
|
||||
time = RTIMER_NOW() - time;
|
||||
printf("Round 1, Side b: %i, %lu ms\n", (unsigned)side_b.result,
|
||||
(uint32_t)((uint64_t)time * 1000 / RTIMER_SECOND));
|
||||
|
||||
/*
|
||||
* Key Exchange
|
||||
*/
|
||||
memcpy(side_a.point_in.x, side_b.point_out.x, sizeof(uint32_t) * 8);
|
||||
memcpy(side_a.point_in.y, side_b.point_out.y, sizeof(uint32_t) * 8);
|
||||
memcpy(side_b.point_in.x, side_a.point_out.x, sizeof(uint32_t) * 8);
|
||||
memcpy(side_b.point_in.y, side_a.point_out.y, sizeof(uint32_t) * 8);
|
||||
|
||||
/*
|
||||
* Round 2
|
||||
*/
|
||||
time = RTIMER_NOW();
|
||||
PT_SPAWN(&(ecdh_test.pt), &(side_a.pt), ecc_multiply(&side_a));
|
||||
time = RTIMER_NOW() - time;
|
||||
printf("Round 2, Side a: %i, %lu ms\n", (unsigned)side_a.result,
|
||||
(uint32_t)((uint64_t)time * 1000 / RTIMER_SECOND));
|
||||
time = RTIMER_NOW();
|
||||
PT_SPAWN(&(ecdh_test.pt), &(side_b.pt), ecc_multiply(&side_b));
|
||||
time = RTIMER_NOW() - time;
|
||||
printf("Round 2, Side b: %i, %lu ms\n", (unsigned)side_b.result,
|
||||
(uint32_t)((uint64_t)time * 1000 / RTIMER_SECOND));
|
||||
|
||||
/*
|
||||
* Check Result
|
||||
*/
|
||||
memcpy(state.a, side_a.point_out.x, sizeof(uint32_t) * 8);
|
||||
memcpy(state.b, side_b.point_out.x, sizeof(uint32_t) * 8);
|
||||
|
||||
PT_SPAWN(&(ecdh_test.pt), &(state.pt), ecc_compare(&state));
|
||||
if(state.result) {
|
||||
puts("shared secrets do not match");
|
||||
} else {
|
||||
puts("shared secrets MATCH");
|
||||
}
|
||||
|
||||
puts("-----------------------------------------\n"
|
||||
"Disabling pka...");
|
||||
pka_disable();
|
||||
|
||||
puts("Done!");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
139
examples/cc2538dk/pka/ecc-sign.c
Normal file
139
examples/cc2538dk/pka/ecc-sign.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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-examples
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ecdsa-sign-test cc2538dk ECDSA-Sign Test Project
|
||||
*
|
||||
* ECDSA-Sign example for CC2538 on SmartRF06EB.
|
||||
*
|
||||
* This example shows how ECDSA-Sign should be used. The example also verifies
|
||||
* the ECDSA-Sign functionality.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Example demonstrating ECDSA-Sign on the cc2538dk platform
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "ecc-algorithm.h"
|
||||
#include "ecc-curve.h"
|
||||
#include "rtimer.h"
|
||||
#include "pt.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
PROCESS(ecdsa_sign_test, "ecdsa sign test");
|
||||
AUTOSTART_PROCESSES(&ecdsa_sign_test);
|
||||
|
||||
PROCESS_THREAD(ecdsa_sign_test, ev, data) {
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/*
|
||||
* Variable for Time Measurement
|
||||
*/
|
||||
static rtimer_clock_t time;
|
||||
|
||||
/*
|
||||
* Activate Engine
|
||||
*/
|
||||
puts("-----------------------------------------\n"
|
||||
"Initializing pka...");
|
||||
pka_init();
|
||||
|
||||
/*
|
||||
* Setup Variables
|
||||
*/
|
||||
static ecc_compare_state_t comp_state = {
|
||||
.process = &ecdsa_sign_test,
|
||||
.size = 8,
|
||||
};
|
||||
static ecc_dsa_sign_state_t state = {
|
||||
.process = &ecdsa_sign_test,
|
||||
.curve_info = &nist_p_256,
|
||||
.secret = { 0x94A949FA, 0x401455A1, 0xAD7294CA, 0x896A33BB,
|
||||
0x7A80E714, 0x4321435B, 0x51247A14, 0x41C1CB6B },
|
||||
.k_e = { 0x1D1E1F20, 0x191A1B1C, 0x15161718, 0x11121314,
|
||||
0x0D0E0F10, 0x090A0B0C, 0x05060708, 0x01020304 },
|
||||
.hash = { 0x65637572, 0x20612073, 0x68206F66, 0x20686173,
|
||||
0x69732061, 0x68697320, 0x6F2C2054, 0x48616C6C },
|
||||
};
|
||||
|
||||
/*
|
||||
* Sign
|
||||
*/
|
||||
time = RTIMER_NOW();
|
||||
PT_SPAWN(&(ecdsa_sign_test.pt), &(state.pt), ecc_dsa_sign(&state));
|
||||
time = RTIMER_NOW() - time;
|
||||
printf("ecc_dsa_sign(), %lu ms\n",
|
||||
(uint32_t)((uint64_t)time * 1000 / RTIMER_SECOND));
|
||||
|
||||
/*
|
||||
* Check Result
|
||||
*/
|
||||
static uint32_t ecdsaTestresultR1[] = { 0xC3B4035F, 0x515AD0A6, 0xBF375DCA, 0x0CC1E997,
|
||||
0x7F54FDCD, 0x04D3FECA, 0xB9E396B9, 0x515C3D6E };
|
||||
static uint32_t ecdsaTestresultS1[] = { 0x5366B1AB, 0x0F1DBF46, 0xB0C8D3C4, 0xDB755B6F,
|
||||
0xB9BF9243, 0xE644A8BE, 0x55159A59, 0x6F9E52A6 };
|
||||
|
||||
memcpy(comp_state.a, state.point_r.x, sizeof(uint32_t) * 8);
|
||||
memcpy(comp_state.b, ecdsaTestresultR1, sizeof(uint32_t) * 8);
|
||||
PT_SPAWN(&(ecdsa_sign_test.pt), &(comp_state.pt), ecc_compare(&comp_state));
|
||||
if(comp_state.result) {
|
||||
puts("r1 of signature does not match");
|
||||
} else {
|
||||
puts("r1 of signature OK");
|
||||
}
|
||||
|
||||
memcpy(comp_state.a, state.signature_s, sizeof(uint32_t) * 8);
|
||||
memcpy(comp_state.b, ecdsaTestresultS1, sizeof(uint32_t) * 8);
|
||||
PT_SPAWN(&(ecdsa_sign_test.pt), &(comp_state.pt), ecc_compare(&comp_state));
|
||||
if(comp_state.result) {
|
||||
puts("s1 of signature does not match");
|
||||
} else {
|
||||
puts("s1 of signature OK");
|
||||
}
|
||||
|
||||
puts("-----------------------------------------\n"
|
||||
"Disabling pka...");
|
||||
pka_disable();
|
||||
|
||||
puts("Done!");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
122
examples/cc2538dk/pka/ecc-verify.c
Normal file
122
examples/cc2538dk/pka/ecc-verify.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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-examples
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-ecdsa-verify-test cc2538dk ECDSA-Verify Test Project
|
||||
*
|
||||
* ECDSA-Verify example for CC2538 on SmartRF06EB.
|
||||
*
|
||||
* This example shows how ECDSA-Verify should be used. The example also verifies
|
||||
* the ECDSA-Verify functionality.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Example demonstrating ECDSA-Verify on the cc2538dk platform
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "ecc-algorithm.h"
|
||||
#include "ecc-curve.h"
|
||||
#include "rtimer.h"
|
||||
#include "pt.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
PROCESS(ecdsa_verify_test, "ecdsa verify test");
|
||||
AUTOSTART_PROCESSES(&ecdsa_verify_test);
|
||||
|
||||
PROCESS_THREAD(ecdsa_verify_test, ev, data) {
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/*
|
||||
* Variable for Time Measurement
|
||||
*/
|
||||
static rtimer_clock_t time;
|
||||
|
||||
/*
|
||||
* Activate Engine
|
||||
*/
|
||||
puts("-----------------------------------------\n"
|
||||
"Initializing pka...");
|
||||
pka_init();
|
||||
|
||||
/*
|
||||
* Setup Variables
|
||||
*/
|
||||
static ecc_dsa_verify_state_t state = {
|
||||
.process = &ecdsa_verify_test,
|
||||
.curve_info = &nist_p_256,
|
||||
.signature_r = { 0xC3B4035F, 0x515AD0A6, 0xBF375DCA, 0x0CC1E997,
|
||||
0x7F54FDCD, 0x04D3FECA, 0xB9E396B9, 0x515C3D6E },
|
||||
.signature_s = { 0x5366B1AB, 0x0F1DBF46, 0xB0C8D3C4, 0xDB755B6F,
|
||||
0xB9BF9243, 0xE644A8BE, 0x55159A59, 0x6F9E52A6 },
|
||||
.hash = { 0x65637572, 0x20612073, 0x68206F66, 0x20686173,
|
||||
0x69732061, 0x68697320, 0x6F2C2054, 0x48616C6C },
|
||||
};
|
||||
static uint32_t public_x[8] = { 0x5fa58f52, 0xe47cfbf2, 0x300c28c5, 0x6375ba10,
|
||||
0x62684e91, 0xda0a9a8f, 0xf9f2ed29, 0x36dfe2c6 };
|
||||
static uint32_t public_y[8] = { 0xc772f829, 0x4fabc36f, 0x09daed0b, 0xe93f9872,
|
||||
0x35a7cfab, 0x5a3c7869, 0xde1ab878, 0x71a0d4fc };
|
||||
|
||||
memcpy(state.public.x, public_x, sizeof(public_x));
|
||||
memcpy(state.public.y, public_y, sizeof(public_y));
|
||||
|
||||
/*
|
||||
* Verify
|
||||
*/
|
||||
time = RTIMER_NOW();
|
||||
PT_SPAWN(&(ecdsa_verify_test.pt), &(state.pt), ecc_dsa_verify(&state));
|
||||
time = RTIMER_NOW() - time;
|
||||
printf("ecc_dsa_verify(), %lu ms\n",
|
||||
(uint32_t)((uint64_t)time * 1000 / RTIMER_SECOND));
|
||||
|
||||
if(state.result) {
|
||||
puts("signature verification failed");
|
||||
} else {
|
||||
puts("signature verification OK");
|
||||
}
|
||||
|
||||
puts("-----------------------------------------\n"
|
||||
"Disabling pka...");
|
||||
pka_disable();
|
||||
|
||||
puts("Done!");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -30,6 +30,7 @@ In terms of hardware support, the following drivers have been implemented:
|
|||
* General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development.
|
||||
* ADC
|
||||
* Cryptoprocessor (AES-CCM-256, SHA-256)
|
||||
* Public Key Accelerator (ECDH, ECDSA)
|
||||
* SmartRF06 EB and BB peripherals
|
||||
* LEDs
|
||||
* Buttons
|
||||
|
|
|
@ -45,6 +45,7 @@ In terms of hardware support, the following drivers have been implemented:
|
|||
* General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development.
|
||||
* ADC
|
||||
* Cryptoprocessor (AES-CCM-256, SHA-256)
|
||||
* Public Key Accelerator (ECDH, ECDSA)
|
||||
* LEDs
|
||||
* Buttons
|
||||
* Internal/external 2.4GHz antenna switch controllable by SW.
|
||||
|
|
Loading…
Reference in a new issue