Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
ECDH.h File Reference

Detailed Description

TI Driver for Elliptic Curve Diffie-Hellman key agreement scheme.

Warning
This is a beta API. It may change in future releases.

Overview

Elliptic Curve Diffie-Hellman (ECDH) is a key agreement scheme between two parties based on the Diffie-Hellman key exchange protocol.

It provides a means of generating a shared secret and derived symmetric key between the two parties over an insecure channel.

It does not provide authentication. As such, it does not guarantee that the party you are exchanging keys with is truly the party you wish to establish a secured channel with.

The two parties each generate a private key and a public key. The private key is a random integer in the interval [1, n - 1], where n is the order of a previously agreed upon curve. The public key is generated by multiplying the private key by the generator point of a previously agreed upon elliptic curve such as NISTP256 or Curve 25519. The public key is itself a point upon the elliptic curve. Each public key is then transmitted to the other party over a potentially insecure channel. The other party's public key is then multiplied with the private key, generating a shared secret. This shared secret is also a point on the curve. However, the entropy in the secret is not spread evenly throughout the shared secret. In order to generate one or more shared symmetric keys, the shared secret must be run through a key derivation function (KDF) that was previously agreed upon. The key derivation function can take many forms, from simply hashing the X coordinate of the shared secret with SHA2 and truncating the result to generating multiple symmetric keys with HKDF, an HMAC based KDF.

Usage

Before starting an ECDH operation

Before starting a CCM operation, the application must do the following:

Generating your public-private key pair

To generate a public-private key pair for an agreed upon curve, the application must do the following:

Calculating a shared secret

After trading public keys with the other party, the application should do the following to calculate the shared secret:

Creating one or more symmetric keys from the shared secret

After calculating the shared secret between the application and the other party, the entropy in the shared secret must be evened out and stretched as needed. The API allows for any number of keys to be derived from the shared secret using an application-provided key-derivation function. There are uncountable methods and algorithms to stretch an original seed entropy (the share secret) to generate symmetric keys.

After a key exchange

After the ECDH key exchange completes, the application should either start another operation or close the driver by calling ECDH_close()

General usage

The API expects elliptic curves in short Weierstrass form as defined in ti/drivers/types/ECCParams.h. Several commonly used curves are provided.

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. The Y value can be omitted when using point compression and doing the calculations in the Montgomery domain with X,Z coordinates. This API only uses points expressed in affine coordinates. The point is stored as a concatenated array of X followed by Y.

ECDH Driver Configuration

In order to use the ECDH APIs, the application is required to provide device-specific ECDH configuration in the Board.c file. The ECDH driver interface defines a configuration data structure:

