Data Structures | Macros | Typedefs | Enumerations | Functions
ECJPAKE.h File Reference

Detailed Description

TI Driver for Elliptic Curve Password Authenticated Key Exchange by Juggling.

Overview

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.

Steps involved

Since the scheme is symmetric, the steps involved will be illustrated using Alice and Bob as relevant parties.

  1. Alice and Bob decide on some pre-shared secret, the password, and negotiate this through some offline means such as during commissioning.
  2. Alice generates private keys x1, x2, v1, and v2 uniformly at random from [1, n - 1], where n is the order of the curve.
  3. Alice generates public keys X1 = x1 * G, X2 = x2 * G, V1 = v1 * G, and V2 = v2 * G.
  4. Alice generates Zero-Knowledge Proofs (ZKPs) for (X1, x1) and (X2, x2). The required hash is computed by concatenating G, V, the public key the ZKP authenticates, and the UserID of the authenticator and hashing the new bitstring. The exact order and formatting of all parameters and any extra information such as length words must be agreed upon by both parties to yield the same result.
  5. Alice sends X1, X2, V1, V2, r1, r2, and her UserID to Bob.
  6. Bob generates private keys x3, x4, v3, and v4 uniformly at random from [1, n - 1], where n is the order of the curve.
  7. Bob generates public keys X3 = x3 * G, X4 = x4 * G, V3 = v3 * G, and V4 = v4 * G.
  8. Bob generates Zero-Knowledge Proofs (ZKPs) for (X3, x3) and (X4, x4).
  9. Bob sends X3, X4, V3, V4, r3, r4, and his UserID to Bob.
  10. Alice and Bob verify the other parties ZKPs and break off the scheme if they do not check out.
  11. Alice computes the new generator point G2 = (X1 + X3 + X4).
  12. Alice computes the combined private key x5 = x2 * s, where s is the pre-shared secret.
  13. Alice computes the combined public key X5 = x5 * G2.
  14. Alice computes a ZKP for (X5, x5) using G2 as the generator point of the ZKP.
  15. Alice sends X5, V5, r5, and her UserID to Bob.
  16. Bob computes the new generator point G3 = (X3 + X1 + X2).
  17. Bob computes the combined private key x6 = x4 * s, where s is the pre-shared secret.
  18. Bob computes the combined public key X6 = x6 * G3.
  19. Bob computes a ZKP for (X6, x6) using G3 as the generator point of the ZKP.
  20. Bob sends X6, V6, r6, and his UserID to Alice.
  21. Alice and Bob verify the other parties ZKPs and break off the scheme if they do not check out. This involves computing the other parties generator point.
  22. Alice computes shared secret K = (X6 - (X4 * x5)) * x2.
  23. Bob computes shared secret K = (X5 - (X2 * x6)) * x4.
  24. Alice and Bob each run K through a mutually agreed upon key derivation function to compute the symmetric session key.

Usage

Before starting an ECJPAKE operation

Before starting an ECJPAKE operation, the application must do the following:

  1. Call ECJPAKE_init() to initialize the driver
  2. Call ECJPAKE_Params_init() to initialize the ECJPAKE_Params to default values.
  3. Modify the ECJPAKE_Params as desired
  4. Call ECJPAKE_open() to open an instance of the driver

Round one

  1. Initialize the following private key CryptoKeys. Seed them with keying material uniformly drawn from [1, n - 1]
    • myPrivateKey1
    • myPrivateKey2
    • myPrivateV1
    • myPrivateV2
  2. Initialize the following blank public key CryptoKeys:
    • myPublicKey1
    • myPublicKey2
    • myPublicV1
    • myPublicV2
    • theirPublicKey1
    • theirPublicKey2
    • theirPublicV1
    • theirPublicV2
  3. Call ECJPAKE_roundOneGenerateKeys() to generate all round one keys as needed.
  4. Generate the hashes for the ZKPs using previously agreed upon formatting. Use the default generator point of the curve in the first round.
  5. Generate your two ZKPs by calling ECJPAKE_generateZKP() once per ZKP.
  6. Exchange public keys, UserIDs, and ZKP signatures. Write the received keying material into the relevant buffers or load them into key stores as specified by the CryptoKeys initialised earlier.
  7. Verify the other party's ZKPs after computing their ZKP hash by calling ECJPAKE_verifyZKP() once per ZKP.
  8. You can now let all V keys, myPrivateKey1, and all ZKP signatures go out of scope and re-use their memory.

