|
库
最新资讯
FreeRTOS 路线图和代码贡献流程。
FreeRTOS 路线图和代码贡献流程现已在此处和 GitHub 上发布。请参阅 博客文章。
使用 FreeRTOS 实现 OPC-UA over TSN。
一个开发项目,旨在让应用程序能够一致地访问硬件 TSN 功能。请参阅 博客文章。
FreeRTOS-Plus-TCP 现具有统一的 IPv4 和 IPv6 功能,支持多接口。
为基于 FreeRTOS 的固件实现防砖化 MCU FOTA:
Microvisor IoT 方法。请参阅 博客文章。
宣布停止支持 FreeRTOS 202012 LTS。
您可以将项目迁移到 FreeRTOS 202210.01 LTS 或订阅 FreeRTOS 延长维护计划。请参阅 博客文章。
|
|
PKCS #11 函数
PKCS #11 包含许多函数,并支持各种用例。FreeRTOS PKCS #11库仅实现了第一个描述的用例中的一小部分函数。每个函数均在 PKCS #11 标准中有完整记录。 这些术语对初读者来说可能比较困难,因此我们也在下面提供了示例代码。
PKCS #11 操作函数:
- C_Random。 TCP/IP 协议栈(例如,在选择初始序列号时)、加密算法内以及 TLS 握手协议期间都需要的随机数。
- C_Sign。 对发送到另一个网络节点的信息进行签名,使该节点能够识别信息的真正来源。
- C_FindObject。 查找由 PKCS #11 管理的对象,例如客户端证书。
- C_GetAttributeValue。 该 API 获取一个对象的属性值,例如,如果该对象是一个密钥类型或一个证书类型。
PKCS #11 管理函数:
- C_Initialize。初始化加密库。
- C_Finalize。 清理加密库使用的资源。
- C_OpenSession。在一个软件应用程序和一个特定的加密令牌之间打开一个会话(或连接)。
- C_CloseSession。 关闭由 C_OpenSession 打开的会话。
- C_Login。 登录到令牌。
- C_GetFunctionList。 获取用于调用 PKCS #11 API 的包含函数指针的结构体。
- C_GetSlotList。 获取可用于访问插槽中的任何令牌的插槽列表。
代码示例
以下是一些示例代码段,展示了如何使用 PKCS #11 API。
Using C_GenerateRandom:
此代码段显示了如何使用 PKCS #11 获取随机数。例如,此函数可用于 FreeRTOS-Plus-TCP,以生成随机 TCP 数字。
CK_RV xGetRandomNumber( uint8_t * pRandomNumber,
size_t xNumBytes )
{
CK_RV xResult = CKR_OK;
CK_SESSION_HANDLE xSession;
CK_FUNCTION_LIST_PTR pxFunctionList;
if( ( pRandomNumber == NULL ) || ( xNumBytes == 0 ) )
{
xResult = CKR_ARGUMENTS_BAD;
}
if( xResult == CKR_OK )
{
xResult = C_GetFunctionList( &pxFunctionList );
}
if( xResult == CKR_OK )
{
xResult = prvGetRandomnessSession( &xSession );
}
if( xResult == CKR_OK )
{
xResult = pxFunctionList->C_GenerateRandom( xSession, pRandomNumber, xNumBytes );
}
return xResult;
}
|
使用 C_GetAttributeValue 获取对象属性的值:
static int prvReadCertificateIntoContext( TLSContext_t * pxTlsContext,
const char * pcLabelName,
CK_OBJECT_CLASS xClass,
mbedtls_x509_crt * pxCertificateContext )
{
BaseType_t xResult = CKR_OK;
CK_ATTRIBUTE xTemplate = { 0 };
CK_OBJECT_HANDLE xCertObj = 0;
/* Get the handle of the certificate. */
xResult = xFindObjectWithLabelAndClass( pxTlsContext->xP11Session,
pcLabelName,
xClass,
&xCertObj );
if ( ( CKR_OK == xResult ) && ( xCertObj == CK_INVALID_HANDLE ) )
{
xResult = CKR_OBJECT_HANDLE_INVALID;
}
/* Query the certificate size. */
if ( 0 == xResult )
{
xTemplate.type = CKA_VALUE;
xTemplate.ulValueLen = 0;
xTemplate.pValue = NULL;
xResult = ( BaseType_t ) pxTlsContext->
pxP11FunctionList->C_GetAttributeValue( pxTlsContext->xP11Session,
xCertObj,
&xTemplate,
1 );
}
/* Create a buffer for the certificate. */
if ( 0 == xResult )
{
xTemplate.pValue = pvPortMalloc( xTemplate.ulValueLen );
if ( NULL == xTemplate.pValue )
{
xResult = ( BaseType_t ) CKR_HOST_MEMORY;
}
}
/* Export the certificate. */
if ( 0 == xResult )
{
xResult = ( BaseType_t ) pxTlsContext->
pxP11FunctionList->C_GetAttributeValue( pxTlsContext->xP11Session,
xCertObj,
&xTemplate,
1 );
}
/* Decode the certificate. */
if ( 0 == xResult )
{
xResult = mbedtls_x509_crt_parse( pxCertificateContext,
( const unsigned char * ) xTemplate.pValue,
xTemplate.ulValueLen );
}
/* Free memory. */
if ( NULL != xTemplate.pValue )
{
vPortFree( xTemplate.pValue );
}
return xResult;
}
|
使用 C_Sign 将私钥的签名添加至我们的消息中:
这是我们 TLS 层代码的一个片段,它使用 PKCS #11 进行 C_Sign 操作。在该示例中,我们在发送 TLS 消息前调用 PKCS #11 层,并要求它使用我们的私钥对我们的消息进行签名。
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.
|