knx/examples/knx-cc1310/coresdk_cc13xx_cc26xx/source/ti/drivers/ECJPAKE.h
nanosonde d90843ba45
Add support for CC1310 platform based on SimpleLink SDK (#94)
* Initial commit

* Clean up

* Remove display code

* Change cmake build

* Add SimpleLink SDK for CC13xx/CC26xx as submodule

* Remove commented line from build.sh

* Working build

* Remove SDK submodule

* Squashed 'examples/knx-cc1310/coresdk_cc13xx_cc26xx/' content from commit 0d78d32

git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx
git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5

* Add more comments and enable Power_idleFunc() for NoRTOS variant.
Internal SDK driver functions which have to wait for something
will cause Power_idleFunc to be called instead of doing busy wait.

* Move CC1310 platform init around

* Optimize a bit more in debug build config as the binary does not fit into 128Kb flash otherwise.

* Explicitly list each source/header file in build config. Use linker group to resolve circular dependencies.

* Ignore vscode settings.json

* Increase stacks size

* Only compile CC1310 source code if #define DeviceFamily_CC13X0

* initial commit of CC1310 RF driver with first working RX version

* Better handling of buttonUp() across platforms

* Start cleanup

* continue cleanup

* Fix bau2920 compilation

* Continue cleanup

* Fix compilation in other examples

* Fix compilation

* htons() and ntohs() only for SAMD and STM32, but not for Linux and ESP8266 and ESP32

* htons(9 and ntohs() needed for CC13x0

* Continue cleanup

* Add CC1310 platform to CI

* Fix CI

* Use more recent toolchain from ARM

* Fix travis

* Use Ubuntu Focal

* Fix toolchain for travis

* Fix package name

* Fix toolchain

* Add libstdc++-dev package

* Add newlib packages

* Remove commented commands from CI

* Fix travis

* Fix compilation of knxPython

* Clean up linefeeds

* Fix RX callback

* Move RF CRC16-DNP to bits.cpp

* Fix TX

* Optimization: do not calc CRC for block1 again in rf_data_link_layer

* Make newline optional in printHex

* Cleanup. First working version: ETS5 programming of individual address via KNX/RF coupler.

* Use LEDs and Buttons to control ProgMode and Flash Erase

* Remove settings.json (VScode)

* Add README.md

* Update README.md

* Update README.md

* Fix typo
2020-11-10 21:52:38 +01:00

1340 lines
67 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 ECJPAKE.h
*
* @brief TI Driver for Elliptic Curve Password Authenticated Key Exchange
* by Juggling.
*
* @anchor ti_drivers_ECJPAKE_Overview
* # 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.
*
* -# Alice and Bob decide on some pre-shared secret, the password, and
* negotiate this through some offline means such as during commissioning.
*
* -# Alice generates private keys x1, x2, v1, and v2 uniformly at random from [1, n - 1],
* where n is the order of the curve.
* -# Alice generates public keys X1 = x1 * G, X2 = x2 * G, V1 = v1 * G, and V2 = v2 * G.
* -# 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.
* -# Alice sends X1, X2, V1, V2, r1, r2, and her UserID to Bob.
*
* -# Bob generates private keys x3, x4, v3, and v4 uniformly at random from [1, n - 1],
* where n is the order of the curve.
* -# Bob generates public keys X3 = x3 * G, X4 = x4 * G, V3 = v3 * G, and V4 = v4 * G.
* -# Bob generates Zero-Knowledge Proofs (ZKPs) for (X3, x3) and (X4, x4).
* -# Bob sends X3, X4, V3, V4, r3, r4, and his UserID to Bob.
*
* -# Alice and Bob verify the other parties ZKPs and break off the scheme if they
* do not check out.
*
* -# Alice computes the new generator point G2 = (X1 + X3 + X4).
* -# Alice computes the combined private key x5 = x2 * s, where s is the pre-shared
* secret.
* -# Alice computes the combined public key X5 = x5 * G2.
* -# Alice computes a ZKP for (X5, x5) using G2 as the generator point of the ZKP.
* -# Alice sends X5, V5, r5, and her UserID to Bob.
*
* -# Bob computes the new generator point G3 = (X3 + X1 + X2).
* -# Bob computes the combined private key x6 = x4 * s, where s is the pre-shared
* secret.
* -# Bob computes the combined public key X6 = x6 * G3.
* -# Bob computes a ZKP for (X6, x6) using G3 as the generator point of the ZKP.
* -# Bob sends X6, V6, r6, and his UserID to Alice.
*
* -# 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.
*
* -# Alice computes shared secret K = (X6 - (X4 * x5)) * x2.
*
* -# Bob computes shared secret K = (X5 - (X2 * x6)) * x4.
*
* -# Alice and Bob each run K through a mutually agreed upon key derivation
* function to compute the symmetric session key.
*
* @anchor ti_drivers_ECJPAKE_Usage
* # Usage #
*
* ## Before starting an ECJPAKE operation #
*
* Before starting an ECJPAKE operation, the application must do the following:
* -# Call ECJPAKE_init() to initialize the driver
* -# Call ECJPAKE_Params_init() to initialize the ECJPAKE_Params to default values.
* -# Modify the ECJPAKE_Params as desired
* -# Call ECJPAKE_open() to open an instance of the driver
*
* ## Round one #
* -# Initialize the following private key CryptoKeys.
* Seed them with keying material uniformly drawn from [1, n - 1]
* - myPrivateKey1
* - myPrivateKey2
* - myPrivateV1
* - myPrivateV2
* -# Initialize the following blank public key CryptoKeys:
* - myPublicKey1
* - myPublicKey2
* - myPublicV1
* - myPublicV2
* - theirPublicKey1
* - theirPublicKey2
* - theirPublicV1
* - theirPublicV2
* -# Call ECJPAKE_roundOneGenerateKeys() to generate all round one keys as needed.
* -# Generate the hashes for the ZKPs using previously agreed upon formatting.
* Use the default generator point of the curve in the first round.
* -# Generate your two ZKPs by calling ECJPAKE_generateZKP() once per ZKP.
* -# 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.
* -# Verify the other party's ZKPs after computing their ZKP hash by calling
* ECJPAKE_verifyZKP() once per ZKP.
* -# You can now let all V keys, myPrivateKey1, and all ZKP signatures go out of scope
* and re-use their memory.
*
* ## Round two #
* -# 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
* -# Initialize the following blank public key CryptoKeys:
* - theirNewGenerator
* - myNewGenerator
* - myCombinedPublicKey
* - myPublicV
* -# Call ECJPAKE_roundTwoGenerateKeys() to generate the remaining round two keys.
* -# Generate the hash for your ZKP use myNewGenerator as your generator point.
* -# 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.
* -# Verify the other party's ZKP after computing their ZKP hash b calling
* ECJPAKE_verifyZKP(). Use theirNewGenerator as the generator point for this
* ZKP.
* -# You can now let all keys and keying material but myCombinedPrivateKey,
* theirCombinedPublicKey, theirPublicKey2, and myPrivateKey2 go out of scope.
*
* ## Computing the shared secret #
* -# Initialize the following blank public key CryptoKey:
* - sharedSecret
* -# Call ECJPAKE_computeSharedSecret().
* -# 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 |
*
* @anchor ti_drivers_ECJPAKE_Synopsis
* ## Synopsis
*
* @anchor ti_drivers_ECJPAKE_Synopsis_Code
* @code
* // Import ECJPAKE Driver definitions
* #include <ti/drivers/ECJPAKE.h>
*
* ECJPAKE_init();
*
* // Since we are using default ECJPAKE_Params, we just pass in NULL for that parameter.
* ecjpakeHandle = ECJPAKE_open(0, NULL);
* 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;
*
* result = ECJPAKE_roundOneGenerateKeys(handle, &operationRoundOneGenerateKeys);
*
* // 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);
*
* 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);
*
* // 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);
*
* 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);
*
* // 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);
*
* // 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);
*
* // 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);
*
* // Close the driver
* ECJPAKE_close(handle);
* @endcode
*
* @anchor ti_drivers_ECJPAKE_Examples
* # Examples #
*
* ## Basic ECJPAKE exchange #
*
* @code
*
*
* // 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
* CryptoKeyPlaintext_initKey(&nistP256GeneratorCryptoKey, ECCParams_NISTP256.generatorX, sizeof(ECCParams_NISTP256.length * 2));
*
* // 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_Params params;
* ECJPAKE_Params_init(&params);
*
*
* 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
*
*
* @endcode
*
*
*/
#ifndef ti_drivers_ECJPAKE__include
#define ti_drivers_ECJPAKE__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 ECJPAKE status code reservation offset.
* ECJPAKE driver implementations should offset status codes with
* ECJPAKE_STATUS_RESERVED growing negatively.
*
* Example implementation specific status codes:
* @code
* #define ECJPAKEXYZ_STATUS_ERROR0 ECJPAKE_STATUS_RESERVED - 0
* #define ECJPAKEXYZ_STATUS_ERROR1 ECJPAKE_STATUS_RESERVED - 1
* #define ECJPAKEXYZ_STATUS_ERROR2 ECJPAKE_STATUS_RESERVED - 2
* @endcode
*/
#define ECJPAKE_STATUS_RESERVED (-32)
/*!
* @brief Successful status code.
*
* Functions return ECJPAKE_STATUS_SUCCESS if the function was executed
* successfully.
*/
#define ECJPAKE_STATUS_SUCCESS (0)
/*!
* @brief Generic error status code.
*
* Functions return ECJPAKE_STATUS_ERROR if the function was not executed
* successfully.
*/
#define ECJPAKE_STATUS_ERROR (-1)
/*!
* @brief 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_RESOURCE_UNAVAILABLE (-2)
/*!
* @brief The public key of the other party is not valid.
*
* The public key received from the other party is not valid.
*/
#define ECJPAKE_STATUS_INVALID_PUBLIC_KEY (-3)
/*!
* @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 ECJPAKE_STATUS_PUBLIC_KEY_NOT_ON_CURVE (-4)
/*!
* @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 ECJPAKE_STATUS_PUBLIC_KEY_LARGER_THAN_PRIME (-5)
/*!
* @brief 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_POINT_AT_INFINITY (-6)
/*!
* @brief 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_KEY (-7)
/*!
* @brief 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_INVALID_PRIVATE_V (-8)
/*!
* @brief The ongoing operation was canceled.
*/
#define ECJPAKE_STATUS_CANCELED (-9)
/*!
* @brief A handle that is returned from an ECJPAKE_open() call.
*/
typedef struct ECJPAKE_Config *ECJPAKE_Handle;
/*!
* @brief 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 |
*
*/
typedef enum {
ECJPAKE_RETURN_BEHAVIOR_CALLBACK = 1, /*!< 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 = 2, /*!< 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 = 4, /*!< 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_ReturnBehavior;
/*!
* @brief 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.
*
* @sa ECJPAKE_init()
*/
typedef struct ECJPAKE_Config {
/*! Pointer to a driver specific data object */
void *object;
/*! Pointer to a driver specific hardware attributes structure */
void const *hwAttrs;
} ECJPAKE_Config;
/*!
* @brief Struct containing the parameters required to generate the first round of keys.
*/
typedef struct {
const ECCParams_CurveParams *curve; /*!< A pointer to the elliptic curve parameters
* used in the operation.
*/
CryptoKey *myPrivateKey1; /*!< A pointer to a private ECC key. Must
* be of the same length as other params
* of the curve used.
*/
CryptoKey *myPrivateKey2; /*!< A pointer to a private ECC key. Must
* be of the same length as other params
* of the curve used.
*/
CryptoKey *myPublicKey1; /*!< A pointer to the blank public key of \c
* myPrivateKey1. The keying material will be
* written to the buffer specified in the
* CryptoKey.
*/
CryptoKey *myPublicKey2; /*!< A pointer to the blank public key of \c
* myPrivateKey2. The keying material will be
* written to the buffer specified in the
* CryptoKey.
*/
CryptoKey *myPrivateV1; /*!< A pointer to a private ECC key used in the
* first Schnorr ZKP.
* Must be of the same length as other params
* of the curve used. The CryptoKey and keying material
* may be deleted or go out of scope after
* generating the ZKP.
*/
CryptoKey *myPrivateV2; /*!< A pointer to a private ECC key used in the
* second Schnorr ZKP.
* Must be of the same length as other params
* of the curve used. The CryptoKey and keying material
* may be deleted or go out of scope after
* generating the ZKP.
*/
CryptoKey *myPublicV1; /*!< A pointer to the blank public key of \c
* myPrivateV1. The keying material will be
* written to the buffer specified in the
* CryptoKey. The CryptoKey and keying material
* may be deleted or go out of scope after
* generating the hash and sending \c myPublicV2
* to the other party with the rest of the
* parameters.
*/
CryptoKey *myPublicV2; /*!< A pointer to the blank public key of \c
* myPrivateV2. The keying material will be
* written to the buffer specified in the
* CryptoKey. The CryptoKey and keying material
* may be deleted or go out of scope after
* generating the hash and sending \c myPublicV2
* to the other party with the rest of the
* parameters.
*/
} ECJPAKE_OperationRoundOneGenerateKeys;
/*!
* @brief Struct containing the parameters required to generate a ZKP.
*/
typedef struct {
const ECCParams_CurveParams *curve; /*!< A pointer to the elliptic curve parameters
* used in the operation.
*/
const CryptoKey *myPrivateKey; /*!< A pointer to a private ECC key to be signed. Must
* be of the same length as other params
* of the curve used.
*/
const CryptoKey *myPrivateV; /*!< A pointer to a private ECC key that will be
* used only to generate a ZKP signature.
* 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 of the same length as other params
* of the curve used.
*/
uint8_t *r; /*!< A pointer to where the r component of the
* ZKP will be written to.
*/
} ECJPAKE_OperationGenerateZKP;
/*!
* @brief Struct containing the parameters required to verify a ZKP.
*/
typedef struct {
const ECCParams_CurveParams *curve; /*!< A pointer to the elliptic curve parameters
* used in the operation.
*/
const CryptoKey *theirGenerator; /*!< A CryptoKey describing the generator point
* to be used. In the first round, this will
* be the default generator of the curve.
* In the second round, this parameter is
* computed by ECJPAKE_roundTwoGenerateKeys().
*/
const CryptoKey *theirPublicKey; /*!< A CryptoKey describing the public key
* received from the other party that the
* ZKP to be verified supposedly signed.
*/
const CryptoKey *theirPublicV; /*!< A CryptoKey describing the public V of the
* ZKP. Received from the other party.
*/
const uint8_t *hash; /*!< The hash of the ZKP generated as the
* other party generated it to compute r.
*/
const uint8_t *r; /*!< R component of the ZKP signature. Received
* from the other party.
*/
} ECJPAKE_OperationVerifyZKP;
/*!
* @brief Struct containing the parameters required to generate the second round keys.
*/
typedef struct {
const ECCParams_CurveParams *curve; /*!< A pointer to the elliptic curve parameters
* used in the operation.
*/
const CryptoKey *myPrivateKey2; /*!< A pointer to a private ECC key. Must
* be of the same length as other params
* of the curve used. Generated in round one.
*/
const CryptoKey *myPublicKey1; /*!< A pointer to the public key of
* myPrivateKey1. Generated in round one.
*/
const CryptoKey *myPublicKey2; /*!< A pointer to the second public key.
* Generated in round one.
*/
const CryptoKey *theirPublicKey1; /*!< A CryptoKey describing the first public key
* received from the other party.
*/
const CryptoKey *theirPublicKey2; /*!< A CryptoKey describing the second public key
* received from the other party.
*/
const CryptoKey *preSharedSecret; /*!< A CryptoKey describing the secret shared between
* the two parties prior to starting the scheme.
* This exchange would have happened through some
* offline commissioning scheme most likely.
* The driver expects an integer of the same length
* as the curve parameters of the curve in use as
* keying material even if the original pre-shared
* secret is shorter than this length.
*/
CryptoKey *theirNewGenerator; /*!< A blank CryptoKey describing the generator point
* used by the other party in the second round.
* After it is computed, the keying material will
* be written to the location described in the
* CryptoKey.
*/
CryptoKey *myNewGenerator; /*!< A blank CryptoKey describing the generator point
* used by the application in the second round.
* After it is computed, the keying material will
* be written to the location described in the
* CryptoKey.
*/
CryptoKey *myCombinedPrivateKey; /*!< A pointer to a public ECC key. Must
* be of the same length as other params
* of the curve used. Result of multiplying
* \c myCombinedPrivateKey by \c myNewGenerator.
*/
CryptoKey *myCombinedPublicKey; /*!< A pointer to a public ECC key. Result of multiplying
* \c myCombinedPrivateKey by \c myNewGenerator.
*/
CryptoKey *myPrivateV; /*!< A pointer to a private ECC key used in the
* only second-round Schnorr ZKP.
* Must be of the same length as other params
* of the curve used. The CryptoKey and keying material
* may be deleted or go out of scope after
* generating the ZKP.
*/
CryptoKey *myPublicV; /*!< A pointer to the blank public key of \c
* myPrivateV. The keying material will be
* written to the buffer specified in the
* CryptoKey. The CryptoKey and keying material
* may be deleted or go out of scope after
* generating the hash and sending \c myPublicV2
* to the other party with the rest of the
* parameters.
*/
} ECJPAKE_OperationRoundTwoGenerateKeys;
/*!
* @brief Struct containing the parameters required to compute the shared secret.
*/
typedef struct {
const ECCParams_CurveParams *curve; /*!< A pointer to the elliptic curve parameters
* used in the operation.
*/
const CryptoKey *myCombinedPrivateKey; /*!< A pointer to a private ECC key. Must
* be of the same length as other params
* of the curve used. Generated in round one.
*/
const CryptoKey *theirCombinedPublicKey; /*!< A CryptoKey describing the second public key
* received from the other party.
*/
const CryptoKey *theirPublicKey2; /*!< A pointer to a private ECC key. Must
* be of the same length as other params
* of the curve used. Result of multiplying
* \c myPrivateKey2 by \c preSharedSecret.
*/
const CryptoKey *myPrivateKey2; /*!< Combined public key received in the second
* round and verified by the application against
* the second round ZKP signature.
*/
CryptoKey *sharedSecret; /*!< The shared secret that is identical between both
* parties.
*/
} ECJPAKE_OperationComputeSharedSecret;
/*!
* @brief Union containing pointers to all supported operation structs.
*/
typedef union {
ECJPAKE_OperationRoundOneGenerateKeys *generateRoundOneKeys; /*!< A pointer to an ECJPAKE_OperationRoundOneGenerateKeys struct */
ECJPAKE_OperationGenerateZKP *generateZKP; /*!< A pointer to an ECJPAKE_OperationGenerateZKP struct */
ECJPAKE_OperationVerifyZKP *verifyZKP; /*!< A pointer to an ECJPAKE_OperationVerifyZKP struct */
ECJPAKE_OperationRoundTwoGenerateKeys *generateRoundTwoKeys; /*!< A pointer to an ECJPAKE_OperationRoundTwoGenerateKeys struct */
ECJPAKE_OperationComputeSharedSecret *computeSharedSecret; /*!< A pointer to an ECJPAKE_OperationComputeSharedSecret struct */
} ECJPAKE_Operation;
/*!
* @brief Enum for the operation types supported by the driver.
*/
typedef enum {
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,
} ECJPAKE_OperationType;
/*!
* @brief The definition of a callback function used by the ECJPAKE driver
* when used in ::ECJPAKE_RETURN_BEHAVIOR_CALLBACK
*
* @param handle Handle of the client that started the ECJPAKE operation.
*
* @param returnStatus The result of the ECJPAKE 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 (*ECJPAKE_CallbackFxn) (ECJPAKE_Handle handle,
int_fast16_t returnStatus,
ECJPAKE_Operation operation,
ECJPAKE_OperationType operationType);
/*!
* @brief ECJPAKE Parameters
*
* ECJPAKE Parameters are used to with the ECJPAKE_open() call. Default values for
* these parameters are set using ECJPAKE_Params_init().
*
* @sa ECJPAKE_Params_init()
*/
typedef struct {
ECJPAKE_ReturnBehavior returnBehavior; /*!< Blocking, callback, or polling return behavior */
ECJPAKE_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
*/
} ECJPAKE_Params;
/*!
* @brief This function initializes the ECJPAKE module.
*
* @pre 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.
*/
void ECJPAKE_init(void);
/*!
* @brief Function to initialize an ECJPAKE_OperationRoundOneGenerateKeys struct to its defaults
*
* @param operation A pointer to ECJPAKE_OperationRoundOneGenerateKeys structure for
* initialization
*
* Defaults values are all zeros.
*/
void ECJPAKE_OperationRoundOneGenerateKeys_init(ECJPAKE_OperationRoundOneGenerateKeys *operation);
/*!
* @brief Function to initialize an ECJPAKE_OperationGenerateZKP struct to its defaults
*
* @param operation A pointer to ECJPAKE_OperationGenerateZKP structure for
* initialization
*
* Defaults values are all zeros.
*/
void ECJPAKE_OperationGenerateZKP_init(ECJPAKE_OperationGenerateZKP *operation);
/*!
* @brief Function to initialize an ECJPAKE_OperationVerifyZKP struct to its defaults
*
* @param operation A pointer to ECJPAKE_OperationVerifyZKP structure for
* initialization
*
* Defaults values are all zeros.
*/
void ECJPAKE_OperationVerifyZKP_init(ECJPAKE_OperationVerifyZKP *operation);
/*!
* @brief Function to initialize an ECJPAKE_OperationRoundTwoGenerateKeys struct to its defaults
*
* @param operation A pointer to ECJPAKE_OperationRoundTwoGenerateKeys structure for
* initialization
*
* Defaults values are all zeros.
*/
void ECJPAKE_OperationRoundTwoGenerateKeys_init(ECJPAKE_OperationRoundTwoGenerateKeys *operation);
/*!
* @brief Function to initialize an ECJPAKE_OperationComputeSharedSecret struct to its defaults
*
* @param operation A pointer to ECJPAKE_OperationComputeSharedSecret structure for
* initialization
*
* Defaults values are all zeros.
*/
void ECJPAKE_OperationComputeSharedSecret_init(ECJPAKE_OperationComputeSharedSecret *operation);
/*!
* @brief Function to close an ECJPAKE peripheral specified by the ECJPAKE handle
*
* @pre ECJPAKE_open() has to be called first.
*
* @param handle An ECJPAKE handle returned from ECJPAKE_open()
*
* @sa ECJPAKE_open()
*/
void ECJPAKE_close(ECJPAKE_Handle handle);
/*!
* @brief This function opens a given ECJPAKE peripheral.
*
* @pre ECJPAKE controller has been initialized using ECJPAKE_init()
*
* @param index Logical peripheral number for the ECJPAKE indexed into
* the ECJPAKE_config table
*
* @param params Pointer to an parameter block, if NULL it will use
* default values.
*
* @return An ECJPAKE_Handle on success or a NULL on an error or if it has
* been opened already.
*
* @sa ECJPAKE_init()
* @sa ECJPAKE_close()
*/
ECJPAKE_Handle ECJPAKE_open(uint_least8_t index, ECJPAKE_Params *params);
/*!
* @brief Function to initialize the ECJPAKE_Params struct to its defaults
*
* @param 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
*/
void ECJPAKE_Params_init(ECJPAKE_Params *params);
/*!
* @brief 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.
*
* @param [in] handle An ECJPAKE handle returned from ECJPAKE_open()
*
* @param [in] operation A pointer to a struct containing the requisite
* parameters to execute the function.
*
* @pre Call ECJPAKE_OperationRoundOneGenerateKeys_init() on /c operation.
*
* @post Generate the two sets of hashes and ZKPs for the two public/private key pairs.
*
* @retval #ECJPAKE_STATUS_SUCCESS The operation succeeded.
* @retval #ECJPAKE_STATUS_ERROR The operation failed.
* @retval #ECJPAKE_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later.
* @retval #ECJPAKE_STATUS_CANCELED The operation was canceled.
* @retval #ECJPAKE_STATUS_POINT_AT_INFINITY The computed public key is the point at infinity.
* @retval #ECJPAKE_STATUS_INVALID_PRIVATE_KEY The private key passed into the the call is invalid.
* @retval #ECJPAKE_STATUS_INVALID_PRIVATE_V The private v passed into the the call is invalid.
*
*/
int_fast16_t ECJPAKE_roundOneGenerateKeys(ECJPAKE_Handle handle, ECJPAKE_OperationRoundOneGenerateKeys *operation);
/*!
* @brief Generates the \c r component of a Schnorr Zero-Knowledge Proof (ZKP) signature.
*
* This function generates the \c 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.
*
* @param [in] handle An ECJPAKE handle returned from ECJPAKE_open()
*
* @param [in] operation A pointer to a struct containing the requisite
* parameters to execute the function.
*
* @pre 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.
*
*
* @post Send all ZKP signatures (\c r, public V, user ID) together with the
* public keys to the other party.
*
*
* @retval #ECJPAKE_STATUS_SUCCESS The operation succeeded.
* @retval #ECJPAKE_STATUS_ERROR The operation failed.
* @retval #ECJPAKE_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later.
* @retval #ECJPAKE_STATUS_CANCELED The operation was canceled.
*/
int_fast16_t ECJPAKE_generateZKP(ECJPAKE_Handle handle, ECJPAKE_OperationGenerateZKP *operation);
/*!
* @brief Verifies a Schnorr Zero-Knowledge Proof (ZKP) signature.
*
* This function computes if a received Schnorr ZKP correctly verifies
* a received public key.
*
* @param [in] handle An ECJPAKE handle returned from ECJPAKE_open()
*
* @param [in] operation A pointer to a struct containing the requisite
* parameters to execute the function.
*
* @pre 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.
*
* @retval #ECJPAKE_STATUS_SUCCESS The operation succeeded.
* @retval #ECJPAKE_STATUS_ERROR The operation failed. Signature did not verify correctly.
* @retval #ECJPAKE_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later.
* @retval #ECJPAKE_STATUS_CANCELED The operation was canceled.
* @retval #ECJPAKE_STATUS_PUBLIC_KEY_NOT_ON_CURVE The public key of the other party does not lie upon the curve.
* @retval #ECJPAKE_STATUS_PUBLIC_KEY_LARGER_THAN_PRIME A coordinate of the public key of the other party is too large.
*/
int_fast16_t ECJPAKE_verifyZKP(ECJPAKE_Handle handle, ECJPAKE_OperationVerifyZKP *operation);
/*!
* @brief 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.
*
* @param [in] handle An ECJPAKE handle returned from ECJPAKE_open()
*
* @param [in] operation A pointer to a struct containing the requisite
* parameters to execute the function.
*
* @pre Call ECJPAKE_OperationRoundTwoGenerateKeys_init() on /c operation.
*
* @post Generate the hash and ZKP signature for the second round public/private key.
*
* @retval #ECJPAKE_STATUS_SUCCESS The operation succeeded.
* @retval #ECJPAKE_STATUS_ERROR The operation failed.
* @retval #ECJPAKE_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later.
* @retval #ECJPAKE_STATUS_CANCELED The operation was canceled.
* @retval #ECJPAKE_STATUS_INVALID_PRIVATE_KEY The private key passed into the the call is invalid.
* @retval #ECJPAKE_STATUS_INVALID_PRIVATE_V The private v passed into the the call is invalid.
*/
int_fast16_t ECJPAKE_roundTwoGenerateKeys(ECJPAKE_Handle handle, ECJPAKE_OperationRoundTwoGenerateKeys *operation);
/*!
* @brief 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.
*
* @param [in] handle An ECJPAKE handle returned from ECJPAKE_open()
*
* @param [in] operation A pointer to a struct containing the requisite
* parameters to execute the function.
*
* @pre Call ECJPAKE_OperationComputeSharedSecret_init() on /c operation.
*
* @post 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.
*
* @retval #ECJPAKE_STATUS_SUCCESS The operation succeeded.
* @retval #ECJPAKE_STATUS_ERROR The operation failed.
* @retval #ECJPAKE_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later.
* @retval #ECJPAKE_STATUS_CANCELED The operation was canceled.
*/
int_fast16_t ECJPAKE_computeSharedSecret(ECJPAKE_Handle handle, ECJPAKE_OperationComputeSharedSecret *operation);
/*!
* @brief 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.
*
* @param handle Handle of the operation to cancel
*
* @retval #ECJPAKE_STATUS_SUCCESS The operation was canceled.
* @retval #ECJPAKE_STATUS_ERROR The operation was not canceled. There may be no operation to cancel.
*/
int_fast16_t ECJPAKE_cancelOperation(ECJPAKE_Handle handle);
#ifdef __cplusplus
}
#endif
#endif /* ti_drivers_ECJPAKE__include */