mirror of
https://github.com/thelsing/knx.git
synced 2025-10-12 11:15:54 +02:00
git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5
758 lines
33 KiB
C
758 lines
33 KiB
C
/*
|
|
* Copyright (c) 2017-2019, Texas Instruments Incorporated
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * 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.
|
|
*
|
|
* * Neither the name of Texas Instruments Incorporated 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 OWNER 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.
|
|
*/
|
|
/*!****************************************************************************
|
|
* @file ECDSA.h
|
|
*
|
|
* @brief TI Driver for Elliptic Curve Digital Signature Algorithm.
|
|
*
|
|
*
|
|
* @anchor ti_drivers_ECDSA_Overview
|
|
* # Overview #
|
|
*
|
|
* The Elliptic Curve Digital Signature Algorithm (ECDSA) is a message
|
|
* authentication scheme between two parties based on operation on elliptic
|
|
* curves over finite fields.
|
|
*
|
|
* Signing a message with ECDSA proves to the recipient that the sender of
|
|
* the message is in possession of the private key corresponding to the
|
|
* transmitted public key used during verification.
|
|
* For most practical systems, this ensures message authentication and
|
|
* integrity.
|
|
*
|
|
* # Steps involved #
|
|
* - The sender hashes the message they wish to authenticate and
|
|
* truncates it to the length of the curve parameters of the
|
|
* elliptic curve used by both parties.
|
|
* - The sender generates a per-message secret number (PMSN) where
|
|
* 0 < PMSN < N. This number must (!) be unique for each message and be
|
|
* kept secret. If a PMSN is reused to authenticate more than one message,
|
|
* the secret key of the sender can be derived from these two messages
|
|
* and signatures!
|
|
* - The sender generates r and s where 0 < r, s < N. These two integers
|
|
* constitute the actual signature of the message.
|
|
* - The sender transmits the message, r, s, and the public key to the
|
|
* recipient.
|
|
* - The recipient calculates the hash of the message using an agreed
|
|
* upon hash function and truncates it to the length of the curve
|
|
* parameters of the elliptic curve used by both parties
|
|
* - The recipient uses the hash, s, and the sender's public key to
|
|
* recalculate r.
|
|
* - The recipient accepts the signature if the received and calculated r
|
|
* match. Otherwise, they reject the signature.
|
|
*
|
|
* @anchor ti_drivers_ECDSA_Usage
|
|
* # Usage #
|
|
*
|
|
* ## Before starting an ECDSA operation #
|
|
*
|
|
* Before starting an ECDSA operation, the application must do the following:
|
|
* - Call ECDSA_init() to initialize the driver
|
|
* - Call ECDSA_Params_init() to initialize the ECDSA_Params to default values.
|
|
* - Modify the ECDSA_Params as desired
|
|
* - Call ECDSA_open() to open an instance of the driver
|
|
*
|
|
* ## Signing a message #
|
|
* To sign a message using an agreed upon hash function and elliptic curve, the
|
|
* application must do the following:
|
|
* - Initialize an ECDSA_OperationSign struct by calling ECDSA_OperationSign_init().
|
|
* - Generate the keying material for the private key. This keying material must
|
|
* be an integer in the interval [1, n - 1], where n is the order of the curve.
|
|
* It should be stored in an array with the least significant byte of the integer
|
|
* hex representation stored in the lowest address of the array (little-endian).
|
|
* The array should be the same length as the curve parameters of the curve used.
|
|
* The driver can be configured to validate public and private keys against the
|
|
* provided curve.
|
|
* - Initialize the private key CryptoKey. CryptoKeys are opaque datastructures and representations
|
|
* of keying material and its storage. Depending on how the keying material
|
|
* is stored (RAM or flash, key store, key blob), the CryptoKey must be
|
|
* initialized differently. The ECDSA API can handle all types of CryptoKey.
|
|
* However, not all device-specific implementions support all types of CryptoKey.
|
|
* Devices without a key store will not support CryptoKeys with keying material
|
|
* stored in a key store for example.
|
|
* All devices support plaintext CryptoKeys.
|
|
* - Initialize the pmsn CryptoKey. The PMSN itself should be a 0-padded integer of
|
|
* the same length as the curve parameters of the agreed upon curve and
|
|
* where 0 < PMSN < N. The driver will enforce this restriction and reject invalid
|
|
* PMSNs.
|
|
* - Hash the message using a previously agreed upon hash function and truncate
|
|
* the hash to the length of the curve parameters of the agreed upon curve.
|
|
* - Call ECDSA_sign(). The r and s vectors will be written to the buffers
|
|
* provided in the function call. Ensure the return value is
|
|
* ECDSA_STATUS_SUCCESS.
|
|
*
|
|
* ## Verifying a message #
|
|
* After receiving the message, public key, r, and s, the application should
|
|
* do the following to verify the signature:
|
|
* - Initialize an ECDSA_OperationVerify struct by calling ECDSA_OperationVerify_init().
|
|
* - Hash the message using a previously agreed upon hash function and truncate
|
|
* the hash to the length of the curve parameters of the agreed upon curve.
|
|
* - Initialize a CryptoKey as public key with the keying material received from the other
|
|
* party.
|
|
* - Call ECDSA_verify(). Ensure the return value is ECDSA_STATUS_SUCCESS. The
|
|
* driver will validate the received public key against the provided curve.
|
|
*
|
|
* ## General usage #
|
|
* The API expects elliptic curves as defined in ti/drivers/cryptoutils/ecc/ECCParams.h.
|
|
* Several commonly used curves are provided. Check the device-specific ECDSA documentation
|
|
* for curve type (short Weierstrass, Montgomery, Edwards) support for your device.
|
|
* ECDSA support for a curve type on a device does not imply curve-type support for
|
|
* other ECC schemes.
|
|
*
|
|
* Public keys and shared secrets are points on an elliptic curve. These points can
|
|
* be expressed in several ways. The most common one is in affine coordinates as an
|
|
* X,Y pair.
|
|
* This API uses points expressed in affine coordinates.
|
|
* The point is stored as a concatenated array of X followed by Y in a location
|
|
* described by its CryptoKey.
|
|
*
|
|
* This API accepts and returns the keying material of public keys according
|
|
* to the following table:
|
|
*
|
|
* | Curve Type | Keying Material Array | Array Length |
|
|
* |--------------------|-----------------------|---------------------------|
|
|
* | Short Weierstrass | [X, Y] | 2 * Curve Param Length |
|
|
* | Montgomery | [X, Y] | 2 * Curve Param Length |
|
|
* | Edwards | [X, Y] | 2 * Curve Param Length |
|
|
*
|
|
* @anchor ti_drivers_ECDSA_Synopsis
|
|
* ## Synopsis
|
|
* @anchor ti_drivers_ECDSA_Synopsis_Code
|
|
* @code
|
|
* // Import ECDSA Driver definitions
|
|
* #include <ti/drivers/ECDSA.h>
|
|
*
|
|
* // Since we are using default ECDSA_Params, we just pass in NULL for that parameter.
|
|
* ecdsaHandle = ECDSA_open(0, NULL);
|
|
*
|
|
* if (!ecdsaHandle) {
|
|
* // Handle error
|
|
* }
|
|
*
|
|
* // Initialize myPrivateKey
|
|
* CryptoKeyPlaintext_initKey(&myPrivateKey, myPrivateKeyingMaterial, sizeof(myPrivateKeyingMaterial));
|
|
* CryptoKeyPlaintext_initKey(&pmsnKey, pmsn, sizeof(pmsn));
|
|
*
|
|
* // Initialize the operation
|
|
* ECDSA_OperationSign_init(&operationSign);
|
|
* operationSign.curve = &ECCParams_NISTP256;
|
|
* operationSign.myPrivateKey = &myPrivateKey;
|
|
* operationSign.pmsn = &pmsnKey;
|
|
* operationSign.hash = messageHash;
|
|
* operationSign.r = r;
|
|
* operationSign.s = s;
|
|
*
|
|
* // Generate the signature
|
|
* operationResult = ECDSA_sign(ecdsaHandle, &operationSign);
|
|
*
|
|
* // Initialize theirPublicKey
|
|
* CryptoKeyPlaintext_initKey(&theirPublicKey, theirPublicKeyingMaterial, sizeof(theirPublicKeyingMaterial));
|
|
*
|
|
* ECDSA_OperationVerify_init(&operationVerify);
|
|
* operationVerify.curve = &ECCParams_NISTP256;
|
|
* operationVerify.theirPublicKey = &theirPublicKey;
|
|
* operationVerify.hash = messageHash;
|
|
* operationVerify.r = r;
|
|
* operationVerify.s = s;
|
|
*
|
|
* // Generate the keying material for myPublicKey and store it in myPublicKeyingMaterial
|
|
* operationResult = ECDSA_verify(ecdsaHandle, &operationVerify);
|
|
*
|
|
* // Close the driver
|
|
* ECDSA_close(ecdsaHandle);
|
|
*
|
|
* @anchor ti_drivers_ECDSA_Examples
|
|
*
|
|
* # Examples #
|
|
*
|
|
* ## ECDSA sign with plaintext CryotoKeys #
|
|
*
|
|
* @code
|
|
*
|
|
* #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
|
|
* #include <ti/drivers/ECDSA.h>
|
|
*
|
|
* ...
|
|
*
|
|
* // This vector is taken from the NIST ST toolkit examples from ECDSA_Prime.pdf
|
|
* uint8_t myPrivateKeyingMaterial[32] = {0x96, 0xBF, 0x85, 0x49, 0xC3, 0x79, 0xE4, 0x04,
|
|
* 0xED, 0xA1, 0x08, 0xA5, 0x51, 0xF8, 0x36, 0x23,
|
|
* 0x12, 0xD8, 0xD1, 0xB2, 0xA5, 0xFA, 0x57, 0x06,
|
|
* 0xE2, 0xCC, 0x22, 0x5C, 0xF6, 0xF9, 0x77, 0xC4};
|
|
* uint8_t messageHashSHA256[32] = {0xC4, 0xA8, 0xC8, 0x99, 0x28, 0xCF, 0x80, 0xB6,
|
|
* 0xE4, 0x42, 0xD5, 0xBD, 0x28, 0x4D, 0xE3, 0xFD,
|
|
* 0x3A, 0x13, 0xD8, 0x65, 0x0C, 0x41, 0x1C, 0x21,
|
|
* 0x48, 0x95, 0x79, 0x2A, 0xA1, 0x41, 0x1A, 0xA4};
|
|
* uint8_t pmsn[32] = {0xAE, 0x50, 0xEE, 0xFA, 0x27, 0xB4, 0xDB, 0x14,
|
|
* 0x9F, 0xE1, 0xFB, 0x04, 0xF2, 0x4B, 0x50, 0x58,
|
|
* 0x91, 0xE3, 0xAC, 0x4D, 0x2A, 0x5D, 0x43, 0xAA,
|
|
* 0xCA, 0xC8, 0x7F, 0x79, 0x52, 0x7E, 0x1A, 0x7A};
|
|
* uint8_t r[32] = {0};
|
|
* uint8_t s[32] = {0};
|
|
*
|
|
*
|
|
* CryptoKey myPrivateKey;
|
|
* CryptoKey pmsnKey;
|
|
*
|
|
* ECDSA_Handle ecdsaHandle;
|
|
*
|
|
* int_fast16_t operationResult;
|
|
*
|
|
* // Since we are using default ECDSA_Params, we just pass in NULL for that parameter.
|
|
* ecdsaHandle = ECDSA_open(0, NULL);
|
|
*
|
|
* if (!ecdsaHandle) {
|
|
* // Handle error
|
|
* }
|
|
*
|
|
* // Initialize myPrivateKey
|
|
* CryptoKeyPlaintext_initKey(&myPrivateKey, myPrivateKeyingMaterial, sizeof(myPrivateKeyingMaterial));
|
|
* CryptoKeyPlaintext_initKey(&pmsnKey, pmsn, sizeof(pmsn));
|
|
*
|
|
* // Initialize the operation
|
|
* ECDSA_OperationSign_init(&operationSign);
|
|
* operationSign.curve = &ECCParams_NISTP256;
|
|
* operationSign.myPrivateKey = &myPrivateKey;
|
|
* operationSign.pmsn = &pmsnKey;
|
|
* operationSign.hash = messageHash;
|
|
* operationSign.r = r;
|
|
* operationSign.s = s;
|
|
*
|
|
* // Generate the signature
|
|
* operationResult = ECDSA_sign(ecdsaHandle, &operationSign);
|
|
*
|
|
* if (operationResult != ECDSA_STATUS_SUCCESS) {
|
|
* // Handle error
|
|
* }
|
|
*
|
|
* // Send out signature
|
|
* // r should be 0x4F, 0x10, 0x46, 0xCA, 0x9A, 0xB6, 0x25, 0x73,
|
|
* // 0xF5, 0x3E, 0x0B, 0x1F, 0x6F, 0x31, 0x4C, 0xE4,
|
|
* // 0x81, 0x0F, 0x50, 0xB1, 0xF3, 0xD1, 0x65, 0xFF,
|
|
* // 0x65, 0x41, 0x7F, 0xD0, 0x76, 0xF5, 0x42, 0x2B
|
|
* //
|
|
* // s should be 0xF1, 0xFA, 0x63, 0x6B, 0xDB, 0x9B, 0x32, 0x4B,
|
|
* // 0x2C, 0x26, 0x9D, 0xE6, 0x6F, 0x88, 0xC1, 0x98,
|
|
* // 0x81, 0x2A, 0x50, 0x89, 0x3A, 0x99, 0x3A, 0x3E,
|
|
* // 0xCD, 0x92, 0x63, 0x2D, 0x12, 0xC2, 0x42, 0xDC
|
|
*
|
|
* @endcode
|
|
*
|
|
*
|
|
* ## ECDSA verify with plaintext CryotoKeys #
|
|
*
|
|
* @code
|
|
*
|
|
* #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
|
|
* #include <ti/drivers/ECDSA.h>
|
|
*
|
|
* ...
|
|
*
|
|
* // This vector is taken from the NIST ST toolkit examples from ECDSA_Prime.pdf
|
|
* uint8_t theirPublicKeyingMaterial[64] = {0x19, 0x7A, 0xBC, 0x89, 0x08, 0xCD, 0x01, 0x82,
|
|
* 0xA3, 0xA2, 0x9E, 0x1E, 0xAD, 0xA0, 0xB3, 0x62,
|
|
* 0x1C, 0xBA, 0x98, 0x47, 0x73, 0x8C, 0xDC, 0xF1,
|
|
* 0xD3, 0xBA, 0x94, 0xFE, 0xFD, 0x8A, 0xE0, 0xB7,
|
|
* 0x09, 0x5E, 0xCC, 0x06, 0xC6, 0xBB, 0x63, 0xB5,
|
|
* 0x61, 0x9E, 0x52, 0x43, 0xAE, 0xC7, 0xAD, 0x63,
|
|
* 0x90, 0x72, 0x28, 0x19, 0xE4, 0x26, 0xB2, 0x4B,
|
|
* 0x7A, 0xBF, 0x9D, 0x95, 0x47, 0xF7, 0x03, 0x36};
|
|
* uint8_t messageHashSHA256[32] = {0xC4, 0xA8, 0xC8, 0x99, 0x28, 0xCF, 0x80, 0xB6,
|
|
* 0xE4, 0x42, 0xD5, 0xBD, 0x28, 0x4D, 0xE3, 0xFD,
|
|
* 0x3A, 0x13, 0xD8, 0x65, 0x0C, 0x41, 0x1C, 0x21,
|
|
* 0x48, 0x95, 0x79, 0x2A, 0xA1, 0x41, 0x1A, 0xA4};
|
|
* uint8_t r[32] = {0x4F, 0x10, 0x46, 0xCA, 0x9A, 0xB6, 0x25, 0x73,
|
|
* 0xF5, 0x3E, 0x0B, 0x1F, 0x6F, 0x31, 0x4C, 0xE4,
|
|
* 0x81, 0x0F, 0x50, 0xB1, 0xF3, 0xD1, 0x65, 0xFF,
|
|
* 0x65, 0x41, 0x7F, 0xD0, 0x76, 0xF5, 0x42, 0x2B};
|
|
* uint8_t s[32] = {0xF1, 0xFA, 0x63, 0x6B, 0xDB, 0x9B, 0x32, 0x4B,
|
|
* 0x2C, 0x26, 0x9D, 0xE6, 0x6F, 0x88, 0xC1, 0x98,
|
|
* 0x81, 0x2A, 0x50, 0x89, 0x3A, 0x99, 0x3A, 0x3E,
|
|
* 0xCD, 0x92, 0x63, 0x2D, 0x12, 0xC2, 0x42, 0xDC};
|
|
*
|
|
*
|
|
* CryptoKey theirPublicKey;
|
|
*
|
|
* ECDSA_Handle ecdsaHandle;
|
|
*
|
|
* int_fast16_t operationResult;
|
|
*
|
|
* ECDSA_OperationVerify operationVerify;
|
|
*
|
|
* // Since we are using default ECDSA_Params, we just pass in NULL for that parameter.
|
|
* ecdsaHandle = ECDSA_open(0, NULL);
|
|
*
|
|
* if (!ecdsaHandle) {
|
|
* // Handle error
|
|
* }
|
|
*
|
|
* // Initialize theirPublicKey
|
|
* CryptoKeyPlaintext_initKey(&theirPublicKey, theirPublicKeyingMaterial, sizeof(theirPublicKeyingMaterial));
|
|
*
|
|
* ECDSA_OperationVerify_init(&operationVerify);
|
|
* operationVerify.curve = &ECCParams_NISTP256;
|
|
* operationVerify.theirPublicKey = &theirPublicKey;
|
|
* operationVerify.hash = messageHash;
|
|
* operationVerify.r = r;
|
|
* operationVerify.s = s;
|
|
*
|
|
* // Generate the keying material for myPublicKey and store it in myPublicKeyingMaterial
|
|
* operationResult = ECDSA_verify(ecdsaHandle, &operationVerify);
|
|
*
|
|
* if (operationResult != ECDSA_STATUS_SUCCESS) {
|
|
* // Handle error
|
|
* }
|
|
*
|
|
* @endcode
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef ti_drivers_ECDSA__include
|
|
#define ti_drivers_ECDSA__include
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
|
|
#include <ti/drivers/cryptoutils/ecc/ECCParams.h>
|
|
|
|
/*!
|
|
* Common ECDSA status code reservation offset.
|
|
* ECDSA driver implementations should offset status codes with
|
|
* ECDSA_STATUS_RESERVED growing negatively.
|
|
*
|
|
* Example implementation specific status codes:
|
|
* @code
|
|
* #define ECDSAXYZ_STATUS_ERROR0 ECDSA_STATUS_RESERVED - 0
|
|
* #define ECDSAXYZ_STATUS_ERROR1 ECDSA_STATUS_RESERVED - 1
|
|
* #define ECDSAXYZ_STATUS_ERROR2 ECDSA_STATUS_RESERVED - 2
|
|
* @endcode
|
|
*/
|
|
#define ECDSA_STATUS_RESERVED (-32)
|
|
|
|
/*!
|
|
* @brief Successful status code.
|
|
*
|
|
* Functions return ECDSA_STATUS_SUCCESS if the function was executed
|
|
* successfully.
|
|
*/
|
|
#define ECDSA_STATUS_SUCCESS (0)
|
|
|
|
/*!
|
|
* @brief Generic error status code.
|
|
*
|
|
* Functions return ECDSA_STATUS_ERROR if the function was not executed
|
|
* successfully.
|
|
*/
|
|
#define ECDSA_STATUS_ERROR (-1)
|
|
|
|
/*!
|
|
* @brief An error status code returned if the hardware or software resource
|
|
* is currently unavailable.
|
|
*
|
|
* ECDSA driver implementations may have hardware or software limitations on how
|
|
* many clients can simultaneously perform operations. This status code is returned
|
|
* if the mutual exclusion mechanism signals that an operation cannot currently be performed.
|
|
*/
|
|
#define ECDSA_STATUS_RESOURCE_UNAVAILABLE (-2)
|
|
|
|
/*!
|
|
* @brief The PMSN passed into the the call is invalid.
|
|
*
|
|
* PMSNs must be integers in the interval [1, n - 1], where n is the
|
|
* order of the curve.
|
|
*/
|
|
#define ECDSA_STATUS_INVALID_PMSN (-3)
|
|
|
|
/*!
|
|
* @brief The r value passed in is larger than the order of the curve.
|
|
*
|
|
* Signature components (r and s) must be integers in the interval [1, n - 1], where n is the
|
|
* order of the curve.
|
|
*/
|
|
#define ECDSA_STATUS_R_LARGER_THAN_ORDER (-4)
|
|
|
|
/*!
|
|
* @brief The s value passed in is larger than the order of the curve.
|
|
*
|
|
* Signature components (r and s) must be integers in the interval [1, n - 1], where n is the
|
|
* order of the curve.
|
|
*/
|
|
#define ECDSA_STATUS_S_LARGER_THAN_ORDER (-5)
|
|
|
|
/*!
|
|
* @brief The public key of the other party does not lie upon the curve.
|
|
*
|
|
* The public key received from the other party does not lie upon the agreed upon
|
|
* curve.
|
|
*/
|
|
#define ECDSA_STATUS_PUBLIC_KEY_NOT_ON_CURVE (-6)
|
|
|
|
/*!
|
|
* @brief A coordinate of the public key of the other party is too large.
|
|
*
|
|
* A coordinate of the public key received from the other party is larger than
|
|
* the prime of the curve. This implies that the point was not correctly
|
|
* generated on that curve.
|
|
*/
|
|
#define ECDSA_STATUS_PUBLIC_KEY_LARGER_THAN_PRIME (-7)
|
|
|
|
/*!
|
|
* @brief The public key to verify against is the point at infinity.
|
|
*
|
|
* The point at infinity is not a valid input.
|
|
*/
|
|
#define ECDSA_STATUS_POINT_AT_INFINITY (-8)
|
|
|
|
/*!
|
|
* @brief The ongoing operation was canceled.
|
|
*/
|
|
#define ECDSA_STATUS_CANCELED (-9)
|
|
|
|
/*!
|
|
* @brief A handle that is returned from an ECDSA_open() call.
|
|
*/
|
|
typedef struct ECDSA_Config *ECDSA_Handle;
|
|
|
|
/*!
|
|
* @brief The way in which ECDSA function calls return after performing an
|
|
* encryption + authentication or decryption + verification operation.
|
|
*
|
|
* Not all ECDSA operations exhibit the specified return behavor. Functions that do not
|
|
* require significant computation and cannot offload that computation to a background thread
|
|
* behave like regular functions. Which functions exhibit the specfied return behavior is
|
|
* implementation dependent. Specifically, a software-backed implementation run on the same
|
|
* CPU as the application will emulate the return behavior while not actually offloading
|
|
* the computation to the background thread.
|
|
*
|
|
* ECDSA functions exhibiting the specified return behavior have restrictions on the
|
|
* context from which they may be called.
|
|
*
|
|
* | | Task | Hwi | Swi |
|
|
* |--------------------------------|-------|-------|-------|
|
|
* |ECDSA_RETURN_BEHAVIOR_CALLBACK | X | X | X |
|
|
* |ECDSA_RETURN_BEHAVIOR_BLOCKING | X | | |
|
|
* |ECDSA_RETURN_BEHAVIOR_POLLING | X | X | X |
|
|
*
|
|
*/
|
|
typedef enum {
|
|
ECDSA_RETURN_BEHAVIOR_CALLBACK = 1, /*!< The function call will return immediately while the
|
|
* ECDSA operation goes on in the background. The registered
|
|
* callback function is called after the operation completes.
|
|
* The context the callback function is called (task, HWI, SWI)
|
|
* is implementation-dependent.
|
|
*/
|
|
ECDSA_RETURN_BEHAVIOR_BLOCKING = 2, /*!< The function call will block while ECDSA operation goes
|
|
* on in the background. ECDSA operation results are available
|
|
* after the function returns.
|
|
*/
|
|
ECDSA_RETURN_BEHAVIOR_POLLING = 4, /*!< The function call will continuously poll a flag while ECDSA
|
|
* operation goes on in the background. ECDSA operation results
|
|
* are available after the function returns.
|
|
*/
|
|
} ECDSA_ReturnBehavior;
|
|
|
|
/*!
|
|
* @brief ECDSA Global configuration
|
|
*
|
|
* The ECDSA_Config structure contains a set of pointers used to characterize
|
|
* the ECDSA driver implementation.
|
|
*
|
|
* This structure needs to be defined before calling ECDSA_init() and it must
|
|
* not be changed thereafter.
|
|
*
|
|
* @sa ECDSA_init()
|
|
*/
|
|
typedef struct ECDSA_Config {
|
|
/*! Pointer to a driver specific data object */
|
|
void *object;
|
|
|
|
/*! Pointer to a driver specific hardware attributes structure */
|
|
void const *hwAttrs;
|
|
} ECDSA_Config;
|
|
|
|
/*!
|
|
* @brief Struct containing the parameters required for signing a message.
|
|
*/
|
|
typedef struct {
|
|
const ECCParams_CurveParams *curve; /*!< A pointer to the elliptic curve parameters */
|
|
const CryptoKey *myPrivateKey; /*!< A pointer to the private ECC key that will
|
|
* sign the hash of the message
|
|
*/
|
|
const CryptoKey *pmsn; /*!< A pointer to a per message secret number (PMSN).
|
|
* The number must be provided by the
|
|
* application and be (0 < PMSN < curve order).
|
|
* Must be of the same length as
|
|
* other params of the curve used.
|
|
*/
|
|
const uint8_t *hash; /*!< A pointer to the hash of the message.
|
|
* Must be the same length as the other curve parameters.
|
|
*/
|
|
uint8_t *r; /*!< A pointer to the buffer the r component of
|
|
* the signature will be written to.
|
|
* Must be of the same length as other
|
|
* params of the curve used.
|
|
*/
|
|
uint8_t *s; /*!< A pointer to the buffer the s component of
|
|
* the signature will be written to.
|
|
* Must be of the same length as other
|
|
* params of the curve used.
|
|
*/
|
|
} ECDSA_OperationSign;
|
|
|
|
/*!
|
|
* @brief Struct containing the parameters required for verifying a message.
|
|
*/
|
|
typedef struct {
|
|
const ECCParams_CurveParams *curve; /*!< A pointer to the elliptic curve parameters */
|
|
const CryptoKey *theirPublicKey; /*!< A pointer to the public key of the party
|
|
* that signed the hash of the message
|
|
*/
|
|
const uint8_t *hash; /*!< A pointer to the hash of the message.
|
|
* Must be the same length as the other curve parameters.
|
|
*/
|
|
const uint8_t *r; /*!< A pointer to the r component of the received
|
|
* signature. Must be of the same length
|
|
* as other params of the curve used.
|
|
*/
|
|
const uint8_t *s; /*!< A pointer to the s component of the received
|
|
* signature. Must be of the same length
|
|
* as other params of the curve used.
|
|
*/
|
|
} ECDSA_OperationVerify;
|
|
|
|
/*!
|
|
* @brief Union containing pointers to all supported operation structs.
|
|
*/
|
|
typedef union {
|
|
ECDSA_OperationSign *sign; /*!< A pointer to an ECDSA_OperationSign struct */
|
|
ECDSA_OperationVerify *verify; /*!< A pointer to an ECDSA_OperationVerify struct */
|
|
} ECDSA_Operation;
|
|
|
|
/*!
|
|
* @brief Enum for the operation types supported by the driver.
|
|
*/
|
|
typedef enum {
|
|
ECDSA_OPERATION_TYPE_SIGN = 1,
|
|
ECDSA_OPERATION_TYPE_VERIFY = 2,
|
|
} ECDSA_OperationType;
|
|
|
|
/*!
|
|
* @brief The definition of a callback function used by the ECDSA driver
|
|
* when used in ::ECDSA_RETURN_BEHAVIOR_CALLBACK
|
|
*
|
|
* @param handle Handle of the client that started the ECDSA operation.
|
|
*
|
|
* @param returnStatus The result of the ECDSA operation. May contain an error code
|
|
* if the result is the point at infinity for example.
|
|
*
|
|
* @param operation A union of pointers to operation structs. Only one type
|
|
* of pointer is valid per call to the callback function. Which type
|
|
* is currently valid is determined by /c operationType. The union
|
|
* allows easier access to the struct's fields without the need to
|
|
* typecase the result.
|
|
*
|
|
* @param operationType This parameter determined which operation the
|
|
* callback refers to and which type to access through /c operation.
|
|
*/
|
|
typedef void (*ECDSA_CallbackFxn) (ECDSA_Handle handle,
|
|
int_fast16_t returnStatus,
|
|
ECDSA_Operation operation,
|
|
ECDSA_OperationType operationType);
|
|
|
|
/*!
|
|
* @brief ECDSA Parameters
|
|
*
|
|
* ECDSA Parameters are used to with the ECDSA_open() call. Default values for
|
|
* these parameters are set using ECDSA_Params_init().
|
|
*
|
|
* @sa ECDSA_Params_init()
|
|
*/
|
|
typedef struct {
|
|
ECDSA_ReturnBehavior returnBehavior; /*!< Blocking, callback, or polling return behavior */
|
|
ECDSA_CallbackFxn callbackFxn; /*!< Callback function pointer */
|
|
uint32_t timeout; /*!< Timeout in system ticks before the operation fails
|
|
* and returns
|
|
*/
|
|
void *custom; /*!< Custom argument used by driver
|
|
* implementation
|
|
*/
|
|
} ECDSA_Params;
|
|
|
|
/*!
|
|
* @brief This function initializes the ECDSA module.
|
|
*
|
|
* @pre The ECDSA_config structure must exist and be persistent before this
|
|
* function can be called. This function must also be called before
|
|
* any other ECDSA driver APIs. This function call does not modify any
|
|
* peripheral registers.
|
|
*/
|
|
void ECDSA_init(void);
|
|
|
|
/*!
|
|
* @brief Function to close an ECDSA peripheral specified by the ECDSA handle
|
|
*
|
|
* @pre ECDSA_open() has to be called first.
|
|
*
|
|
* @param handle An ECDSA handle returned from ECDSA_open()
|
|
*
|
|
* @sa ECDSA_open()
|
|
*/
|
|
void ECDSA_close(ECDSA_Handle handle);
|
|
|
|
/*!
|
|
* @brief This function opens a given ECDSA peripheral.
|
|
*
|
|
* @pre ECDSA controller has been initialized using ECDSA_init()
|
|
*
|
|
* @param index Logical peripheral number for the ECDSA indexed into
|
|
* the ECDSA_config table
|
|
*
|
|
* @param params Pointer to an parameter block, if NULL it will use
|
|
* default values.
|
|
*
|
|
* @return An ECDSA_Handle on success or a NULL on an error or if it has been
|
|
* opened already.
|
|
*
|
|
* @sa ECDSA_init()
|
|
* @sa ECDSA_close()
|
|
*/
|
|
ECDSA_Handle ECDSA_open(uint_least8_t index, ECDSA_Params *params);
|
|
|
|
/*!
|
|
* @brief Function to initialize the ECDSA_Params struct to its defaults
|
|
*
|
|
* @param params An pointer to ECDSA_Params structure for
|
|
* initialization
|
|
*
|
|
* Defaults values are:
|
|
* returnBehavior = ECDSA_RETURN_BEHAVIOR_BLOCKING
|
|
* callbackFxn = NULL
|
|
* timeout = SemaphoreP_WAIT_FOREVER
|
|
* custom = NULL
|
|
*/
|
|
void ECDSA_Params_init(ECDSA_Params *params);
|
|
|
|
/*!
|
|
* @brief Function to initialize an ECDSA_OperationSign struct to its defaults
|
|
*
|
|
* @param operation A pointer to ECDSA_OperationSign structure for
|
|
* initialization
|
|
*
|
|
* Defaults values are all zeros.
|
|
*/
|
|
void ECDSA_OperationSign_init(ECDSA_OperationSign *operation);
|
|
|
|
/*!
|
|
* @brief Function to initialize an ECDSA_OperationSign struct to its defaults
|
|
*
|
|
* @param operation An pointer to ECDSA_OperationSign structure for
|
|
* initialization
|
|
*
|
|
* Defaults values are all zeros.
|
|
*/
|
|
void ECDSA_OperationVerify_init(ECDSA_OperationVerify *operation);
|
|
|
|
/*!
|
|
* @brief Signs a hashed message.
|
|
*
|
|
* ECDSA_sign() generates a signature (\c r, \c s) of a \c hash of a message.
|
|
*
|
|
* @pre ECDSA_OperationSign_init() must be called on \c operation first.
|
|
* The driver must have been opened by calling ECDSA_open() first.
|
|
*
|
|
* @param [in] handle An ECDSA handle returned from ECDSA_open()
|
|
*
|
|
* @param [in] operation A struct containing the pointers to the
|
|
* buffers necessary to perform the operation
|
|
* @sa ECDSA_verify()
|
|
*
|
|
* @retval #ECDSA_STATUS_SUCCESS The operation succeeded.
|
|
* @retval #ECDSA_STATUS_ERROR The operation failed.
|
|
* @retval #ECDSA_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later.
|
|
* @retval #ECDSA_STATUS_CANCELED The operation was canceled.
|
|
* @retval #ECDSA_STATUS_INVALID_PMSN The PMSN passed into the the call is invalid.
|
|
*/
|
|
int_fast16_t ECDSA_sign(ECDSA_Handle handle, ECDSA_OperationSign *operation);
|
|
|
|
/*!
|
|
* @brief Verifies a received signature matches a hash and public key
|
|
*
|
|
* @pre ECDSA_OperationVerify_init() must be called on \c operation first.
|
|
* The driver must have been opened by calling ECDSA_open() first.
|
|
*
|
|
* @param [in] handle An ECDSA handle returned from ECDSA_open()
|
|
*
|
|
* @param [in] operation A struct containing the pointers to the
|
|
* buffers necessary to perform the operation
|
|
*
|
|
* @sa ECDSA_sign()
|
|
*
|
|
* @retval #ECDSA_STATUS_SUCCESS The operation succeeded.
|
|
* @retval #ECDSA_STATUS_ERROR The operation failed. This is the return status if the signature did not match.
|
|
* @retval #ECDSA_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later.
|
|
* @retval #ECDSA_STATUS_CANCELED The operation was canceled.
|
|
* @retval #ECDSA_STATUS_R_LARGER_THAN_ORDER The r value passed in is larger than the order of the curve.
|
|
* @retval #ECDSA_STATUS_S_LARGER_THAN_ORDER The s value passed in is larger than the order of the curve.
|
|
* @retval #ECDSA_STATUS_PUBLIC_KEY_NOT_ON_CURVE The public key of the other party does not lie upon the curve.
|
|
* @retval #ECDSA_STATUS_PUBLIC_KEY_LARGER_THAN_PRIME One of the public key coordinates is larger the the curve's prime.
|
|
* @retval #ECDSA_STATUS_POINT_AT_INFINITY The public key to verify against is the point at infinity.
|
|
*/
|
|
int_fast16_t ECDSA_verify(ECDSA_Handle handle, ECDSA_OperationVerify *operation);
|
|
|
|
/*!
|
|
* @brief Cancels an ongoing ECDSA operation.
|
|
*
|
|
* Asynchronously cancels an ECDSA operation. Only available when using
|
|
* ECDSA_RETURN_BEHAVIOR_CALLBACK or ECDSA_RETURN_BEHAVIOR_BLOCKING.
|
|
* The operation will terminate as though an error occured. The
|
|
* return status code of the operation will be ECDSA_STATUS_CANCELED.
|
|
*
|
|
* @param handle Handle of the operation to cancel
|
|
*
|
|
* @retval #ECDSA_STATUS_SUCCESS The operation was canceled.
|
|
* @retval #ECDSA_STATUS_ERROR The operation was not canceled. There may be no operation to cancel.
|
|
*/
|
|
int_fast16_t ECDSA_cancelOperation(ECDSA_Handle handle);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* ti_drivers_ECDSA__include */
|