typedef struct ECDH_Config_ {
void *object;
void const *hwAttrs;

The application must declare an array of ECDH_Config elements, named ECDH_config[]. Each element of ECDH_config[] must be populated with pointers to a device specific ECDH driver implementation's driver object, hardware attributes. The hardware attributes define properties such as the ECDH peripheral's base address. Each element in ECDH_config[] corresponds to an ECDH instance, and none of the elements should have NULL pointers. There is no correlation between the index and the peripheral designation (such as ECDH0 or ECDH1). For example, it is possible to use ECDH_config[0] for ECDH1. Multiple drivers and driver instances may all access the same underlying hardware. This is transparent to the application. Mutual exclusion is performed automatically by the drivers as necessary.

Because the ECDH configuration is very device dependent, you will need to check the doxygen for the device specific ECDH implementation. There you will find a description of the ECDH hardware attributes. Please also refer to the Board.c file of any of your examples to see the ECDH configuration.

ECDH Parameters

The ECDH_Params structure is passed to the ECDH_open() call. If NULL is passed for the parameters, ECDH_open() uses default parameters. An ECDH_Params structure is initialized with default values by passing it to ECDH_Params_init(). Some of the ECDH parameters are described below. To see brief descriptions of all the parameters, see ECDH_Params.

ECDH Return Behavior

The ECDH driver supports three return behaviors when processing data: blocking, polling, and callback. The ECDH driver defaults to blocking mode, if the application does not set it. Once an ECDH driver is opened, the only way to change the return behavior is to close and re-open the ECDH instance with the new return behavior.

In blocking mode, a task's code execution is blocked until an ECDH operation has completed. This ensures that only one ECDH operation operates at a given time. Other tasks requesting ECDH operations while a operation is currently taking place are also placed into a blocked state. ECDH operations are executed in the order in which they were received. In blocking mode, you cannot perform ECDH operations in the context of a software or hardware ISR.

In callback mode, an ECDH operation functions asynchronously, which means that it does not block code execution. After an ECDH operation has been completed, the ECDH driver calls a user-provided hook function. Callback mode is supported in the task, SWI, and HWI execution context, However, if an ECDH operation is requested while a operation is taking place, the call returns an error code.

In polling mode, an ECDH operation behaves the almost the same way as in blocking mode. Instead of pending on a semaphore and letting other scheduled tasks run, the application task, SWI, or HWI continuously polls a flag until the operation completes. If an ECDH operation is requested while a operation is taking place, the call returns an error code. When starting an ECDH operation in polling mode from HWI or SWI context, the ECDH HWI and SWI must be configured to have a higher priority to pre-empt the polling context.

Examples

ECDH exchange with plaintext CryptoKeys

...
// Our private key is 0x0000000000000000000000000000000000000000000000000000000000000001
// In practice, this value should come from a TRNG, PRNG, PUF, or device-specific pre-seeded key
uint8_t myPrivateKeyingMaterial[32] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t myPublicKeyingMaterial[64] = {0};
uint8_t theirPublicKeyingMaterial[64] = {0};
uint8_t sharedSecretKeyingMaterial[64] = {0};
uint8_t symmetricKeyingMaterial[16] = {0};
CryptoKey myPrivateKey;
CryptoKey myPublicKey;
CryptoKey theirPublicKey;
CryptoKey sharedSecret;
CryptoKey symmetricKey;
ECDH_Handle ecdhHandle;
int_fast16_t operationResult;
// Since we are using default ECDH_Params, we just pass in NULL for that parameter.
ecdhHandle = ECDH_open(0, NULL);
if (!ecdhHandle) {
// Handle error
}
// Initialize myPrivateKey and myPublicKey
CryptoKeyPlaintext_initKey(&myPrivateKey, myPrivateKeyingMaterial, sizeof(myPrivateKeyingMaterial));
CryptoKeyPlaintext_initBlankKey(&myPublicKey, myPublicKeyingMaterial, sizeof(myPublicKeyingMaterial));
// Generate the keying material for myPublicKey and store it in myPublicKeyingMaterial
operationResult = ECDH_generatePublicKey(ecdhHandle, &ECC_NISTP256, &myPrivateKey, &myPublicKey);
if (operationResult != ECDH_STATUS_SUCCESS) {
// Handle error
}
// Now send the content of myPublicKeyingMaterial to theother party,
// receive their public key, and copy their public keying material to theirPublicKeyingMaterial
// Initialise their public CryptoKey and the shared secret CryptoKey
CryptoKeyPlaintext_initKey(&theirPublicKey, theirPublicKeyingMaterial, sizeof(theirPublicKeyingMaterial));
CryptoKeyPlaintext_initBlankKey(&sharedSecret, sharedSecretKeyingMaterial, sizeof(sharedSecretKeyingMaterial));
// Compute the shared secret and copy it to sharedSecretKeyingMaterial
// The ECC_NISTP256 struct is provided in ti/drivers/types/EccPArams.h and the corresponding device-specific implementation
operationResult = ECDH_computeSharedSecret(ecdhHandle, &ECC_NISTP256, &myPrivateKey, &theirPublicKey, &sharedSecret);
if (operationResult != ECDH_STATUS_SUCCESS) {
// Handle error
}
CryptoKeyPlaintext_initBlankKey(&symmetricKey, symmetricKeyingMaterial, sizeof(symmetricKeyingMaterial));
// Set up a KDF such as HKDF and open the requisite cryptographic primitive driver to implement it
// HKDF and SHA2 were chosen as an example and may not be available directly
// Since we only have one symmetric CryptoKey we wish to generate, we can pass it directly to the function
operationResult = ECDH_calculateSharedEntropy(ecdhHandle, &sharedSecret, KDF_HKDF, sha2Handle, &symmetricKey, 1);
if (operationResult != ECDH_STATUS_SUCCESS) {
// Handle error
}
// At this point, you and the other party have both created the content within symmetricKeyingMaterial without
// someone else listening to your communication channel being able to do so
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
#include <ti/drivers/cryptoutils/ecc/ECCParams.h>

Go to the source code of this file.

Data Structures

struct  ECDH_Params_
 ECC Parameters. More...
 
struct  ECDH_Config_
 ECC Global configuration. More...
 

Macros

#define ECDH_CMD_RESERVED   (32)
 
#define ECDH_STATUS_RESERVED   (-32)
 
#define ECDH_STATUS_SUCCESS   (0)
 Successful status code. More...
 
#define ECDH_STATUS_ERROR   (-1)
 Generic error status code. More...
 
#define ECDH_STATUS_UNDEFINEDCMD   (-2)
 An error status code returned by ECDH_control() for undefined command codes. More...
 
#define ECDH_STATUS_RESOURCE_UNAVAILABLE   (-3)
 An error status code returned if the hardware or software resource is currently unavailable. More...
 
#define ECDH_STATUS_RESULT_POINT_AT_INFINITY   (-4)
 The result of the operation is the point at infinity. More...
 
#define ECDH_STATUS_RESULT_PRIVATE_KEY_LARGER_THAN_ORDER   (-5)
 The private key passed in is larger than the order of the curve. More...
 
#define ECDH_STATUS_RESULT_PUBLIC_KEY_NOT_ON_CURVE   (-6)
 The public key of the other party does not lie upon the curve. More...
 

Typedefs

typedef struct ECDH_Config_ECDH_Handle
 A handle that is returned from an ECDH_open() call. More...
 
typedef void(* ECDH_CallbackFxn) (ECDH_Handle handle, int_fast16_t operationStatus)
 The definition of a callback function used by the ECC driver when used in ECDH_RETURN_BEHAVIOR_CALLBACK. More...
 
typedef enum ECDH_ReturnBehavior_ ECDH_ReturnBehavior
 The way in which ECC function calls return after performing an encryption + authentication or decryption + verification operation. More...
 
typedef struct ECDH_Params_ ECDH_Params
 ECC Parameters. More...
 
typedef struct ECDH_Config_ ECDH_Config
 ECC Global configuration. More...
 
typedef int_fast16_t(* ECDH_KDFFxn) (void *driverHandle, const uint8_t *seedEntropy, size_t seedEntropyLength, CryptoKey derivedKeys[], uint32_t derivedKeysCount)
 Function that implements a key derivation function (KDF) More...
 

Enumerations

enum  ECDH_ReturnBehavior_ { ECDH_RETURN_BEHAVIOR_CALLBACK = 1, ECDH_RETURN_BEHAVIOR_BLOCKING = 2, ECDH_RETURN_BEHAVIOR_POLLING = 4 }
 The way in which ECC function calls return after performing an encryption + authentication or decryption + verification operation. More...
 

Functions

void ECDH_init (void)
 This function initializes the ECC module. More...
 
void ECDH_Params_init (ECDH_Params *params)
 Function to initialize the ECDH_Params struct to its defaults. More...
 
ECDH_Handle ECDH_open (uint_least8_t index, ECDH_Params *params)
 This function opens a given ECC peripheral. More...
 
void ECDH_close (ECDH_Handle handle)
 Function to close a ECC peripheral specified by the ECC handle. More...
 
int_fast16_t ECDH_control (ECDH_Handle handle, uint32_t cmd, void *args)
 Function performs implementation specific features on a given ECDH_Handle. More...
 
int_fast16_t ECDH_generatePublicKey (ECDH_Handle handle, const ECCParams_CurveParams *eccParams, const CryptoKey *myPrivateKey, CryptoKey *myPublicKey)
 Generates a public key for use in key agreement. More...
 
int_fast16_t ECDH_computeSharedSecret (ECDH_Handle handle, const ECCParams_CurveParams *eccParams, const CryptoKey *myPrivateKey, const CryptoKey *theirPublicKey, CryptoKey *sharedSecret)
 Computes a shared secret. More...
 
int_fast16_t ECDH_calculateSharedEntropy (ECDH_Handle handle, const CryptoKey *sharedSecret, const ECDH_KDFFxn kdf, void *kdfPrimitiveDriverHandle, CryptoKey derivedKeys[], uint32_t derivedKeysCount)
 Calculates key material. More...
 

Variables

const ECDH_Params ECDH_defaultParams
 Default ECDH_Params structure. More...
 

Typedef Documentation

§ ECDH_Handle

typedef struct ECDH_Config_* ECDH_Handle

A handle that is returned from an ECDH_open() call.

§ ECDH_CallbackFxn

typedef void(* ECDH_CallbackFxn) (ECDH_Handle handle, int_fast16_t operationStatus)

The definition of a callback function used by the ECC driver when used in ECDH_RETURN_BEHAVIOR_CALLBACK.

Parameters
handleHandle of the client that started the ECC operation.
operationStatusThe result of the ECC operation. May contain an error code if the result is the point at infinity for example.

§ ECDH_ReturnBehavior

The way in which ECC function calls return after performing an encryption + authentication or decryption + verification operation.

Not all ECC 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 not 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.

ECC functions exhibiting the specified return behavior have restrictions on the context from which they may be called.

Task Hwi Swi
ECDH_RETURN_BEHAVIOR_CALLBACK X X X
ECDH_RETURN_BEHAVIOR_BLOCKING X
ECDH_RETURN_BEHAVIOR_POLLING X X X

§ ECDH_Params

typedef struct ECDH_Params_ ECDH_Params

ECC Parameters.

ECC Parameters are used to with the ECDH_open() call. Default values for these parameters are set using ECDH_Params_init().

See also
ECDH_Params_init()

§ ECDH_Config

typedef struct ECDH_Config_ ECDH_Config

ECC Global configuration.

The ECDH_Config structure contains a set of pointers used to characterize the ECC driver implementation.

This structure needs to be defined before calling ECDH_init() and it must not be changed thereafter.

See also
ECDH_init()

§ ECDH_KDFFxn

typedef int_fast16_t(* ECDH_KDFFxn) (void *driverHandle, const uint8_t *seedEntropy, size_t seedEntropyLength, CryptoKey derivedKeys[], uint32_t derivedKeysCount)

Function that implements a key derivation function (KDF)

Key derivation functions take a string of random entropy as their input and generate a deterministic pseudo-random bit stream of arbitrary length. Specialised KDFs may produce outputs of fixed length or with maximum lengths.

Parameters
[in]driverHandleHandle of the of the driver used to execute the crypto primitive underlying the KDF. This primitive could be a cryptographic hash or a block cipher.
[in]seedEntropyThe entropy used to seed the KDF. Reusing the same seed will yield the same pseudo-random bit stream.
[in]seedEntropyLengthLength of the seed entropy.
[out]derivedKeysThe CryptoKeys seeded with deterministic pseudo-random output of the KDF.
[in]derivedKeysCountThe number of keys to seed.

Enumeration Type Documentation

§ ECDH_ReturnBehavior_

The way in which ECC function calls return after performing an encryption + authentication or decryption + verification operation.

Not all ECC 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 not 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.

ECC functions exhibiting the specified return behavior have restrictions on the context from which they may be called.

Task Hwi Swi
ECDH_RETURN_BEHAVIOR_CALLBACK X X X
ECDH_RETURN_BEHAVIOR_BLOCKING X
ECDH_RETURN_BEHAVIOR_POLLING X X X
Enumerator
ECDH_RETURN_BEHAVIOR_CALLBACK 

The function call will return immediately while the ECC 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.

ECDH_RETURN_BEHAVIOR_BLOCKING 

The function call will block while ECC operation goes on in the background. ECC operation results are available after the function returns.

ECDH_RETURN_BEHAVIOR_POLLING 

The function call will continuously poll a flag while ECC operation goes on in the background. ECC operation results are available after the function returns.

Function Documentation

§ ECDH_init()

void ECDH_init ( void  )

This function initializes the ECC module.

Precondition
The ECDH_config structure must exist and be persistent before this function can be called. This function must also be called before any other ECC driver APIs. This function call does not modify any peripheral registers.

§ ECDH_Params_init()

void ECDH_Params_init ( ECDH_Params params)

Function to initialize the ECDH_Params struct to its defaults.

Parameters
paramsAn pointer to ECDH_Params structure for initialization

Defaults values are: returnBehavior = ECDH_RETURN_BEHAVIOR_BLOCKING callbackFxn = NULL timeout = SemaphoreP_WAIT_FOREVER custom = NULL

§ ECDH_open()

ECDH_Handle ECDH_open ( uint_least8_t  index,
ECDH_Params params 
)

This function opens a given ECC peripheral.

Precondition
ECC controller has been initialized using ECDH_init()
Parameters
indexLogical peripheral number for the ECC indexed into the ECDH_config table
paramsPointer to an parameter block, if NULL it will use default values.
Returns
A ECDH_Handle on success or a NULL on an error or if it has been opened already.
See also
ECDH_init()
ECDH_close()

§ ECDH_close()

void ECDH_close ( ECDH_Handle  handle)

Function to close a ECC peripheral specified by the ECC handle.

Precondition
ECDH_open() has to be called first.
Parameters
handleA ECC handle returned from ECDH_open()
See also
ECDH_open()

§ ECDH_control()

int_fast16_t ECDH_control ( ECDH_Handle  handle,
uint32_t  cmd,
void *  args 
)

Function performs implementation specific features on a given ECDH_Handle.

Commands for ECDH_control can originate from ECC.h or from implementation specific ECC*.h (ECCCC26XX.h, EECCSP432.h, etc.. ) files. While commands from ECC.h are API portable across driver implementations, not all implementations may support all these commands. Conversely, commands from driver implementation specific ECC*.h files add unique driver capabilities but are not API portable across all ECC driver implementations.

Commands supported by ECC.h follow an ECDH_CMD_<cmd> naming convention.
Commands supported by ECC*.h follow an ECC*_CMD_<cmd> naming convention.
Each control command defines arg differently. The types of arg are documented with each command.

See ECDH_control command codes for command codes.

See ECDH_control return status codes for status codes.

Precondition
ECDH_open() has to be called first.
Parameters
handleA ECC handle returned from ECDH_open()
cmdECC.h or ECC*.h commands.
argsAn optional R/W (read/write) command argument accompanied with cmd
Returns
Implementation specific return codes. Negative values indicate unsuccessful operations.
See also
ECDH_open()

§ ECDH_generatePublicKey()

int_fast16_t ECDH_generatePublicKey ( ECDH_Handle  handle,
const ECCParams_CurveParams eccParams,
const CryptoKey myPrivateKey,
CryptoKey myPublicKey 
)

Generates a public key for use in key agreement.

ECDH_generateKey() can be used for generating ephemeral keys.

Parameters
handleA ECC handle returned from ECDH_open()
eccParamsA pointer to the elliptic curve parameters for myPrivateKey
myPrivateKeyA pointer to the private ECC key from which the new public key will be generated. (maybe your static key)
myPublicKeyA pointer to a public ECC key which has been initialized blank. Newly generated key will be placed in this location.
Postcondition
ECDH_computeSharedSecret()

§ ECDH_computeSharedSecret()

int_fast16_t ECDH_computeSharedSecret ( ECDH_Handle  handle,
const ECCParams_CurveParams eccParams,
const CryptoKey myPrivateKey,
const CryptoKey theirPublicKey,
CryptoKey sharedSecret 
)

Computes a shared secret.

This secret can be used to generate shared keys for encryption and authentication.

Parameters
handleA ECC handle returned from ECDH_open()
eccParamsA pointer to the elliptic curve parameters for myPrivateKey (if ECDH_generateKey() was used, this should be the same private key)
myPrivateKeyA pointer to the private ECC key which will be used in to compute the shared secret
theirPublicKeyA pointer to the public key of the party with whom the shared secret will be generated
sharedSecretA pointer to a CryptoKey which has been initialized blank. The shared secret will be placed here.
Postcondition
ECDH_calculateSharedEntropy()

§ ECDH_calculateSharedEntropy()

int_fast16_t ECDH_calculateSharedEntropy ( ECDH_Handle  handle,
const CryptoKey sharedSecret,
const ECDH_KDFFxn  kdf,
void *  kdfPrimitiveDriverHandle,
CryptoKey  derivedKeys[],
uint32_t  derivedKeysCount 
)

Calculates key material.

Precondition
ECDH_computeSharedSecret()
Parameters
handleA ECC handle returned from ECDH_open()
sharedSecretThe shared secret produced by ECDH_calculateSharedEntropy()
kdfA pointer to the key derivation function to be used
kdfPrimitiveDriverHandleA pointer to the handle of a driver of a cryptographic primitive used to implement the KDF
derivedKeysA an array of CryptoKeys to seed with calculated entropy
derivedKeysCountThe number of CryptoKeys to seed with calculated entropy

Variable Documentation

§ ECDH_defaultParams

const ECDH_Params ECDH_defaultParams

Default ECDH_Params structure.

See also
ECDH_Params_init()
Copyright 2017, Texas Instruments Incorporated