Round two

  1. Initialize the following private key CryptoKeys. Seed myPrivateV with keying material uniformly drawn from [1, n - 1]. Initialise the preSharedSecret with the common keying material previously shared between you and the other party.
    • preSharedSecret
    • myCombinedPrivateKey
  2. Initialize the following blank public key CryptoKeys:
    • theirNewGenerator
    • myNewGenerator
    • myCombinedPublicKey
    • myPublicV
  3. Call ECJPAKE_roundTwoGenerateKeys() to generate the remaining round two keys.
  4. Generate the hash for your ZKP use myNewGenerator as your generator point.
  5. Exchange public keys, UserIDs, and ZKP signatures. Write the received keying material into the relevant buffers or load them into key stores as specified by the CryptoKeys initialised earlier.
  6. Verify the other party's ZKP after computing their ZKP hash b calling ECJPAKE_verifyZKP(). Use theirNewGenerator as the generator point for this ZKP.
  7. You can now let all keys and keying material but myCombinedPrivateKey, theirCombinedPublicKey, theirPublicKey2, and myPrivateKey2 go out of scope.

Computing the shared secret

  1. Initialize the following blank public key CryptoKey:
    • sharedSecret
  2. Call ECJPAKE_computeSharedSecret().
  3. Run sharedSecret through a key derivation function to compute the shared symmetric session key.

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 ECJPAKE documentation for curve type (short Weierstrass, Montgomery, Edwards) support for your device. ECJPAKE 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

ECJPAKE Driver Configuration

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

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

The application must declare an array of ECJPAKE_Config elements, named ECJPAKE_config[]. Each element of ECJPAKE_config[] must be populated with pointers to a device specific ECJPAKE driver implementation's driver object, hardware attributes. Each element in ECJPAKE_config[] corresponds to an ECJPAKE instance, and none of the elements should have NULL pointers. There is no correlation between the index and the peripheral designation (such as ECJPAKE0 or ECJPAKE1). For example, it is possible to use ECJPAKE_config[0] for ECJPAKE1. 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 ECJPAKE configuration is highly device dependent, you will need to check the doxygen for the device specific ECJPAKE implementation. There you will find a description of the ECJPAKE hardware attributes. Please also refer to the Board.c file of any of your examples to see the ECJPAKE configuration.

ECJPAKE Parameters

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

Examples

Basic ECJPAKE exchange

