Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

TLS Shim Layer DRBG #2274

Merged
merged 2 commits into from
Jul 15, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 73 additions & 48 deletions libraries/freertos_plus/standard/tls/src/iot_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ typedef struct TLSContext
mbedtls_x509_crt xMbedX509Cli;
mbedtls_pk_context xMbedPkCtx;
mbedtls_pk_info_t xMbedPkInfo;
mbedtls_ctr_drbg_context xMbedDrbgCtx;

/* PKCS#11. */
CK_FUNCTION_LIST_PTR pxP11FunctionList;
Expand Down Expand Up @@ -158,6 +159,7 @@ static void prvFreeContext( TLSContext_t * pxCtx )
mbedtls_ssl_close_notify( &pxCtx->xMbedSslCtx ); /*lint !e534 The error is already taken care of inside mbedtls_ssl_close_notify*/
mbedtls_ssl_free( &pxCtx->xMbedSslCtx );
mbedtls_ssl_config_free( &pxCtx->xMbedSslConfig );
mbedtls_ctr_drbg_free( &pxCtx->xMbedDrbgCtx );

/* Cleanup PKCS11 only if the handshake was started. */
if( ( TLS_HANDSHAKE_NOT_STARTED != pxCtx->xTLSHandshakeState ) &&
Expand Down Expand Up @@ -228,11 +230,11 @@ static int prvGenerateRandomBytes( void * pvCtx,
size_t xRandomLength )
{
TLSContext_t * pxCtx = ( TLSContext_t * ) pvCtx; /*lint !e9087 !e9079 Allow casting void* to other types. */
BaseType_t xResult;
int xResult = 0;

xResult = pxCtx->pxP11FunctionList->C_GenerateRandom( pxCtx->xP11Session, pucRandom, xRandomLength );
xResult = mbedtls_ctr_drbg_random( &pxCtx->xMbedDrbgCtx, pucRandom, xRandomLength );

if( xResult != CKR_OK )
if( xResult != 0 )
{
TLS_PRINT( ( "ERROR: Failed to generate random bytes %s : %s \r\n",
mbedtlsHighLevelCodeOrDefault( xResult ),
Expand Down Expand Up @@ -524,7 +526,6 @@ static int prvReadCertificateIntoContext( TLSContext_t * pxTlsContext,
static int prvInitializeClientCredential( TLSContext_t * pxCtx )
{
BaseType_t xResult = CKR_OK;
CK_SLOT_ID * pxSlotIds = NULL;
CK_ULONG xCount = 0;
CK_ATTRIBUTE xTemplate[ 2 ];
mbedtls_pk_type_t xKeyAlgo = ( mbedtls_pk_type_t ) ~0;
Expand All @@ -533,42 +534,10 @@ static int prvInitializeClientCredential( TLSContext_t * pxCtx )
/* Initialize the mbed contexts. */
mbedtls_x509_crt_init( &pxCtx->xMbedX509Cli );

/* Get the PKCS #11 module/token slot count. */
if( CKR_OK == xResult )
{
xResult = ( BaseType_t ) pxCtx->pxP11FunctionList->C_GetSlotList( CK_TRUE,
NULL,
&xCount );
}

/* Allocate memory to store the token slots. */
if( CKR_OK == xResult )
{
pxSlotIds = ( CK_SLOT_ID * ) pvPortMalloc( sizeof( CK_SLOT_ID ) * xCount );

if( NULL == pxSlotIds )
{
xResult = CKR_HOST_MEMORY;
}
}

/* Get all of the available private key slot identities. */
if( CKR_OK == xResult )
if( pxCtx->xP11Session == CK_INVALID_HANDLE )
{
xResult = ( BaseType_t ) pxCtx->pxP11FunctionList->C_GetSlotList( CK_TRUE,
pxSlotIds,
&xCount );
}

/* Start a private session with the P#11 module using the first
* enumerated slot. */
if( CKR_OK == xResult )
{
xResult = ( BaseType_t ) pxCtx->pxP11FunctionList->C_OpenSession( pxSlotIds[ 0 ],
CKF_SERIAL_SESSION,
NULL,
NULL,
&pxCtx->xP11Session );
xResult = CKR_SESSION_HANDLE_INVALID;
TLS_PRINT( ( "Error: PKCS #11 session was not initialized.\r\n" ) );
}

/* Put the module in authenticated mode. */
Expand Down Expand Up @@ -682,17 +651,54 @@ static int prvInitializeClientCredential( TLSContext_t * pxCtx )
&pxCtx->xMbedPkCtx );
}

/* Free memory. */
if( NULL != pxSlotIds )
{
vPortFree( pxSlotIds );
}

return xResult;
}

/*-----------------------------------------------------------*/

/**
* @brief Helper to seed the entropy module used by the DRBG. Periodically this
* this function will be called to get more random data from the TRNG.
*
* @param[in] tlsContext The TLS context.
* @param[out] outputBuffer The output buffer to return the generated random data.
* @param[in] outputBufferLength Length of the output buffer.
*
* @return Zero on success, otherwise a negative error code telling the cause of the error.
*/
static int prvEntropyCallback( void * tlsContext,
unsigned char * outputBuffer,
size_t outputBufferLength )
{
int ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
CK_RV xResult = CKR_OK;
TLSContext_t * pxCtx = ( TLSContext_t * ) tlsContext; /*lint !e9087 !e9079 Allow casting void* to other types. */

if( pxCtx->xP11Session != CK_INVALID_HANDLE )
{
xResult = C_GenerateRandom( pxCtx->xP11Session,
outputBuffer,
outputBufferLength );
}
else
{
xResult = CKR_SESSION_HANDLE_INVALID;
TLS_PRINT( ( "Error: PKCS #11 session was not initialized.\r\n" ) );
}

if( xResult == CKR_OK )
{
ret = 0;
}
else
{
TLS_PRINT( ( "Error: PKCS #11 C_GenerateRandom failed with error code:" \
"%d\r\n", xResult ) );
}

return ret;
}

/*
* Interface routines.
*/
Expand All @@ -701,6 +707,7 @@ BaseType_t TLS_Init( void ** ppvContext,
TLSParams_t * pxParams )
{
BaseType_t xResult = CKR_OK;
int mbedTLSResult = 0;
TLSContext_t * pxCtx = NULL;
CK_C_GetFunctionList xCkGetFunctionList = NULL;

Expand All @@ -726,17 +733,35 @@ BaseType_t TLS_Init( void ** ppvContext,
xCkGetFunctionList = C_GetFunctionList;
xResult = ( BaseType_t ) xCkGetFunctionList( &pxCtx->pxP11FunctionList );

/* Ensure that the PKCS #11 module is initialized. */
if( CKR_OK == xResult )
/* Ensure that the PKCS #11 module is initialized and create a session. */
if( xResult == CKR_OK )
{
xResult = ( BaseType_t ) xInitializePKCS11();
xResult = xInitializePkcs11Session( &pxCtx->xP11Session );

/* It is ok if the module was previously initialized. */
if( xResult == CKR_CRYPTOKI_ALREADY_INITIALIZED )
{
xResult = CKR_OK;
}
}

if( xResult == CKR_OK )
{
mbedtls_ctr_drbg_init( &pxCtx->xMbedDrbgCtx );
mbedTLSResult = mbedtls_ctr_drbg_seed( &pxCtx->xMbedDrbgCtx,
prvEntropyCallback,
pxCtx,
NULL,
0 );

if( 0 != mbedTLSResult )
{
TLS_PRINT( ( "ERROR: Failed to setup DRBG seed %s : %s \r\n",
mbedtlsHighLevelCodeOrDefault( mbedTLSResult ),
mbedtlsLowLevelCodeOrDefault( mbedTLSResult ) ) );
xResult = CKR_FUNCTION_FAILED;
}
}
}
else
{
Expand Down