TI Driver for Elliptic Curve Password Authenticated Key Exchange by Juggling.
Elliptic Curve Password Authenticated Key Exchange by Juggling (EC-JPAKE) is a key agreement scheme that establishes a secure channel over an insecure network. It only requires sharing a password offline and does not require public key infrastructure or trusted third parties such as certificate authorities.
At the end of the EC-JPAKE scheme, both parties derive a shared secret from which a session key is derived.
The scheme is symmetric. Both parties perform the exact same operations to end up with the shared secret.
Since the scheme is symmetric, the steps involved will be illustrated using Alice and Bob as relevant parties.
Before starting an ECJPAKE operation, the application must do the following:
The ECJPAKE API expects the private and public keys to be formatted in octet string format. The details of octet string formatting can be found in SEC 1: Elliptic Curve Cryptography.
Private keys and V's are formatted as big-endian integers of the same length as the curve length.
Public keys, public V's, generator points, and shared secrets are points on an elliptic curve. These points can be expressed in several ways. This API uses points expressed in uncompressed affine coordinates by default. The octet string format requires a formatting byte in the first byte of the public key. When using uncompressed affine coordinates, this is the value 0x04. The point itself is stored as a concatenated array of X followed by Y. X and Y are big-endian. Some implementations do not require or yield the Y coordinate for ECJPAKE on certain curves. It is recommended that the full keying material buffer of twice the curve param length is used to facilitate code-reuse. Implementations that do not use the Y coordinate will zero-out the Y-coordinate whenever they write a point to the 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 | [0x04, X, Y] | 1 + 2 * Curve Param Length |
Montgomery | [0x04, X, Y] | 1 + 2 * Curve Param Length |
Edwards | [0x04, X, Y] | 1 + 2 * Curve Param Length |
The r component of the ZKP signature, hash, and preSharedSecret also all use the octet string format. They are interpreted as big-endian integers.
#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 | ECJPAKE_Config |
ECJPAKE Global configuration. More... | |
struct | ECJPAKE_OperationRoundOneGenerateKeys |
Struct containing the parameters required to generate the first round of keys. More... | |
struct | ECJPAKE_OperationGenerateZKP |
Struct containing the parameters required to generate a ZKP. More... | |
struct | ECJPAKE_OperationVerifyZKP |
Struct containing the parameters required to verify a ZKP. More... | |
struct | ECJPAKE_OperationRoundTwoGenerateKeys |
Struct containing the parameters required to generate the second round keys. More... | |
struct | ECJPAKE_OperationComputeSharedSecret |
Struct containing the parameters required to compute the shared secret. More... | |
union | ECJPAKE_Operation |
Union containing pointers to all supported operation structs. More... | |
struct | ECJPAKE_Params |
ECJPAKE Parameters. More... | |
Macros | |
#define | ECJPAKE_STATUS_RESERVED (-32) |
#define | ECJPAKE_STATUS_SUCCESS (0) |
Successful status code. More... | |
#define | ECJPAKE_STATUS_ERROR (-1) |
Generic error status code. More... | |
#define | ECJPAKE_STATUS_RESOURCE_UNAVAILABLE (-2) |
An error status code returned if the hardware or software resource is currently unavailable. More... | |
#define | ECJPAKE_STATUS_INVALID_PUBLIC_KEY (-3) |
The public key of the other party is not valid. More... | |
#define | ECJPAKE_STATUS_PUBLIC_KEY_NOT_ON_CURVE (-4) |
The public key of the other party does not lie upon the curve. More... | |
#define | ECJPAKE_STATUS_PUBLIC_KEY_LARGER_THAN_PRIME (-5) |
A coordinate of the public key of the other party is too large. More... | |
#define | ECJPAKE_STATUS_POINT_AT_INFINITY (-6) |
The result of the operation is the point at infinity. More... | |
#define | ECJPAKE_STATUS_INVALID_PRIVATE_KEY (-7) |
The private key passed into the the call is invalid. More... | |
#define | ECJPAKE_STATUS_INVALID_PRIVATE_V (-8) |
The private v passed into the the call is invalid. More... | |
#define | ECJPAKE_STATUS_CANCELED (-9) |
The ongoing operation was canceled. More... | |
#define | ECJPAKE_STATUS_OUTPUT_KEY_NOT_BLANK (-10) |
A provided output key was not initialized as blank. More... | |
#define | ECJPAKE_STATUS_KEYSTORE_ERROR (-11) |
KeyStore operation within ECJPAKE failed. More... | |
#define | ECJPAKE_STATUS_NOT_SUPPORTED (-12) |
ECJPAKE operation not supported. More... | |
Typedefs | |
typedef ECJPAKE_Config * | ECJPAKE_Handle |
A handle that is returned from an ECJPAKE_open() call. More... | |
typedef void(* | ECJPAKE_CallbackFxn) (ECJPAKE_Handle handle, int_fast16_t returnStatus, ECJPAKE_Operation operation, ECJPAKE_OperationType operationType) |
The definition of a callback function used by the ECJPAKE driver when used in ECJPAKE_RETURN_BEHAVIOR_CALLBACK. More... | |
Enumerations | |
enum | ECJPAKE_ReturnBehavior { ECJPAKE_RETURN_BEHAVIOR_CALLBACK = 1, ECJPAKE_RETURN_BEHAVIOR_BLOCKING = 2, ECJPAKE_RETURN_BEHAVIOR_POLLING = 4 } |
The way in which ECJPAKE function calls return after performing an encryption + authentication or decryption + verification operation. More... | |
enum | ECJPAKE_OperationType { ECJPAKE_OPERATION_TYPE_ROUND_ONE_GENERATE_KEYS = 1, ECJPAKE_OPERATION_TYPE_GENERATE_ZKP = 2, ECJPAKE_OPERATION_TYPE_VERIFY_ZKP = 3, ECJPAKE_OPERATION_TYPE_ROUND_TWO_GENERATE_KEYS = 4, ECJPAKE_OPERATION_TYPE_COMPUTE_SHARED_SECRET = 5 } |
Enum for the operation types supported by the driver. More... | |
Functions | |
void | ECJPAKE_init (void) |
This function initializes the ECJPAKE module. More... | |
void | ECJPAKE_OperationRoundOneGenerateKeys_init (ECJPAKE_OperationRoundOneGenerateKeys *operation) |
Function to initialize an ECJPAKE_OperationRoundOneGenerateKeys struct to its defaults. More... | |
void | ECJPAKE_OperationGenerateZKP_init (ECJPAKE_OperationGenerateZKP *operation) |
Function to initialize an ECJPAKE_OperationGenerateZKP struct to its defaults. More... | |
void | ECJPAKE_OperationVerifyZKP_init (ECJPAKE_OperationVerifyZKP *operation) |
Function to initialize an ECJPAKE_OperationVerifyZKP struct to its defaults. More... | |
void | ECJPAKE_OperationRoundTwoGenerateKeys_init (ECJPAKE_OperationRoundTwoGenerateKeys *operation) |
Function to initialize an ECJPAKE_OperationRoundTwoGenerateKeys struct to its defaults. More... | |
void | ECJPAKE_OperationComputeSharedSecret_init (ECJPAKE_OperationComputeSharedSecret *operation) |
Function to initialize an ECJPAKE_OperationComputeSharedSecret struct to its defaults. More... | |
void | ECJPAKE_close (ECJPAKE_Handle handle) |
Function to close an ECJPAKE peripheral specified by the ECJPAKE handle. More... | |
ECJPAKE_Handle | ECJPAKE_open (uint_least8_t index, const ECJPAKE_Params *params) |
This function opens a given ECJPAKE peripheral. More... | |
void | ECJPAKE_Params_init (ECJPAKE_Params *params) |
Function to initialize the ECJPAKE_Params struct to its defaults. More... | |
int_fast16_t | ECJPAKE_roundOneGenerateKeys (ECJPAKE_Handle handle, ECJPAKE_OperationRoundOneGenerateKeys *operation) |
Generates all public and private keying material for the first round of the EC-JPAKE scheme. More... | |
int_fast16_t | ECJPAKE_generateZKP (ECJPAKE_Handle handle, ECJPAKE_OperationGenerateZKP *operation) |
Generates the r component of a Schnorr Zero-Knowledge Proof (ZKP) signature. More... | |
int_fast16_t | ECJPAKE_verifyZKP (ECJPAKE_Handle handle, ECJPAKE_OperationVerifyZKP *operation) |
Verifies a Schnorr Zero-Knowledge Proof (ZKP) signature. More... | |
int_fast16_t | ECJPAKE_roundTwoGenerateKeys (ECJPAKE_Handle handle, ECJPAKE_OperationRoundTwoGenerateKeys *operation) |
Generates all public and private keying material for the first round of the EC-JPAKE scheme. More... | |
int_fast16_t | ECJPAKE_computeSharedSecret (ECJPAKE_Handle handle, ECJPAKE_OperationComputeSharedSecret *operation) |
Computes the shared secret. More... | |
int_fast16_t | ECJPAKE_cancelOperation (ECJPAKE_Handle handle) |
Cancels an ongoing ECJPAKE operation. More... | |
ECJPAKE_Handle | ECJPAKE_construct (ECJPAKE_Config *config, const ECJPAKE_Params *params) |
Constructs a new ECJPAKE object. More... | |
#define ECJPAKE_STATUS_RESERVED (-32) |
Common ECJPAKE status code reservation offset. ECJPAKE driver implementations should offset status codes with ECJPAKE_STATUS_RESERVED growing negatively.
Example implementation specific status codes:
#define ECJPAKE_STATUS_SUCCESS (0) |
Successful status code.
Functions return ECJPAKE_STATUS_SUCCESS if the function was executed successfully.
#define ECJPAKE_STATUS_ERROR (-1) |
Generic error status code.
Functions return ECJPAKE_STATUS_ERROR if the function was not executed successfully.
#define ECJPAKE_STATUS_RESOURCE_UNAVAILABLE (-2) |
An error status code returned if the hardware or software resource is currently unavailable.
ECJPAKE 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 ECJPAKE_STATUS_INVALID_PUBLIC_KEY (-3) |
The public key of the other party is not valid.
The public key received from the other party is not valid.
#define ECJPAKE_STATUS_PUBLIC_KEY_NOT_ON_CURVE (-4) |
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 ECJPAKE_STATUS_PUBLIC_KEY_LARGER_THAN_PRIME (-5) |
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 ECJPAKE_STATUS_POINT_AT_INFINITY (-6) |
The result of the operation is the point at infinity.
The operation yielded the point at infinity on this curve. This point is not permitted for further use in ECC operations.
#define ECJPAKE_STATUS_INVALID_PRIVATE_KEY (-7) |
The private key passed into the the call is invalid.
Private keys must be integers in the interval [1, n - 1], where n is the order of the curve.
#define ECJPAKE_STATUS_INVALID_PRIVATE_V (-8) |
The private v passed into the the call is invalid.
Private v must be integers in the interval [1, n - 1], where n is the order of the curve.
#define ECJPAKE_STATUS_CANCELED (-9) |
The ongoing operation was canceled.
#define ECJPAKE_STATUS_OUTPUT_KEY_NOT_BLANK (-10) |
A provided output key was not initialized as blank.
#define ECJPAKE_STATUS_KEYSTORE_ERROR (-11) |
KeyStore operation within ECJPAKE failed.
#define ECJPAKE_STATUS_NOT_SUPPORTED (-12) |
ECJPAKE operation not supported.
typedef ECJPAKE_Config* ECJPAKE_Handle |
A handle that is returned from an ECJPAKE_open() call.
typedef void(* ECJPAKE_CallbackFxn) (ECJPAKE_Handle handle, int_fast16_t returnStatus, ECJPAKE_Operation operation, ECJPAKE_OperationType operationType) |
The definition of a callback function used by the ECJPAKE driver when used in ECJPAKE_RETURN_BEHAVIOR_CALLBACK.
handle | Handle of the client that started the ECJPAKE operation. |
returnStatus | The result of the ECJPAKE operation. May contain an error code if the result is the point at infinity for example. |
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. |
operationType | This parameter determined which operation the callback refers to and which type to access through /c operation. |
The way in which ECJPAKE function calls return after performing an encryption + authentication or decryption + verification operation.
Not all ECJPAKE 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.
ECJPAKE functions exhibiting the specified return behavior have restrictions on the context from which they may be called.
Task | Hwi | Swi | |
---|---|---|---|
ECJPAKE_RETURN_BEHAVIOR_CALLBACK | X | X | X |
ECJPAKE_RETURN_BEHAVIOR_BLOCKING | X | ||
ECJPAKE_RETURN_BEHAVIOR_POLLING | X | X | X |
void ECJPAKE_init | ( | void | ) |
This function initializes the ECJPAKE module.
void ECJPAKE_OperationRoundOneGenerateKeys_init | ( | ECJPAKE_OperationRoundOneGenerateKeys * | operation | ) |
Function to initialize an ECJPAKE_OperationRoundOneGenerateKeys struct to its defaults.
operation | A pointer to ECJPAKE_OperationRoundOneGenerateKeys structure for initialization |
Defaults values are all zeros.
void ECJPAKE_OperationGenerateZKP_init | ( | ECJPAKE_OperationGenerateZKP * | operation | ) |
Function to initialize an ECJPAKE_OperationGenerateZKP struct to its defaults.
operation | A pointer to ECJPAKE_OperationGenerateZKP structure for initialization |
Defaults values are all zeros.
void ECJPAKE_OperationVerifyZKP_init | ( | ECJPAKE_OperationVerifyZKP * | operation | ) |
Function to initialize an ECJPAKE_OperationVerifyZKP struct to its defaults.
operation | A pointer to ECJPAKE_OperationVerifyZKP structure for initialization |
Defaults values are all zeros.
void ECJPAKE_OperationRoundTwoGenerateKeys_init | ( | ECJPAKE_OperationRoundTwoGenerateKeys * | operation | ) |
Function to initialize an ECJPAKE_OperationRoundTwoGenerateKeys struct to its defaults.
operation | A pointer to ECJPAKE_OperationRoundTwoGenerateKeys structure for initialization |
Defaults values are all zeros.
void ECJPAKE_OperationComputeSharedSecret_init | ( | ECJPAKE_OperationComputeSharedSecret * | operation | ) |
Function to initialize an ECJPAKE_OperationComputeSharedSecret struct to its defaults.
operation | A pointer to ECJPAKE_OperationComputeSharedSecret structure for initialization |
Defaults values are all zeros.
void ECJPAKE_close | ( | ECJPAKE_Handle | handle | ) |
Function to close an ECJPAKE peripheral specified by the ECJPAKE handle.
handle | An ECJPAKE handle returned from ECJPAKE_open() |
ECJPAKE_Handle ECJPAKE_open | ( | uint_least8_t | index, |
const ECJPAKE_Params * | params | ||
) |
This function opens a given ECJPAKE peripheral.
index | Logical peripheral number for the ECJPAKE indexed into the ECJPAKE_config table |
params | Pointer to an parameter block, if NULL it will use default values. |
void ECJPAKE_Params_init | ( | ECJPAKE_Params * | params | ) |
Function to initialize the ECJPAKE_Params struct to its defaults.
params | An pointer to ECJPAKE_Params structure for initialization |
Defaults values are: returnBehavior = ECJPAKE_RETURN_BEHAVIOR_BLOCKING callbackFxn = NULL timeout = SemaphoreP_WAIT_FOREVER custom = NULL
int_fast16_t ECJPAKE_roundOneGenerateKeys | ( | ECJPAKE_Handle | handle, |
ECJPAKE_OperationRoundOneGenerateKeys * | operation | ||
) |
Generates all public and private keying material for the first round of the EC-JPAKE scheme.
This function generates all public and private keying material required for the first round of the EC-JPAKE scheme.
[in] | handle | An ECJPAKE handle returned from ECJPAKE_open() |
[in] | operation | A pointer to a struct containing the requisite parameters to execute the function. |
ECJPAKE_STATUS_SUCCESS | The operation succeeded. |
ECJPAKE_STATUS_ERROR | The operation failed. |
ECJPAKE_STATUS_RESOURCE_UNAVAILABLE | The required hardware resource was not available. Try again later. |
ECJPAKE_STATUS_CANCELED | The operation was canceled. |
ECJPAKE_STATUS_POINT_AT_INFINITY | The computed public key is the point at infinity. |
ECJPAKE_STATUS_INVALID_PRIVATE_KEY | The private key passed into the the call is invalid. |
ECJPAKE_STATUS_INVALID_PRIVATE_V | The private v passed into the the call is invalid. |
ECJPAKE_STATUS_KEYSTORE_ERROR | The keystore operation to retrieve or store the keys failed. |
ECJPAKE_STATUS_NOT_SUPPORTED | The driver does not support persistent keystore keys. |
int_fast16_t ECJPAKE_generateZKP | ( | ECJPAKE_Handle | handle, |
ECJPAKE_OperationGenerateZKP * | operation | ||
) |
Generates the r
component of a Schnorr Zero-Knowledge Proof (ZKP) signature.
This function generates the r
component of a ZKP using the hash and private keys. The hash must be computed prior. This function does not compute the hash for the application. There is no strictly defined bit-level implementation guideline for generating the hash in the EC-JPAKE scheme. Hence, interoperability could not be guaranteed between different EC-JPAKE implementations. Usually, the hash will be a concatenation of the public V, public key, generator point, and user ID. There may be other components such as length fields mixed in.
[in] | handle | An ECJPAKE handle returned from ECJPAKE_open() |
[in] | operation | A pointer to a struct containing the requisite parameters to execute the function. |
r
, public V, user ID) together with the public keys to the other party.ECJPAKE_STATUS_SUCCESS | The operation succeeded. |
ECJPAKE_STATUS_ERROR | The operation failed. |
ECJPAKE_STATUS_RESOURCE_UNAVAILABLE | The required hardware resource was not available. Try again later. |
ECJPAKE_STATUS_CANCELED | The operation was canceled. |
ECJPAKE_STATUS_KEYSTORE_ERROR | The keystore operation to retrieve or store the keys failed. |
int_fast16_t ECJPAKE_verifyZKP | ( | ECJPAKE_Handle | handle, |
ECJPAKE_OperationVerifyZKP * | operation | ||
) |
Verifies a Schnorr Zero-Knowledge Proof (ZKP) signature.
This function computes if a received Schnorr ZKP correctly verifies a received public key.
[in] | handle | An ECJPAKE handle returned from ECJPAKE_open() |
[in] | operation | A pointer to a struct containing the requisite parameters to execute the function. |
ECJPAKE_STATUS_SUCCESS | The operation succeeded. |
ECJPAKE_STATUS_ERROR | The operation failed. Signature did not verify correctly. |
ECJPAKE_STATUS_RESOURCE_UNAVAILABLE | The required hardware resource was not available. Try again later. |
ECJPAKE_STATUS_CANCELED | The operation was canceled. |
ECJPAKE_STATUS_PUBLIC_KEY_NOT_ON_CURVE | The public key of the other party does not lie upon the curve. |
ECJPAKE_STATUS_PUBLIC_KEY_LARGER_THAN_PRIME | A coordinate of the public key of the other party is too large. |
ECJPAKE_STATUS_KEYSTORE_ERROR | The keystore operation to retrieve or store the keys failed. |
int_fast16_t ECJPAKE_roundTwoGenerateKeys | ( | ECJPAKE_Handle | handle, |
ECJPAKE_OperationRoundTwoGenerateKeys * | operation | ||
) |
Generates all public and private keying material for the first round of the EC-JPAKE scheme.
This function generates all public and private keying material required for the first round of the EC-JPAKE scheme.
[in] | handle | An ECJPAKE handle returned from ECJPAKE_open() |
[in] | operation | A pointer to a struct containing the requisite parameters to execute the function. |
ECJPAKE_STATUS_SUCCESS | The operation succeeded. |
ECJPAKE_STATUS_ERROR | The operation failed. |
ECJPAKE_STATUS_RESOURCE_UNAVAILABLE | The required hardware resource was not available. Try again later. |
ECJPAKE_STATUS_CANCELED | The operation was canceled. |
ECJPAKE_STATUS_INVALID_PRIVATE_KEY | The private key passed into the the call is invalid. |
ECJPAKE_STATUS_INVALID_PRIVATE_V | The private v passed into the the call is invalid. |
ECJPAKE_STATUS_KEYSTORE_ERROR | The keystore operation to retrieve or store the keys failed. |
ECJPAKE_STATUS_NOT_SUPPORTED | The driver does not support persistent keystore keys. |
int_fast16_t ECJPAKE_computeSharedSecret | ( | ECJPAKE_Handle | handle, |
ECJPAKE_OperationComputeSharedSecret * | operation | ||
) |
Computes the shared secret.
This function computes the shared secret between both parties. The shared secret is a point on the elliptic curve and is used to further derive the symmetric session key via a key derivation function.
[in] | handle | An ECJPAKE handle returned from ECJPAKE_open() |
[in] | operation | A pointer to a struct containing the requisite parameters to execute the function. |
ECJPAKE_STATUS_SUCCESS | The operation succeeded. |
ECJPAKE_STATUS_ERROR | The operation failed. |
ECJPAKE_STATUS_RESOURCE_UNAVAILABLE | The required hardware resource was not available. Try again later. |
ECJPAKE_STATUS_CANCELED | The operation was canceled. |
ECJPAKE_STATUS_KEYSTORE_ERROR | The keystore operation to retrieve or store the keys failed. |
ECJPAKE_STATUS_NOT_SUPPORTED | The driver does not support persistent keystore keys. |
int_fast16_t ECJPAKE_cancelOperation | ( | ECJPAKE_Handle | handle | ) |
Cancels an ongoing ECJPAKE operation.
Asynchronously cancels an ECJPAKE operation. Only available when using ECJPAKE_RETURN_BEHAVIOR_CALLBACK or ECJPAKE_RETURN_BEHAVIOR_BLOCKING. The operation will terminate as though an error occured. The return status code of the operation will be ECJPAKE_STATUS_CANCELED.
handle | Handle of the operation to cancel |
ECJPAKE_STATUS_SUCCESS | The operation was canceled. |
ECJPAKE_STATUS_ERROR | The operation was not canceled. There may be no operation to cancel. |
ECJPAKE_Handle ECJPAKE_construct | ( | ECJPAKE_Config * | config, |
const ECJPAKE_Params * | params | ||
) |
Constructs a new ECJPAKE object.
Unlike ECJPAKE_open(), ECJPAKE_construct() does not require the hwAttrs and object to be allocated in a ECJPAKE_Config array that is indexed into. Instead, the ECJPAKE_Config, hwAttrs, and object can be allocated at any location. This allows for relatively simple run-time allocation of temporary driver instances on the stack or the heap. The drawback is that this makes it more difficult to write device-agnostic code. If you use an ifdef with DeviceFamily, you can choose the correct object and hwAttrs to allocate. That compilation unit will be tied to the device it was compiled for at this point. To change devices, recompilation of the application with a different DeviceFamily setting is necessary.
config | ECJPAKE_Config describing the location of the object and hwAttrs. |
params | ECJPAKE_Params to configure the driver instance. |
config
points to must be zeroed out prior to calling this function. Otherwise, unexpected behavior may ensue.