corePKCS11  V3.0.0
PKCS #11 Cryptoki Library
C_GenerateKeyPair
CK_DECLARE_FUNCTION( CK_RV, C_GenerateKeyPair )( CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_ATTRIBUTE_PTR pPublicKeyTemplate,
CK_ULONG ulPublicKeyAttributeCount,
CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
CK_ULONG ulPrivateKeyAttributeCount,
CK_OBJECT_HANDLE_PTR phPublicKey,
CK_OBJECT_HANDLE_PTR phPrivateKey )
{
uint8_t * pucDerFile = mbedtls_calloc( 1, pkcs11KEY_GEN_MAX_DER_SIZE );
int32_t lMbedTLSResult = 0;
uint32_t ulIndex = 0;
mbedtls_pk_context xCtx = { 0 };
CK_ATTRIBUTE_PTR pxPrivateLabel = NULL;
CK_ATTRIBUTE_PTR pxPublicLabel = NULL;
CK_OBJECT_HANDLE xPalPublic = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE xPalPrivate = CK_INVALID_HANDLE;
uint32_t xPublicRequiredAttributeMap = ( LABEL_IN_TEMPLATE | EC_PARAMS_IN_TEMPLATE | VERIFY_IN_TEMPLATE );
uint32_t xPrivateRequiredAttributeMap = ( LABEL_IN_TEMPLATE | PRIVATE_IN_TEMPLATE | SIGN_IN_TEMPLATE );
uint32_t xAttributeMap = 0;
const P11Session_t * pxSession = prvSessionPointerFromHandle( hSession );
CK_RV xResult = prvCheckValidSessionAndModule( pxSession );
#if ( pkcs11configSUPPRESS_ECDSA_MECHANISM == 1 )
if( xResult == CKR_OK )
{
LogDebug( ( "ECDSA Mechanism is suppressed on this port." ) );
xResult = CKR_MECHANISM_INVALID;
}
#endif
if( xResult == CKR_OK )
{
if( ( pPublicKeyTemplate == NULL ) ||
( pPrivateKeyTemplate == NULL ) ||
( phPublicKey == NULL ) ||
( phPrivateKey == NULL ) ||
( pMechanism == NULL ) )
{
LogError( ( "Failed generating a key pair. One of the arguments "
"was NULL." ) );
xResult = CKR_ARGUMENTS_BAD;
}
}
if( xResult == CKR_OK )
{
if( pucDerFile == NULL )
{
LogError( ( "Failed generating a key pair. Could not allocated a "
"buffer of size %u bytes.", ( unsigned int ) pkcs11KEY_GEN_MAX_DER_SIZE ) );
xResult = CKR_HOST_MEMORY;
}
}
if( xResult == CKR_OK )
{
if( CKM_EC_KEY_PAIR_GEN != pMechanism->mechanism )
{
LogError( ( "Failed generating a key pair. CKM_EC_KEY_PAIR_GEN is "
"the only valid key generation mechanism currently." ) );
xResult = CKR_MECHANISM_INVALID;
}
}
if( xResult == CKR_OK )
{
for( ulIndex = 0; ulIndex < ulPrivateKeyAttributeCount; ++ulIndex )
{
xResult = prvCheckGenerateKeyPairPrivateTemplate( &pxPrivateLabel,
&pPrivateKeyTemplate[ ulIndex ],
&xAttributeMap );
if( xResult != CKR_OK )
{
break;
}
}
if( ( xResult == CKR_OK ) && ( ( xAttributeMap & xPrivateRequiredAttributeMap ) != xPrivateRequiredAttributeMap ) )
{
LogError( ( "Failed generating a key pair. Attributes were missing "
"in the private key template." ) );
xResult = CKR_TEMPLATE_INCOMPLETE;
}
}
if( xResult == CKR_OK )
{
xAttributeMap = 0;
for( ulIndex = 0; ulIndex < ulPublicKeyAttributeCount; ++ulIndex )
{
xResult = prvCheckGenerateKeyPairPublicTemplate( &pxPublicLabel,
&pPublicKeyTemplate[ ulIndex ],
&xAttributeMap );
if( xResult != CKR_OK )
{
break;
}
}
if( ( xResult == CKR_OK ) && ( ( xAttributeMap & xPublicRequiredAttributeMap ) != xPublicRequiredAttributeMap ) )
{
LogError( ( "Failed generating a key pair. Attributes were missing "
"in the public key template." ) );
xResult = CKR_TEMPLATE_INCOMPLETE;
}
}
if( xResult == CKR_OK )
{
mbedtls_pk_init( &xCtx );
lMbedTLSResult = mbedtls_pk_setup( &xCtx, mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) );
if( lMbedTLSResult != 0 )
{
LogError( ( "Failed generating a key pair. mbedtls_pk_setup failed: "
"mbed TLS error = %s : %s.",
mbedtlsHighLevelCodeOrDefault( lMbedTLSResult ),
mbedtlsLowLevelCodeOrDefault( lMbedTLSResult ) ) );
xResult = CKR_FUNCTION_FAILED;
}
else
{
LogDebug( ( "mbedtls_pk_setup was successful." ) );
}
}
if( xResult == CKR_OK )
{
lMbedTLSResult = mbedtls_ecp_gen_key( MBEDTLS_ECP_DP_SECP256R1,
mbedtls_pk_ec( xCtx ),
mbedtls_ctr_drbg_random,
&xP11Context.xMbedDrbgCtx );
if( 0 != lMbedTLSResult )
{
LogError( ( "Failed generating a key pair. mbedtls_ecp_gen_key "
"failed: mbed TLS error = %s : %s.",
mbedtlsHighLevelCodeOrDefault( lMbedTLSResult ),
mbedtlsLowLevelCodeOrDefault( lMbedTLSResult ) ) );
xResult = CKR_FUNCTION_FAILED;
}
}
if( xResult == CKR_OK )
{
lMbedTLSResult = mbedtls_pk_write_pubkey_der( &xCtx, pucDerFile, pkcs11KEY_GEN_MAX_DER_SIZE );
if( lMbedTLSResult > 0 )
{
xPalPublic = PKCS11_PAL_SaveObject( pxPublicLabel, pucDerFile + pkcs11KEY_GEN_MAX_DER_SIZE - lMbedTLSResult, ( uint32_t ) lMbedTLSResult );
LogDebug( ( "PKCS11_PAL_SaveObject returned a %lu PAL handle value "
"for the public key.", ( unsigned long int ) xPalPublic ) );
}
else
{
LogError( ( "Failed generating a key pair. "
"mbedtls_pk_write_pubkey_der failed: mbed TLS error = %s : %s.",
mbedtlsHighLevelCodeOrDefault( lMbedTLSResult ),
mbedtlsLowLevelCodeOrDefault( lMbedTLSResult ) ) );
xResult = CKR_GENERAL_ERROR;
}
}
if( xResult == CKR_OK )
{
lMbedTLSResult = mbedtls_pk_write_key_der( &xCtx, pucDerFile, pkcs11KEY_GEN_MAX_DER_SIZE );
if( lMbedTLSResult > 0 )
{
xPalPrivate = PKCS11_PAL_SaveObject( pxPrivateLabel, pucDerFile + pkcs11KEY_GEN_MAX_DER_SIZE - lMbedTLSResult, ( uint32_t ) lMbedTLSResult );
LogDebug( ( "PKCS11_PAL_SaveObject returned a %lu PAL handle value "
"for the private key.", ( unsigned long int ) xPalPrivate ) );
}
else
{
LogError( ( "Failed generating a key pair. mbedtls_pk_write_key_der "
"failed: mbed TLS error = %s : %s.",
mbedtlsHighLevelCodeOrDefault( lMbedTLSResult ),
mbedtlsLowLevelCodeOrDefault( lMbedTLSResult ) ) );
xResult = CKR_GENERAL_ERROR;
}
}
if( ( xPalPublic != CK_INVALID_HANDLE ) && ( xPalPrivate != CK_INVALID_HANDLE ) )
{
xResult = prvAddObjectToList( xPalPrivate, phPrivateKey, pxPrivateLabel->pValue, pxPrivateLabel->ulValueLen );
if( xResult == CKR_OK )
{
xResult = prvAddObjectToList( xPalPublic, phPublicKey, pxPublicLabel->pValue, pxPublicLabel->ulValueLen );
if( xResult != CKR_OK )
{
( void ) PKCS11_PAL_DestroyObject( *phPrivateKey );
LogDebug( ( "Destroyed %lu private key handle due to errors.", ( unsigned long int ) *phPrivateKey ) );
}
}
else
{
LogDebug( ( "Could not add private key to object list." ) );
}
}
/* Clean up. */
mbedtls_free( pucDerFile );
mbedtls_pk_free( &xCtx );
return xResult;
}
PKCS11_PAL_DestroyObject
CK_RV PKCS11_PAL_DestroyObject(CK_OBJECT_HANDLE xHandle)
Delete an object from NVM.
CK_DECLARE_FUNCTION
#define CK_DECLARE_FUNCTION(returnType, name)
Macro for defining a PKCS #11 functions.
Definition: core_pkcs11.h:72
PKCS11_PAL_SaveObject
CK_OBJECT_HANDLE PKCS11_PAL_SaveObject(CK_ATTRIBUTE_PTR pxLabel, CK_BYTE_PTR pucData, CK_ULONG ulDataSize)
Saves an object in non-volatile storage.