Merge pull request #1078 from drandreas/cc2538-crypto
cc2538: Add PKA drivers, ECC algorithms and examples
This commit is contained in:
commit
bf41de1be5
|
@ -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 += 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 += crypto.c aes.c ccm.c sha256.c
|
||||||
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.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 += dbg.c ieee-addr.c
|
||||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
||||||
CONTIKI_CPU_SOURCEFILES += i2c.c cc2538-temp-sensor.c vdd3-sensor.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
|
#ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||||
#else
|
#else
|
||||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 3
|
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static lpm_periph_permit_pm1_func_t
|
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 uart0_isr(void) WEAK_ALIAS(default_handler);
|
||||||
void uart1_isr(void) WEAK_ALIAS(default_handler);
|
void uart1_isr(void) WEAK_ALIAS(default_handler);
|
||||||
void crypto_isr(void);
|
void crypto_isr(void);
|
||||||
|
void pka_isr(void);
|
||||||
|
|
||||||
/* Boot Loader Backdoor selection */
|
/* Boot Loader Backdoor selection */
|
||||||
#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR
|
#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_rx_tx_isr, /* 157 RFCORE RX/TX */
|
||||||
cc2538_rf_err_isr, /* 158 RFCORE Error */
|
cc2538_rf_err_isr, /* 158 RFCORE Error */
|
||||||
crypto_isr, /* 159 AES */
|
crypto_isr, /* 159 AES */
|
||||||
default_handler, /* 160 PKA */
|
pka_isr, /* 160 PKA */
|
||||||
rtimer_isr, /* 161 SM Timer */
|
rtimer_isr, /* 161 SM Timer */
|
||||||
default_handler, /* 162 MACTimer */
|
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.
|
* General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development.
|
||||||
* ADC
|
* ADC
|
||||||
* Cryptoprocessor (AES-CCM-256, SHA-256)
|
* Cryptoprocessor (AES-CCM-256, SHA-256)
|
||||||
|
* Public Key Accelerator (ECDH, ECDSA)
|
||||||
* SmartRF06 EB and BB peripherals
|
* SmartRF06 EB and BB peripherals
|
||||||
* LEDs
|
* LEDs
|
||||||
* Buttons
|
* 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.
|
* General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development.
|
||||||
* ADC
|
* ADC
|
||||||
* Cryptoprocessor (AES-CCM-256, SHA-256)
|
* Cryptoprocessor (AES-CCM-256, SHA-256)
|
||||||
|
* Public Key Accelerator (ECDH, ECDSA)
|
||||||
* LEDs
|
* LEDs
|
||||||
* Buttons
|
* Buttons
|
||||||
* Internal/external 2.4GHz antenna switch controllable by SW.
|
* Internal/external 2.4GHz antenna switch controllable by SW.
|
||||||
|
|
Loading…
Reference in a new issue