MCUX CLNS
MCUX Crypto Library Normal Secure
Loading...
Searching...
No Matches
General User Security Guidance

Good pratices

Handling CLNS return values & using safe defaults

Whenever you call a CLNS function which returns a status code - and especially whenever a security-critical decision depends on the result of a CLNS function - please take care of securely initializing the variable with a safe default value. For example, if you need to validate a cryptographic signature, you should initialize the variable for the result with NXPCLSIGNATURE_STATUS_FAILURE, then perform the signature verification, and check the actual return value afterwards. This way you will be able to detect a skipped function call.

In general, the return values of all CLNS API functions must be checked. These checks should ideally be written in such a way that, on an assembly code level, the code for the error condition is executed by default. This means that skipping all branch instructions must lead to an error condition, which helps avoid fault injection vulnerabilities. Depending on the architecture, the compiler may generate branch instructions or conditional instructions to reach the code for the success condition. We encourage that you check this manually.

Buffer clearing

In order to keep the chance of secret values leaking low, please clear any buffers used by CLNS properly by using nxpClSession_cleanup.

Code-flow monitoring

Most CLNS API functions monitor the code path taken internally and calculate a protection value that must be verified by the caller of the library. This can be done with e.g. the following code snippet:

#include <nxpCsslFlowProtection.h>
#include <nxpClEls.h>
int main(void)
{
/* Enable the ELS.
*
* This macro opens a new scope `{}`.
* `result` and `token` are variables which are only valid in this scope.
*
* - `result` contains the function's return value.
* - `token`, referred to in the documentation as the protection token, contains the monitored code path check value.
* Under normal circumstances, this token must be equal to the reference value `NXP_CSSL_FP_FUNCTION_CALLED(nxpClEls_WaitForOperation)`.
* If the two differ, the code path has been altered, pointing to a fault injection attack.
*/
NXP_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, nxpClEls_Enable_Async());
/* Check the protection token and result. If an attack occurred, handle it here. */
if(NXP_CSSL_FP_FUNCTION_CALLED(nxpClEls_WaitForOperation) != token || NXPCLELS_STATUS_SW_FAULT == result || NXPCLELS_STATUS_HW_FAULT == result)
{
/* Attack handling */
resetDevice();
}
/* Check the result for functional errors. */
if(NXPCLELS_STATUS_OK != result)
{
/* Error handling */
return false;
}
/* This macro closes the scope `{}`. After this point, the variables `result` and `token` are no longer visible. */
NXP_CSSL_FP_FUNCTION_CALL_END();
/* Don't forget to do the same for nxpClEls_WaitForOperation()! */
return 0;
}

In cases where the attack handling and error handling methods are identical, the two if-statements may be merged like this:

#include <nxpCsslFlowProtection.h>
#include <nxpClEls.h>
int main(void)
{
/* Enable the ELS. */
NXP_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, nxpClEls_Enable_Async());
/* Check for attacks and/or errors. */
if(NXP_CSSL_FP_FUNCTION_CALLED(nxpClEls_WaitForOperation) != token || NXPCLELS_STATUS_OK != result)
{
/* Attack and error handling */
resetDevice();
}
NXP_CSSL_FP_FUNCTION_CALL_END();
/* Don't forget to do the same for nxpClEls_WaitForOperation()! */
return 0;
}

CLNS API functions which support this feature can be identified by their declaration: if NXP_CSSL_FP_FUNCTION_DECL is part of the declaration, the function supports code flow monitoring.

The underlying monitoring functionality is provided by a library called CSSL, which is bundled together with CLNS. For details, you may want to check the CSSL documentation.

Parameter integrity protection

Protection with Checksum (used with CSSL APIs)

Some CLNS API functions use parameter integrity protection, which provides additional assurance against fault injection attacks. The first parameter of such functions has the type nxpCsslParamIntegrity_Checksum_t. In order to call these functions correctly, you must first calculate the parameter checksum. See the example below:

#include <stdint.h>
#include <nxpCsslMemory.h>
#include <nxpCsslFlowProtection.h>
#include <nxpCsslParamIntegrity.h>
int main(void) {
uint8_t arr1[33U] = {0xe4u, 0xf9u, 0x26u, 0x4cu, 0x65u, 0xe2u, 0x13u, 0xa3u, 0x9au, 0x40u, 0xd7u, 0x87u, 0xccu, 0x0bu, 0x31u, 0x18u, 0xacu, 0x55u, 0xb5u, 0x7du, 0x06u, 0x7fu, 0xceu, 0xe4u, 0xb2u, 0x7eu, 0xd5u, 0xaau, 0x90u, 0x9au, 0x42u, 0x56u, 0x76u};
/* Compare arr1 with itself. Compute the parameter checksum and pass it to the function.
* The first parameter here is the number of arguments, and is followed by the actual arguments.
*/
nxpCsslParamIntegrity_Checksum_t checksum = NXP_CSSL_PI_PROTECT(arr1, arr1, sizeof(arr1));
NXP_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, nxpCsslMemory_Compare(checksum, arr1, arr1, sizeof(arr1)));
/* Check for attacks and/or errors. */
if(NXP_CSSL_FP_FUNCTION_CALLED(nxpCsslMemory_Compare) != token || NXPCSSLMEMORY_STATUS_EQUAL != result)
{
/* Attack and error handling */
return -1;
}
NXP_CSSL_FP_FUNCTION_CALL_END();
return 0;
}

Side-channel analysis resistance

All sensitive data (such as private keys), including sensitive CLNS API function parameters, shall be aligned on a 4-byte (or CPU word size, whichever is greater) boundary to provide some protection against side-channel analysis.

For claims regarding side-channel analysis resistance of the hardware used by CLNS, please refer to your product's Security Guidance Manual or Reference Manual.

Input sanitization and preventing privilege escalation

Do not use unsanitized input to compute input values to CLNS functions.

If you integrate CLNS so that it runs at a privileged execution level and can be called from a lower privileged level, take special care that the following types of input, which are directly used as pointers by CLNS (and called at the privilege level of CLNS), are not derived in any way from unsanitized input:

  • (callback) function pointers passed to CLNS functions
  • mode pointers passed to CLNS functions (e.g. MAC, Hash or Cipher algorithms)

Otherwise privilege escalation attacks will be possible.