// My fixed keying material
uint8_t myPrivateKeyMaterial1[32];
uint8_t myPrivateKeyMaterial2[32];
uint8_t myPrivateVMaterial1[32];
uint8_t myPrivateVMaterial2[32];
uint8_t myPrivateVMaterial3[32];
uint8_t myHash1[32];
uint8_t myHash2[32];
uint8_t myHash3[32];
// My derived keying material
uint8_t myR1[32];
uint8_t myR2[32];
uint8_t myR3[32];
uint8_t myPublicKeyMaterial1[64];
uint8_t myPublicKeyMaterial2[64];
uint8_t myPublicVMaterial1[64];
uint8_t myPublicVMaterial2[64];
uint8_t myPublicVMaterial3[64];
uint8_t myCombinedPublicKeyMaterial1[64];
uint8_t myCombinedPrivateKeyMaterial1[32];
uint8_t myGenerator[64];
// Their fixed keying material
uint8_t theirHash1[32];
uint8_t theirHash2[32];
uint8_t theirHash3[32];
// Their derived keying material
uint8_t theirR1[32];
uint8_t theirR2[32];
uint8_t theirR3[32];
uint8_t theirPublicKeyMaterial1[64];
uint8_t theirPublicKeyMaterial2[64];
uint8_t theirPublicVMaterial1[64];
uint8_t theirPublicVMaterial2[64];
uint8_t theirPublicVMaterial3[64];
uint8_t theirCombinedPublicKeyMaterial1[64];
uint8_t theirGenerator[64];
// Shared secrets
uint8_t preSharedSecretKeyingMaterial[32] = "This is our password";
uint8_t sharedSecretKeyingMaterial1[64];
// CryptoKeys
CryptoKey nistP256GeneratorCryptoKey;
// Pre-Shared Secret Key
CryptoKey preSharedSecretCryptoKey;
// Final shared secret keys
CryptoKey sharedSecretCryptoKey;
// My's keys
CryptoKey myPrivateCryptoKey1;
CryptoKey myPrivateCryptoKey2;
CryptoKey myPrivateCryptoV1;
CryptoKey myPrivateCryptoV2;
CryptoKey myPrivateCryptoV3;
CryptoKey myCombinedPrivateKey;
CryptoKey myPublicCryptoKey1;
CryptoKey myPublicCryptoKey2;
CryptoKey myPublicCryptoV1;
CryptoKey myPublicCryptoV2;
CryptoKey myPublicCryptoV3;
CryptoKey myCombinedPublicKey;
CryptoKey myGeneratorKey;
// Their's Keys
CryptoKey theirPublicCryptoKey1;
CryptoKey theirPublicCryptoKey2;
CryptoKey theirPublicCryptoV1;
CryptoKey theirPublicCryptoV2;
CryptoKey theirPublicCryptoV3;
CryptoKey theirCombinedPublicKey;
CryptoKey theirGeneratorKey;
// NISTP256 generator
// Pre-shared secret
CryptoKeyPlaintext_initKey(&preSharedSecretCryptoKey, preSharedSecretKeyingMaterial, sizeof(preSharedSecretKeyingMaterial));
// Final shared secret key
CryptoKeyPlaintext_initKey(&sharedSecretCryptoKey, sharedSecretKeyingMaterial1, sizeof(sharedSecretKeyingMaterial1));
CryptoKeyPlaintext_initKey(&sharedSecretCryptoKey2, sharedSecretKeyingMaterial2, sizeof(sharedSecretKeyingMaterial2));
// My keys
CryptoKeyPlaintext_initKey(&myPrivateCryptoKey1, myPrivateKeyMaterial1, sizeof(myPrivateKeyMaterial1));
CryptoKeyPlaintext_initKey(&myPrivateCryptoKey2, myPrivateKeyMaterial2, sizeof(myPrivateKeyMaterial2));
CryptoKeyPlaintext_initKey(&myPrivateCryptoV1, myPrivateVMaterial1, sizeof(myPrivateVMaterial1));
CryptoKeyPlaintext_initKey(&myPrivateCryptoV2, myPrivateVMaterial2, sizeof(myPrivateVMaterial2));
CryptoKeyPlaintext_initKey(&myPrivateCryptoV3, myPrivateVMaterial3, sizeof(myPrivateVMaterial3));
CryptoKeyPlaintext_initBlankKey(&myPublicCryptoKey1, myPublicKeyMaterial1, sizeof(myPublicKeyMaterial1));
CryptoKeyPlaintext_initBlankKey(&myPublicCryptoKey2, myPublicKeyMaterial2, sizeof(myPublicKeyMaterial2));
CryptoKeyPlaintext_initBlankKey(&myPublicCryptoV1, myPublicVMaterial1, sizeof(myPublicVMaterial1));
CryptoKeyPlaintext_initBlankKey(&myPublicCryptoV2, myPublicVMaterial2, sizeof(myPublicVMaterial2));
CryptoKeyPlaintext_initBlankKey(&myPublicCryptoV3, myPublicVMaterial3, sizeof(myPublicVMaterial3));
CryptoKeyPlaintext_initBlankKey(&myCombinedPrivateKey, myCombinedPrivateKeyMaterial1, sizeof(myCombinedPrivateKeyMaterial1));
CryptoKeyPlaintext_initBlankKey(&myCombinedPublicKey, myCombinedPublicKeyMaterial1, sizeof(myCombinedPublicKeyMaterial1));
CryptoKeyPlaintext_initBlankKey(&myGeneratorKey, myGenerator, sizeof(myGenerator));
// Their keys
CryptoKeyPlaintext_initBlankKey(&theirPublicCryptoKey1, theirPublicKeyMaterial1, sizeof(theirPublicKeyMaterial1));
CryptoKeyPlaintext_initBlankKey(&theirPublicCryptoKey2, theirPublicKeyMaterial2, sizeof(theirPublicKeyMaterial2));
CryptoKeyPlaintext_initBlankKey(&theirPublicCryptoV1, theirPublicVMaterial1, sizeof(theirPublicVMaterial1));
CryptoKeyPlaintext_initBlankKey(&theirPublicCryptoV2, theirPublicVMaterial2, sizeof(theirPublicVMaterial2));
CryptoKeyPlaintext_initBlankKey(&theirPublicCryptoV3, theirPublicVMaterial3, sizeof(theirPublicVMaterial3));
CryptoKeyPlaintext_initBlankKey(&theirCombinedPublicKey, theirCombinedPublicKeyMaterial1, sizeof(theirCombinedPublicKeyMaterial1));
CryptoKeyPlaintext_initBlankKey(&theirGeneratorKey, theirGenerator, sizeof(theirGenerator));
// Initial driver setup
ECJPAKE_Handle handle = ECJPAKE_open(0, &params);
ECJPAKE_OperationRoundOneGenerateKeys operationRoundOneGenerateKeys;
ECJPAKE_OperationRoundTwoGenerateKeys operationRoundTwoGenerateKeys;
ECJPAKE_OperationGenerateZKP operationGenerateZKP;
ECJPAKE_OperationVerifyZKP operationVerifyZKP;
ECJPAKE_OperationComputeSharedSecret operationComputeSharedSecret;
// Generate my round one keys
ECJPAKE_OperationRoundOneGenerateKeys_init(&operationRoundOneGenerateKeys);
operationRoundOneGenerateKeys.curve = &ECCParams_NISTP256;
operationRoundOneGenerateKeys.myPrivateKey1 = &myPrivateCryptoKey1;
operationRoundOneGenerateKeys.myPrivateKey2 = &myPrivateCryptoKey2;
operationRoundOneGenerateKeys.myPublicKey1 = &myPublicCryptoKey1;
operationRoundOneGenerateKeys.myPublicKey2 = &myPublicCryptoKey2;
operationRoundOneGenerateKeys.myPrivateV1 = &myPrivateCryptoV1;
operationRoundOneGenerateKeys.myPrivateV2 = &myPrivateCryptoV2;
operationRoundOneGenerateKeys.myPublicV1 = &myPublicCryptoV1;
operationRoundOneGenerateKeys.myPublicV2 = &myPublicCryptoV2;
int_fast16_t result = ECJPAKE_roundOneGenerateKeys(handle, &operationRoundOneGenerateKeys);
if (result != ECJPAKE_STATUS_SUCCESS) {
while(1);
}
// Generate hashes here
// generate my round one ZKPs
ECJPAKE_OperationGenerateZKP_init(&operationGenerateZKP);
operationGenerateZKP.curve = &ECCParams_NISTP256;
operationGenerateZKP.myPrivateKey = &myPrivateCryptoKey1;
operationGenerateZKP.myPrivateV = &myPrivateCryptoV1;
operationGenerateZKP.hash = myHash1;
operationGenerateZKP.r = myR1;
result = ECJPAKE_generateZKP(handle, &operationGenerateZKP);
if (result != ECJPAKE_STATUS_SUCCESS) {
while(1);
}
ECJPAKE_OperationGenerateZKP_init(&operationGenerateZKP);
operationGenerateZKP.curve = &ECCParams_NISTP256;
operationGenerateZKP.myPrivateKey = &myPrivateCryptoKey2;
operationGenerateZKP.myPrivateV = &myPrivateCryptoV2;
operationGenerateZKP.hash = myHash2;
operationGenerateZKP.r = myR2;
result = ECJPAKE_generateZKP(handle, &operationGenerateZKP);
if (result != ECJPAKE_STATUS_SUCCESS) {
while(1);
}
// Do ZKP and key transmission here
// Verify their round one ZKPs
// Generate their hashes here
ECJPAKE_OperationVerifyZKP_init(&operationVerifyZKP);
operationVerifyZKP.curve = &ECCParams_NISTP256;
operationVerifyZKP.theirGenerator = &nistP256GeneratorCryptoKey;
operationVerifyZKP.theirPublicKey = &theirPublicCryptoKey1;
operationVerifyZKP.theirPublicV = &theirPublicCryptoV1;
operationVerifyZKP.hash = theirHash1;
operationVerifyZKP.r = theirR1;
result = ECJPAKE_verifyZKP(handle, &operationVerifyZKP);
if (result != ECJPAKE_STATUS_SUCCESS) {
while(1);
}
ECJPAKE_OperationVerifyZKP_init(&operationVerifyZKP);
operationVerifyZKP.curve = &ECCParams_NISTP256;
operationVerifyZKP.theirGenerator = &nistP256GeneratorCryptoKey;
operationVerifyZKP.theirPublicKey = &theirPublicCryptoKey2;
operationVerifyZKP.theirPublicV = &theirPublicCryptoV2;
operationVerifyZKP.hash = theirHash2;
operationVerifyZKP.r = theirR2;
result = ECJPAKE_verifyZKP(handle,&operationVerifyZKP);
if (result != ECJPAKE_STATUS_SUCCESS) {
while(1);
}
// Round two starts now
// Generate my round two keys
ECJPAKE_OperationRoundTwoGenerateKeys_init(&operationRoundTwoGenerateKeys);
operationRoundTwoGenerateKeys.curve = &ECCParams_NISTP256;
operationRoundTwoGenerateKeys.myPrivateKey2 = &myPrivateCryptoKey2;
operationRoundTwoGenerateKeys.myPublicKey1 = &myPublicCryptoKey1;
operationRoundTwoGenerateKeys.myPublicKey2 = &myPublicCryptoKey2;
operationRoundTwoGenerateKeys.theirPublicKey1 = &theirPublicCryptoKey1;
operationRoundTwoGenerateKeys.theirPublicKey2 = &theirPublicCryptoKey2;
operationRoundTwoGenerateKeys.preSharedSecret = &preSharedSecretCryptoKey;
operationRoundTwoGenerateKeys.theirNewGenerator = &theirGeneratorKey;
operationRoundTwoGenerateKeys.myNewGenerator = &myGeneratorKey;
operationRoundTwoGenerateKeys.myCombinedPrivateKey = &myCombinedPrivateKey;
operationRoundTwoGenerateKeys.myCombinedPublicKey = &myCombinedPublicKey;
operationRoundTwoGenerateKeys.myPrivateV = &myPrivateCryptoV3;
operationRoundTwoGenerateKeys.myPublicV = &myPublicCryptoV3;
result = ECJPAKE_roundTwoGenerateKeys(handle, &operationRoundTwoGenerateKeys);
// Generate my round two ZKP
// Generate the round two hash here
ECJPAKE_OperationGenerateZKP_init(&operationGenerateZKP);
operationGenerateZKP.curve = &ECCParams_NISTP256;
operationGenerateZKP.myPrivateKey = &myCombinedPrivateKey;
operationGenerateZKP.myPrivateV = &myPrivateCryptoV3;
operationGenerateZKP.hash = myHash3;
operationGenerateZKP.r = myR3;
result = ECJPAKE_generateZKP(handle, &operationGenerateZKP);
if (result != ECJPAKE_STATUS_SUCCESS) {
while(1);
}
// Exchange keys and ZKPs again
// Verify their second round ZKP
// Generate their round two hash here
ECJPAKE_OperationVerifyZKP_init(&operationVerifyZKP);
operationVerifyZKP.curve = &ECCParams_NISTP256;
operationVerifyZKP.theirGenerator = &theirGeneratorKey;
operationVerifyZKP.theirPublicKey = &theirCombinedPublicKey;
operationVerifyZKP.theirPublicV = &theirPublicCryptoV3;
operationVerifyZKP.hash = theirHash3;
operationVerifyZKP.r = theirR3;
result = ECJPAKE_verifyZKP(handle, &operationVerifyZKP);
if (result != ECJPAKE_STATUS_SUCCESS) {
while(1);
}
// Generate shared secret
ECJPAKE_OperationComputeSharedSecret_init(&operationComputeSharedSecret);
operationComputeSharedSecret.curve = &ECCParams_NISTP256;
operationComputeSharedSecret.myCombinedPrivateKey = &myCombinedPrivateKey;
operationComputeSharedSecret.theirCombinedPublicKey = &theirCombinedPublicKey;
operationComputeSharedSecret.theirPublicKey2 = &theirPublicCryptoKey2;
operationComputeSharedSecret.myPrivateKey2 = &myPrivateCryptoKey2;
operationComputeSharedSecret.sharedSecret = &sharedSecretCryptoKey;
result = ECJPAKE_computeSharedSecret(handle, &operationComputeSharedSecret);
if (result != ECJPAKE_STATUS_SUCCESS) {
while(1);
}
// Run sharedSecretCryptoKey through a key derivation function and
// confirm to the other party that we have derived the same key
#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_CMD_RESERVED   (32)
 
