MCUX CLNS
MCUX Crypto Library Normal Secure
 
Loading...
Searching...
No Matches
mcuxClEls_Tls_Master_Key_Session_Keys_example.c

TLS key derivation example.

TLS key derivation example

/*--------------------------------------------------------------------------*/
/* Copyright 2020, 2022-2023 NXP */
/* */
/* NXP Confidential. This software is owned or controlled by NXP and may */
/* only be used strictly in accordance with the applicable license terms. */
/* By expressly accepting such terms or by downloading, installing, */
/* activating and/or otherwise using the software, you are agreeing that */
/* you have read, and that you agree to comply with and are bound by, such */
/* license terms. If you do not agree to be bound by the applicable license */
/* terms, then you may not retain, install, activate or otherwise use the */
/* software. */
/*--------------------------------------------------------------------------*/
#include <mcuxClToolchain.h>
#include <mcuxClEls.h> // Interface to the entire mcuxClEls component
#include <mcuxClMemory.h>
#include <mcuxClCore_FunctionIdentifiers.h> // Code flow protection
#include <mcuxClCore_Examples.h>
#include <mcuxClExample_ELS_Helper.h>
#include <mcuxClExample_ELS_Key_Helper.h>
static ALIGNED uint8_t derivation_data[MCUXCLELS_TLS_DERIVATIONDATA_SIZE];
static ALIGNED uint8_t client_random[MCUXCLELS_TLS_RANDOM_SIZE];
static ALIGNED uint8_t server_random[MCUXCLELS_TLS_RANDOM_SIZE];
static ALIGNED uint8_t master_key_string[] = "master secret";
static ALIGNED uint8_t key_expansion_string[] = "key expansion";
MCUXCLEXAMPLE_FUNCTION(mcuxClEls_Tls_Master_Key_Session_Keys_example)
{
if(!mcuxClExample_Els_Init(MCUXCLELS_RESET_DO_NOT_CANCEL))
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
/* Generate client key pair */
mcuxClEls_EccKeyGenOption_t KeyGenOptions = {0};
KeyGenOptions.bits.kgsrc = MCUXCLELS_ECC_OUTPUTKEY_RANDOM; // Configure that a non-deterministic key is generated.
KeyGenOptions.bits.kgtypedh = MCUXCLELS_ECC_OUTPUTKEY_KEYEXCHANGE; //Key will be used for Key Exchange
mcuxClEls_KeyProp_t GenKeyProp = {0};
GenKeyProp.bits.upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_FALSE; // Configure that user access rights: non-privileged access
GenKeyProp.bits.upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE; // Configure that user access rights: secure access
mcuxClEls_KeyIndex_t keyIdxPrivClient = 0u; // Set keystore index at which mcuxClEls_EccKeyGen_Async is storing the private key.
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_EccKeyGen_Async( // Perform key generation.
KeyGenOptions, // Set the prepared configuration.
(mcuxClEls_KeyIndex_t) 0U, // This parameter (signingKeyIdx) is ignored, since no signature is requested in the configuration.
keyIdxPrivClient, // Keystore index at which the generated private key is stored.
GenKeyProp, // Set the generated key properties.
NULL,
ecc_public_key_client // Output buffer, which the operation will write the public key to.
));
// mcuxClEls_EccKeyGen_Async is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR; // Expect that no error occurred, meaning that the mcuxClEls_EccKeyGen_Async operation was started.
}
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_LimitedWaitForOperation(0x00100000U, MCUXCLELS_ERROR_FLAGS_CLEAR)); // Wait for the mcuxClEls_EccKeyGen_Async operation to complete.
// mcuxClEls_LimitedWaitForOperation is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
/* Generate server key pair */
mcuxClEls_KeyIndex_t keyIdxPrivServer = 2u; // Set keystore index at which mcuxClEls_EccKeyGen_Async is storing the private key.
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_EccKeyGen_Async( // Perform key generation.
KeyGenOptions, // Set the prepared configuration.
(mcuxClEls_KeyIndex_t) 0U, // This parameter (signingKeyIdx) is ignored, since no signature is requested in the configuration.
keyIdxPrivServer, // Keystore index at which the generated private key is stored.
GenKeyProp, // Set the generated key properties.
NULL,
ecc_public_key_server // Output buffer, which the operation will write the public key to.
));
// mcuxClEls_EccKeyGen_Async is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR; // Expect that no error occurred, meaning that the mcuxClEls_EccKeyGen_Async operation was started.
}
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_LimitedWaitForOperation(0x00100000U, MCUXCLELS_ERROR_FLAGS_CLEAR)); // Wait for the mcuxClEls_EccKeyGen_Async operation to complete.
// mcuxClEls_LimitedWaitForOperation is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
//Perform Key Exchange
mcuxClEls_KeyIndex_t sharedSecretIdx = 10U; // Set shared key index
mcuxClEls_KeyProp_t SharedSecretProp = {0}; // Initialize a new configuration for the mcuxClEls_EccKeyExchange_Async generated key properties.
SharedSecretProp.bits.upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_FALSE; // Configure that user access rights: non-privileged access
SharedSecretProp.bits.upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE; // Configure that user access rights: secure access
SharedSecretProp.bits.utlpsms = MCUXCLELS_KEYPROPERTY_TLS_PREMASTER_SECRET_TRUE; //Shared Secret is used as pre-master secret for TLS
keyIdxPrivClient,
ecc_public_key_server,
sharedSecretIdx,
SharedSecretProp));
// mcuxClEls_EccKeyExchange_Async is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR; // Expect that no error occurred, meaning that the mcuxClEls_EccKeyExchange_Async operation was started.
}
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_LimitedWaitForOperation(0x00100000U, MCUXCLELS_ERROR_FLAGS_CLEAR)); // Wait for the mcuxClEls_EccKeyExchange_Async operation to complete.
// mcuxClEls_LimitedWaitForOperation is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
// PRNG needs to be initialized; this can be done by calling mcuxClEls_KeyDelete_Async (delete any key slot, can be empty)
// However mcuxClEls_EccKeyExchange_Async also guarantees PRNG is initialized
//generate server random
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_Prng_GetRandom(server_random, 32U));
// mcuxClEls_Prng_GetRandom is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR; // Expect that no error occurred, meaning that the mcuxClEls_Prng_GetRandom operation was started.
}
//generate client random
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_Prng_GetRandom(client_random, 32U));
// mcuxClEls_Prng_GetRandom is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR; // Expect that no error occurred, meaning that the mcuxClEls_Prng_GetRandom operation was started.
}
//perpare derivation data for master key
//the derivation data has a fixed length of 640 bits and is composed as follows
//"key expansion"||server random||client random||800000
derivation_data,
key_expansion_string,
sizeof(key_expansion_string),
sizeof(key_expansion_string)
));
// mcuxClMemory_copy is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
derivation_data+sizeof(key_expansion_string),
server_random,
sizeof(server_random),
sizeof(server_random)
));
// mcuxClMemory_copy is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
derivation_data+sizeof(key_expansion_string)+32U,
client_random,
sizeof(client_random),
sizeof(client_random)
));
// mcuxClMemory_set is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
derivation_data+sizeof(key_expansion_string)+32U+32U,
0x80,
1U,
1U
));
// mcuxClMemory_copy is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
derivation_data+sizeof(key_expansion_string)+32U+32U+1U,
0x00,
2U,
2U
));
// mcuxClMemory_set is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
mcuxClEls_KeyProp_t tlsMasterKeyProp = {0};
tlsMasterKeyProp.bits.upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_FALSE; // Configure that user access rights: non-privileged access
tlsMasterKeyProp.bits.upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE; // Configure that user access rights: secure access
//Generate TLS master key
derivation_data,
tlsMasterKeyProp,
sharedSecretIdx
));
// mcuxClEls_TlsGenerateMasterKeyFromPreMasterKey_Async is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_LimitedWaitForOperation(0x00100000U, MCUXCLELS_ERROR_FLAGS_CLEAR)); // Wait for the mcuxClEls_TlsGenerateMasterKeyFromPreMasterKey_Async operation to complete.
// mcuxClEls_LimitedWaitForOperation is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
//perpare derivation data for session keys
//the derivation data has a fixed length of 640 bits and is composed as follows
//"master secret"||client random||server random||800000
derivation_data,
master_key_string,
sizeof(master_key_string),
sizeof(master_key_string)
));
// mcuxClMemory_copy is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
derivation_data+sizeof(master_key_string),
client_random,
sizeof(client_random),
sizeof(client_random)
));
// mcuxClMemory_copy is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
derivation_data+sizeof(master_key_string)+32U,
server_random,
sizeof(server_random),
sizeof(server_random)
));
// mcuxClMemory_set is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
derivation_data+sizeof(master_key_string)+32U+32U,
0x80,
1U,
1U
));
// mcuxClMemory_copy is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
derivation_data+sizeof(master_key_string)+32U+32U+1U,
0x00,
2U,
2U
));
// mcuxClMemory_set is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
mcuxClEls_KeyProp_t KeyProp = {0};
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result_keyprop, token, mcuxClEls_GetKeyProperties(sharedSecretIdx, &KeyProp));
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
//Generate TLS session keys
derivation_data,
GenKeyProp,
sharedSecretIdx
));
// mcuxClEls_TlsGenerateSessionKeysFromMasterKey_Async is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_LimitedWaitForOperation(0x00100000U, MCUXCLELS_ERROR_FLAGS_CLEAR)); // Wait for the mcuxClEls_TlsGenerateSessionKeysFromMasterKey_Async operation to complete.
// mcuxClEls_LimitedWaitForOperation is a flow-protected function: Check the protection token and the return value
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
//Delete all keys from keystore
if(!mcuxClExample_Els_KeyDelete(keyIdxPrivClient))
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
if(!mcuxClExample_Els_KeyDelete(keyIdxPrivServer))
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
for(mcuxClEls_KeyIndex_t i = sharedSecretIdx; i < sharedSecretIdx + 6u; i++)
{
if(!mcuxClExample_Els_KeyDelete(i))
{
return MCUXCLEXAMPLE_STATUS_ERROR;
}
}
//Now the session keys are stored in the key store as follows:
//Client Mac Key : sharedSecretIdx (2-3)
//Server Mac Key : sharedSecretIdx+2 (4-5)
//Client Encryption Key : sharedSecretIdx+4 (6)
//Server Encryption Key : sharedSecretIdx+6 (7)
return MCUXCLEXAMPLE_STATUS_OK;
}
static mcuxClEls_EccByte_t ecc_public_key_client[MCUXCLELS_ECC_PUBLICKEY_SIZE] ALIGNED
Destination buffer to receive the public key of the mcuxClEls_EccKeyGen_Async operation.
Definition mcuxClEls_Tls_Master_Key_Session_Keys_example.c:33
Definition of function identifiers for the flow protection mechanism.
Top-level include file for the ELS driver.
Top-level include file for the memory operations.
Provides the API for the CSSL flow protection mechanism.
#define MCUXCLELS_ERROR_FLAGS_CLEAR
Set this option at mcuxClEls_ErrorHandling_t to clear all ELS error flags.
Definition mcuxClEls_Common.h:110
#define MCUXCLELS_RESET_DO_NOT_CANCEL
Set this option at mcuxClEls_ResetOption_t to abort the requested command if another ELS operation is...
Definition mcuxClEls_Common.h:119
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_LimitedWaitForOperation(uint32_t counterLimit, mcuxClEls_ErrorHandling_t errorHandling)
Await the completion of an ELS operation for a limited amount of time and optionally clear the error ...
#define MCUXCLELS_ECC_OUTPUTKEY_RANDOM
Set this option at mcuxClEls_EccKeyGenOption_t.kgsrc to specify output key is random.
Definition mcuxClEls_Ecc.h:115
#define MCUXCLELS_ECC_OUTPUTKEY_KEYEXCHANGE
Set this option at mcuxClEls_EccKeyGenOption_t.kgtypedh to specify output key will be a Diffie Helman...
Definition mcuxClEls_Ecc.h:112
#define MCUXCLELS_ECC_PUBLICKEY_SIZE
Size of the public key.
Definition mcuxClEls_Ecc.h:151
uint8_t mcuxClEls_EccByte_t
Data type for ECC parameters in ELS format.
Definition mcuxClEls_Ecc.h:177
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_EccKeyGen_Async(mcuxClEls_EccKeyGenOption_t options, mcuxClEls_KeyIndex_t signingKeyIdx, mcuxClEls_KeyIndex_t privateKeyIdx, mcuxClEls_KeyProp_t generatedKeyProperties, uint8_t const *pRandomData, uint8_t *pPublicKey)
Generates an ECC key pair on the NIST P-256 curve.
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_EccKeyExchange_Async(mcuxClEls_KeyIndex_t privateKeyIdx, uint8_t const *pPublicKey, mcuxClEls_KeyIndex_t sharedSecretIdx, mcuxClEls_KeyProp_t sharedSecretProperties)
Performs a Diffie-Hellman key exchange with an internal ECC private key and an external ECC public ke...
#define MCUXCLELS_TLS_DERIVATIONDATA_SIZE
Size of TLS derivation data.
Definition mcuxClEls_Kdf.h:82
#define MCUXCLELS_TLS_RANDOM_SIZE
Size of random bytes for TLS.
Definition mcuxClEls_Kdf.h:83
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_TlsGenerateSessionKeysFromMasterKey_Async(uint8_t const *pDerivationData, mcuxClEls_KeyProp_t keyProperties, mcuxClEls_KeyIndex_t keyIdx)
Generates TLS session keys based on a master key and derivation data, according to the TLS 1....
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_TlsGenerateMasterKeyFromPreMasterKey_Async(uint8_t const *pDerivationData, mcuxClEls_KeyProp_t keyProperties, mcuxClEls_KeyIndex_t keyIdx)
Generates a TLS master key based on a pre-master key and derivation data, according to the TLS 1....
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_GetKeyProperties(mcuxClEls_KeyIndex_t keyIdx, mcuxClEls_KeyProp_t *pKeyProp)
Exports the properties of the keys stored in the ELS internal keystore.
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_Prng_GetRandom(uint8_t *pOutput, size_t outputLength)
Writes random data from the ELS PRNG to the given buffer.
#define MCUXCLELS_KEYPROPERTY_SECURE_TRUE
This value of mcuxClEls_KeyProp_t.upprot_sec indicates that the caller must be in secure mode to use ...
Definition mcuxClEls_Types.h:158
#define MCUXCLELS_KEYPROPERTY_TLS_MASTER_SECRET_TRUE
This value of mcuxClEls_KeyProp_t.utlsms indicates that the key is a TLS Master Secret.
Definition mcuxClEls_Types.h:146
#define MCUXCLELS_KEYPROPERTY_PRIVILEGED_FALSE
This value of mcuxClEls_KeyProp_t.upprot_priv indicates that the caller does not need to be in privil...
Definition mcuxClEls_Types.h:157
#define MCUXCLELS_KEYPROPERTY_TLS_PREMASTER_SECRET_TRUE
This value of mcuxClEls_KeyProp_t.utlspms indicates that the key is a TLS Premaster Secret.
Definition mcuxClEls_Types.h:144
#define MCUXCLELS_STATUS_OK
No error occurred.
Definition mcuxClEls_Types.h:171
#define MCUXCLELS_STATUS_OK_WAIT
An _Async function successfully started an ELS command. Call mcuxClEls_WaitForOperation to complete i...
Definition mcuxClEls_Types.h:172
uint32_t mcuxClEls_KeyIndex_t
Type for ELS keystore indices.
Definition mcuxClEls_Types.h:222
void mcuxClMemory_copy(uint8_t *pDst, uint8_t const *pSrc, size_t length, size_t bufLength)
Copies a memory buffer to another location.
void mcuxClMemory_set(uint8_t *pDst, uint8_t val, size_t length, size_t bufLength)
Sets all bytes of a memory buffer to a specified value.
#define MCUX_CSSL_FP_FUNCTION_CALL_VOID_BEGIN(...)
Call a flow protected void function and check the protection token.
Definition mcuxCsslFlowProtection.h:652
#define MCUX_CSSL_FP_FUNCTION_CALL_VOID_END(...)
End a void function call section started by MCUX_CSSL_FP_FUNCTION_CALL_VOID_BEGIN.
Definition mcuxCsslFlowProtection.h:683
#define MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(...)
Call a flow protected function and check the protection token.
Definition mcuxCsslFlowProtection.h:581
#define MCUX_CSSL_FP_FUNCTION_CALLED(...)
Expectation of a called function.
Definition mcuxCsslFlowProtection.h:735
#define MCUX_CSSL_FP_FUNCTION_CALL_END(...)
End a function call section started by MCUX_CSSL_FP_FUNCTION_CALL_BEGIN.
Definition mcuxCsslFlowProtection.h:616
Command option bit field for mcuxClEls_EccKeyGen_Async Bit field to configure mcuxClEls_EccKeyGenOpti...
Definition mcuxClEls_Ecc.h:229
uint32_t kgsrc
Define if the output key is deterministic or random.
Definition mcuxClEls_Ecc.h:238
uint32_t kgtypedh
Define the usage of the output key.
Definition mcuxClEls_Ecc.h:237
struct mcuxClEls_EccKeyGenOption_t::@25 bits
Access mcuxClEls_EccKeyGenOption_t bit-wise.
Type for ELS key store key properties.
Definition mcuxClEls_Types.h:226
uint32_t upprot_sec
Access restriction to TrustZone secure mode.
Definition mcuxClEls_Types.h:270
uint32_t upprot_priv
Access restriction to privileged mode.
Definition mcuxClEls_Types.h:269
uint32_t utlsms
Usage permission as a TLS master secret.
Definition mcuxClEls_Types.h:264
struct mcuxClEls_KeyProp_t::@41 bits
Access mcuxClEls_KeyProp_t bit-wise.