[修改] 增加freeRTOS

1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
2023-05-06 16:43:01 +00:00
commit a345df017b
20944 changed files with 11094377 additions and 0 deletions

View File

@ -0,0 +1,402 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "core_pkcs11_config.h"
#include "core_pkcs11_config_defaults.h"
#include "core_pkcs11.h"
/* C runtime includes. */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
/**
* @file core_pkcs11.c
* @brief corePKCS11 Interface.
*
* This file contains wrapper functions for common PKCS #11 operations.
*/
/*-----------------------------------------------------------*/
/** @brief Open a PKCS #11 Session.
*
* \param[out] pxSession Pointer to the session handle to be created.
* \param[out] xSlotId Slot ID to be used for the session.
*
* \return CKR_OK or PKCS #11 error code. (PKCS #11 error codes are positive).
*/
static CK_RV prvOpenSession( CK_SESSION_HANDLE * pxSession,
CK_SLOT_ID xSlotId )
{
CK_RV xResult;
CK_FUNCTION_LIST_PTR pxFunctionList;
xResult = C_GetFunctionList( &pxFunctionList );
if( ( xResult == CKR_OK ) && ( pxFunctionList != NULL ) && ( pxFunctionList->C_OpenSession != NULL ) )
{
xResult = pxFunctionList->C_OpenSession( xSlotId,
CKF_SERIAL_SESSION | CKF_RW_SESSION,
NULL, /* Application defined pointer. */
NULL, /* Callback function. */
pxSession );
}
return xResult;
}
/*-----------------------------------------------------------*/
CK_RV xGetSlotList( CK_SLOT_ID ** ppxSlotId,
CK_ULONG * pxSlotCount )
{
CK_RV xResult = CKR_OK;
CK_FUNCTION_LIST_PTR pxFunctionList = NULL;
CK_SLOT_ID * pxSlotId = NULL;
if( ( ppxSlotId == NULL ) || ( pxSlotCount == NULL ) )
{
xResult = CKR_ARGUMENTS_BAD;
}
else
{
xResult = C_GetFunctionList( &pxFunctionList );
if( pxFunctionList == NULL )
{
xResult = CKR_FUNCTION_FAILED;
}
else if( pxFunctionList->C_GetSlotList == NULL )
{
xResult = CKR_FUNCTION_FAILED;
}
else
{
/* MISRA */
}
}
if( xResult == CKR_OK )
{
xResult = pxFunctionList->C_GetSlotList( CK_TRUE, /* Token Present. */
NULL, /* We just want to know how many slots there are. */
pxSlotCount );
}
if( xResult == CKR_OK )
{
if( *pxSlotCount == ( ( sizeof( CK_SLOT_ID ) * ( *pxSlotCount ) ) / ( sizeof( CK_SLOT_ID ) ) ) )
{
/* MISRA Ref 11.5.1 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxSlotId = pkcs11configPKCS11_MALLOC( sizeof( CK_SLOT_ID ) * ( *pxSlotCount ) );
if( pxSlotId == NULL )
{
xResult = CKR_HOST_MEMORY;
}
else
{
*ppxSlotId = pxSlotId;
}
}
else
{
xResult = CKR_HOST_MEMORY;
}
}
if( xResult == CKR_OK )
{
xResult = pxFunctionList->C_GetSlotList( CK_TRUE, pxSlotId, pxSlotCount );
}
if( ( xResult != CKR_OK ) && ( pxSlotId != NULL ) )
{
pkcs11configPKCS11_FREE( pxSlotId );
*ppxSlotId = NULL;
}
return xResult;
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
#ifdef CreateMutex
#undef CreateMutex /* This is a workaround because CreateMutex is redefined to CreateMutexW in synchapi.h in windows. :/ */
#endif
/*-----------------------------------------------------------*/
CK_RV xInitializePKCS11( void )
{
CK_RV xResult = CKR_OK;
CK_FUNCTION_LIST_PTR pxFunctionList = NULL;
CK_C_INITIALIZE_ARGS xInitArgs = { 0 };
xInitArgs.CreateMutex = NULL;
xInitArgs.DestroyMutex = NULL;
xInitArgs.LockMutex = NULL;
xInitArgs.UnlockMutex = NULL;
xInitArgs.flags = CKF_OS_LOCKING_OK;
xInitArgs.pReserved = NULL;
xResult = C_GetFunctionList( &pxFunctionList );
/* Initialize the PKCS #11 module. */
if( ( xResult == CKR_OK ) && ( pxFunctionList != NULL ) && ( pxFunctionList->C_Initialize != NULL ) )
{
xResult = pxFunctionList->C_Initialize( &xInitArgs );
}
return xResult;
}
/*-----------------------------------------------------------*/
CK_RV xInitializePkcs11Token( void )
{
CK_RV xResult = CKR_OK;
CK_FUNCTION_LIST_PTR pxFunctionList = NULL;
CK_SLOT_ID * pxSlotId = NULL;
CK_ULONG xSlotCount;
CK_FLAGS xTokenFlags = 0;
CK_TOKEN_INFO_PTR pxTokenInfo = NULL;
xResult = C_GetFunctionList( &pxFunctionList );
if( ( pxFunctionList == NULL ) || ( pxFunctionList->C_GetTokenInfo == NULL ) || ( pxFunctionList->C_InitToken == NULL ) )
{
xResult = CKR_FUNCTION_FAILED;
}
if( xResult == CKR_OK )
{
xResult = xInitializePKCS11();
}
if( ( xResult == CKR_OK ) || ( xResult == CKR_CRYPTOKI_ALREADY_INITIALIZED ) )
{
xResult = xGetSlotList( &pxSlotId, &xSlotCount );
}
if( ( xResult == CKR_OK ) &&
( NULL != pxFunctionList->C_GetTokenInfo ) &&
( NULL != pxFunctionList->C_InitToken ) )
{
/* Check if the token requires further initialization. */
/* MISRA Ref 11.5.1 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxTokenInfo = pkcs11configPKCS11_MALLOC( sizeof( CK_TOKEN_INFO ) );
if( pxTokenInfo != NULL )
{
/* We will take the first slot available. If your application
* has multiple slots, insert logic for selecting an appropriate
* slot here.
*/
xResult = pxFunctionList->C_GetTokenInfo( pxSlotId[ 0 ], pxTokenInfo );
}
else
{
xResult = CKR_HOST_MEMORY;
}
if( CKR_OK == xResult )
{
xTokenFlags = pxTokenInfo->flags;
}
if( ( CKR_OK == xResult ) && ( ( CKF_TOKEN_INITIALIZED & xTokenFlags ) != CKF_TOKEN_INITIALIZED ) )
{
/* Initialize the token if it is not already. */
xResult = pxFunctionList->C_InitToken( pxSlotId[ 0 ],
( CK_UTF8CHAR_PTR ) pkcs11configPKCS11_DEFAULT_USER_PIN,
sizeof( pkcs11configPKCS11_DEFAULT_USER_PIN ) - 1UL,
( CK_UTF8CHAR_PTR ) "FreeRTOS" );
}
}
if( pxTokenInfo != NULL )
{
pkcs11configPKCS11_FREE( pxTokenInfo );
}
if( pxSlotId != NULL )
{
pkcs11configPKCS11_FREE( pxSlotId );
}
return xResult;
}
/*-----------------------------------------------------------*/
CK_RV xInitializePkcs11Session( CK_SESSION_HANDLE * pxSession )
{
CK_RV xResult = CKR_OK;
CK_SLOT_ID * pxSlotId = NULL;
CK_FUNCTION_LIST_PTR pxFunctionList = NULL;
CK_ULONG xSlotCount = 0;
xResult = C_GetFunctionList( &pxFunctionList );
if( pxSession == NULL )
{
xResult = CKR_ARGUMENTS_BAD;
}
/* Initialize the module. */
if( xResult == CKR_OK )
{
xResult = xInitializePKCS11();
if( xResult == CKR_CRYPTOKI_ALREADY_INITIALIZED )
{
xResult = CKR_OK;
}
}
/* Get a list of slots available. */
if( xResult == CKR_OK )
{
xResult = xGetSlotList( &pxSlotId, &xSlotCount );
}
/* Open a PKCS #11 session. */
if( ( xResult == CKR_OK ) && ( pxSlotId != NULL ) && ( xSlotCount >= 1UL ) )
{
/* We will take the first slot available.
* If your application has multiple slots, insert logic
* for selecting an appropriate slot here.
*/
xResult = prvOpenSession( pxSession, pxSlotId[ 0 ] );
/* Free the memory allocated by xGetSlotList. */
pkcs11configPKCS11_FREE( pxSlotId );
}
if( ( xResult == CKR_OK ) && ( pxFunctionList != NULL ) && ( pxFunctionList->C_Login != NULL ) )
{
xResult = pxFunctionList->C_Login( *pxSession,
CKU_USER,
( CK_UTF8CHAR_PTR ) pkcs11configPKCS11_DEFAULT_USER_PIN,
sizeof( pkcs11configPKCS11_DEFAULT_USER_PIN ) - 1UL );
}
return xResult;
}
/*-----------------------------------------------------------*/
CK_RV xFindObjectWithLabelAndClass( CK_SESSION_HANDLE xSession,
char * pcLabelName,
CK_ULONG ulLabelNameLen,
CK_OBJECT_CLASS xClass,
CK_OBJECT_HANDLE_PTR pxHandle )
{
CK_RV xResult = CKR_OK;
CK_ULONG ulCount = 0;
CK_FUNCTION_LIST_PTR pxFunctionList = NULL;
CK_ATTRIBUTE xTemplate[ 2 ] = { 0 };
if( ( pcLabelName == NULL ) || ( pxHandle == NULL ) )
{
xResult = CKR_ARGUMENTS_BAD;
}
else
{
xTemplate[ 0 ].type = CKA_LABEL;
xTemplate[ 0 ].pValue = ( CK_VOID_PTR ) pcLabelName;
xTemplate[ 0 ].ulValueLen = ulLabelNameLen;
xTemplate[ 1 ].type = CKA_CLASS;
xTemplate[ 1 ].pValue = &xClass;
xTemplate[ 1 ].ulValueLen = sizeof( CK_OBJECT_CLASS );
xResult = C_GetFunctionList( &pxFunctionList );
if( ( pxFunctionList == NULL ) || ( pxFunctionList->C_FindObjectsInit == NULL ) ||
( pxFunctionList->C_FindObjects == NULL ) || ( pxFunctionList->C_FindObjectsFinal == NULL ) )
{
xResult = CKR_FUNCTION_FAILED;
}
}
/* Initialize the FindObject state in the underlying PKCS #11 module based
* on the search template provided by the caller. */
if( CKR_OK == xResult )
{
xResult = pxFunctionList->C_FindObjectsInit( xSession, xTemplate, sizeof( xTemplate ) / sizeof( CK_ATTRIBUTE ) );
}
if( CKR_OK == xResult )
{
/* Find the first matching object, if any. */
xResult = pxFunctionList->C_FindObjects( xSession,
pxHandle,
1UL,
&ulCount );
}
if( CKR_OK == xResult )
{
xResult = pxFunctionList->C_FindObjectsFinal( xSession );
}
if( ( NULL != pxHandle ) && ( ulCount == 0UL ) )
{
*pxHandle = CK_INVALID_HANDLE;
}
return xResult;
}
/*-----------------------------------------------------------*/
CK_RV vAppendSHA256AlgorithmIdentifierSequence( const uint8_t * puc32ByteHashedMessage,
uint8_t * puc51ByteHashOidBuffer )
{
CK_RV xResult = CKR_OK;
const uint8_t pucOidSequence[] = pkcs11STUFF_APPENDED_TO_RSA_SIG;
if( ( puc32ByteHashedMessage == NULL ) || ( puc51ByteHashOidBuffer == NULL ) )
{
xResult = CKR_ARGUMENTS_BAD;
}
if( xResult == CKR_OK )
{
( void ) memcpy( puc51ByteHashOidBuffer, pucOidSequence, sizeof( pucOidSequence ) );
( void ) memcpy( &puc51ByteHashOidBuffer[ sizeof( pucOidSequence ) ], puc32ByteHashedMessage, 32 );
}
return xResult;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,213 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file core_pki_utils.c
* @brief Helper functions for PKCS #11
*/
#include "core_pki_utils.h"
/* CRT includes. */
#include <stdint.h>
#include <string.h>
/**
* @ingroup pkcs11_macros
* @brief Failure value for PKI utils functions.
*/
#define FAILURE ( -1 )
/*-----------------------------------------------------------*/
/* Convert the EC signature from DER encoded to PKCS #11 format. */
/* @[declare pkcs11_utils_pkipkcs11signaturetombedtlssignature] */
int8_t PKI_mbedTLSSignatureToPkcs11Signature( uint8_t * pxSignaturePKCS,
const uint8_t * pxMbedSignature )
{
int8_t xReturn = 0;
const uint8_t * pxNextLength = NULL;
uint8_t ucSigComponentLength;
if( ( pxSignaturePKCS == NULL ) || ( pxMbedSignature == NULL ) )
{
xReturn = FAILURE;
}
if( xReturn == 0 )
{
/* The signature has the format
* SEQUENCE LENGTH (of entire rest of signature)
* INTEGER LENGTH (of R component)
* INTEGER LENGTH (of S component)
*/
/* The 4th byte contains the length of the R component */
ucSigComponentLength = pxMbedSignature[ 3 ];
/* The new signature will be 64 bytes long (32 bytes for R, 32 bytes for S).
* Zero this buffer out in case a component is shorter than 32 bytes. */
( void ) memset( pxSignaturePKCS, 0, 64 );
/********* R Component. *********/
/* R components are represented by mbedTLS as 33 bytes when the first bit is zero to avoid any sign confusion. */
if( ucSigComponentLength == 33UL )
{
/* Chop off the leading zero. The first 4 bytes were SEQUENCE, LENGTH, INTEGER, LENGTH, 0x00 padding. */
( void ) memcpy( pxSignaturePKCS, &pxMbedSignature[ 5 ], 32 );
/* SEQUENCE, LENGTH, INTEGER, LENGTH, leading zero, R, S's integer tag */
pxNextLength = &pxMbedSignature[ 5U + 32U + 1U ];
}
else if( ucSigComponentLength <= 32UL )
{
/* The R component is 32 bytes or less. Copy so that it is properly represented as a 32 byte value,
* leaving leading 0 pads at beginning if necessary. */
( void ) memcpy( &pxSignaturePKCS[ 32UL - ucSigComponentLength ], /* If the R component is less than 32 bytes, leave the leading zeros. */
&pxMbedSignature[ 4 ], /* SEQUENCE, LENGTH, INTEGER, LENGTH, (R component begins as the 5th byte) */
ucSigComponentLength );
pxNextLength = &pxMbedSignature[ 4U + ucSigComponentLength + 1U ]; /* Move the pointer to get rid of
* SEQUENCE, LENGTH, INTEGER, LENGTH, R Component, S integer tag. */
}
else
{
xReturn = FAILURE;
}
/********** S Component. ***********/
if( xReturn != FAILURE )
{
/* Now pxNextLength is pointing to the length of the S component. */
ucSigComponentLength = pxNextLength[ 0 ];
if( ucSigComponentLength == 33UL )
{
( void ) memcpy( &pxSignaturePKCS[ 32 ],
&pxNextLength[ 2 ], /*LENGTH (of S component), 0x00 padding, S component is 3rd byte - we want to skip the leading zero. */
32 );
}
else if( ucSigComponentLength <= 32UL )
{
/* The S component is 32 bytes or less. Copy so that it is properly represented as a 32 byte value,
* leaving leading 0 pads at beginning if necessary. */
( void ) memcpy( &pxSignaturePKCS[ 64UL - ucSigComponentLength ],
&pxNextLength[ 1 ],
ucSigComponentLength );
}
else
{
xReturn = FAILURE;
}
}
}
return xReturn;
}
/* @[declare pkcs11_utils_pkipkcs11signaturetombedtlssignature] */
/*-----------------------------------------------------------*/
/* Convert an EC signature from PKCS #11 format to DER encoded. */
/* @[declare pkcs11_utils_pkimbedtlssignaturetopkcs11signature] */
int8_t PKI_pkcs11SignatureTombedTLSSignature( uint8_t * pucSig,
size_t * pxSigLen )
{
int8_t xReturn = 0;
uint8_t * pucSigPtr = NULL;
uint8_t ucTemp[ 64 ] = { 0 }; /* A temporary buffer for the pre-formatted signature. */
if( ( pucSig == NULL ) || ( pxSigLen == NULL ) )
{
xReturn = FAILURE;
}
if( xReturn == 0 )
{
( void ) memcpy( ucTemp, pucSig, 64 );
/* The ASN.1 encoded signature has the format
* SEQUENCE LENGTH (of entire rest of signature)
* INTEGER LENGTH (of R component)
* INTEGER LENGTH (of S component)
*
* and a signature coming out of PKCS #11 C_Sign will have the format
* R[32] + S[32]
*/
pucSig[ 0 ] = 0x30; /* Sequence. */
pucSig[ 1 ] = 0x44; /* The minimum length the signature could be. */
pucSig[ 2 ] = 0x02; /* Integer. */
/*************** R Component. *******************/
/* If the first bit is one, pre-append a 00 byte.
* This prevents the number from being interpreted as negative. */
if( ( ucTemp[ 0 ] & 0x80UL ) == 0x80UL )
{
pucSig[ 1 ]++; /* Increment the length of the structure to account for the 0x00 pad. */
pucSig[ 3 ] = 0x21; /* Increment the length of the R value to account for the 0x00 pad. */
pucSig[ 4 ] = 0x0; /* Write the 0x00 pad. */
( void ) memcpy( &pucSig[ 5 ], ucTemp, 32 ); /* Copy the 32-byte R value. */
pucSigPtr = pucSig + 33; /* Increment the pointer to compensate for padded R length. */
}
else
{
pucSig[ 3 ] = 0x20; /* R length with be 32 bytes. */
( void ) memcpy( &pucSig[ 4 ], ucTemp, 32 ); /* Copy 32 bytes of R into the signature buffer. */
pucSigPtr = pucSig + 32; /* Increment the pointer for 32 byte R length. */
}
pucSigPtr += 4; /* Increment the pointer to offset the SEQUENCE, LENGTH, R-INTEGER, LENGTH. */
pucSigPtr[ 0 ] = 0x02; /* INTEGER tag for S. */
pucSigPtr += 1; /* Increment over S INTEGER tag. */
/******************* S Component. ****************/
/* If the first bit is one, pre-append a 00 byte.
* This prevents the number from being interpreted as negative. */
if( ( ucTemp[ 32 ] & 0x80UL ) == 0x80UL )
{
pucSig[ 1 ]++; /* Increment the length of the structure to account for the 0x00 pad. */
pucSigPtr[ 0 ] = 0x21; /* Increment the length of the S value to account for the 0x00 pad. */
pucSigPtr[ 1 ] = 0x00; /* Write the 0x00 pad. */
pucSigPtr += 2; /* pucSigPtr was pointing at the S-length. Increment by 2 to hop over length and 0 padding. */
( void ) memcpy( pucSigPtr, &ucTemp[ 32 ], 32 ); /* Copy the S value. */
}
else
{
pucSigPtr[ 0 ] = 0x20; /* S length will be 32 bytes. */
pucSigPtr++; /* Hop pointer over the length byte. */
( void ) memcpy( pucSigPtr, &ucTemp[ 32 ], 32 ); /* Copy the S value. */
}
/* The total signature length is the length of the R and S integers plus 2 bytes for
* the SEQUENCE and LENGTH wrapping the entire struct. */
*pxSigLen = pucSig[ 1 ] + 2UL;
}
return xReturn;
}
/* @[declare pkcs11_utils_pkimbedtlssignaturetopkcs11signature] */

View File

@ -0,0 +1,272 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file mbedtls_utils.c
* @brief Helper functions originating from mbedTLS.
*/
/* Standard includes. */
#include <string.h>
/* mbedTLS includes. */
#include "mbedtls/base64.h"
#include "mbedtls/rsa.h"
#include "mbedtls/asn1.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/oid.h"
/*-----------------------------------------------------------*/
/* @brief Converts PEM documents into DER formatted byte arrays.
* This is a helper function from mbedTLS util pem2der.c
* (https://github.com/ARMmbed/mbedtls/blob/development/programs/util/pem2der.c#L75)
*
* \param pucInput[in] Pointer to PEM object
* \param xLen[in] Length of PEM object
* \param pucOutput[out] Pointer to buffer where DER oboject will be placed
* \param pxOlen[in/out] Pointer to length of DER buffer. This value is updated
* to contain the actual length of the converted DER object.
*
* \return 0 if successful. Negative if conversion failed. If buffer is not
* large enough to hold converted object, pxOlen is still updated but -1 is returned.
*
*/
int convert_pem_to_der( const unsigned char * pucInput,
size_t xLen,
unsigned char * pucOutput,
size_t * pxOlen )
{
int lRet;
const unsigned char * pucS1;
const unsigned char * pucS2;
const unsigned char * pucEnd = pucInput + xLen;
size_t xOtherLen = 0;
pucS1 = ( unsigned char * ) strstr( ( const char * ) pucInput, "-----BEGIN" );
if( pucS1 == NULL )
{
return( -1 );
}
pucS2 = ( unsigned char * ) strstr( ( const char * ) pucInput, "-----END" );
if( pucS2 == NULL )
{
return( -1 );
}
pucS1 += 10;
while( pucS1 < pucEnd && *pucS1 != '-' )
{
pucS1++;
}
while( pucS1 < pucEnd && *pucS1 == '-' )
{
pucS1++;
}
if( *pucS1 == '\r' )
{
pucS1++;
}
if( *pucS1 == '\n' )
{
pucS1++;
}
if( ( pucS2 <= pucS1 ) || ( pucS2 > pucEnd ) )
{
return( -1 );
}
lRet = mbedtls_base64_decode( NULL, 0, &xOtherLen, ( const unsigned char * ) pucS1, pucS2 - pucS1 );
if( lRet == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
{
return( lRet );
}
if( xOtherLen > *pxOlen )
{
return( -1 );
}
if( ( lRet = mbedtls_base64_decode( pucOutput, xOtherLen, &xOtherLen, ( const unsigned char * ) pucS1,
pucS2 - pucS1 ) ) != 0 )
{
return( lRet );
}
*pxOlen = xOtherLen;
return( 0 );
}
/*-----------------------------------------------------------*/
/* This function is a modified version of the static function
* rsa_rsassa_pkcs1_v15_encode() inside of rsa.c in mbedTLS. It has been extracted
* so that corePKCS11 libraries and testing may use it. */
/* Construct a PKCS v1.5 encoding of a hashed message
*
* This is used both for signature generation and verification.
*
* Parameters:
* - md_alg: Identifies the hash algorithm used to generate the given hash;
* MBEDTLS_MD_NONE if raw data is signed.
* - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE.
* - hash: Buffer containing the hashed message or the raw data.
* - dst_len: Length of the encoded message.
* - dst: Buffer to hold the encoded message.
*
* Assumptions:
* - hash has size hashlen if md_alg == MBEDTLS_MD_NONE.
* - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE.
* - dst points to a buffer of size at least dst_len.
*
*/
/* \brief Formats cryptographically hashed data for RSA signing in accordance
* with PKCS #1 version 1.5.
*
* Currently assumes SHA-256.
*/
int PKI_RSA_RSASSA_PKCS1_v15_Encode( const unsigned char * hash,
size_t dst_len,
unsigned char * dst )
{
size_t oid_size = 0;
size_t nb_pad = dst_len;
unsigned char * p = dst;
const char * oid = NULL;
mbedtls_md_type_t md_alg = MBEDTLS_MD_SHA256;
unsigned int hashlen = 0;
const mbedtls_md_info_t * md_info = mbedtls_md_info_from_type( md_alg );
if( md_info == NULL )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
hashlen = mbedtls_md_get_size( md_info );
/* Double-check that 8 + hashlen + oid_size can be used as a
* 1-byte ASN.1 length encoding and that there's no overflow. */
if( ( 8 + hashlen + oid_size >= 0x80 ) ||
( 10 + hashlen < hashlen ) ||
( 10 + hashlen + oid_size < 10 + hashlen ) )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
/*
* Static bounds check:
* - Need 10 bytes for five tag-length pairs.
* (Insist on 1-byte length encodings to protect against variants of
* Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
* - Need hashlen bytes for hash
* - Need oid_size bytes for hash alg OID.
*/
if( nb_pad < 10 + hashlen + oid_size )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
nb_pad -= 10 + hashlen + oid_size;
/* Need space for signature header and padding delimiter (3 bytes),
* and 8 bytes for the minimal padding */
if( nb_pad < 3 + 8 )
{
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
nb_pad -= 3;
/* Now nb_pad is the amount of memory to be filled
* with padding, and at least 8 bytes long. */
/* Write signature header and padding */
*p++ = 0;
*p++ = MBEDTLS_RSA_SIGN;
memset( p, 0xFF, nb_pad );
p += nb_pad;
*p++ = 0;
/* Are we signing raw data? */
if( md_alg == MBEDTLS_MD_NONE )
{
memcpy( p, hash, hashlen );
return( 0 );
}
/* Signing hashed data, add corresponding ASN.1 structure
*
* DigestInfo ::= SEQUENCE {
* digestAlgorithm DigestAlgorithmIdentifier,
* digest Digest }
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
* Digest ::= OCTET STRING
*
* Schematic:
* TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ]
* TAG-NULL + LEN [ NULL ] ]
* TAG-OCTET + LEN [ HASH ] ]
*/
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
*p++ = ( unsigned char ) ( 0x08 + oid_size + hashlen );
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
*p++ = ( unsigned char ) ( 0x04 + oid_size );
*p++ = MBEDTLS_ASN1_OID;
*p++ = ( unsigned char ) oid_size;
memcpy( p, oid, oid_size );
p += oid_size;
*p++ = MBEDTLS_ASN1_NULL;
*p++ = 0x00;
*p++ = MBEDTLS_ASN1_OCTET_STRING;
*p++ = ( unsigned char ) hashlen;
memcpy( p, hash, hashlen );
p += hashlen;
/* Just a sanity-check, should be automatic
* after the initial bounds check. */
if( p != dst + dst_len )
{
mbedtls_platform_zeroize( dst, dst_len );
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
return( 0 );
}

View File

@ -0,0 +1,92 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file mbedtls_utils.h
* @brief Helper functions originating from mbedTLS.
*/
#ifndef _MBEDTLS_UTILS_H_
#define _MBEDTLS_UTILS_H_
/* Standard includes. */
#include <string.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/*-----------------------------------------------------------*/
/**
* @brief Converts PEM documents into DER formatted byte arrays.
* This is a helper function from MbedTLS util pem2der.c
* (https://github.com/ARMmbed/mbedtls/blob/development/programs/util/pem2der.c#L75)
*
* @param pucInput[in] Pointer to PEM object
* @param xLen[in] Length of PEM object
* @param pucOutput[out] Pointer to buffer where DER oboject will be placed
* @param pxOlen[in/out] Pointer to length of DER buffer. This value is updated
* to contain the actual length of the converted DER object.
*
* @return 0 if successful. Negative if conversion failed. If buffer is not
* large enough to hold converted object, pxOlen is still updated but -1 is
* returned.
*/
int convert_pem_to_der( const unsigned char * pucInput,
size_t xLen,
unsigned char * pucOutput,
size_t * pxOlen );
/*-----------------------------------------------------------*/
/**
* @brief This function is a modified version of the static function
* rsa_rsassa_pkcs1_v15_encode() inside of rsa.c in MbedTLS. It has been
* extracted so that corePKCS11 libraries and testing may use it.
*
* Formats cryptographically hashed data for RSA signing in accordance
* with PKCS #1 version 1.5.
*
* Currently assumes SHA-256.
*
* @param hash[in] Buffer containing the hashed message or the raw data.
* @param dst_len[in] Length of the encoded message.
* @param dst[out] Buffer to hold the encoded message.
*/
int PKI_RSA_RSASSA_PKCS1_v15_Encode( const unsigned char * hash,
size_t dst_len,
unsigned char * dst );
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* ifndef _MBEDTLS_UTILS_H_ */

View File

@ -0,0 +1,20 @@
<div>
<h2>Repository Contributions, Participation, and Public Access</h2>
<p><b>Who may Contribute?</b> Contributors to <a href="https://github.com/oasis-tcs/pkcs11/">this repository</a> are expected to be <a href="https://www.oasis-open.org/policies-guidelines/oasis-defined-terms-2017-05-26#dMember">Members</a> of the
<a href="https://www.oasis-open.org/committees/pkcs11/">OASIS PKCS 11 TC</a>, for any
substantive contributions. Anyone wishing to <a href="https://www.oasis-open.org/org/faq#committee-participation">participate</a>
in the TC's technical activity is invited to <a href="https://www.oasis-open.org/committees/join">join</a> as a TC Member.
<i>Member</i> in this context means any TC role or office other than OASIS TC Observer, per
<a href="https://www.oasis-open.org/policies-guidelines/tc-process#membership">TC Process</a>
(Member, Voting Member, Persistent Non-Voting Member; Chair, Secretary...)</p>
<p>Persons who are not TC members are invited to open issues and provide comments using this repository's <a href="https://github.com/oasis-tcs/pkcs11/issues/new">GitHub Issues</a> tracking facility or using the
TC's <a href="https://www.oasis-open.org/committees/comments/index.php?wg_abbrev=pkcs11">comment list</a>. All such content created in GitHub Issues and/or posted to the TC's <a href="https://lists.oasis-open.org/archives/pkcs11-comment/">archived comment list</a> is governed by the terms of the <a href="https://www.oasis-open.org/policies-guidelines/ipr#appendixa">OASIS Feedback License</a>.</p>
<p><b>Use of Contributions</b>. As with all OASIS Technical Committee assets (TC <a href="https://wiki.oasis-open.org/">Wiki</a>, TC <a href="https://issues.oasis-open.org/secure/Dashboard.jspa">Issues Tracker</a>, TC <a href="https://lists.oasis-open.org/archives/">General Discussion List archives</a>, TC <a href="http://docs.oasis-open.org/">OASIS Library</a> assets), content placed into this GitHub repository is visible and publicly accessible. Subject to applicable <a href="https://github.com/oasis-tcs/pkcs11/blob/master/LICENSE.md">licensing</a> rules, the repository content may be re-used freely, including the creation and publication of derivative works.</p>
<p><b>Cloning and forking</b>. May users clone and fork this repository? Yes. Just as versioned content maintained in any OASIS TC's <a href="https://tools.oasis-open.org/version-control/browse/">SVN/Subversion repository</a> may be checked out to a remote SVN repository and used by anyone, this GitHub repository may be forked or cloned for use by any party. Compare, <i>e.g.</i>, <tt>svn checkout https://tools.oasis-open.org/version-control/svn/dita/trunk/doctypes/ dita-doctypes</tt>.</p>
<p>Please see the <a href="https://github.com/oasis-tcs/pkcs11/blob/master/README.md">README</a> for general description of this repository, and the <a href="https://github.com/oasis-tcs/pkcs11/blob/master/LICENSE.md">LICENSE</a> file for licensing.</p>
</div>

View File

@ -0,0 +1,7 @@
<div>
<h2>License Terms</h2>
<p>Content in this GitHub code repository has been <a href="https://www.oasis-open.org/policies-guidelines/ipr#def-contribution">contributed</a> by OASIS TC Members, and is governed by the OASIS policies, including the <a href="https://www.oasis-open.org/policies-guidelines/ipr">Intellectual Property Rights (IPR) Policy</a>, the <a href="https://www.oasis-open.org/policies-guidelines/tc-process">Technical Committee (TC) Process</a>, <a href="https://www.oasis-open.org/policies-guidelines/bylaws">Bylaws</a>, and the Technical Committee's choice of <a href="https://www.oasis-open.org/policies-guidelines/ipr#def-ipr-mode">IPR Mode</a> (<i>viz</i>, <a href="https://www.oasis-open.org/policies-guidelines/ipr#RF-on-RAND-Mode">RF on RAND Terms Mode</a>), including any applicable <a href="https://www.oasis-open.org/committees/pkcs11/ipr.php">declarations</a>. Feedback from non-TC members, if any, is governed by the terms of the <a href="https://www.oasis-open.org/policies-guidelines/ipr#appendixa">OASIS Feedback License</a>.</p>
<p>Description of this repository is presented in the <a href="https://github.com/oasis-tcs/pkcs11/blob/master/README.md">README</a> file, and guidelines for contribution/participation are given in the <a href="https://github.com/oasis-tcs/pkcs11/blob/master/CONTRIBUTING.md">CONTRIBUTING</a> file.</p>
</div>

View File

@ -0,0 +1,37 @@
<div>
<h2>README</h2>
<p>This repository is a fork of the OASIS PKCS 11 TC repo. The only modification is the folder structure, where we have pulled out 3 files of interest into the root of the repository</p>
<p>Members of the <a href="https://www.oasis-open.org/committees/pkcs11/">OASIS PKCS 11 TC</a> create and manage technical content in this TC GitHub repository ( <a href="https://github.com/oasis-tcs/pkcs11">https://github.com/oasis-tcs/pkcs11</a> ) as part of the TC's chartered work (<i>i.e.</i>, the program of work and deliverables described in its <a href="https://www.oasis-open.org/committees/pkcs11/charter.php">charter</a>).</p>
<p>OASIS TC GitHub repositories, as described in <a href="https://www.oasis-open.org/resources/tcadmin/github-repositories-for-oasis-tc-members-chartered-work">GitHub Repositories for OASIS TC Members' Chartered Work</a>, are governed by the OASIS <a href="https://www.oasis-open.org/policies-guidelines/tc-process">TC Process</a>, <a href="https://www.oasis-open.org/policies-guidelines/ipr">IPR Policy</a>, and other policies, similar to TC Wikis, TC JIRA issues tracking instances, TC SVN/Subversion repositories, etc. While they make use of public GitHub repositories, these TC GitHub repositories are distinct from <a href="https://www.oasis-open.org/resources/open-repositories">OASIS Open Repositories</a>, which are used for development of open source <a href="https://www.oasis-open.org/resources/open-repositories/licenses">licensed</a> content.</p>
</div>
<div>
<h3>Description</h3>
<p>The purpose of this repository is to support version control for development of technical files associated with the OASIS PKCS11 specification.</p>
</div>
<div>
<h3>Contributions</h3>
<p>As stated in this repository's <a href="https://github.com/oasis-tcs/pkcs11/blob/master/CONTRIBUTING.md">CONTRIBUTING file</a>, contributors to this repository are expected to be Members of the OASIS PKCS 11 TC, for any substantive change requests. Anyone wishing to contribute to this GitHub project and <a href="https://www.oasis-open.org/join/participation-instructions">participate</a> in the TC's technical activity is invited to join as an OASIS TC Member. Public feedback is also accepted, subject to the terms of the <a href="https://www.oasis-open.org/policies-guidelines/ipr#appendixa">OASIS Feedback License</a>.</p>
</div>
<div>
<h3>Licensing</h3>
<p>Please see the <a href="https://github.com/oasis-tcs/pkcs11/blob/master/LICENSE.md">LICENSE</a> file for description of the license terms and OASIS policies applicable to the TC's work in this GitHub project. Content in this repository is intended to be part of the PKCS 11 TC's permanent record of activity, visible and freely available for all to use, subject to applicable OASIS policies, as presented in the repository <a href="https://github.com/oasis-tcs/pkcs11/blob/master/LICENSE.md">LICENSE</a> file.</p>
</div>
<div>
<h3>Further Description of this Repository</h3>
<p>[Any narrative content may be provided here by the TC, for example, if the Members wish to provide an extended statement of purpose.]</p>
</div>
<div>
<h3>Contact</h3>
<p>Please send questions or comments about <a href="https://www.oasis-open.org/resources/tcadmin/github-repositories-for-oasis-tc-members-chartered-work">OASIS TC GitHub repositories</a> to <a href="mailto:robin@oasis-open.org">Robin Cover</a> and <a href="mailto:chet.ensign@oasis-open.org">Chet Ensign</a>. For questions about content in this repository, please contact the TC Chair or Co-Chairs as listed on the the PKCS 11 TC's <a href="https://www.oasis-open.org/committees/pkcs11/">home page</a>.</p>
</div>

View File

@ -0,0 +1,265 @@
/* Copyright (c) OASIS Open 2016. All Rights Reserved./
* /Distributed under the terms of the OASIS IPR Policy,
* [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY
* IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others.
*/
/* Latest version of the specification:
* http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
*/
#ifndef _PKCS11_H_
#define _PKCS11_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* Before including this file (pkcs11.h) (or pkcs11t.h by
* itself), 5 platform-specific macros must be defined. These
* macros are described below, and typical definitions for them
* are also given. Be advised that these definitions can depend
* on both the platform and the compiler used (and possibly also
* on whether a Cryptoki library is linked statically or
* dynamically).
*
* In addition to defining these 5 macros, the packing convention
* for Cryptoki structures should be set. The Cryptoki
* convention on packing is that structures should be 1-byte
* aligned.
*
* If you're using Microsoft Developer Studio 5.0 to produce
* Win32 stuff, this might be done by using the following
* preprocessor directive before including pkcs11.h or pkcs11t.h:
*
* #pragma pack(push, cryptoki, 1)
*
* and using the following preprocessor directive after including
* pkcs11.h or pkcs11t.h:
*
* #pragma pack(pop, cryptoki)
*
* If you're using an earlier version of Microsoft Developer
* Studio to produce Win16 stuff, this might be done by using
* the following preprocessor directive before including
* pkcs11.h or pkcs11t.h:
*
* #pragma pack(1)
*
* In a UNIX environment, you're on your own for this. You might
* not need to do (or be able to do!) anything.
*
*
* Now for the macros:
*
*
* 1. CK_PTR: The indirection string for making a pointer to an
* object. It can be used like this:
*
* typedef CK_BYTE CK_PTR CK_BYTE_PTR;
*
* If you're using Microsoft Developer Studio 5.0 to produce
* Win32 stuff, it might be defined by:
*
* #define CK_PTR *
*
* If you're using an earlier version of Microsoft Developer
* Studio to produce Win16 stuff, it might be defined by:
*
* #define CK_PTR far *
*
* In a typical UNIX environment, it might be defined by:
*
* #define CK_PTR *
*
*
* 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
* an importable Cryptoki library function declaration out of a
* return type and a function name. It should be used in the
* following fashion:
*
* extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
* CK_VOID_PTR pReserved
* );
*
* If you're using Microsoft Developer Studio 5.0 to declare a
* function in a Win32 Cryptoki .dll, it might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType __declspec(dllimport) name
*
* If you're using an earlier version of Microsoft Developer
* Studio to declare a function in a Win16 Cryptoki .dll, it
* might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType __export _far _pascal name
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType name
*
*
* 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
* which makes a Cryptoki API function pointer declaration or
* function pointer type declaration out of a return type and a
* function name. It should be used in the following fashion:
*
* // Define funcPtr to be a pointer to a Cryptoki API function
* // taking arguments args and returning CK_RV.
* CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
*
* or
*
* // Define funcPtrType to be the type of a pointer to a
* // Cryptoki API function taking arguments args and returning
* // CK_RV, and then define funcPtr to be a variable of type
* // funcPtrType.
* typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
* funcPtrType funcPtr;
*
* If you're using Microsoft Developer Studio 5.0 to access
* functions in a Win32 Cryptoki .dll, in might be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType __declspec(dllimport) (* name)
*
* If you're using an earlier version of Microsoft Developer
* Studio to access functions in a Win16 Cryptoki .dll, it might
* be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType __export _far _pascal (* name)
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType (* name)
*
*
* 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
* a function pointer type for an application callback out of
* a return type for the callback and a name for the callback.
* It should be used in the following fashion:
*
* CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
*
* to declare a function pointer, myCallback, to a callback
* which takes arguments args and returns a CK_RV. It can also
* be used like this:
*
* typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
* myCallbackType myCallback;
*
* If you're using Microsoft Developer Studio 5.0 to do Win32
* Cryptoki development, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType (* name)
*
* If you're using an earlier version of Microsoft Developer
* Studio to do Win16 development, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType _far _pascal (* name)
*
* In a UNIX environment, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType (* name)
*
*
* 5. NULL_PTR: This macro is the value of a NULL pointer.
*
* In any ANSI/ISO C environment (and in many others as well),
* this should best be defined by
*
* #ifndef NULL_PTR
* #define NULL_PTR 0
* #endif
*/
/* All the various Cryptoki types and #define'd values are in the
* file pkcs11t.h.
*/
#include "pkcs11t.h"
#define __PASTE(x,y) x##y
/* ==============================================================
* Define the "extern" form of all the entry points.
* ==============================================================
*/
#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
extern CK_DECLARE_FUNCTION(CK_RV, name)
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes.
*/
#include "pkcs11f.h"
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
/* ==============================================================
* Define the typedef form of all the entry points. That is, for
* each Cryptoki function C_XXX, define a type CK_C_XXX which is
* a pointer to that kind of function.
* ==============================================================
*/
#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes.
*/
#include "pkcs11f.h"
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
/* ==============================================================
* Define structed vector of entry points. A CK_FUNCTION_LIST
* contains a CK_VERSION indicating a library's Cryptoki version
* and then a whole slew of function pointers to the routines in
* the library. This type was declared, but not defined, in
* pkcs11t.h.
* ==============================================================
*/
#define CK_PKCS11_FUNCTION_INFO(name) \
__PASTE(CK_,name) name;
struct CK_FUNCTION_LIST {
CK_VERSION version; /* Cryptoki version */
/* Pile all the function pointers into the CK_FUNCTION_LIST. */
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes.
*/
#include "pkcs11f.h"
};
#undef CK_PKCS11_FUNCTION_INFO
#undef __PASTE
#ifdef __cplusplus
}
#endif
#endif /* _PKCS11_H_ */

View File

@ -0,0 +1,939 @@
/* Copyright (c) OASIS Open 2016. All Rights Reserved./
* /Distributed under the terms of the OASIS IPR Policy,
* [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY
* IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others.
*/
/* Latest version of the specification:
* http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
*/
/* This header file contains pretty much everything about all the
* Cryptoki function prototypes. Because this information is
* used for more than just declaring function prototypes, the
* order of the functions appearing herein is important, and
* should not be altered.
*/
/* General-purpose */
/* C_Initialize initializes the Cryptoki library. */
CK_PKCS11_FUNCTION_INFO(C_Initialize)
#ifdef CK_NEED_ARG_LIST
(
CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
* cast to CK_C_INITIALIZE_ARGS_PTR
* and dereferenced
*/
);
#endif
/* C_Finalize indicates that an application is done with the
* Cryptoki library.
*/
CK_PKCS11_FUNCTION_INFO(C_Finalize)
#ifdef CK_NEED_ARG_LIST
(
CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
);
#endif
/* C_GetInfo returns general information about Cryptoki. */
CK_PKCS11_FUNCTION_INFO(C_GetInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_INFO_PTR pInfo /* location that receives information */
);
#endif
/* C_GetFunctionList returns the function list. */
CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
#ifdef CK_NEED_ARG_LIST
(
CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
* function list
*/
);
#endif
/* Slot and token management */
/* C_GetSlotList obtains a list of slots in the system. */
CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
#ifdef CK_NEED_ARG_LIST
(
CK_BBOOL tokenPresent, /* only slots with tokens */
CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
CK_ULONG_PTR pulCount /* receives number of slots */
);
#endif
/* C_GetSlotInfo obtains information about a particular slot in
* the system.
*/
CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* the ID of the slot */
CK_SLOT_INFO_PTR pInfo /* receives the slot information */
);
#endif
/* C_GetTokenInfo obtains information about a particular token
* in the system.
*/
CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_TOKEN_INFO_PTR pInfo /* receives the token information */
);
#endif
/* C_GetMechanismList obtains a list of mechanism types
* supported by a token.
*/
CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of token's slot */
CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
CK_ULONG_PTR pulCount /* gets # of mechs. */
);
#endif
/* C_GetMechanismInfo obtains information about a particular
* mechanism possibly supported by a token.
*/
CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_MECHANISM_TYPE type, /* type of mechanism */
CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
);
#endif
/* C_InitToken initializes a token. */
CK_PKCS11_FUNCTION_INFO(C_InitToken)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
CK_ULONG ulPinLen, /* length in bytes of the PIN */
CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
);
#endif
/* C_InitPIN initializes the normal user's PIN. */
CK_PKCS11_FUNCTION_INFO(C_InitPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
CK_ULONG ulPinLen /* length in bytes of the PIN */
);
#endif
/* C_SetPIN modifies the PIN of the user who is logged in. */
CK_PKCS11_FUNCTION_INFO(C_SetPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
CK_ULONG ulOldLen, /* length of the old PIN */
CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
CK_ULONG ulNewLen /* length of the new PIN */
);
#endif
/* Session management */
/* C_OpenSession opens a session between an application and a
* token.
*/
CK_PKCS11_FUNCTION_INFO(C_OpenSession)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* the slot's ID */
CK_FLAGS flags, /* from CK_SESSION_INFO */
CK_VOID_PTR pApplication, /* passed to callback */
CK_NOTIFY Notify, /* callback function */
CK_SESSION_HANDLE_PTR phSession /* gets session handle */
);
#endif
/* C_CloseSession closes a session between an application and a
* token.
*/
CK_PKCS11_FUNCTION_INFO(C_CloseSession)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_CloseAllSessions closes all sessions with a token. */
CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID /* the token's slot */
);
#endif
/* C_GetSessionInfo obtains information about the session. */
CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_SESSION_INFO_PTR pInfo /* receives session info */
);
#endif
/* C_GetOperationState obtains the state of the cryptographic operation
* in a session.
*/
CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pOperationState, /* gets state */
CK_ULONG_PTR pulOperationStateLen /* gets state length */
);
#endif
/* C_SetOperationState restores the state of the cryptographic
* operation in a session.
*/
CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pOperationState, /* holds state */
CK_ULONG ulOperationStateLen, /* holds state length */
CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
);
#endif
/* C_Login logs a user into a token. */
CK_PKCS11_FUNCTION_INFO(C_Login)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_USER_TYPE userType, /* the user type */
CK_UTF8CHAR_PTR pPin, /* the user's PIN */
CK_ULONG ulPinLen /* the length of the PIN */
);
#endif
/* C_Logout logs a user out from a token. */
CK_PKCS11_FUNCTION_INFO(C_Logout)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Object management */
/* C_CreateObject creates a new object. */
CK_PKCS11_FUNCTION_INFO(C_CreateObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
);
#endif
/* C_CopyObject copies an object, creating a new object for the
* copy.
*/
CK_PKCS11_FUNCTION_INFO(C_CopyObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
);
#endif
/* C_DestroyObject destroys an object. */
CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject /* the object's handle */
);
#endif
/* C_GetObjectSize gets the size of an object in bytes. */
CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ULONG_PTR pulSize /* receives size of object */
);
#endif
/* C_GetAttributeValue obtains the value of one or more object
* attributes.
*/
CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
CK_ULONG ulCount /* attributes in template */
);
#endif
/* C_SetAttributeValue modifies the value of one or more object
* attributes.
*/
CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
CK_ULONG ulCount /* attributes in template */
);
#endif
/* C_FindObjectsInit initializes a search for token and session
* objects that match a template.
*/
CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
CK_ULONG ulCount /* attrs in search template */
);
#endif
/* C_FindObjects continues a search for token and session
* objects that match a template, obtaining additional object
* handles.
*/
CK_PKCS11_FUNCTION_INFO(C_FindObjects)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
CK_ULONG ulMaxObjectCount, /* max handles to get */
CK_ULONG_PTR pulObjectCount /* actual # returned */
);
#endif
/* C_FindObjectsFinal finishes a search for token and session
* objects.
*/
CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Encryption and decryption */
/* C_EncryptInit initializes an encryption operation. */
CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
CK_OBJECT_HANDLE hKey /* handle of encryption key */
);
#endif
/* C_Encrypt encrypts single-part data. */
CK_PKCS11_FUNCTION_INFO(C_Encrypt)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pData, /* the plaintext data */
CK_ULONG ulDataLen, /* bytes of plaintext */
CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
);
#endif
/* C_EncryptUpdate continues a multiple-part encryption
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext data len */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
);
#endif
/* C_EncryptFinal finishes a multiple-part encryption
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session handle */
CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
);
#endif
/* C_DecryptInit initializes a decryption operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
CK_OBJECT_HANDLE hKey /* handle of decryption key */
);
#endif
/* C_Decrypt decrypts encrypted data in a single part. */
CK_PKCS11_FUNCTION_INFO(C_Decrypt)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedData, /* ciphertext */
CK_ULONG ulEncryptedDataLen, /* ciphertext length */
CK_BYTE_PTR pData, /* gets plaintext */
CK_ULONG_PTR pulDataLen /* gets p-text size */
);
#endif
/* C_DecryptUpdate continues a multiple-part decryption
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* encrypted data */
CK_ULONG ulEncryptedPartLen, /* input length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* p-text size */
);
#endif
/* C_DecryptFinal finishes a multiple-part decryption
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pLastPart, /* gets plaintext */
CK_ULONG_PTR pulLastPartLen /* p-text size */
);
#endif
/* Message digesting */
/* C_DigestInit initializes a message-digesting operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
);
#endif
/* C_Digest digests data in a single part. */
CK_PKCS11_FUNCTION_INFO(C_Digest)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* data to be digested */
CK_ULONG ulDataLen, /* bytes of data to digest */
CK_BYTE_PTR pDigest, /* gets the message digest */
CK_ULONG_PTR pulDigestLen /* gets digest length */
);
#endif
/* C_DigestUpdate continues a multiple-part message-digesting
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* data to be digested */
CK_ULONG ulPartLen /* bytes of data to be digested */
);
#endif
/* C_DigestKey continues a multi-part message-digesting
* operation, by digesting the value of a secret key as part of
* the data already digested.
*/
CK_PKCS11_FUNCTION_INFO(C_DigestKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hKey /* secret key to digest */
);
#endif
/* C_DigestFinal finishes a multiple-part message-digesting
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pDigest, /* gets the message digest */
CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
);
#endif
/* Signing and MACing */
/* C_SignInit initializes a signature (private key encryption)
* operation, where the signature is (will be) an appendix to
* the data, and plaintext cannot be recovered from the
* signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
CK_OBJECT_HANDLE hKey /* handle of signature key */
);
#endif
/* C_Sign signs (encrypts with private key) data in a single
* part, where the signature is (will be) an appendix to the
* data, and plaintext cannot be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_Sign)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* the data to sign */
CK_ULONG ulDataLen, /* count of bytes to sign */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* C_SignUpdate continues a multiple-part signature operation,
* where the signature is (will be) an appendix to the data,
* and plaintext cannot be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* the data to sign */
CK_ULONG ulPartLen /* count of bytes to sign */
);
#endif
/* C_SignFinal finishes a multiple-part signature operation,
* returning the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* C_SignRecoverInit initializes a signature operation, where
* the data can be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
CK_OBJECT_HANDLE hKey /* handle of the signature key */
);
#endif
/* C_SignRecover signs data in a single operation, where the
* data can be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignRecover)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* the data to sign */
CK_ULONG ulDataLen, /* count of bytes to sign */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* Verifying signatures and MACs */
/* C_VerifyInit initializes a verification operation, where the
* signature is an appendix to the data, and plaintext cannot
* cannot be recovered from the signature (e.g. DSA).
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
CK_OBJECT_HANDLE hKey /* verification key */
);
#endif
/* C_Verify verifies a signature in a single-part operation,
* where the signature is an appendix to the data, and plaintext
* cannot be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_Verify)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* signed data */
CK_ULONG ulDataLen, /* length of signed data */
CK_BYTE_PTR pSignature, /* signature */
CK_ULONG ulSignatureLen /* signature length*/
);
#endif
/* C_VerifyUpdate continues a multiple-part verification
* operation, where the signature is an appendix to the data,
* and plaintext cannot be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* signed data */
CK_ULONG ulPartLen /* length of signed data */
);
#endif
/* C_VerifyFinal finishes a multiple-part verification
* operation, checking the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* signature to verify */
CK_ULONG ulSignatureLen /* signature length */
);
#endif
/* C_VerifyRecoverInit initializes a signature verification
* operation, where the data is recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
CK_OBJECT_HANDLE hKey /* verification key */
);
#endif
/* C_VerifyRecover verifies a signature in a single-part
* operation, where the data is recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* signature to verify */
CK_ULONG ulSignatureLen, /* signature length */
CK_BYTE_PTR pData, /* gets signed data */
CK_ULONG_PTR pulDataLen /* gets signed data len */
);
#endif
/* Dual-function cryptographic operations */
/* C_DigestEncryptUpdate continues a multiple-part digesting
* and encryption operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext length */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
);
#endif
/* C_DecryptDigestUpdate continues a multiple-part decryption and
* digesting operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* gets plaintext len */
);
#endif
/* C_SignEncryptUpdate continues a multiple-part signing and
* encryption operation.
*/
CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext length */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
);
#endif
/* C_DecryptVerifyUpdate continues a multiple-part decryption and
* verify operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* gets p-text length */
);
#endif
/* Key management */
/* C_GenerateKey generates a secret key, creating a new key
* object.
*/
CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* key generation mech. */
CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
CK_ULONG ulCount, /* # of attrs in template */
CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
);
#endif
/* C_GenerateKeyPair generates a public-key/private-key pair,
* creating new key objects.
*/
CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session handle */
CK_MECHANISM_PTR pMechanism, /* key-gen mech. */
CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */
CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */
CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */
CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */
CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */
CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */
);
#endif
/* C_WrapKey wraps (i.e., encrypts) a key. */
CK_PKCS11_FUNCTION_INFO(C_WrapKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
CK_OBJECT_HANDLE hKey, /* key to be wrapped */
CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
);
#endif
/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
* key object.
*/
CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
CK_BYTE_PTR pWrappedKey, /* the wrapped key */
CK_ULONG ulWrappedKeyLen, /* wrapped key len */
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
CK_ULONG ulAttributeCount, /* template length */
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
);
#endif
/* C_DeriveKey derives a key from a base key, creating a new key
* object.
*/
CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
CK_OBJECT_HANDLE hBaseKey, /* base key */
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
CK_ULONG ulAttributeCount, /* template length */
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
);
#endif
/* Random number generation */
/* C_SeedRandom mixes additional seed material into the token's
* random number generator.
*/
CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSeed, /* the seed material */
CK_ULONG ulSeedLen /* length of seed material */
);
#endif
/* C_GenerateRandom generates random data. */
CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR RandomData, /* receives the random data */
CK_ULONG ulRandomLen /* # of bytes to generate */
);
#endif
/* Parallel function management */
/* C_GetFunctionStatus is a legacy function; it obtains an
* updated status of a function running in parallel with an
* application.
*/
CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_CancelFunction is a legacy function; it cancels a function
* running in parallel.
*/
CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_WaitForSlotEvent waits for a slot event (token insertion,
* removal, etc.) to occur.
*/
CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
#ifdef CK_NEED_ARG_LIST
(
CK_FLAGS flags, /* blocking/nonblocking flag */
CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,339 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _CORE_PKCS11_H_
#define _CORE_PKCS11_H_
#include <stdint.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#ifdef _WIN32
#pragma pack(push, cryptoki, 1)
#endif
/**
* @file core_pkcs11.h
* @brief Wrapper functions for PKCS #11
*/
/**
* @brief corePKCS11 Interface.
* The following definitions are required by the PKCS#11 standard public
* headers.
*/
/**
* @ingroup pkcs11_wrapper_macros
* @brief PKCS #11 pointer data type
*/
#define CK_PTR *
/**
* @ingroup pkcs11_wrapper_macros
* @brief PKCS #11 NULL pointer value
*/
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
/**
* @ingroup pkcs11_wrapper_macros
* @brief CK_DEFINE_FUNCTION is deprecated. Implementations should use CK_DECLARE_FUNCTION
* instead when possible.
*/
#define CK_DEFINE_FUNCTION( returnType, name ) returnType name
/**
* @ingroup pkcs11_wrapper_macros
* @brief Macro for defining a PKCS #11 functions.
*
*/
#define CK_DECLARE_FUNCTION( returnType, name ) returnType name
/**
* @ingroup pkcs11_wrapper_macros
* @brief Macro for defining a PKCS #11 function pointers.
*
*/
#define CK_DECLARE_FUNCTION_POINTER( returnType, name ) returnType( CK_PTR name )
/**
* @ingroup pkcs11_wrapper_macros
* @brief Macro for defining a PKCS #11 callback functions.
*
*/
#define CK_CALLBACK_FUNCTION( returnType, name ) returnType( CK_PTR name )
/**
* @ingroup pkcs11_wrapper_macros
* @brief Length of a SHA256 digest, in bytes.
*/
#define pkcs11SHA256_DIGEST_LENGTH 32UL
/**
* @ingroup pkcs11_wrapper_macros
* @brief Length of a CMAC signature, in bytes.
*/
#define pkcs11AES_CMAC_SIGNATURE_LENGTH 16UL
/**
* @ingroup pkcs11_wrapper_macros
* @brief Length of a curve P-256 ECDSA signature, in bytes.
* PKCS #11 EC signatures are represented as a 32-bit R followed
* by a 32-bit S value, and not ASN.1 encoded.
*/
#define pkcs11ECDSA_P256_SIGNATURE_LENGTH 64UL
/**
* @ingroup pkcs11_wrapper_macros
* @brief Key strength for elliptic-curve P-256.
*/
#define pkcs11ECDSA_P256_KEY_BITS 256UL
/**
* @ingroup pkcs11_wrapper_macros
* @brief Public exponent for RSA.
*/
#define pkcs11RSA_PUBLIC_EXPONENT { 0x01, 0x00, 0x01 }
/**
* @ingroup pkcs11_wrapper_macros
* @brief The number of bits in the RSA-2048 modulus.
*
*/
#define pkcs11RSA_2048_MODULUS_BITS 2048UL
/**
* @ingroup pkcs11_wrapper_macros
* @brief Length of PKCS #11 signature for RSA 2048 key, in bytes.
*/
#define pkcs11RSA_2048_SIGNATURE_LENGTH ( pkcs11RSA_2048_MODULUS_BITS / 8UL )
/**
* @ingroup pkcs11_wrapper_macros
* @brief Length of RSA signature data before padding.
*
* This is calculated by adding the SHA-256 hash len (32) to the 19 bytes in
* pkcs11STUFF_APPENDED_TO_RSA_SIG = 51 bytes total.
*/
#define pkcs11RSA_SIGNATURE_INPUT_LENGTH 51UL
/**
* @ingroup pkcs11_wrapper_macros
* @brief Elliptic-curve object identifiers.
* From https://tools.ietf.org/html/rfc6637#section-11.
*/
#define pkcs11ELLIPTIC_CURVE_NISTP256 "1.2.840.10045.3.1.7"
/**
* @ingroup pkcs11_wrapper_macros
* @brief Maximum length of storage for PKCS #11 label, in bytes.
*/
#define pkcs11MAX_LABEL_LENGTH 32UL /* 31 characters + 1 null terminator. */
/**
* @ingroup pkcs11_wrapper_macros
* @brief OID for curve P-256.
*/
#define pkcs11DER_ENCODED_OID_P256 { 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 }
/**
* @brief Set to 1 if importing private keys is supported.
*
* If private key import is not supported, this value should be defined 0 in aws_pkcs11_config.h
*/
#ifndef pkcs11configIMPORT_PRIVATE_KEYS_SUPPORTED
#define pkcs11configIMPORT_PRIVATE_KEYS_SUPPORTED 1
#endif
/**
* @ingroup pkcs11_wrapper_macros
* @brief RSA signature padding for interoperability between providing hashed messages
* and providing hashed messages encoded with the digest information.
*
* The TLS connection for mbedTLS expects a hashed, but unpadded input,
* and it appended message digest algorithm encoding. However, the PKCS #11 sign
* function either wants unhashed data which it will both hash and pad OR
* as done in this workaround, we provide hashed data with padding appended.
*
* DigestInfo :: = SEQUENCE{
* digestAlgorithm DigestAlgorithmIdentifier,
* digest Digest }
*
* DigestAlgorithmIdentifier :: = AlgorithmIdentifier
* Digest :: = OCTET STRING
*
* This is the DigestInfo sequence, digest algorithm, and the octet string/length
* for the digest, without the actual digest itself.
*/
#define pkcs11STUFF_APPENDED_TO_RSA_SIG { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }
/* Bring in the public header. */
/* Undefine the macro for Keil Compiler to avoid conflict */
#if defined( __PASTE ) && defined( __CC_ARM )
/* ARM RCVT stdint.h has a duplicate definition with PKCS #11. */
#undef __PASTE
#endif
#ifdef CreateMutex
#undef CreateMutex /* This is a workaround because CreateMutex is redefined to CreateMutexW in synchapi.h in windows. :/ */
#endif
#include "pkcs11.h"
/**
* @ingroup pkcs11_datatypes
* @brief Certificate Template
* The object class must be the first attribute in the array.
*/
typedef struct PKCS11_CertificateTemplate
{
CK_ATTRIBUTE xObjectClass; /**< @brief CKA_CLASS, set to CKO_CERTIFICATE. */
CK_ATTRIBUTE xSubject; /**< @brief CKA_SUBJECT, this parameter is required by the PKCS #11 standard. */
CK_ATTRIBUTE xCertificateType; /**< @brief CKA_CERTIFICATE_TYPE, set to CKC_X_509. */
CK_ATTRIBUTE xValue; /**< @brief CKA_VALUE, the DER byte array of the certificate contents. */
CK_ATTRIBUTE xLabel; /**< @brief CKA_LABEL. */
CK_ATTRIBUTE xTokenObject; /**< @brief CKA_TOKEN. */
} PKCS11_CertificateTemplate_t;
/*------------------------ PKCS #11 wrapper functions -------------------------*/
/**
* @brief Initializes a PKCS #11 session.
*
* @return CKR_OK if successful.
*/
/* @[declare_pkcs11_core_xinitializepkcs11] */
CK_RV xInitializePKCS11( void );
/* @[declare_pkcs11_core_xinitializepkcs11] */
/**
* @brief Get a list of available PKCS #11 slots.
*
* \note This function allocates memory for slots.
* Freeing this memory is the responsibility of the caller.
*
* \param[out] ppxSlotId Pointer to slot list. This slot list is
* malloc'ed by the function and must be
* freed by the caller.
* \param[out] pxSlotCount Pointer to the number of slots found.
*
* \return CKR_OK or PKCS #11 error code. (PKCS #11 error codes are positive).
*
*/
/* @[declare_pkcs11_core_xgetslotlist] */
CK_RV xGetSlotList( CK_SLOT_ID ** ppxSlotId,
CK_ULONG * pxSlotCount );
/* @[declare_pkcs11_core_xgetslotlist] */
/**
* \brief Initializes the PKCS #11 module and opens a session.
*
* \param[out] pxSession Pointer to the PKCS #11 session handle
* that is created by this function.
*
* \return CKR_OK upon success. PKCS #11 error code on failure.
* Note that PKCS #11 error codes are positive.
*/
/* @[declare_pkcs11_core_xinitializepkcs11session] */
CK_RV xInitializePkcs11Session( CK_SESSION_HANDLE * pxSession );
/* @[declare_pkcs11_core_xinitializepkcs11session] */
/**
* \brief Initializes a PKCS #11 module and token.
*
* \return CKR_OK upon success. PKCS #11 error code on failure.
* Note that PKCS #11 error codes are positive.
*/
/* @[declare_pkcs11_core_xinitializepkcs11token] */
CK_RV xInitializePkcs11Token( void );
/* @[declare_pkcs11_core_xinitializepkcs11token] */
/**
* \brief Searches for an object with a matching label and class provided.
*
* \param[in] xSession An open PKCS #11 session.
* \param[in] pcLabelName A pointer to the object's label (CKA_LABEL).
* \param[in] ulLabelNameLen The size (in bytes) of pcLabelName.
* \param[in] xClass The class (CKA_CLASS) of the object.
* ex: CKO_PUBLIC_KEY, CKO_PRIVATE_KEY, CKO_CERTIFICATE
* \param[out] pxHandle Pointer to the location where the handle of
* the found object should be placed.
*
* \note If no matching object is found, pxHandle will point
* to an object with handle 0 (Invalid Object Handle).
*
* \note This function assumes that there is only one
* object that meets the CLASS/LABEL criteria.
*/
/* @[declare_pkcs11_core_xfindobjectwithlabelandclass] */
CK_RV xFindObjectWithLabelAndClass( CK_SESSION_HANDLE xSession,
char * pcLabelName,
CK_ULONG ulLabelNameLen,
CK_OBJECT_CLASS xClass,
CK_OBJECT_HANDLE_PTR pxHandle );
/* @[declare_pkcs11_core_xfindobjectwithlabelandclass] */
/**
* \brief Appends digest algorithm sequence to SHA-256 hash for RSA signatures
*
* This function pre-appends the digest algorithm identifier to the SHA-256
* hash of a message.
*
* DigestInfo :: = SEQUENCE{
* digestAlgorithm DigestAlgorithmIdentifier,
* digest Digest }
*
* \param[in] puc32ByteHashedMessage A 32-byte buffer containing the SHA-256
* hash of the data to be signed.
* \param[out] puc51ByteHashOidBuffer A 51-byte output buffer containing the
* DigestInfo structure. This memory
* must be allocated by the caller.
*
* \return CKR_OK if successful, CKR_ARGUMENTS_BAD if NULL pointer passed in.
*
*/
/* @[declare_pkcs11_core_vappendsha256algorithmidentifiersequence] */
CK_RV vAppendSHA256AlgorithmIdentifierSequence( const uint8_t * puc32ByteHashedMessage,
uint8_t * puc51ByteHashOidBuffer );
/* @[declare_pkcs11_core_vappendsha256algorithmidentifiersequence] */
#ifdef _WIN32
#pragma pack(pop, cryptoki)
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* ifndef _CORE_PKCS11_H_ */

View File

@ -0,0 +1,386 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file core_pkcs11_config_defaults.h
* @brief List of configuration macros for the corePKCS11 library along with
* their default values.
*/
#ifndef CORE_PKCS11_CONFIG_DEFAULTS_H_
#define CORE_PKCS11_CONFIG_DEFAULTS_H_
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/**
* @brief Definitions mapping deprecated configuration macro names to their current equivalent
* configurations for backwards compatibility of API.
*/
#ifndef DOXYGEN
#ifdef PKCS11_MALLOC
#define pkcs11configPKCS11_MALLOC PKCS11_MALLOC
#endif
#ifdef PKCS11_FREE
#define pkcs11configPKCS11_FREE PKCS11_FREE
#endif
#ifdef configPKCS11_DEFAULT_USER_PIN
#define pkcs11configPKCS11_DEFAULT_USER_PIN configPKCS11_DEFAULT_USER_PIN
#endif
#endif /* ifndef DOXYGEN */
/**
* @brief Malloc API used by iot_pkcs11.h
*
* <br><b>Possible values:</b> Any platform-specific function for allocating memory.<br>
* <b>Default value:</b> The standard C `"malloc"` function
*/
#ifndef pkcs11configPKCS11_MALLOC
#define pkcs11configPKCS11_MALLOC malloc
#endif
/**
* @brief Free API used by iot_pkcs11.h
*
* <br><b>Possible values:</b> Any platform-specific function for freeing memory.<br>
* <b>Default value:</b> The standard C `"free"` function
*/
#ifndef pkcs11configPKCS11_FREE
#define pkcs11configPKCS11_FREE free
#endif
/**
* @brief PKCS #11 default user PIN.
*
* The PKCS #11 standard specifies the presence of a user PIN. That feature is
* sensible for applications that have an interactive user interface and memory
* protections. However, since typical microcontroller applications lack one or
* both of those, the user PIN is assumed to be used herein for interoperability
* purposes only, and not as a security feature.
*
* @note Do not cast this to a pointer! The library calls sizeof to get the length
* of this string.
*
* <b>Possible values:</b> Any four digit code<br>
* <b>Default value:</b> `"0000"`
*/
#ifndef pkcs11configPKCS11_DEFAULT_USER_PIN
#define pkcs11configPKCS11_DEFAULT_USER_PIN "0000"
#endif
/**
* @brief Maximum length (in characters) for a PKCS #11 CKA_LABEL
* attribute.
*
* <br><b>Possible values:</b> Any positive integer.<br>
* <b>Default value:</b> `32`
*/
#ifndef pkcs11configMAX_LABEL_LENGTH
#define pkcs11configMAX_LABEL_LENGTH 32
#endif
/**
* @brief Maximum number of token objects that can be stored
* by the PKCS #11 module.
*
* <br><b>Possible values:</b> Any positive integer.<br>
* <b>Default value:</b> `6`
*/
#ifndef pkcs11configMAX_NUM_OBJECTS
#define pkcs11configMAX_NUM_OBJECTS 6
#endif
/**
* @brief Maximum number of sessions that can be stored
* by the PKCS #11 module.
*
* @note The windows test port has an abnormally large value in order to have
* enough sessions to successfully run all the model based PKCS #11 tests.
*
* <b>Possible values:</b> Any positive integer.<br>
* <b>Default value:</b> 10
*/
#ifndef pkcs11configMAX_SESSIONS
#define pkcs11configMAX_SESSIONS 10
#endif
/**
* @brief Set to 1 if a PAL destroy object is implemented.
*
* If set to 0, no PAL destroy object is implemented, and this functionality
* is implemented in the common PKCS #11 layer.
*
* <b>Possible values:</b> `0` or `1`<br>
* <b>Default value:</b> `0`
*/
#ifndef pkcs11configPAL_DESTROY_SUPPORTED
#define pkcs11configPAL_DESTROY_SUPPORTED 0
#endif
/**
* @brief Set to 1 if OTA image verification via PKCS #11 module is supported.
*
* If set to 0, OTA code signing certificate is built in via
* aws_ota_codesigner_certificate.h.
*
* <b>Possible values:</b> `0` or `1`<br>
* <b>Default value:</b> `0`
*/
#ifndef pkcs11configOTA_SUPPORTED
#define pkcs11configOTA_SUPPORTED 0
#endif
/**
* @brief Set to 1 if PAL supports storage for JITP certificate,
* code verify certificate, and trusted server root certificate.
*
* If set to 0, PAL does not support storage mechanism for these, and
* they are accessed via headers compiled into the code.
*
* <b>Possible values:</b> `0` or `1`<br>
* <b>Default value:</b> `0`
*/
#ifndef pkcs11configJITP_CODEVERIFY_ROOT_CERT_SUPPORTED
#define pkcs11configJITP_CODEVERIFY_ROOT_CERT_SUPPORTED 0
#endif
/**
* @brief The PKCS #11 label for device private key.
*
* Private key for connection to AWS IoT endpoint. The corresponding
* public key should be registered with the AWS IoT endpoint.
*
* <b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `Device Priv TLS Key`
*/
#ifndef pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS
#define pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS "Device Priv TLS Key"
#endif
/**
* @brief The PKCS #11 label for device public key.
*
* The public key corresponding to pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS.
*
* <b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `Device Pub TLS Key`
*/
#ifndef pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS
#define pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS "Device Pub TLS Key"
#endif
/**
* @brief The PKCS #11 label for the device certificate.
*
* Device certificate corresponding to pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS.
*
* <b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `Device Cert`
*/
#ifndef pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS
#define pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS "Device Cert"
#endif
/**
* @brief The PKCS #11 label for the AWS Trusted Root Certificate.
*
* @see aws_default_root_certificates.h
*
* <b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `Root Cert`
*/
#ifndef pkcs11configLABEL_ROOT_CERTIFICATE
#define pkcs11configLABEL_ROOT_CERTIFICATE "Root Cert"
#endif
/**
* @brief The PKCS #11 label for the object to be used for HMAC operations.
*
* <br><b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `HMAC Key`
*/
#ifndef pkcs11configLABEL_HMAC_KEY
#define pkcs11configLABEL_HMAC_KEY "HMAC Key"
#endif
/**
* @brief The PKCS #11 label for the object to be used for CMAC operations.
*
* <br><b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `CMAC Key`
*/
#ifndef pkcs11configLABEL_CMAC_KEY
#define pkcs11configLABEL_CMAC_KEY "CMAC Key"
#endif
/**
* @brief The PKCS #11 label for the object to be used for code verification.
*
* Used by AWS IoT Over-the-Air Update (OTA) code to verify an incoming signed image.
*
* <b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `Code Verify Key`
*/
#ifndef pkcs11configLABEL_CODE_VERIFICATION_KEY
#define pkcs11configLABEL_CODE_VERIFICATION_KEY "Code Verify Key"
#endif
/**
* @brief The PKCS #11 label for AWS IoT Just-In-Time-Provisioning.
*
* The certificate corresponding to the issuer of the device certificate
* (pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS) when using the JITR or
* JITP flow.
*
* <b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `Code Verify Key`
*/
#ifndef pkcs11configLABEL_JITP_CERTIFICATE
#define pkcs11configLABEL_JITP_CERTIFICATE "JITP Cert"
#endif
/**
* @brief The PKCS #11 label for AWS IoT Fleet Provisioning claim certificate.
*
* This label is used for the provisioning claim certificate. The provisioning
* claim certificate is used to connect to AWS IoT Core for provisioning a
* client device using "Provisioning by Claim" workflow of the Fleet
* Provisioning Service.
*
* <b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `Claim Cert`
*/
#ifndef pkcs11configLABEL_CLAIM_CERTIFICATE
#define pkcs11configLABEL_CLAIM_CERTIFICATE "Claim Cert"
#endif
/**
* @brief The PKCS #11 label for AWS IoT Fleet Provisioning claim private key.
*
* This label is used for the provisioning claim private key. The provisioning
* claim private key corresponds to the provisioning claim certificate and is
* used to to connect to AWS IoT Core for provisioning a client device using
* "Provisioning by Claim" workflow of the Fleet Provisioning Service.
*
* <b>Possible values:</b> Any String smaller then pkcs11configMAX_LABEL_LENGTH.<br>
* <b>Default value:</b> `Claim Key`
*/
#ifndef pkcs11configLABEL_CLAIM_PRIVATE_KEY
#define pkcs11configLABEL_CLAIM_PRIVATE_KEY "Claim Key"
#endif
/**
* @brief Macro that is called in the corePKCS11 library for logging "Error" level
* messages.
*
* To enable error level logging in the corePKCS11 library, this macro should be mapped to the
* application-specific logging implementation that supports error logging.
*
* @note This logging macro is called in the corePKCS11 library with parameters wrapped in
* double parentheses to be ISO C89/C90 standard compliant.
* For a reference implementation of the logging macros in POSIX environment,
* refer to core_pkcs11_config.h files, and the logging-stack in demos folder of the
* [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main).
*
* <b>Default value</b>: Error logging is turned off, and no code is generated for calls
* to the macro in the corePKCS11 library on compilation.
*/
#ifndef LogError
#define LogError( message )
#endif
/**
* @brief Macro that is called in the corePKCS11 library for logging "Warning" level
* messages.
*
* To enable warning level logging in the corePKCS11 library, this macro should be mapped to the
* application-specific logging implementation that supports warning logging.
*
* @note This logging macro is called in the corePKCS11 library with parameters wrapped in
* double parentheses to be ISO C89/C90 standard compliant.
* For a reference implementation of the logging macros in POSIX environment,
* refer to core_pkcs11_config.h files, and the logging-stack in demos folder of the
* [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main).
*
* <b>Default value</b>: Warning logs are turned off, and no code is generated for calls
* to the macro in the corePKCS11 library on compilation.
*/
#ifndef LogWarn
#define LogWarn( message )
#endif
/**
* @brief Macro that is called in the corePKCS11 library for logging "Info" level
* messages.
*
* To enable info level logging in the corePKCS11 library, this macro should be mapped to the
* application-specific logging implementation that supports info logging.
*
* @note This logging macro is called in the corePKCS11 library with parameters wrapped in
* double parentheses to be ISO C89/C90 standard compliant.
* For a reference implementation of the logging macros in POSIX environment,
* refer to core_pkcs11_config.h files, and the logging-stack in demos folder of the
* [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main).
*
* <b>Default value</b>: Info logging is turned off, and no code is generated for calls
* to the macro in the corePKCS11 library on compilation.
*/
#ifndef LogInfo
#define LogInfo( message )
#endif
/**
* @brief Macro that is called in the corePKCS11 library for logging "Debug" level
* messages.
*
* To enable debug level logging from corePKCS11 library, this macro should be mapped to the
* application-specific logging implementation that supports debug logging.
*
* @note This logging macro is called in the corePKCS11 library with parameters wrapped in
* double parentheses to be ISO C89/C90 standard compliant.
* For a reference implementation of the logging macros in POSIX environment,
* refer to core_pkcs11_config.h files, and the logging-stack in demos folder of the
* [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main).
*
* <b>Default value</b>: Debug logging is turned off, and no code is generated for calls
* to the macro in the corePKCS11 library on compilation.
*/
#ifndef LogDebug
#define LogDebug( message )
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* CORE_PKCS11_CONFIG_DEFAULTS_H_ include guard. */

View File

@ -0,0 +1,154 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef CORE_PKCS11_PAL
#define CORE_PKCS11_PAL
/**
* @file core_pkcs11_pal.h
* @brief Port Specific File Access functions for PKCS #11
*/
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/*-----------------------------------------------------------*/
/*------------ Port Specific File Access API ----------------*/
/*--------- See core_pkcs11_pal.c for definitions ------------*/
/*-----------------------------------------------------------*/
/*------------------------ PKCS #11 PAL functions -------------------------*/
/**
* @brief Initializes the PKCS #11 PAL.
*
* This is always called first in C_Initialize if the module is not already
* initialized.
*
* @return CKR_OK on success.
* CKR_FUNCTION_FAILED on failure.
*/
/* @[declare_pkcs11_pal_initialize] */
CK_RV PKCS11_PAL_Initialize( void );
/* @[declare_pkcs11_pal_initialize] */
/**
* @brief Saves an object in non-volatile storage.
*
* Port-specific file write for cryptographic information.
*
* @param[in] pxLabel Attribute containing label of the object to be stored.
* @param[in] pucData The object data to be saved.
* @param[in] ulDataSize Size (in bytes) of object data.
*
* @return The object handle if successful.
* eInvalidHandle = 0 if unsuccessful.
*/
/* @[declare_pkcs11_pal_saveobject] */
CK_OBJECT_HANDLE PKCS11_PAL_SaveObject( CK_ATTRIBUTE_PTR pxLabel,
CK_BYTE_PTR pucData,
CK_ULONG ulDataSize );
/* @[declare_pkcs11_pal_saveobject] */
/**
* @brief Delete an object from NVM.
*
* @param[in] xHandle Handle to a PKCS #11 object.
*/
/* @[declare_pkcs11_pal_destroyobject] */
CK_RV PKCS11_PAL_DestroyObject( CK_OBJECT_HANDLE xHandle );
/* @[declare_pkcs11_pal_destroyobject] */
/**
* @brief Translates a PKCS #11 label into an object handle.
*
* Port-specific object handle retrieval.
*
*
* @param[in] pxLabel Pointer to the label of the object
* who's handle should be found.
* @param[in] usLength The length of the label, in bytes.
*
* @return The object handle if operation was successful.
* Returns eInvalidHandle if unsuccessful.
*/
/* @[declare_pkcs11_pal_findobject] */
CK_OBJECT_HANDLE PKCS11_PAL_FindObject( CK_BYTE_PTR pxLabel,
CK_ULONG usLength );
/* @[declare_pkcs11_pal_findobject] */
/**
* @brief Gets the value of an object in storage, by handle.
*
* Port-specific file access for cryptographic information.
*
* This call dynamically allocates the buffer which object value
* data is copied into. PKCS11_PAL_GetObjectValueCleanup()
* should be called after each use to free the dynamically allocated
* buffer.
*
* @sa PKCS11_PAL_GetObjectValueCleanup
*
* @param[in] xHandle The PKCS #11 object handle of the object to get the value of.
* @param[out] ppucData Pointer to buffer for file data.
* @param[out] pulDataSize Size (in bytes) of data located in file.
* @param[out] pIsPrivate Boolean indicating if value is private (CK_TRUE)
* or exportable (CK_FALSE)
*
* @return CKR_OK if operation was successful. CKR_KEY_HANDLE_INVALID if
* no such object handle was found, CKR_DEVICE_MEMORY if memory for
* buffer could not be allocated, CKR_FUNCTION_FAILED for device driver
* error.
*/
/* @[declare_pkcs11_pal_getobjectvalue] */
CK_RV PKCS11_PAL_GetObjectValue( CK_OBJECT_HANDLE xHandle,
CK_BYTE_PTR * ppucData,
CK_ULONG_PTR pulDataSize,
CK_BBOOL * pIsPrivate );
/* @[declare_pkcs11_pal_getobjectvalue] */
/**
* @brief Cleanup after PKCS11_GetObjectValue().
*
* @param[in] pucData The buffer to free.
* (*ppucData from PKCS11_PAL_GetObjectValue())
* @param[in] ulDataSize The length of the buffer to free.
* (*pulDataSize from PKCS11_PAL_GetObjectValue())
*/
/* @[declare_pkcs11_pal_getobjectvaluecleanup] */
void PKCS11_PAL_GetObjectValueCleanup( CK_BYTE_PTR pucData,
CK_ULONG ulDataSize );
/* @[declare_pkcs11_pal_getobjectvaluecleanup] */
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* CORE_PKCS11_PAL include guard. */

View File

@ -0,0 +1,100 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _CORE_PKI_UTILS_H_
#define _CORE_PKI_UTILS_H_
#include <stdint.h>
#include <stddef.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/**
* @file core_pki_utils.h
* @brief Helper functions for PKCS #11
*/
/**
* @brief Converts an ECDSA P-256 signature from the format provided by mbedTLS
* to the format expected by PKCS #11.
*
* For P-256 signatures, PKCS #11 expects a 64 byte signature, in the
* format of 32 byte R component followed by 32 byte S component.
*
* mbedTLS provides signatures in DER encoded, zero-padded format.
*
* @param[out] pxSignaturePKCS Pointer to a 64 byte buffer
* where PKCS #11 formatted signature
* will be placed. Caller must
* allocate 64 bytes of memory.
* @param[in] pxMbedSignature Pointer to DER encoded ECDSA
* signature. Buffer size is expected to be 72 bytes.
*
* \return 0 on success, -1 on failure.
*/
/* @[declare_pkcs11_utils_pkimbedtlssignaturetopkcs11signature] */
int8_t PKI_mbedTLSSignatureToPkcs11Signature( uint8_t * pxSignaturePKCS,
const uint8_t * pxMbedSignature );
/* @[declare_pkcs11_utils_pkimbedtlssignaturetopkcs11signature] */
/**
* @brief Converts and ECDSA P-256 signature from the format provided by PKCS #11
* to an ASN.1 formatted signature.
*
* For P-256 signature, ASN.1 formatting has the format
*
* SEQUENCE LENGTH
* INTEGER LENGTH R-VALUE
* INTEGER LENGTH S-VALUE
*
* @param[in,out] pucSig This pointer serves dual purpose.
* It should both contain the 64-byte PKCS #11
* style signature on input, and will be modified
* to hold the ASN.1 formatted signature (max length
* 72 bytes). It is the responsibility of the caller
* to guarantee that this pointer is large enough to
* hold the (longer) formatted signature.
*@param[out] pxSigLen Pointer to the length of the ASN.1 formatted signature.
*
* \return 0 if successful, -1 on failure.
*
*/
/* @[declare_pkcs11_utils_pkipkcs11signaturetombedtlssignature] */
int8_t PKI_pkcs11SignatureTombedTLSSignature( uint8_t * pucSig,
size_t * pxSigLen );
/* @[declare_pkcs11_utils_pkipkcs11signaturetombedtlssignature] */
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* ifndef _CORE_PKI_UTILS_H_ */

View File

@ -0,0 +1,218 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file core_pkcs11_pal_utils.c
* @brief Utility functions that are common for the software based PKCS #11
* implementation provided by corePKCS11 for both PAL layers of POSIX and
* Windows Simulator based FreeRTOS environments.
* These utils contain information of the on-flash storage files used for
* storing all PKCS #11 labels supported by the corePKCS11 library.
*/
/*-----------------------------------------------------------*/
/* C standard includes. */
#include <string.h>
#include <stdint.h>
/* corePKCS11 header include. */
#include "core_pkcs11_pal_utils.h"
/**
* @ingroup pkcs11_macros
* @brief Macros for managing PKCS #11 objects in flash.
*
*/
#define pkcs11palFILE_NAME_CLIENT_CERTIFICATE "corePKCS11_Certificate.dat" /**< The file name of the Certificate object. */
#define pkcs11palFILE_NAME_KEY "corePKCS11_Key.dat" /**< The file name of the Key object. */
#define pkcs11palFILE_NAME_PUBLIC_KEY "corePKCS11_PubKey.dat" /**< The file name of the Public Key object. */
#define pkcs11palFILE_CODE_SIGN_PUBLIC_KEY "corePKCS11_CodeSignKey.dat" /**< The file name of the Code Sign Key object. */
#define pkcs11palFILE_HMAC_SECRET_KEY "corePKCS11_HMACKey.dat" /**< The file name of the HMAC Secret Key object. */
#define pkcs11palFILE_CMAC_SECRET_KEY "corePKCS11_CMACKey.dat" /**< The file name of the CMAC Secret Key object. */
#define pkcs11palFILE_NAME_CLAIM_CERTIFICATE "corePKCS11_Claim_Certificate.dat" /**< The file name of the Provisioning Claim Certificate object. */
#define pkcs11palFILE_NAME_CLAIM_KEY "corePKCS11_Claim_Key.dat" /**< The file name of the Provisioning Claim Key object. */
void PAL_UTILS_LabelToFilenameHandle( const char * pcLabel,
const char ** pcFileName,
CK_OBJECT_HANDLE_PTR pHandle )
{
if( ( pcLabel != NULL ) && ( pHandle != NULL ) && ( pcFileName != NULL ) )
{
if( 0 == strncmp( pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS,
pcLabel,
sizeof( pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS ) ) )
{
*pcFileName = pkcs11palFILE_NAME_CLIENT_CERTIFICATE;
*pHandle = ( CK_OBJECT_HANDLE ) eAwsDeviceCertificate;
}
else if( 0 == strncmp( pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS,
pcLabel,
sizeof( pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS ) ) )
{
*pcFileName = pkcs11palFILE_NAME_KEY;
*pHandle = ( CK_OBJECT_HANDLE ) eAwsDevicePrivateKey;
}
else if( 0 == strncmp( pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS,
pcLabel,
sizeof( pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS ) ) )
{
*pcFileName = pkcs11palFILE_NAME_PUBLIC_KEY;
*pHandle = ( CK_OBJECT_HANDLE ) eAwsDevicePublicKey;
}
else if( 0 == strncmp( pkcs11configLABEL_CODE_VERIFICATION_KEY,
pcLabel,
sizeof( pkcs11configLABEL_CODE_VERIFICATION_KEY ) ) )
{
*pcFileName = pkcs11palFILE_CODE_SIGN_PUBLIC_KEY;
*pHandle = ( CK_OBJECT_HANDLE ) eAwsCodeSigningKey;
}
else if( 0 == strncmp( pkcs11configLABEL_HMAC_KEY,
pcLabel,
sizeof( pkcs11configLABEL_HMAC_KEY ) ) )
{
*pcFileName = pkcs11palFILE_HMAC_SECRET_KEY;
*pHandle = ( CK_OBJECT_HANDLE ) eAwsHMACSecretKey;
}
else if( 0 == strncmp( pkcs11configLABEL_CMAC_KEY,
pcLabel,
sizeof( pkcs11configLABEL_CMAC_KEY ) ) )
{
*pcFileName = pkcs11palFILE_CMAC_SECRET_KEY;
*pHandle = ( CK_OBJECT_HANDLE ) eAwsCMACSecretKey;
}
else if( 0 == strncmp( pkcs11configLABEL_CLAIM_CERTIFICATE,
pcLabel,
sizeof( pkcs11configLABEL_CLAIM_CERTIFICATE ) ) )
{
*pcFileName = pkcs11palFILE_NAME_CLAIM_CERTIFICATE;
*pHandle = ( CK_OBJECT_HANDLE ) eAwsClaimCertificate;
}
else if( 0 == strncmp( pkcs11configLABEL_CLAIM_PRIVATE_KEY,
pcLabel,
sizeof( pkcs11configLABEL_CLAIM_PRIVATE_KEY ) ) )
{
*pcFileName = pkcs11palFILE_NAME_CLAIM_KEY;
*pHandle = ( CK_OBJECT_HANDLE ) eAwsClaimPrivateKey;
}
else
{
*pcFileName = NULL;
*pHandle = ( CK_OBJECT_HANDLE ) eInvalidHandle;
}
LogDebug( ( "Converted %s to %s", pcLabel, *pcFileName ) );
}
else
{
LogError( ( "Could not convert label to filename. Received a NULL parameter." ) );
}
}
CK_RV PAL_UTILS_HandleToFilename( CK_OBJECT_HANDLE xHandle,
const char ** pcFileName,
CK_BBOOL * pIsPrivate )
{
CK_RV xReturn = CKR_OK;
if( pcFileName != NULL )
{
switch( ( CK_OBJECT_HANDLE ) xHandle )
{
case eAwsDeviceCertificate:
*pcFileName = pkcs11palFILE_NAME_CLIENT_CERTIFICATE;
/* MISRA Ref 10.5.1 [Essential type casting] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-105 */
/* coverity[misra_c_2012_rule_10_5_violation] */
*pIsPrivate = ( CK_BBOOL ) CK_FALSE;
break;
case eAwsDevicePrivateKey:
*pcFileName = pkcs11palFILE_NAME_KEY;
/* MISRA Ref 10.5.1 [Essential type casting] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-105 */
/* coverity[misra_c_2012_rule_10_5_violation] */
*pIsPrivate = ( CK_BBOOL ) CK_TRUE;
break;
case eAwsDevicePublicKey:
*pcFileName = pkcs11palFILE_NAME_PUBLIC_KEY;
/* MISRA Ref 10.5.1 [Essential type casting] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-105 */
/* coverity[misra_c_2012_rule_10_5_violation] */
*pIsPrivate = ( CK_BBOOL ) CK_FALSE;
break;
case eAwsCodeSigningKey:
*pcFileName = pkcs11palFILE_CODE_SIGN_PUBLIC_KEY;
/* MISRA Ref 10.5.1 [Essential type casting] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-105 */
/* coverity[misra_c_2012_rule_10_5_violation] */
*pIsPrivate = ( CK_BBOOL ) CK_FALSE;
break;
case eAwsHMACSecretKey:
*pcFileName = pkcs11palFILE_HMAC_SECRET_KEY;
/* MISRA Ref 10.5.1 [Essential type casting] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-105 */
/* coverity[misra_c_2012_rule_10_5_violation] */
*pIsPrivate = ( CK_BBOOL ) CK_TRUE;
break;
case eAwsCMACSecretKey:
*pcFileName = pkcs11palFILE_CMAC_SECRET_KEY;
/* MISRA Ref 10.5.1 [Essential type casting] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-105 */
/* coverity[misra_c_2012_rule_10_5_violation] */
*pIsPrivate = ( CK_BBOOL ) CK_TRUE;
break;
case eAwsClaimCertificate:
*pcFileName = pkcs11palFILE_NAME_CLAIM_CERTIFICATE;
/* MISRA Ref 10.5.1 [Essential type casting] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-105 */
/* coverity[misra_c_2012_rule_10_5_violation] */
*pIsPrivate = ( CK_BBOOL ) CK_FALSE;
break;
case eAwsClaimPrivateKey:
*pcFileName = pkcs11palFILE_NAME_CLAIM_KEY;
/* MISRA Ref 10.5.1 [Essential type casting] */
/* More details at: https://github.com/FreeRTOS/corePKCS11/blob/main/MISRA.md#rule-105 */
/* coverity[misra_c_2012_rule_10_5_violation] */
*pIsPrivate = ( CK_BBOOL ) CK_TRUE;
break;
default:
xReturn = CKR_KEY_HANDLE_INVALID;
break;
}
}
else
{
LogError( ( "Could not convert label to filename. Received a NULL parameter." ) );
}
return xReturn;
}

View File

@ -0,0 +1,83 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file core_pkcs11_pal_utils.h
* @brief Utility functions that are common for the software based PKCS #11
* implementation provided by corePKCS11 for both PAL layers of POSIX and
* Windows Simulator based FreeRTOS environments.
* These utils contain information of the on-flash storage files used for
* storing all PKCS #11 labels supported by the corePKCS11 library.
*/
/*-----------------------------------------------------------*/
/* PKCS 11 includes. */
#include "core_pkcs11_config.h"
#include "core_pkcs11_config_defaults.h"
#include "core_pkcs11.h"
/**
* @ingroup pkcs11_enums
* @brief Enums for managing PKCS #11 object types.
*
*/
enum eObjectHandles
{
eInvalidHandle = 0, /**< According to PKCS #11 spec, 0 is never a valid object handle. */
eAwsDevicePrivateKey = 1, /**< Private Key. */
eAwsDevicePublicKey, /**< Public Key. */
eAwsDeviceCertificate, /**< Certificate. */
eAwsCodeSigningKey, /**< Code Signing Key. */
eAwsHMACSecretKey, /**< HMAC Secret Key. */
eAwsCMACSecretKey, /**< CMAC Secret Key. */
eAwsClaimPrivateKey, /**< Provisioning Claim Private Key. */
eAwsClaimCertificate /**< Provisioning Claim Certificate. */
};
/**
* @brief Checks to see if a file exists
*
* @param[in] pcLabel The PKCS #11 label to convert to a file name
* @param[out] pcFileName The name of the file to check for existence.
* @param[out] pHandle The type of the PKCS #11 object.
*
*/
void PAL_UTILS_LabelToFilenameHandle( const char * pcLabel,
const char ** pcFileName,
CK_OBJECT_HANDLE_PTR pHandle );
/**
* @brief Maps object handle to file name.
*
* @param[in] pcLabel The PKCS #11 label to convert to a file name
* @param[out] pcFileName This will be populated with the file name that the
* @p pcLabel maps to.
* @param[out] pIsPrivateKey This will be set to true if the object handle
* represents a secret credential like asymmetric private key or a symmetric
* key.
*/
CK_RV PAL_UTILS_HandleToFilename( CK_OBJECT_HANDLE xHandle,
const char ** pcFileName,
CK_BBOOL * pIsPrivateKey );

View File

@ -0,0 +1,292 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file core_pkcs11_pal.c
* @brief Windows Simulator file save and read implementation
* for PKCS#11 based on mbedTLS with for software keys. This
* file deviates from the FreeRTOS style standard for some function names and
* data types in order to maintain compliance with the PKCS#11 standard.
*/
/*-----------------------------------------------------------*/
#include "FreeRTOS.h"
#include "core_pkcs11.h"
#include "core_pkcs11_config.h"
#include "core_pkcs11_config_defaults.h"
/* C runtime includes. */
#include <stdio.h>
#include <string.h>
#include "core_pkcs11_pal_utils.h"
/*-----------------------------------------------------------*/
/**
* @brief Checks to see if a file exists
*
* @param[in] pcFileName The name of the file to check for existence.
*
* @returns pdTRUE if the file exists, pdFALSE if not.
*/
BaseType_t prvFileExists( const char * pcFileName )
{
DWORD xReturn;
xReturn = GetFileAttributesA( pcFileName );
if( INVALID_FILE_ATTRIBUTES == xReturn )
{
return pdFALSE;
}
else
{
return pdTRUE;
}
}
/*-----------------------------------------------------------*/
CK_RV PKCS11_PAL_Initialize( void )
{
return CKR_OK;
}
CK_OBJECT_HANDLE PKCS11_PAL_SaveObject( CK_ATTRIBUTE_PTR pxLabel,
CK_BYTE_PTR pucData,
CK_ULONG ulDataSize )
{
uint32_t ulStatus = 0;
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD lpNumberOfBytesWritten;
char * pcFileName = NULL;
CK_OBJECT_HANDLE xHandle = eInvalidHandle;
/* Converts a label to its respective filename and handle. */
PAL_UTILS_LabelToFilenameHandle( pxLabel->pValue,
&pcFileName,
&xHandle );
/* If your project requires additional PKCS#11 objects, add them here. */
if( pcFileName != NULL )
{
/* Create the file. */
hFile = CreateFileA( pcFileName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( INVALID_HANDLE_VALUE == hFile )
{
ulStatus = GetLastError();
LogError( ( "Unable to create file %d \r\n", ulStatus ) );
xHandle = eInvalidHandle;
}
/* Write the object data. */
if( ERROR_SUCCESS == ulStatus )
{
if( FALSE == WriteFile( hFile, pucData, ulDataSize, &lpNumberOfBytesWritten, NULL ) )
{
ulStatus = GetLastError();
xHandle = eInvalidHandle;
}
}
/* Clean up. */
if( INVALID_HANDLE_VALUE != hFile )
{
CloseHandle( hFile );
}
}
return xHandle;
}
/*-----------------------------------------------------------*/
CK_OBJECT_HANDLE PKCS11_PAL_FindObject( CK_BYTE_PTR pxLabel,
CK_ULONG usLength )
{
/* Avoid compiler warnings about unused variables. */
( void ) usLength;
CK_OBJECT_HANDLE xHandle = eInvalidHandle;
char * pcFileName = NULL;
/* Converts a label to its respective filename and handle. */
PAL_UTILS_LabelToFilenameHandle( pxLabel,
&pcFileName,
&xHandle );
/* Check if object exists/has been created before returning. */
if( pdTRUE != prvFileExists( pcFileName ) )
{
xHandle = eInvalidHandle;
}
return xHandle;
}
/*-----------------------------------------------------------*/
CK_RV PKCS11_PAL_GetObjectValue( CK_OBJECT_HANDLE xHandle,
CK_BYTE_PTR * ppucData,
CK_ULONG_PTR pulDataSize,
CK_BBOOL * pIsPrivate )
{
CK_RV ulReturn = CKR_KEY_HANDLE_INVALID;
uint32_t ulDriverReturn = 0;
HANDLE hFile = INVALID_HANDLE_VALUE;
uint32_t ulSize = 0;
char * pcFileName = NULL;
ulReturn = PAL_UTILS_HandleToFilename( xHandle,
&pcFileName,
pIsPrivate );
if( ( pcFileName != NULL ) && ( pdTRUE == prvFileExists( pcFileName ) ) )
{
/* Open the file. */
hFile = CreateFileA( pcFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( INVALID_HANDLE_VALUE == hFile )
{
ulDriverReturn = GetLastError();
LogError( ( "Unable to open file %d \r\n", ulDriverReturn ) );
ulReturn = CKR_FUNCTION_FAILED;
}
if( 0 == ulReturn )
{
/* Get the file size. */
*pulDataSize = GetFileSize( hFile, ( LPDWORD ) ( &ulSize ) );
/* Create a buffer. */
*ppucData = pvPortMalloc( *pulDataSize );
if( NULL == *ppucData )
{
ulReturn = CKR_HOST_MEMORY;
}
}
/* Read the file. */
if( 0 == ulReturn )
{
if( FALSE == ReadFile( hFile,
*ppucData,
*pulDataSize,
( LPDWORD ) ( &ulSize ),
NULL ) )
{
LogError( ( "Unable to read file \r\n" ) );
ulReturn = CKR_FUNCTION_FAILED;
}
}
/* Confirm the amount of data read. */
if( 0 == ulReturn )
{
ulReturn = CKR_OK;
if( ulSize != *pulDataSize )
{
ulReturn = CKR_FUNCTION_FAILED;
}
}
/* Clean up. */
if( INVALID_HANDLE_VALUE != hFile )
{
CloseHandle( hFile );
}
}
return ulReturn;
}
/*-----------------------------------------------------------*/
void PKCS11_PAL_GetObjectValueCleanup( CK_BYTE_PTR pucData,
CK_ULONG ulDataSize )
{
/* Unused parameters. */
( void ) ulDataSize;
if( NULL != pucData )
{
vPortFree( pucData );
}
}
/*-----------------------------------------------------------*/
CK_RV PKCS11_PAL_DestroyObject( CK_OBJECT_HANDLE xHandle )
{
const char * pcFileName = NULL;
CK_BBOOL xIsPrivate = CK_TRUE;
CK_RV xResult = CKR_OBJECT_HANDLE_INVALID;
BOOL ret = 0;
xResult = PAL_UTILS_HandleToFilename( xHandle,
&pcFileName,
&xIsPrivate );
if( xResult == CKR_OK )
{
if( pdTRUE == prvFileExists( pcFileName ) )
{
ret = DeleteFileA( pcFileName );
if( ret == 0 )
{
xResult = CKR_FUNCTION_FAILED;
}
else
{
xResult = CKR_OK;
}
}
}
return xResult;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,312 @@
/*
* corePKCS11 v3.5.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file core_pkcs11_pal.c
* @brief Linux file save and read implementation
* for PKCS #11 based on mbedTLS with for software keys. This
* file deviates from the FreeRTOS style standard for some function names and
* data types in order to maintain compliance with the PKCS #11 standard.
*/
/*-----------------------------------------------------------*/
/* PKCS 11 includes. */
#include "core_pkcs11_config.h"
#include "core_pkcs11_config_defaults.h"
#include "core_pkcs11.h"
#include "core_pkcs11_pal_utils.h"
/* C runtime includes. */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*-----------------------------------------------------------*/
/**
* @brief Checks to see if a file exists
*
* @param[in] pcFileName The name of the file to check for existence.
*
* @returns CKR_OK if the file exists, CKR_OBJECT_HANDLE_INVALID if not.
*/
static CK_RV prvFileExists( const char * pcFileName )
{
FILE * pxFile = NULL;
CK_RV xReturn = CKR_OK;
/* fopen returns NULL if the file does not exist. */
pxFile = fopen( pcFileName, "r" );
if( pxFile == NULL )
{
xReturn = CKR_OBJECT_HANDLE_INVALID;
LogDebug( ( "File %s does not exist or could not opened for reading.", pcFileName ) );
}
else
{
( void ) fclose( pxFile );
LogDebug( ( "Found file %s and was able to open it for reading.", pcFileName ) );
}
return xReturn;
}
/**
* @brief Reads object value from file system.
*
* @param[in] pcLabel The PKCS #11 label to convert to a file name
* @param[out] pcFileName The name of the file to check for existence.
* @param[out] pHandle The type of the PKCS #11 object.
*
*/
static CK_RV prvReadData( const char * pcFileName,
CK_BYTE_PTR * ppucData,
CK_ULONG_PTR pulDataSize )
{
CK_RV xReturn = CKR_OK;
FILE * pxFile = NULL;
size_t lSize = 0;
pxFile = fopen( pcFileName, "r" );
if( NULL == pxFile )
{
LogError( ( "PKCS #11 PAL failed to get object value. "
"Could not open file named %s for reading.", pcFileName ) );
xReturn = CKR_FUNCTION_FAILED;
}
else
{
( void ) fseek( pxFile, 0, SEEK_END );
lSize = ftell( pxFile );
( void ) fseek( pxFile, 0, SEEK_SET );
if( lSize > 0UL )
{
*pulDataSize = lSize;
*ppucData = malloc( *pulDataSize );
if( NULL == *ppucData )
{
LogError( ( "Could not get object value. Malloc failed to allocate memory." ) );
xReturn = CKR_HOST_MEMORY;
}
}
else
{
LogError( ( "Could not get object value. Failed to determine object size." ) );
xReturn = CKR_FUNCTION_FAILED;
}
}
if( CKR_OK == xReturn )
{
lSize = 0;
lSize = fread( *ppucData, sizeof( uint8_t ), *pulDataSize, pxFile );
if( lSize != *pulDataSize )
{
LogError( ( "PKCS #11 PAL Failed to get object value. Expected to read %ld "
"from %s but received %ld", *pulDataSize, pcFileName, lSize ) );
xReturn = CKR_FUNCTION_FAILED;
}
}
if( NULL != pxFile )
{
( void ) fclose( pxFile );
}
return xReturn;
}
/*-----------------------------------------------------------*/
CK_RV PKCS11_PAL_Initialize( void )
{
return CKR_OK;
}
CK_OBJECT_HANDLE PKCS11_PAL_SaveObject( CK_ATTRIBUTE_PTR pxLabel,
CK_BYTE_PTR pucData,
CK_ULONG ulDataSize )
{
FILE * pxFile = NULL;
size_t ulBytesWritten;
const char * pcFileName = NULL;
CK_OBJECT_HANDLE xHandle = ( CK_OBJECT_HANDLE ) eInvalidHandle;
if( ( pxLabel != NULL ) && ( pucData != NULL ) )
{
/* Converts a label to its respective filename and handle. */
PAL_UTILS_LabelToFilenameHandle( pxLabel->pValue,
&pcFileName,
&xHandle );
}
else
{
LogError( ( "Could not save object. Received invalid parameters." ) );
}
if( pcFileName != NULL )
{
/* Overwrite the file every time it is saved. */
pxFile = fopen( pcFileName, "w" );
if( NULL == pxFile )
{
LogError( ( "PKCS #11 PAL was unable to save object to file. "
"The PAL was unable to open a file with name %s in write mode.", pcFileName ) );
xHandle = ( CK_OBJECT_HANDLE ) eInvalidHandle;
}
else
{
ulBytesWritten = fwrite( pucData, sizeof( uint8_t ), ulDataSize, pxFile );
if( ulBytesWritten != ulDataSize )
{
LogError( ( "PKCS #11 PAL was unable to save object to file. "
"Expected to write %lu bytes, but wrote %lu bytes.", ulDataSize, ulBytesWritten ) );
xHandle = ( CK_OBJECT_HANDLE ) eInvalidHandle;
}
else
{
LogDebug( ( "Successfully wrote %lu to %s", ulBytesWritten, pcFileName ) );
}
}
if( NULL != pxFile )
{
( void ) fclose( pxFile );
}
}
else
{
LogError( ( "Could not save object. Unable to find the correct file." ) );
}
return xHandle;
}
/*-----------------------------------------------------------*/
CK_OBJECT_HANDLE PKCS11_PAL_FindObject( CK_BYTE_PTR pxLabel,
CK_ULONG usLength )
{
const char * pcFileName = NULL;
CK_OBJECT_HANDLE xHandle = ( CK_OBJECT_HANDLE ) eInvalidHandle;
( void ) usLength;
if( pxLabel != NULL )
{
PAL_UTILS_LabelToFilenameHandle( ( const char * ) pxLabel,
&pcFileName,
&xHandle );
if( CKR_OK != prvFileExists( pcFileName ) )
{
xHandle = ( CK_OBJECT_HANDLE ) eInvalidHandle;
}
}
else
{
LogError( ( "Could not find object. Received a NULL label." ) );
}
return xHandle;
}
/*-----------------------------------------------------------*/
CK_RV PKCS11_PAL_GetObjectValue( CK_OBJECT_HANDLE xHandle,
CK_BYTE_PTR * ppucData,
CK_ULONG_PTR pulDataSize,
CK_BBOOL * pIsPrivate )
{
CK_RV xReturn = CKR_OK;
const char * pcFileName = NULL;
if( ( ppucData == NULL ) || ( pulDataSize == NULL ) || ( pIsPrivate == NULL ) )
{
xReturn = CKR_ARGUMENTS_BAD;
LogError( ( "Could not get object value. Received a NULL argument." ) );
}
else
{
xReturn = PAL_UTILS_HandleToFilename( xHandle, &pcFileName, pIsPrivate );
}
if( xReturn == CKR_OK )
{
xReturn = prvReadData( pcFileName, ppucData, pulDataSize );
}
return xReturn;
}
/*-----------------------------------------------------------*/
void PKCS11_PAL_GetObjectValueCleanup( CK_BYTE_PTR pucData,
CK_ULONG ulDataSize )
{
/* Unused parameters. */
( void ) ulDataSize;
if( NULL != pucData )
{
free( pucData );
}
}
/*-----------------------------------------------------------*/
CK_RV PKCS11_PAL_DestroyObject( CK_OBJECT_HANDLE xHandle )
{
const char * pcFileName = NULL;
CK_BBOOL xIsPrivate = CK_TRUE;
CK_RV xResult = CKR_OBJECT_HANDLE_INVALID;
int ret = 0;
xResult = PAL_UTILS_HandleToFilename( xHandle,
&pcFileName,
&xIsPrivate );
if( ( xResult == CKR_OK ) && ( prvFileExists( pcFileName ) == CKR_OK ) )
{
ret = remove( pcFileName );
if( ret != 0 )
{
xResult = CKR_FUNCTION_FAILED;
}
}
return xResult;
}
/*-----------------------------------------------------------*/