#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_UNDEFINEDCMD   (-2)
 An error status code returned by ECJPAKE_control() for undefined command codes. More...
 
#define ECJPAKE_STATUS_RESOURCE_UNAVAILABLE   (-3)
 An error status code returned if the hardware or software resource is currently unavailable. More...
 
#define ECJPAKE_STATUS_INVALID_PUBLIC_KEY   (-4)
 The public key of the other party is not valid. More...
 
#define ECJPAKE_STATUS_PUBLIC_KEY_NOT_ON_CURVE   (-5)
 The public key of the other party does not lie upon the curve. More...
 
#define ECJPAKE_STATUS_PUBLIC_KEY_LARGER_THAN_PRIME   (-6)
 A coordinate of the public key of the other party is too large. More...
 
#define ECJPAKE_STATUS_POINT_AT_INFINITY   (-7)
 The result of the operation is the point at infinity. More...
 
#define ECJPAKE_STATUS_INVALID_PRIVATE_KEY   (-8)
 The private key passed into the the call is invalid. More...
 
#define ECJPAKE_STATUS_INVALID_PRIVATE_V   (-9)
 The private v passed into the the call is invalid. More...
 

Typedefs

typedef struct ECJPAKE_Config_ECJPAKE_Handle
 A handle that is returned from an ECJPAKE_open() call. More...
 
