FreeRTOS: PKCS11
PKCS11 Cryptoki Library
Return to main page ↑
C_Sign

Signs single-part data.

CK_DECLARE_FUNCTION( CK_RV, C_Sign )( CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pSignature,
CK_ULONG_PTR pulSignatureLen )
{
P11Session_t * pxSessionObj = prvSessionPointerFromHandle( hSession );
CK_RV xResult = prvCheckValidSessionAndModule( pxSessionObj );
CK_ULONG xSignatureLength = 0;
size_t xExpectedInputLength = 0;
CK_BYTE_PTR pxSignatureBuffer = pSignature;
/* See explanation in prvCheckValidSessionAndModule for this exception. */
/* coverity[misra_c_2012_rule_10_5_violation] */
CK_BBOOL xSignatureGenerated = ( CK_BBOOL ) CK_FALSE;
uint8_t ecSignature[ pkcs11ECDSA_P256_SIGNATURE_LENGTH + 15 ]; /*TODO: Figure out this length. */
int32_t lMbedTLSResult;
if( ( NULL == pulSignatureLen ) || ( NULL == pData ) )
{
xResult = CKR_ARGUMENTS_BAD;
}
if( CKR_OK == xResult )
{
/* Update the signature length. */
if( pxSessionObj->xOperationSignMechanism == CKM_RSA_PKCS )
{
xSignatureLength = pkcs11RSA_2048_SIGNATURE_LENGTH;
xExpectedInputLength = pkcs11RSA_SIGNATURE_INPUT_LENGTH;
}
else if( pxSessionObj->xOperationSignMechanism == CKM_ECDSA )
{
xExpectedInputLength = pkcs11SHA256_DIGEST_LENGTH;
pxSignatureBuffer = ecSignature;
}
else
{
xResult = CKR_OPERATION_NOT_INITIALIZED;
}
}
if( xResult == CKR_OK )
{
/* Calling application is trying to determine length needed for signature buffer. */
if( NULL != pSignature )
{
/* Check that the signature buffer is long enough. */
if( *pulSignatureLen < xSignatureLength )
{
xResult = CKR_BUFFER_TOO_SMALL;
}
/* Check that input data to be signed is the expected length. */
if( CKR_OK == xResult )
{
if( xExpectedInputLength != ulDataLen )
{
xResult = CKR_DATA_LEN_RANGE;
}
}
/* Sign the data.*/
if( CKR_OK == xResult )
{
if( pdTRUE == xSemaphoreTake( pxSessionObj->xSignMutex, portMAX_DELAY ) )
{
lMbedTLSResult = mbedtls_pk_sign( &pxSessionObj->xSignKey,
MBEDTLS_MD_NONE,
pData,
ulDataLen,
pxSignatureBuffer,
&xExpectedInputLength,
mbedtls_ctr_drbg_random,
if( lMbedTLSResult != 0 )
{
PKCS11_PRINT( ( "mbedTLS sign failed with error %s : ",
mbedtlsHighLevelCodeOrDefault( lMbedTLSResult ) ) );
PKCS11_PRINT( ( "%s \r\n",
mbedtlsLowLevelCodeOrDefault( lMbedTLSResult ) ) );
xResult = CKR_FUNCTION_FAILED;
}
( void ) xSemaphoreGive( pxSessionObj->xSignMutex );
/* See explanation in prvCheckValidSessionAndModule for this exception. */
/* coverity[misra_c_2012_rule_10_5_violation] */
xSignatureGenerated = ( CK_BBOOL ) CK_TRUE;
}
else
{
xResult = CKR_CANT_LOCK;
}
}
}
}
if( xResult == CKR_OK )
{
/* If this an EC signature, reformat from ASN.1 encoded to 64-byte R & S components */
/* See explanation in prvCheckValidSessionAndModule for this exception. */
/* coverity[misra_c_2012_rule_10_5_violation] */
if( ( pxSessionObj->xOperationSignMechanism == CKM_ECDSA ) && ( xSignatureGenerated == ( CK_BBOOL ) CK_TRUE ) )
{
lMbedTLSResult = PKI_mbedTLSSignatureToPkcs11Signature( pSignature, ecSignature );
if( lMbedTLSResult != 0 )
{
xResult = CKR_FUNCTION_FAILED;
}
}
}
if( ( xResult == CKR_OK ) || ( xResult == CKR_BUFFER_TOO_SMALL ) )
{
*pulSignatureLen = xSignatureLength;
}
/* Complete the operation in the context. */
if( ( xResult != CKR_BUFFER_TOO_SMALL ) && ( xResult != CKR_SESSION_HANDLE_INVALID ) )
{
}
return xResult;
}
See also
C_SignInit() initiates signatures signature creation.
Note
C_Sign() parameters are shared by a session. Calling C_SignInit() & C_Sign() with the same session across different tasks may lead to unexpected results.
Parameters
[in]hSessionHandle of a valid PKCS #11 session.
[in]pDataData to be signed. Note: Some applications may require this data to be hashed before passing to C_Sign().
[in]ulDataLenLength of pucData, in bytes.
[out]pSignatureBuffer where signature will be placed. Caller is responsible for allocating memory. Providing NULL for this input will cause pulSignatureLen to be updated for length of buffer required.
[in,out]pulSignatureLenLength of pucSignature buffer. If pucSignature is non-NULL, pulSignatureLen is updated to contain the actual signature length. If pucSignature is NULL, pulSignatureLen is updated to the buffer length required for signature data.
Returns
CKR_OK if successful. Else, see PKCS #11 specification for more information.
CK_DECLARE_FUNCTION
#define CK_DECLARE_FUNCTION(returnType, name)
Macro for defining a PKCS #11 functions.
Definition: iot_pkcs11.h:66
pkcs11RSA_SIGNATURE_INPUT_LENGTH
#define pkcs11RSA_SIGNATURE_INPUT_LENGTH
Length of RSA signature data before padding.
Definition: iot_pkcs11.h:119
P11Session_t::xSignKey
mbedtls_pk_context xSignKey
Signing key. Set during C_SignInit.
Definition: iot_pkcs11_mbedtls.c:228
pkcs11SHA256_DIGEST_LENGTH
#define pkcs11SHA256_DIGEST_LENGTH
Length of a SHA256 digest, in bytes.
Definition: iot_pkcs11.h:83
PKI_mbedTLSSignatureToPkcs11Signature
BaseType_t PKI_mbedTLSSignatureToPkcs11Signature(uint8_t *pxSignaturePKCS, const uint8_t *pxMbedSignature)
Converts an ECDSA P-256 signature from the format provided by mbedTLS to the format expected by PKCS ...
P11Session_t::xOperationSignMechanism
CK_MECHANISM_TYPE xOperationSignMechanism
Mechanism of the sign operation in progress. Set during C_SignInit.
Definition: iot_pkcs11_mbedtls.c:226
mbedtlsLowLevelCodeOrDefault
#define mbedtlsLowLevelCodeOrDefault(mbedTlsCode)
Utility for converting the level-level code in an mbedTLS error to string, if the code-contains a lev...
Definition: iot_pkcs11_mbedtls.c:94
PKCS11_PRINT
#define PKCS11_PRINT(X)
Macro for logging in PKCS #11.
Definition: iot_pkcs11_mbedtls.c:103
pkcs11RSA_2048_SIGNATURE_LENGTH
#define pkcs11RSA_2048_SIGNATURE_LENGTH
Length of PKCS #11 signature for RSA 2048 key, in bytes.
Definition: iot_pkcs11.h:111
prvSessionPointerFromHandle
static P11Session_t * prvSessionPointerFromHandle(CK_SESSION_HANDLE xSession)
Maps an opaque caller session handle into its internal state structure.
Definition: iot_pkcs11_mbedtls.c:287
C_Sign
CK_RV C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
Signs single-part data.
Definition: iot_pkcs11_mbedtls.c:3535
prvCheckValidSessionAndModule
static CK_RV prvCheckValidSessionAndModule(const P11Session_t *pxSession)
Helper to check if the current session is initialized and valid.
Definition: iot_pkcs11_mbedtls.c:248
P11Struct_t::xMbedDrbgCtx
mbedtls_ctr_drbg_context xMbedDrbgCtx
CTR-DRBG context for PKCS #11 module - used to generate pseudo-random numbers.
Definition: iot_pkcs11_mbedtls.c:203
mbedtlsHighLevelCodeOrDefault
#define mbedtlsHighLevelCodeOrDefault(mbedTlsCode)
Utility for converting the high-level code in an mbedTLS error to string, if the code-contains a high...
Definition: iot_pkcs11_mbedtls.c:86
P11Session_t
Session structure.
Definition: iot_pkcs11_mbedtls.c:217
P11Session_t::xSignMutex
SemaphoreHandle_t xSignMutex
Protects the signing key from being modified while in use.
Definition: iot_pkcs11_mbedtls.c:227
pkcs11ECDSA_P256_SIGNATURE_LENGTH
#define pkcs11ECDSA_P256_SIGNATURE_LENGTH
Length of a curve P-256 ECDSA signature, in bytes. PKCS #11 EC signatures are represented as a 32-bit...
Definition: iot_pkcs11.h:90
pkcs11NO_OPERATION
#define pkcs11NO_OPERATION
Indicates that no PKCS #11 operation is underway for given session.
Definition: iot_pkcs11_mbedtls.c:117
xP11Context
static P11Struct_t xP11Context
The global PKCS #11 module object. Entropy/randomness and object lists are shared across PKCS #11 ses...
Definition: iot_pkcs11_mbedtls.c:238