Simplifying Authenticated Cloud Connectivity for Any Device.
How Wi-Fi and Cellular connectivity modules with ExpressLink can help create secure cloud connected devices. See the blog post.
Designing an energy efficient and cloud-connected IoT solution with CoAP.
A client/server, request/response, UDP-based protocol for efficiency and cloud compatibility. See the blog post.
Introducing FreeRTOS Kernel version 11.0.0:
A Major Release with Symmetric Multiprocessing (SMP) Support. See the blog post.
FreeRTOS Roadmap and Code Contribution process.
The FreeRTOS roadmap and code contribution process are now published here and on GitHub. See the blog post.
OPC-UA over TSN with FreeRTOS.
A development project to give applications consistent access to hardware TSN capabilities. See the blog post.
PKCS #11 Functions
PKCS #11 includes many functions and supports a variety of use cases. The FreeRTOS PKCS #11 library only implements a small subset of functions for the use cases first describe. Each function is fully documented in the PKCS #11 standard. The terminology can be difficult for the first reader, so we also provide examples code below.
PKCS #11 operational functions:
C_Random. Random numbers are required by the TCP/IP stack (for example, when selecting an initial sequence number), within cryptographic algorithms, and during the TLS handshake.
C_Sign. Signing a message sent to another network node allows that node to identify the messages true origin.
C_FindObject. Finds an object managed by PKCS #11, for example the client certificate.
C_GetAttributeValue. This API gets the value of an object's attribute, for example if the object is a key type or a certificate type.
PKCS #11 administrative functions:
C_Initialize. Initializes the crypto libraries.
C_Finalize. Cleans up resources used by the crypto libraries.
C_OpenSession. Opens a session (or connection) between a software application and a particular crypto token.
C_CloseSession. Closes the session opened by C_OpenSession.
C_Login. Logs into a token.
C_GetFunctionList. Obtains a struct containing function pointers for use in calling the PKCS #11 APIs.
C_GetSlotList. Obtains the list of slots, which can be used to access any token in a slot.
Code Samples
Here are some example code snippets that showcase how one might use the PKCS #11 API.
Using C_GenerateRandom:
This code snippet shows how to use PKCS #11 to get a random number. For example, this function can be used for FreeRTOS-Plus-TCP to generate random TCP numbers.
Using C_Sign to add our private key's signature to our message:
This is a snippet from the TLS layer of our code that uses PKCS #11 for the C_Sign operation. In this example, just before we send a TLS message, we call into the PKCS #11 layer and ask it to sign our message with our private key.
static int prvPrivateKeySigningCallback( void * pvContext,
mbedtls_md_type_t xMdAlg,
const unsigned char * pucHash,
size_t xHashLen,
unsigned char* pucSig,
size_t * pxSigLen,
int ( *piRng ) ( void *, unsigned char *, size_t ),
void * pvRng )
{
CK_RV xResult = CKR_OK;
int lFinalResult = 0;
TLSContext_t * pxTLSContext = ( TLSContext_t* ) pvContext;
CK_MECHANISM xMech = { 0 };
CK_BYTE xToBeSigned[ 256 ];
CK_ULONG xToBeSignedLen = sizeof( xToBeSigned );
/* Unreferenced parameters. */
( void )( piRng );
( void )( pvRng );
( void )( xMdAlg);
/* Sanity check buffer length. */
if ( xHashLen > sizeof( xToBeSigned ) )
{
xResult = CKR_ARGUMENTS_BAD;
}
/* Format the hash data to be signed. */
if ( CKK_RSA == pxTLSContext->xKeyType )
{
xMech.mechanism = CKM_RSA_PKCS;
/* mbedTLS expects hashed data without padding, but PKCS #11 C_Sign
* function performs a hash & sign if hash algorithm is specified. This
* helper function applies padding indicating data was hashed with
* SHA-256 while still allowing pre-hashed data to be provided. */
xResult = vAppendSHA256AlgorithmIdentifierSequence( ( uint8_t * ) pucHash, xToBeSigned );
xToBeSignedLen = pkcs11RSA_SIGNATURE_INPUT_LENGTH;
}
else if ( CKK_EC == pxTLSContext->xKeyType )
{
xMech.mechanism = CKM_ECDSA;
memcpy( xToBeSigned, pucHash, xHashLen );
xToBeSignedLen = xHashLen;
}
else
{
xResult = CKR_ARGUMENTS_BAD;
}
if ( CKR_OK == xResult )
{
/* Use the PKCS#11 module to sign. */
xResult = pxTLSContext->
pxP11FunctionList->C_SignInit( pxTLSContext->xP11Session,
&xMech,
pxTLSContext->xP11PrivateKey );
}
if ( CKR_OK == xResult )
{
*pxSigLen = sizeof( xToBeSigned );
xResult = pxTLSContext->
pxP11FunctionList->C_Sign( ( CK_SESSION_HANDLE ) pxTLSContext->xP11Session,
xToBeSigned,
xToBeSignedLen,
pucSig,
( CK_ULONG_PTR ) pxSigLen );
}
if ( ( xResult == CKR_OK ) && ( CKK_EC == pxTLSContext->xKeyType ) )
{
/* PKCS #11 for P256 returns a 64-byte signature with 32 bytes for R and
* 32 bytes for S. This must be converted to an ASN.1 encoded array. */
if (*pxSigLen != pkcs11ECDSA_P256_SIGNATURE_LENGTH)
{
xResult = CKR_FUNCTION_FAILED;
}
if ( xResult == CKR_OK )
{
PKI_pkcs11SignatureTombedTLSSignature( pucSig, pxSigLen );
}
}
if ( xResult != CKR_OK )
{
TLS_PRINT( ( "ERROR: Failure in signing callback: %d \r\n", xResult ) );
lFinalResult = TLS_ERROR_SIGN;
}
return lFinalResult;
}
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.