typedef enum ECJPAKE_ReturnBehavior_ ECJPAKE_ReturnBehavior
 The way in which ECJPAKE function calls return after performing an encryption + authentication or decryption + verification operation. More...
 
typedef struct ECJPAKE_Config_ ECJPAKE_Config
 ECJPAKE Global configuration. More...
 
typedef struct ECJPAKE_OperationRoundOneGenerateKeys_ ECJPAKE_OperationRoundOneGenerateKeys
 Struct containing the parameters required to generate the first round of keys. More...
 
typedef struct ECJPAKE_OperationGenerateZKP_ ECJPAKE_OperationGenerateZKP
 Struct containing the parameters required to generate a ZKP. More...
 
typedef struct ECJPAKE_OperationVerifyZKP_ ECJPAKE_OperationVerifyZKP
 Struct containing the parameters required to verify a ZKP. More...
 
typedef struct ECJPAKE_OperationRoundTwoGenerateKeys_ ECJPAKE_OperationRoundTwoGenerateKeys
 Struct containing the parameters required to generate the second round keys. More...
 
typedef struct ECJPAKE_OperationComputeSharedSecret_ ECJPAKE_OperationComputeSharedSecret
 Struct containing the parameters required to compute the shared secret. More...
 
typedef union ECJPAKE_Operation_ ECJPAKE_Operation
 Union containing pointers to all supported operation structs. More...
 
typedef enum ECJPAKE_OperationType_ ECJPAKE_OperationType
 Enum for the operation types supported by the driver. 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...
 
typedef struct ECJPAKE_Params_ ECJPAKE_Params
 ECJPAKE Parameters. 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...
 
int_fast16_t ECJPAKE_control (ECJPAKE_Handle handle, uint32_t cmd, void *args)
 Function performs implementation specific features on a given ECJPAKE_Handle. More...
 
ECJPAKE_Handle ECJPAKE_open (uint_least8_t index, 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...
 

Typedef Documentation

§ ECJPAKE_Handle

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

§ ECJPAKE_ReturnBehavior

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

§ ECJPAKE_Config

ECJPAKE Global configuration.

The ECJPAKE_Config structure contains a set of pointers used to characterize the ECJPAKE driver implementation.

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

See also
ECJPAKE_init()

§ ECJPAKE_OperationRoundOneGenerateKeys

Struct containing the parameters required to generate the first round of keys.

§ ECJPAKE_OperationGenerateZKP

Struct containing the parameters required to generate a ZKP.

§ ECJPAKE_OperationVerifyZKP

Struct containing the parameters required to verify a ZKP.

§ ECJPAKE_OperationRoundTwoGenerateKeys

Struct containing the parameters required to generate the second round keys.

§ ECJPAKE_OperationComputeSharedSecret

Struct containing the parameters required to compute the shared secret.

§ ECJPAKE_Operation

Union containing pointers to all supported operation structs.

§ ECJPAKE_OperationType

Enum for the operation types supported by the driver.

§ ECJPAKE_CallbackFxn

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.

Parameters
handleHandle of the client that started the ECJPAKE operation.
returnStatusThe result of the ECJPAKE operation. May contain an error code if the result is the point at infinity for example.
operationA 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.
operationTypeThis parameter determined which operation the callback refers to and which type to access through /c operation.

§ ECJPAKE_Params

ECJPAKE Parameters.

ECJPAKE Parameters are used to with the ECJPAKE_open() call. Default values for these parameters are set using ECJPAKE_Params_init().

See also
ECJPAKE_Params_init()

Enumeration Type Documentation

§ ECJPAKE_ReturnBehavior_

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
Enumerator
ECJPAKE_RETURN_BEHAVIOR_CALLBACK 

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

ECJPAKE_RETURN_BEHAVIOR_BLOCKING 

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

ECJPAKE_RETURN_BEHAVIOR_POLLING 

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

§ ECJPAKE_OperationType_

Enum for the operation types supported by the driver.

Enumerator
ECJPAKE_OPERATION_TYPE_ROUND_ONE_GENERATE_KEYS 
ECJPAKE_OPERATION_TYPE_GENERATE_ZKP 
ECJPAKE_OPERATION_TYPE_VERIFY_ZKP 
ECJPAKE_OPERATION_TYPE_ROUND_TWO_GENERATE_KEYS 
ECJPAKE_OPERATION_TYPE_COMPUTE_SHARED_SECRET 

Function Documentation

§ ECJPAKE_init()

void ECJPAKE_init ( void  )

This function initializes the ECJPAKE module.

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

§ ECJPAKE_OperationRoundOneGenerateKeys_init()

void ECJPAKE_OperationRoundOneGenerateKeys_init ( ECJPAKE_OperationRoundOneGenerateKeys operation)

Function to initialize an ECJPAKE_OperationRoundOneGenerateKeys struct to its defaults.

Parameters
operationA pointer to ECJPAKE_OperationRoundOneGenerateKeys structure for initialization

Defaults values are all zeros.

§ ECJPAKE_OperationGenerateZKP_init()

void ECJPAKE_OperationGenerateZKP_init ( ECJPAKE_OperationGenerateZKP operation)

Function to initialize an ECJPAKE_OperationGenerateZKP struct to its defaults.

Parameters
operationA pointer to ECJPAKE_OperationGenerateZKP structure for initialization

Defaults values are all zeros.

§ ECJPAKE_OperationVerifyZKP_init()

void ECJPAKE_OperationVerifyZKP_init ( ECJPAKE_OperationVerifyZKP operation)

Function to initialize an ECJPAKE_OperationVerifyZKP struct to its defaults.

Parameters
operationA pointer to ECJPAKE_OperationVerifyZKP structure for initialization

Defaults values are all zeros.

§ ECJPAKE_OperationRoundTwoGenerateKeys_init()

void ECJPAKE_OperationRoundTwoGenerateKeys_init ( ECJPAKE_OperationRoundTwoGenerateKeys operation)

Function to initialize an ECJPAKE_OperationRoundTwoGenerateKeys struct to its defaults.

Parameters
operationA pointer to ECJPAKE_OperationRoundTwoGenerateKeys structure for initialization

Defaults values are all zeros.

§ ECJPAKE_OperationComputeSharedSecret_init()

void ECJPAKE_OperationComputeSharedSecret_init ( ECJPAKE_OperationComputeSharedSecret operation)

Function to initialize an ECJPAKE_OperationComputeSharedSecret struct to its defaults.

Parameters
operationA pointer to ECJPAKE_OperationComputeSharedSecret structure for initialization

Defaults values are all zeros.

§ ECJPAKE_close()

void ECJPAKE_close ( ECJPAKE_Handle  handle)

Function to close an ECJPAKE peripheral specified by the ECJPAKE handle.

Precondition
ECJPAKE_open() has to be called first.
Parameters
handleAn ECJPAKE handle returned from ECJPAKE_open()
See also
ECJPAKE_open()

§ ECJPAKE_control()

int_fast16_t ECJPAKE_control ( ECJPAKE_Handle  handle,
uint32_t  cmd,
void *  args 
)

Function performs implementation specific features on a given ECJPAKE_Handle.

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

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

See ECJPAKE_control command codes for command codes.

See ECJPAKE_control return status codes for status codes.

Precondition
ECJPAKE_open() has to be called first.
Parameters
handleAn ECJPAKE handle returned from ECJPAKE_open()
cmdECJPAKE.h or ECJPAKE*.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
ECJPAKE_open()

§ ECJPAKE_open()

ECJPAKE_Handle ECJPAKE_open ( uint_least8_t  index,
ECJPAKE_Params params 
)

This function opens a given ECJPAKE peripheral.

Precondition
ECJPAKE controller has been initialized using ECJPAKE_init()
Parameters
indexLogical peripheral number for the ECJPAKE indexed into the ECJPAKE_config table
paramsPointer to an parameter block, if NULL it will use default values.
Returns
An ECJPAKE_Handle on success or a NULL on an error or if it has been opened already.
See also
ECJPAKE_init()
ECJPAKE_close()

§ ECJPAKE_Params_init()

void ECJPAKE_Params_init ( ECJPAKE_Params params)

Function to initialize the ECJPAKE_Params struct to its defaults.

Parameters
paramsAn pointer to ECJPAKE_Params structure for initialization

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

§ ECJPAKE_roundOneGenerateKeys()

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.

Parameters
[in]handleAn ECJPAKE handle returned from ECJPAKE_open()
[in]operationA pointer to a struct containing the requisite parameters to execute the function.
Precondition
Call ECJPAKE_OperationRoundOneGenerateKeys_init() on /c operation.
Postcondition
Generate the two sets of hashes and ZKPs for the two public/private key pairs.

§ ECJPAKE_generateZKP()

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.

Parameters
[in]handleAn ECJPAKE handle returned from ECJPAKE_open()
[in]operationA pointer to a struct containing the requisite parameters to execute the function.
Precondition
If in round one, ECJPAKE_roundOneGenerateKeys() must be called prior. Else, ECJPAKE_roundTwoGenerateKeys() must be called prior. The hash must also have been computed prior to calling this function. Call ECJPAKE_OperationGenerateZKP_init() on /c operation.
Postcondition
Send all ZKP signatures (r, public V, user ID) together with the public keys to the other party.

§ ECJPAKE_verifyZKP()

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.

Parameters
[in]handleAn ECJPAKE handle returned from ECJPAKE_open()
[in]operationA pointer to a struct containing the requisite parameters to execute the function.
Precondition
Receive the relevant ZKP signature parameters. Compute the hash. If in the second round, compute the generator first by calling ECJPAKE_roundTwoGenerateKeys(). Call ECJPAKE_OperationVerifyZKP_init() on /c operation.

§ ECJPAKE_roundTwoGenerateKeys()

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.

Parameters
[in]handleAn ECJPAKE handle returned from ECJPAKE_open()
[in]operationA pointer to a struct containing the requisite parameters to execute the function.
Precondition
Call ECJPAKE_OperationRoundTwoGenerateKeys_init() on /c operation.
Postcondition
Generate the hash and ZKP signature for the second round public/private key.

§ ECJPAKE_computeSharedSecret()

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.

Parameters
[in]handleAn ECJPAKE handle returned from ECJPAKE_open()
[in]operationA pointer to a struct containing the requisite parameters to execute the function.
Precondition
Call ECJPAKE_OperationComputeSharedSecret_init() on /c operation.
Postcondition
The shared secret must be processed by a key derivation function to compute the symmetric session key. It is recommended that the two parties prove to each other that they are in posession of the symmetric session key. While this should be implied by the successful verification of the three ZKPs in the scheme, it is nonetheless good practice.
Copyright 2018, Texas Instruments Incorporated