blob: 76134f7b61ed8c6b8d1874d0ad6a88f926506c5a [file] [log] [blame]
/*
* Amazon FreeRTOS PKCS#11 for A71CH V1.0.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2018 NXP
*
* 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.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
#if defined(SSS_USE_FTR_FILE)
#include "fsl_sss_ftr.h"
#else
#include "fsl_sss_ftr_default.h"
#endif
#if (SSS_HAVE_SSCP || SSS_HAVE_APPLET_SE05X_IOT)
/* FreeRTOS includes. */
#if defined(USE_RTOS) && USE_RTOS == 1
#include "FreeRTOS.h"
#include "FreeRTOSIPConfig.h"
#include "iot_crypto.h"
#include "semphr.h"
#include "task.h"
#endif
#include "iot_pkcs11.h"
/* mbedTLS includes. */
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/base64.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
#include "mbedtls/oid.h"
#include "mbedtls/pk.h"
#include "mbedtls/pk_internal.h"
#include "mbedtls/sha256.h"
#include "mbedtls/x509_crt.h"
#include "pkcs11_mbedtls_utils.h"
#if defined(USE_RTOS) && USE_RTOS == 1
#include "aws_clientcredential.h"
#endif
/*Other includes */
#include <nxEnsure.h>
#include <nxLog_App.h>
#include "HLSEAPI.h"
#include "ex_sss.h"
#if SSS_HAVE_ALT_A71CH
#include "ax_mbedtls.h"
#endif
#if SSS_HAVE_ALT_SSS
#include "sss_mbedtls.h"
#endif
#if SSS_HAVE_APPLET_SE05X_IOT
#include <fsl_sss_se05x_apis.h>
#include <se05x_APDU.h>
#include <se05x_const.h>
#include "se05x_APDU_apis.h"
#include "se05x_enums.h"
#endif
#if defined(PKCS11_LIBRARY)
#include <projdefs.h>
#if (__GNUC__ && !AX_EMBEDDED)
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
/* Only for base session with os */
static pthread_mutex_t gSessionlock;
static pthread_mutex_t gFilelock;
#endif
#endif
#if defined(USE_RTOS) && USE_RTOS == 1
static SemaphoreHandle_t xSemaphore;
#endif
/* C runtime includes. */
#include <PlugAndTrust_Pkg_Ver.h>
#include <fsl_sss_util_asn1_der.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Remove this later */
#include <ex_sss_boot.h>
extern ex_sss_boot_ctx_t *pex_sss_demo_boot_ctx;
extern ex_sss_cloud_ctx_t *pex_sss_demo_tls_ctx;
extern char *g_port_name;
#define PKCS11_TOKEN_LABEL \
{ \
'S', 'S', 'S', '_', 'P', 'K', 'C', 'S', '1', '1' \
}
#define PKCS11_MANUFACTURER \
{ \
'N', 'X', 'P' \
}
#define PKCS11_LIBRARY_VERSION \
(CK_VERSION) \
{ \
.major = PLUGANDTRUST_VER_MAJOR, .minor = PLUGANDTRUST_VER_MINOR, \
}
#define pkcs11SLOT_ID 1
#define pkcs11OBJECT_HANDLE_PUBLIC_KEY 1
#define pkcs11OBJECT_HANDLE_PRIVATE_KEY 2
#define pkcs11OBJECT_HANDLE_CERTIFICATE 3
#define pkcs11OBJECT_HANDLE_SYMMETRIC 4
#define SIZE_CLIENT_CERTIFICATE 500
#define SIZE_INTER_ROOT_CERTIFICATE 900
#define CKA_SSS_ID CKA_VENDOR_DEFINED + CKA_OBJECT_ID
/**
* @brief Definitions for parameter checking
*/
#define pkcs11CREATEOBJECT_MINIMUM_ATTRIBUTE_COUNT 2
/**
* Defines for the set key pair through create object
*/
#define pkcs11CREATEOBJECT_SET_KEYPAIR_LENGTH 138
#define pkcs11CREATEOBJECT_SET_PUBKEY_LENGTH 65
#define pkcs11CREATEOBJECT_PUBLIC_KEY_INDEX 32
#define pkcs11NO_OPERATION ((CK_MECHANISM_TYPE)0xFFFFFFFFF)
#define pkcs11INVALID_OBJECT_CLASS ((CK_OBJECT_CLASS)0x0FFFFFFF)
#define pkcs11INVALID_KEY_TYPE ((CK_KEY_TYPE)0x0FFFFFFF)
#if defined(USE_RTOS) && USE_RTOS == 1
#define LOCK_MUTEX_FOR_RTOS if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE)
#else
#define LOCK_MUTEX_FOR_RTOS
#endif
#if defined(USE_RTOS) && USE_RTOS == 1
#define UNLOCK_MUTEX_FOR_RTOS_RET(RET) \
xSemaphoreGive(xSemaphore); \
return RET;
#else
#define UNLOCK_MUTEX_FOR_RTOS_RET(RET) return RET;
#endif
#if defined(USE_RTOS) && USE_RTOS == 1
#define UNLOCK_MUTEX_FOR_RTOS xSemaphoreGive(xSemaphore);
#else
#define UNLOCK_MUTEX_FOR_RTOS
#endif
#if defined(USE_RTOS) && USE_RTOS == 1
#define UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(CONDITION) \
if (!(CONDITION)) { \
NX_ENSURE_MESSAGE(#CONDITION); \
xSemaphoreGive(xSemaphore); \
goto exit; \
}
#else
#define UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(CONDITION) ENSURE_OR_GO_EXIT(CONDITION)
#endif
#define ASN1_SKIP_TO_NEXT_TAG(pTLV, taglen) \
{ \
if (taglen < 0x7F) { \
pTLV += taglen + 1 + 1 /* Length byte */; \
} \
else if (taglen < 0xFF) { \
pTLV += taglen + 1 + 2 /* Length bytes */; \
} \
else { \
pTLV += taglen + 1 + 3 /* Length bytes */; \
} \
}
// uint8_t nist_header_start[] = { 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13,
// 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
// 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
// 0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02,
// 0x01, 0x01, 0x04, 0x20};
// uint8_t nist_header_end[] = {0xA1, 0x44, 0x03, 0x42, 0x00 };
static int sessionCount = 0;
static bool cryptokiInitialized = false;
static bool mutex_initialised = false;
// #if (__GNUC__ && !AX_EMBEDDED)
// #endif
typedef int (*pfnMbedTlsSign)(void *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash,
size_t hash_len,
unsigned char *sig,
size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng);
/**
* @brief Key structure.
*/
typedef struct P11Key
{
mbedtls_pk_context xMbedPkCtx;
mbedtls_x509_crt xMbedX509Cli;
mbedtls_pk_info_t xMbedPkInfo;
pfnMbedTlsSign pfnSavedMbedSign;
void *pvSavedMbedPkCtx;
uint16_t pem_len_client;
uint16_t pem_len_client_ca;
unsigned char *certificate_buf; //[2500];
} P11Key_t, *P11KeyPtr_t;
/**
* @brief Session structure.
*/
typedef struct P11Session
{
P11KeyPtr_t pxCurrentKey;
CK_ULONG ulState;
CK_BBOOL xOpened;
CK_MECHANISM_TYPE xOperationInProgress;
CK_BBOOL digestUpdateCalled;
CK_OBJECT_HANDLE xOperationKeyHandle;
CK_BBOOL xFindObjectInit;
CK_BBOOL xFindObjectComplete;
CK_OBJECT_CLASS xFindObjectClass;
uint32_t xFindObjectTotalFound;
CK_KEY_TYPE xFindObjectKeyType;
mbedtls_ctr_drbg_context xMbedDrbgCtx;
mbedtls_entropy_context xMbedEntropyContext;
mbedtls_pk_context xPublicKey;
mbedtls_sha256_context xSHA256Context;
CK_BBOOL labelPresent;
CK_BBOOL keyIdPresent;
uint32_t keyId;
char label[32];
size_t labelLen;
void *mechParameter;
CK_ULONG mechParameterLen;
#if SSS_HAVE_ALT_SSS
sss_digest_t digest_ctx;
#endif
} P11Session_t, *P11SessionPtr_t;
/*-----------------------------------------------------------*/
// static void prvFreeKey( P11KeyPtr_t pxKey );
// static int awsRetreieve_certificate(unsigned char *pbuf, uint8_t index, uint32_t *outbuflen);
// static int convertdertopemformat(const unsigned char * int_ca_cert_der, int len_der, unsigned char * int_ca_cert_pem, int dst_buf_len, U16 *outlength);
CK_RV ParseSignMechanism(P11SessionPtr_t pxSession, sss_algorithm_t *algorithm);
CK_RV ParseEncryptionMechanism(P11SessionPtr_t pxSession, sss_algorithm_t *algorithm);
CK_RV ParseDigestMechanism(P11SessionPtr_t pxSession, sss_algorithm_t *algorithm);
CK_RV AsymmetricEncrypt(P11SessionPtr_t pxSessionObj,
sss_algorithm_t algorithm,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pEncryptedData,
CK_ULONG_PTR pulEncryptedDataLen);
CK_RV AsymmetricDecrypt(P11SessionPtr_t pxSessionObj,
sss_algorithm_t algorithm,
CK_BYTE_PTR pEncryptedData,
CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDataLen);
CK_RV SymmetricEncrypt(P11SessionPtr_t pxSessionObj,
sss_algorithm_t algorithm,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pEncryptedData,
CK_ULONG_PTR pulEncryptedDataLen);
CK_RV SymmetricDecrypt(P11SessionPtr_t pxSessionObj,
sss_algorithm_t algorithm,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pEncryptedData,
CK_ULONG_PTR pulEncryptedDataLen);
CK_RV GetAttributeParameterIndex(
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type, CK_ULONG_PTR index);
CK_RV LabelToKeyId(unsigned char *label, size_t labelSize, uint32_t *keyId);
CK_RV CreateRawPrivateKey(CK_ATTRIBUTE_PTR pxTemplate, CK_ULONG ulCount, uint8_t *key, size_t *keyLen);
CK_RV CreateRawPublicKey(CK_ATTRIBUTE_PTR pxTemplate, CK_ULONG ulCount, uint8_t *key, size_t *keyLen);
CK_RV EcSignatureToRandS(uint8_t *signature, size_t *sigLen);
CK_RV EcRandSToSignature(uint8_t *rands, const size_t rands_len, uint8_t *output, size_t *outputLen);
CK_RV EcPublickeyGetEcParams(uint8_t *input, size_t *dataLen);
CK_RV parseCertificateGetAttribute(
uint32_t xObject, CK_ATTRIBUTE_TYPE attributeType, uint8_t *pData, CK_ULONG *ulAttrLength);
#if SSS_HAVE_ALT_A71CH
static U16 HLSE_Create_token(
uint32_t keyId, HLSE_OBJECT_TYPE objType, void *buff, unsigned long bufflen, HLSE_OBJECT_HANDLE handle_object);
static mbedtls_ecp_group_id curve_list[16] = {
0,
};
#endif
#if SSS_HAVE_APPLET_SE05X_IOT
static smStatus_t read_id_list(uint32_t *idlist, size_t *idlistlen);
static CK_RV read_object_size_with_lock(uint32_t keyId, uint16_t *keyLen);
static CK_RV read_object_size(uint32_t keyId, uint16_t *keyLen);
static uint8_t CheckIfKeyIdExists(uint32_t keyId, pSe05xSession_t session_ctx);
#endif
#if SSS_HAVE_ALT_SSS
static int convertpemtoder(const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen);
static sss_status_t sss_create_token(sss_key_store_t *keystore,
sss_object_t *CreateObject,
U32 ObjectId,
sss_key_part_t KeyPart,
sss_cipher_type_t CipherType,
U8 *buffer,
U32 bufferLen,
U32 bitLen);
static mbedtls_ecp_group_id curve_list[16] = {
0,
};
#endif
#define ID_ECPUBLICKEY \
{ \
0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 \
}
typedef struct _object_identifiers
{
uint32_t identifier[16];
size_t indentifier_len;
int groupId;
char *name;
} object_identifiers_t;
static object_identifiers_t object_identifiers[] = {
{{1, 2, 840, 10045, 3, 1, 1}, 7, MBEDTLS_ECP_DP_SECP192R1, "MBEDTLS_ECP_DP_SECP192R1"},
{{1, 3, 132, 0, 33}, 5, MBEDTLS_ECP_DP_SECP224R1, "MBEDTLS_ECP_DP_SECP224R1"},
{{1, 2, 840, 10045, 3, 1, 7}, 7, MBEDTLS_ECP_DP_SECP256R1, "MBEDTLS_ECP_DP_SECP256R1"},
{{1, 3, 132, 0, 34}, 5, MBEDTLS_ECP_DP_SECP384R1, "MBEDTLS_ECP_DP_SECP384R1"},
{{1, 3, 132, 0, 35}, 5, MBEDTLS_ECP_DP_SECP521R1, "MBEDTLS_ECP_DP_SECP521R1"},
{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7}, 10, MBEDTLS_ECP_DP_BP256R1, "MBEDTLS_ECP_DP_BP256R1"},
{{1, 3, 24, 3, 3, 2, 8, 1, 1, 7}, 10, MBEDTLS_ECP_DP_BP256R1, "MBEDTLS_ECP_DP_BP256R1"},
{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11}, 10, MBEDTLS_ECP_DP_BP384R1, "MBEDTLS_ECP_DP_BP384R1"},
{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13}, 10, MBEDTLS_ECP_DP_BP512R1, "MBEDTLS_ECP_DP_BP512R1"},
{{1, 3, 132, 0, 31}, 5, MBEDTLS_ECP_DP_SECP192K1, "MBEDTLS_ECP_DP_SECP192K1"},
{{1, 3, 132, 0, 32}, 5, MBEDTLS_ECP_DP_SECP224K1, "MBEDTLS_ECP_DP_SECP224K1"},
{{1, 3, 132, 0, 10}, 5, MBEDTLS_ECP_DP_SECP256K1, "MBEDTLS_ECP_DP_SECP256K1"},
{
{
0,
},
0,
0,
},
};
#if SSS_HAVE_ALT
// int mbedtls_ssl_set_curve_list(mbedtls_ssl_config *conf, const char * pcLabelName)
int mbedtls_ssl_set_curve_list(mbedtls_ssl_config *conf, uint32_t keyIndex)
{
sss_status_t status = kStatus_SSS_Fail;
sss_object_t clientKey = {
0,
};
uint32_t objectId[16] = {
0,
};
uint8_t objectIdLen = sizeof(objectId);
int i = 0;
// uint32_t keyIndex = 0;
// LabelToKeyId((unsigned char*)pcLabelName, strlen(pcLabelName), &keyIndex);
// printf(" \n\n%s\n\n", __FUNCTION__);
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&clientKey, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(kStatus_SSS_Fail);
// return kStatus_SSS_Fail;
}
status = sss_key_object_get_handle(&clientKey, keyIndex);
if (status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(kStatus_SSS_Fail);
// return kStatus_SSS_Fail;
}
status = sss_util_asn1_get_oid_from_sssObj(&clientKey, objectId, &objectIdLen);
if (status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(1);
// return 1;
}
UNLOCK_MUTEX_FOR_RTOS
}
while (1) {
if (object_identifiers[i].indentifier_len == 0) {
break;
}
if (object_identifiers[i].indentifier_len != objectIdLen) {
i++;
continue;
}
if (0 == memcmp(object_identifiers[i].identifier, objectId, (objectIdLen * sizeof(uint32_t)))) {
curve_list[0] = object_identifiers[i].groupId;
curve_list[1] = MBEDTLS_ECP_DP_NONE;
mbedtls_ssl_conf_curves(conf, curve_list);
return 0;
}
i++;
}
return 1;
}
#endif //SSS_HAVE_ALT
/**
* @brief Maps an opaque caller session handle into its internal state structure.
*/
static P11SessionPtr_t prvSessionPointerFromHandle(CK_SESSION_HANDLE xSession)
{
return (P11SessionPtr_t)xSession; /*lint !e923 Allow casting integer type to pointer for handle. */
}
/*-----------------------------------------------------------*/
/**
* @brief Initializes a key structure.
*/
/*-----------------------------------------------------------*/
/**
* @brief Load the default key and certificate from storage.
*/
CK_RV GetAttributeParameterIndex(
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type, CK_ULONG_PTR index)
{
CK_RV xResult = CKR_ARGUMENTS_BAD;
CK_ULONG i = 0;
CK_BBOOL foundType = CK_FALSE;
for (i = 0; i < ulCount; i++) {
if (pTemplate[i].type == type) {
foundType = CK_TRUE;
xResult = CKR_OK;
break;
}
}
if (foundType) {
*index = i;
}
return xResult;
}
CK_RV AsymmetricEncrypt(P11SessionPtr_t pxSessionObj,
sss_algorithm_t algorithm,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pEncryptedData,
CK_ULONG_PTR pulEncryptedDataLen)
{
CK_RV xResult = CKR_OK;
sss_status_t status = kStatus_SSS_Fail;
uint8_t data[2048] = {0};
size_t dataLen = sizeof(data);
// sss_algorithm_t digest_algorithm = kAlgorithm_None;
sss_asymmetric_t asymmCtx;
sss_object_t sss_object = {0};
if (pxSessionObj->xOperationInProgress == CKM_RSA_PKCS) {
xResult = (2048 >= (ulDataLen + 11)) ? CKR_OK : CKR_MECHANISM_INVALID;
if (xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
}
#if 0 //Check if hashing is performed in applet because we are not calculating hash in AKM
if(pxSessionObj->xOperationInProgress != CKM_RSA_PKCS) {
xResult = GetSSSAlgorithm(algorithm, &digest_algorithm);
if(xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
sss_digest_t digestCtx;
status = sss_digest_context_init(&digestCtx,
&pex_sss_demo_boot_ctx->session,
digest_algorithm,
kMode_SSS_Digest);
if(status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_DEVICE_ERROR;
}
status = sss_digest_one_go(&digestCtx,
pData,
(size_t) ulDataLen,
&data[0],
&dataLen);
if(status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_DEVICE_ERROR;
}
sss_digest_context_free(&digestCtx);
}
else
#endif
{
memcpy(&data[0], pData, ulDataLen);
dataLen = ulDataLen;
}
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
}
status = sss_key_object_get_handle(&sss_object, pxSessionObj->xOperationKeyHandle);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
}
status = sss_asymmetric_context_init(
&asymmCtx, &pex_sss_demo_boot_ctx->session, &sss_object, algorithm, kMode_SSS_Encrypt);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_asymmetric_context_ sign init Failed...");
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
/* Do Encryption */
uint8_t encData[256] = {0};
size_t encDataLen = sizeof(encData);
status = sss_asymmetric_encrypt(&asymmCtx, &data[0], dataLen, &encData[0], &encDataLen);
if (status != kStatus_SSS_Success) {
LOG_E("sss_asymmetric_encrypt failed");
xResult = CKR_FUNCTION_FAILED;
}
if (xResult == CKR_OK) {
if (pEncryptedData) {
if (*pulEncryptedDataLen < encDataLen) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
memcpy(pEncryptedData, &encData[0], encDataLen);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
}
}
*pulEncryptedDataLen = encDataLen;
}
sss_asymmetric_context_free(&asymmCtx);
UNLOCK_MUTEX_FOR_RTOS
}
return xResult;
}
CK_RV AsymmetricDecrypt(P11SessionPtr_t pxSessionObj,
sss_algorithm_t algorithm,
CK_BYTE_PTR pEncryptedData,
CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDataLen)
{
CK_RV xResult = CKR_OK;
sss_status_t status = kStatus_SSS_Fail;
uint8_t data[2048] = {0};
size_t dataLen = sizeof(data);
// sss_algorithm_t digest_algorithm = kAlgorithm_None;
sss_asymmetric_t asymmCtx;
sss_object_t sss_object = {0};
// if(pxSessionObj->xOperationInProgress == CKM_RSA_PKCS) {
// xResult = (2048 >= (ulEncryptedDataLen + 11)) ? CKR_OK : CKR_MECHANISM_INVALID;
// if(xResult != CKR_OK) {
// pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
// return xResult;
// }
// }
#if 0 // Not required for decryption. Not sure how to process Algorithm with hashing.
if(pxSessionObj->xOperationInProgress != CKM_RSA_PKCS /*&&
pxSessionObj->xOperationInProgress != CKM_RSA_PKCS_PSS*/) {
xResult = GetSSSAlgorithm(algorithm, &digest_algorithm);
if(xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
sss_digest_t digestCtx;
status = sss_digest_context_init(&digestCtx,
&pex_sss_demo_boot_ctx->session,
digest_algorithm,
kMode_SSS_Digest);
if(status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_DEVICE_ERROR;
}
status = sss_digest_one_go(&digestCtx,
pEncryptedData,
(size_t) ulEncryptedDataLen,
&data[0],
&dataLen);
if(status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_DEVICE_ERROR;
}
sss_digest_context_free(&digestCtx);
}
else
#endif
{
memcpy(&data[0], pEncryptedData, ulEncryptedDataLen);
dataLen = ulEncryptedDataLen;
}
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
}
status = sss_key_object_get_handle(&sss_object, pxSessionObj->xOperationKeyHandle);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
}
status = sss_asymmetric_context_init(
&asymmCtx, &pex_sss_demo_boot_ctx->session, &sss_object, algorithm, kMode_SSS_Decrypt);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_asymmetric_context_ sign init Failed...");
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
/* Do Signing */
uint8_t signature[256] = {0};
size_t sigLen = sizeof(signature);
status = sss_asymmetric_decrypt(&asymmCtx, &data[0], dataLen, &signature[0], &sigLen);
// status = sss_asymmetric_sign_digest(
// &asymmCtx, &data[0], dataLen, &signature[0], &sigLen);
if (status != kStatus_SSS_Success) {
LOG_E("sss_asymmetric_decrypt failed");
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
xResult = CKR_FUNCTION_FAILED;
}
if (xResult == CKR_OK) {
if (pData) {
if (*pulDataLen < sigLen) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
memcpy(pData, &signature[0], sigLen);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
}
}
*pulDataLen = sigLen;
}
sss_asymmetric_context_free(&asymmCtx);
UNLOCK_MUTEX_FOR_RTOS
}
return xResult;
}
CK_RV SymmetricEncrypt(P11SessionPtr_t pxSessionObj,
sss_algorithm_t algorithm,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pEncryptedData,
CK_ULONG_PTR pulEncryptedDataLen)
{
CK_RV xResult = CKR_OK;
sss_status_t status = kStatus_SSS_Fail;
// uint8_t data[2048] = { 0 };
// size_t dataLen = sizeof(data);
sss_symmetric_t symmCtx;
sss_object_t symmObject;
// memcpy(&data[0], pData, ulDataLen);
// dataLen = ulDataLen;
uint8_t iv[16] = {0};
size_t ivLen = sizeof(iv);
uint8_t encData[256] = {0};
size_t encDataLen = sizeof(encData);
size_t tempOutBufLen = encDataLen;
uint8_t *pOut = &encData[0];
if (algorithm == kAlgorithm_SSS_AES_CBC) {
if (pxSessionObj->mechParameterLen != 0) {
memcpy(iv, pxSessionObj->mechParameter, ivLen);
}
}
#if 0
//PKCS11 Documentation not clear. Ignoring currently
if(algorithm == kAlgorithm_SSS_AES_CTR) {
if(!pxSessionObj->mechParameterLen) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_ARGUMENTS_BAD;
}
else {
CK_AES_CTR_PARAMS_PTR ctrParams = (CK_AES_CTR_PARAMS_PTR) pxSessionObj->mechParameter;
memcpy(&iv[0], &pxSessionObj->mechParameter.cb[0], sizeof(iv));
}
}
#endif
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&symmObject, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
// return CKR_DEVICE_ERROR;
}
status = sss_key_object_get_handle(&symmObject, pxSessionObj->xOperationKeyHandle);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
// return CKR_DEVICE_ERROR;
}
status = sss_symmetric_context_init(
&symmCtx, &pex_sss_demo_boot_ctx->session, &symmObject, algorithm, kMode_SSS_Encrypt);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
// return CKR_DEVICE_ERROR;
}
/*Do Encryption*/
status = sss_cipher_init(&symmCtx, iv, ivLen);
if (status != kStatus_SSS_Success) {
sss_symmetric_context_free(&symmCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
}
status = sss_cipher_update(&symmCtx, (const uint8_t *)pData, (size_t)ulDataLen, pOut, &tempOutBufLen);
if (status != kStatus_SSS_Success) {
sss_symmetric_context_free(&symmCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
// return CKR_DEVICE_ERROR;
}
pOut = pOut + tempOutBufLen;
encDataLen = tempOutBufLen;
tempOutBufLen = sizeof(encData) - tempOutBufLen;
status = sss_cipher_finish(&symmCtx, NULL, 0, pOut, &tempOutBufLen);
if (status != kStatus_SSS_Success) {
sss_symmetric_context_free(&symmCtx);
LOG_E("sss_cipher_one_go failed");
xResult = CKR_FUNCTION_FAILED;
}
encDataLen = encDataLen + tempOutBufLen;
if (xResult == CKR_OK) {
if (pEncryptedData) {
if (*pulEncryptedDataLen < encDataLen) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
memcpy(pEncryptedData, &encData[0], encDataLen);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
}
}
*pulEncryptedDataLen = encDataLen;
}
sss_symmetric_context_free(&symmCtx);
UNLOCK_MUTEX_FOR_RTOS
}
return xResult;
}
CK_RV SymmetricDecrypt(P11SessionPtr_t pxSessionObj,
sss_algorithm_t algorithm,
CK_BYTE_PTR pEncryptedData,
CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDecryptedDataLen)
{
CK_RV xResult = CKR_OK;
sss_status_t status = kStatus_SSS_Fail;
// uint8_t data[2048] = { 0 };
// size_t dataLen = sizeof(data);
sss_symmetric_t symmCtx;
sss_object_t symmObject;
// status = sss_key_object_get_handle(&symmObject, CLIENT_SYMMETRIC_KEY_INDEX);
// if(status != kStatus_SSS_Success) {
// pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
// return CKR_DEVICE_ERROR;
// }
// memcpy(&data[0], pEncryptedData, ulEncryptedDataLen);
// dataLen = ulEncryptedDataLen;
uint8_t iv[16] = {0};
size_t ivLen = sizeof(iv);
uint8_t encData[256] = {0};
size_t encDataLen = sizeof(encData);
size_t tempOutBufLen = encDataLen;
uint8_t *pOut = &encData[0];
if (algorithm == kAlgorithm_SSS_AES_CBC) {
if (pxSessionObj->mechParameterLen != 0) {
memcpy(iv, pxSessionObj->mechParameter, ivLen);
}
}
#if 0
//PKCS11 Documentation not clear. Ignoring currently
if(algorithm == kAlgorithm_SSS_AES_CTR) {
if(!pxSessionObj->mechParameterLen) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_ARGUMENTS_BAD;
}
else {
CK_AES_CTR_PARAMS_PTR ctrParams = (CK_AES_CTR_PARAMS_PTR) pxSessionObj->mechParameter;
memcpy(&iv[0], &pxSessionObj->mechParameter.cb[0], sizeof(iv));
}
}
#endif
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&symmObject, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
}
status = sss_key_object_get_handle(&symmObject, pxSessionObj->xOperationKeyHandle);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
}
status = sss_symmetric_context_init(
&symmCtx, &pex_sss_demo_boot_ctx->session, &symmObject, algorithm, kMode_SSS_Decrypt);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
// return CKR_DEVICE_ERROR;
}
/*Do Decryption*/
status = sss_cipher_init(&symmCtx, iv, ivLen);
if (status != kStatus_SSS_Success) {
sss_symmetric_context_free(&symmCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
}
status = sss_cipher_update(
&symmCtx, (const uint8_t *)pEncryptedData, (size_t)ulEncryptedDataLen, pOut, &tempOutBufLen);
if (status != kStatus_SSS_Success) {
sss_symmetric_context_free(&symmCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR)
// return CKR_DEVICE_ERROR;
}
pOut = pOut + tempOutBufLen;
encDataLen = tempOutBufLen;
tempOutBufLen = sizeof(encData) - tempOutBufLen;
status = sss_cipher_finish(&symmCtx, NULL, 0, pOut, &tempOutBufLen);
if (status != kStatus_SSS_Success) {
sss_symmetric_context_free(&symmCtx);
LOG_E("sss_cipher_one_go failed");
xResult = CKR_FUNCTION_FAILED;
}
encDataLen = encDataLen + tempOutBufLen;
if (xResult == CKR_OK) {
size_t i = 0;
while ((encData[encDataLen - 1 - i] == 0) && i < encDataLen) {
i++;
}
encDataLen = encDataLen - i;
if (pData) {
if (*pulDecryptedDataLen < encDataLen) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
memcpy(pData, &encData[0], encDataLen);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
}
}
*pulDecryptedDataLen = encDataLen;
}
sss_symmetric_context_free(&symmCtx);
UNLOCK_MUTEX_FOR_RTOS
}
return xResult;
}
CK_RV GetSSSAlgorithm(const sss_algorithm_t algorithm, sss_algorithm_t *digest_algo)
{
switch (algorithm) {
case kAlgorithm_SSS_SHA1:
case kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA1:
case kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA1:
case kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA1:
case kAlgorithm_SSS_ECDSA_SHA1:
*digest_algo = kAlgorithm_SSS_SHA1;
break;
case kAlgorithm_SSS_SHA224:
case kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA224:
case kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA224:
case kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA224:
case kAlgorithm_SSS_ECDSA_SHA224:
*digest_algo = kAlgorithm_SSS_SHA224;
break;
case kAlgorithm_SSS_SHA256:
case kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA256:
case kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA256:
case kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA256:
case kAlgorithm_SSS_ECDSA_SHA256:
*digest_algo = kAlgorithm_SSS_SHA256;
break;
case kAlgorithm_SSS_SHA384:
case kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA384:
case kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA384:
case kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA384:
case kAlgorithm_SSS_ECDSA_SHA384:
*digest_algo = kAlgorithm_SSS_SHA384;
break;
case kAlgorithm_SSS_SHA512:
case kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA512:
case kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA512:
case kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA512:
case kAlgorithm_SSS_ECDSA_SHA512:
*digest_algo = kAlgorithm_SSS_SHA512;
break;
default:
return CKR_ARGUMENTS_BAD;
}
return CKR_OK;
}
CK_RV LabelToKeyId(unsigned char *label, size_t labelSize, uint32_t *keyId)
{
CK_RV result = CKR_OK;
sss_status_t status = kStatus_SSS_Fail;
sss_digest_t digest_ctx;
uint8_t digest[64] = {0};
size_t digest_size = sizeof(digest);
if (labelSize == 0) {
LOCK_MUTEX_FOR_RTOS
{
sss_rng_context_t sss_rng_ctx;
uint8_t rngData[10];
size_t rngDataLen = sizeof(rngData);
status = sss_rng_context_init(&sss_rng_ctx, &pex_sss_demo_boot_ctx->session /* Session */);
status = sss_rng_get_random(&sss_rng_ctx, rngData, rngDataLen);
if (status != kStatus_SSS_Success) {
result = CKR_DEVICE_ERROR;
UNLOCK_MUTEX_FOR_RTOS
goto exit;
}
*keyId =
(rngData[6] << (3 * 8)) | (rngData[7] << (2 * 8)) | (rngData[8] << (1 * 8)) | (rngData[9] << (0 * 8));
UNLOCK_MUTEX_FOR_RTOS
}
goto exit;
}
else if (strncmp((char *)label, "sss:", strlen("sss:")) == 0) {
char labelCopy[32] = {0};
memset(labelCopy, '\0', sizeof(labelCopy));
strncpy(labelCopy, (char *)label, labelSize);
unsigned long long_id = 0;
char *id = (char *)&labelCopy[0];
long_id = strtoul(id + 4, NULL, 16);
*keyId = long_id;
goto exit;
}
LOCK_MUTEX_FOR_RTOS
{
status = sss_digest_context_init(
&digest_ctx, &pex_sss_demo_boot_ctx->session, kAlgorithm_SSS_SHA512, kMode_SSS_Digest);
if (status != kStatus_SSS_Success) {
result = CKR_DEVICE_ERROR;
UNLOCK_MUTEX_FOR_RTOS
goto exit;
}
status = sss_digest_one_go(&digest_ctx, label, labelSize, &digest[0], &digest_size);
if (status != kStatus_SSS_Success) {
result = CKR_DEVICE_ERROR;
}
sss_digest_context_free(&digest_ctx);
if (status == kStatus_SSS_Success) {
*keyId =
(digest[60] << (3 * 8)) | (digest[61] << (2 * 8)) | (digest[62] << (1 * 8)) | (digest[63] << (0 * 8));
}
UNLOCK_MUTEX_FOR_RTOS
}
exit:
return result;
}
/*
This is a simple function to insert a TLV into a buffer.
params:
tag - ASN.1 Tag
component - byte array to be inserted
componentLen - Size of component to be inserted
key - Buffer into which component will be inserted
keyLen - Size of the buffer (key).
Note : This function inserts the component at the end of the buffer and updates the
keyLen to where the component is inserted with tag. (Points to the tag)
*/
CK_RV SetASNTLV(uint8_t tag, uint8_t *component, const size_t componentLen, uint8_t *key, size_t *keyLen)
{
if (componentLen <= 0) {
return CKR_ARGUMENTS_BAD;
}
if (*keyLen < componentLen) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - componentLen;
memcpy(&key[*keyLen], component, componentLen);
if (componentLen <= 127) {
if (*keyLen < 1) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 1;
key[*keyLen] = componentLen;
}
else if (componentLen <= 255) {
if (*keyLen < 2) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 2;
key[*keyLen] = 0x81;
key[*keyLen + 1] = componentLen;
}
else {
if (*keyLen < 3) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 3;
key[*keyLen] = 0x82;
key[*keyLen + 1] = (componentLen & 0x00FF00) >> 8;
key[*keyLen + 2] = (componentLen & 0x00FF);
}
if (*keyLen < 1) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 1;
key[*keyLen] = tag;
return CKR_OK;
}
CK_RV CreateRawPrivateKey(CK_ATTRIBUTE_PTR pxTemplate, CK_ULONG ulCount, uint8_t *key_buffer, size_t *keyLen)
{
CK_RV xResult = CKR_FUNCTION_FAILED;
CK_ULONG keyTypeIndex;
CK_KEY_TYPE key_type = CKK_RSA;
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_KEY_TYPE, &keyTypeIndex);
if (xResult != CKR_OK) {
goto exit;
}
memcpy(&key_type, pxTemplate[keyTypeIndex].pValue, pxTemplate[keyTypeIndex].ulValueLen);
if (key_type == CKK_RSA) {
CK_ULONG componentIndex;
if (GetAttributeParameterIndex(pxTemplate, ulCount, CKA_MODULUS, &componentIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PUBLIC_EXPONENT, &componentIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PRIVATE_EXPONENT, &componentIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PRIME_1, &componentIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PRIME_2, &componentIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EXPONENT_1, &componentIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EXPONENT_2, &componentIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_COEFFICIENT, &componentIndex)) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
/**
N = CKA_MODULUS | Nlen = Length of CKA_MODULUS
P = CKA_PRIME_1 | Plen = Length of CKA_PRIME_1
Q = CKA_PRIME_2 | Qlen = Length of CKA_PRIME_2
D = CKA_PRIVATE_EXPONENT | Dlen = Length of CKA_PRIVATE_EXPONENT
E = CKA_PUBLIC_EXPONENT | Elen = Length of CKA_PUBLIC_EXPONENT
*/
size_t bufferSize_copy = *keyLen;
size_t componentLen = 0;
uint8_t tag = ASN_TAG_INT;
uint8_t key[4096] = {0};
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_COEFFICIENT, &componentIndex);
componentLen = (size_t)pxTemplate[componentIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[componentIndex].pValue, componentLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EXPONENT_2, &componentIndex);
componentLen = (size_t)pxTemplate[componentIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[componentIndex].pValue, componentLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EXPONENT_1, &componentIndex);
componentLen = (size_t)pxTemplate[componentIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[componentIndex].pValue, componentLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PRIME_2, &componentIndex);
componentLen = (size_t)pxTemplate[componentIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[componentIndex].pValue, componentLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PRIME_1, &componentIndex);
componentLen = (size_t)pxTemplate[componentIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[componentIndex].pValue, componentLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PRIVATE_EXPONENT, &componentIndex);
componentLen = (size_t)pxTemplate[componentIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[componentIndex].pValue, componentLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PUBLIC_EXPONENT, &componentIndex);
componentLen = (size_t)pxTemplate[componentIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[componentIndex].pValue, componentLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_MODULUS, &componentIndex);
componentLen = (size_t)pxTemplate[componentIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[componentIndex].pValue, componentLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
uint8_t int_val = 0x00;
xResult = SetASNTLV(tag, &int_val, 1, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
size_t totalLen = bufferSize_copy - *keyLen;
if (totalLen <= 127) {
if (*keyLen < 1) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 1;
key[*keyLen] = totalLen;
}
else if (totalLen <= 255) {
if (*keyLen < 2) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 2;
key[*keyLen] = 0x81;
key[*keyLen + 1] = totalLen;
}
else {
if (*keyLen < 3) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 3;
key[*keyLen] = 0x82;
key[*keyLen + 1] = (totalLen & 0x00FF00) >> 8;
key[*keyLen + 2] = (totalLen & 0x00FF);
}
if (*keyLen < 1) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
*keyLen = *keyLen - 1;
key[*keyLen] = ASN_TAG_SEQUENCE;
totalLen = bufferSize_copy - *keyLen;
memcpy(&key_buffer[0], &key[*keyLen], totalLen);
*keyLen = totalLen;
}
else if (key_type == CKK_EC) {
CK_ULONG parameterIndex;
if (GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EC_PARAMS, &parameterIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_VALUE, &parameterIndex)) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
uint8_t key[1024] = {0};
size_t bufferSize_copy = *keyLen;
size_t parameterLen = 0;
uint8_t tag = ASN_TAG_CRL_EXTENSIONS;
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EC_PARAMS, &parameterIndex);
parameterLen = (size_t)pxTemplate[parameterIndex].ulValueLen;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[parameterIndex].pValue, parameterLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_VALUE, &parameterIndex);
parameterLen = (size_t)pxTemplate[parameterIndex].ulValueLen;
tag = ASN_TAG_OCTETSTRING;
xResult = SetASNTLV(tag, (uint8_t *)pxTemplate[parameterIndex].pValue, parameterLen, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
tag = ASN_TAG_INT;
uint8_t int_val = 0x01;
xResult = SetASNTLV(tag, &int_val, 1, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
size_t totalLen = bufferSize_copy - *keyLen;
if (totalLen <= 127) {
if (*keyLen < 1) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 1;
key[*keyLen] = totalLen;
}
else if (totalLen <= 255) {
if (*keyLen < 2) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 2;
key[*keyLen] = 0x81;
key[*keyLen + 1] = totalLen;
}
else {
if (*keyLen < 3) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 3;
key[*keyLen] = 0x82;
key[*keyLen + 1] = (totalLen & 0x00FF00) >> 8;
key[*keyLen + 2] = (totalLen & 0x00FF);
}
if (*keyLen < 1) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 1;
key[*keyLen] = ASN_TAG_SEQUENCE;
totalLen = bufferSize_copy - *keyLen;
uint8_t temp[1024] = {0};
size_t tLen = sizeof(temp);
int ret = 0;
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
ret = mbedtls_pk_parse_key(&pk, &key[*keyLen], totalLen, NULL, 0);
if (ret != 0) {
xResult = CKR_ARGUMENTS_BAD;
mbedtls_pk_free(&pk);
goto exit;
}
ret = mbedtls_pk_write_key_der(&pk, temp, tLen);
if (ret < 0) {
xResult = CKR_FUNCTION_FAILED;
mbedtls_pk_free(&pk);
goto exit;
}
mbedtls_pk_free(&pk);
memcpy(&key_buffer[0], &temp[tLen - ret], ret);
*keyLen = ret;
}
else {
xResult = CKR_ARGUMENTS_BAD;
}
exit:
return xResult;
}
mbedtls_ecp_group_id EcParametersToGrpId(uint8_t *ecparameters, size_t len)
{
mbedtls_ecp_group ecp_group;
mbedtls_ecp_group_init(&ecp_group);
mbedtls_asn1_buf params;
unsigned char *ptr = &ecparameters[0];
if ((pk_get_ecparams(&ptr, ptr + len, &params)) != 0 || (pk_use_ecparams(&params, &ecp_group)) != 0) {
LOG_E("FAILURE");
return MBEDTLS_ECP_DP_NONE;
}
LOG_I("mbedtls_mpi_read_binary successfull");
return ecp_group.id;
}
CK_RV CreateRawPublicKey(CK_ATTRIBUTE_PTR pxTemplate, CK_ULONG ulCount, uint8_t *key_buffer, size_t *keyLen)
{
CK_RV xResult = CKR_FUNCTION_FAILED;
CK_ULONG keyTypeIndex;
CK_KEY_TYPE key_type = CKK_RSA;
CK_ULONG parameterIndex;
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_KEY_TYPE, &keyTypeIndex);
if (xResult != CKR_OK) {
goto exit;
}
memcpy(&key_type, pxTemplate[keyTypeIndex].pValue, pxTemplate[keyTypeIndex].ulValueLen);
if (key_type == CKK_RSA) {
uint8_t publicExponent[] = {0x01, 0x00, 0x01};
if (GetAttributeParameterIndex(pxTemplate, ulCount, CKA_PUBLIC_EXPONENT, &parameterIndex) == 0) {
if ((pxTemplate[parameterIndex].ulValueLen == 1) ||
(memcmp((void *)publicExponent, pxTemplate[parameterIndex].pValue, sizeof(publicExponent)))) {
LOG_E("Public Exponent not supported");
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
}
if (GetAttributeParameterIndex(pxTemplate, ulCount, CKA_MODULUS, &parameterIndex)) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
uint8_t key[2048] = {0};
uint8_t modulus[520] = {0};
uint8_t *pInputModulus = (uint8_t *)pxTemplate[parameterIndex].pValue;
size_t modulusLen = (size_t)pxTemplate[parameterIndex].ulValueLen;
size_t bufferSize_copy = *keyLen;
uint8_t tag = ASN_TAG_INT;
if (pInputModulus[0] != 0x00) {
memcpy(&modulus[1], pInputModulus, modulusLen);
modulusLen++;
}
else {
memcpy(modulus, pInputModulus, modulusLen);
}
xResult = SetASNTLV(tag, publicExponent, sizeof(publicExponent), key, keyLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
xResult = SetASNTLV(tag, modulus, modulusLen, key, keyLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
size_t totalLen = bufferSize_copy - *keyLen;
if (totalLen <= 127) {
if (*keyLen < 1) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 1;
key[*keyLen] = totalLen;
}
else if (totalLen <= 255) {
if (*keyLen < 2) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 2;
key[*keyLen] = 0x81;
key[*keyLen + 1] = totalLen;
}
else {
if (*keyLen < 3) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 3;
key[*keyLen] = 0x82;
key[*keyLen + 1] = (totalLen & 0x00FF00) >> 8;
key[*keyLen + 2] = (totalLen & 0x00FF);
}
if (*keyLen < 1) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 1;
key[*keyLen] = ASN_TAG_SEQUENCE;
totalLen = bufferSize_copy - *keyLen;
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
int ret = mbedtls_pk_parse_public_key(&pk, &key[*keyLen], totalLen);
if (ret != 0) {
LOG_E("mbedtls_pk_parse_public_key failed");
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
ret = mbedtls_pk_write_pubkey_der(&pk, key, sizeof(key));
if (ret < 0) {
xResult = CKR_FUNCTION_FAILED;
}
else {
memcpy(key_buffer, &key[sizeof(key) - ret], ret);
*keyLen = ret;
}
mbedtls_pk_free(&pk);
}
else if (key_type == CKK_EC) {
if (GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EC_PARAMS, &parameterIndex) ||
GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EC_POINT, &parameterIndex)) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
uint8_t key[2048] = {0};
size_t bufferSize_copy = *keyLen;
size_t parameterLen = 0;
uint8_t tag = ASN_TAG_BITSTRING;
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EC_POINT, &parameterIndex);
parameterLen = (size_t)pxTemplate[parameterIndex].ulValueLen;
/**
CKA_EC_POINT passed is DER encoded under Octet String tag. Decode the tag, length
and parse the value.
*/
uint8_t ecPointInput[150] = {0};
size_t ecPointInput_size = sizeof(ecPointInput);
if (ecPointInput_size < (size_t)pxTemplate[parameterIndex].ulValueLen) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
memcpy(&ecPointInput[0],
(uint8_t *)pxTemplate[parameterIndex].pValue,
(size_t)pxTemplate[parameterIndex].ulValueLen);
int i = 0;
if (ecPointInput[i++] != ASN_TAG_OCTETSTRING) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
size_t len = ecPointInput[i++];
if ((len & 0x80) == 0x80) {
if ((len & 0x7F) == 0x01) {
len = ecPointInput[i++];
}
else if ((len & 0x7F) == 0x02) {
len = (ecPointInput[i] << 8) | (ecPointInput[i + 1]);
i = i + 2;
}
else {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
}
uint8_t ecPoint[150] = {0};
// size_t ecPoint_size = sizeof(ecPoint);
memcpy(&ecPoint[1], &ecPointInput[i], len);
// xResult = SetASNTLV(tag, (uint8_t*) pxTemplate[parameterIndex].pValue, parameterLen, key, keyLen);
xResult = SetASNTLV(tag, &ecPoint[0], len + 1, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
uint8_t ecPubParams[50] = {0};
size_t ecPubParams_size = sizeof(ecPubParams);
tag = ASN_TAG_OBJ_IDF;
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_EC_PARAMS, &parameterIndex);
parameterLen = (size_t)pxTemplate[parameterIndex].ulValueLen;
if (ecPubParams_size < parameterLen) {
mbedtls_ecp_group_id grp_id =
EcParametersToGrpId((uint8_t *)pxTemplate[parameterIndex].pValue, parameterLen);
/* TODO: Add conditions for other grp_id */
if (grp_id == MBEDTLS_ECP_DP_SECP521R1) {
uint8_t oid[] = {MBEDTLS_OID_EC_GRP_SECP521R1};
size_t oidLen = sizeof(oid) - 1;
// ecPubParams_size = ecPubParams_size - oidLen - 1;
// memcpy(&ecPubParams[ecPubParams_size], oid, oidLen);
xResult = SetASNTLV(tag, &oid[0], oidLen, ecPubParams, &ecPubParams_size);
if (xResult != CKR_OK) {
goto exit;
}
}
else {
LOG_W("Parsing ECParameters supported only for SECP521R1");
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
}
else {
ecPubParams_size = ecPubParams_size - parameterLen;
memcpy(&ecPubParams[ecPubParams_size], (uint8_t *)pxTemplate[parameterIndex].pValue, parameterLen);
}
// // xResult = SetASNTLV(tag, (uint8_t*) pxTemplate[parameterIndex].pValue, parameterLen, ecPubParams, &ecPubParams_size);
// if(xResult != CKR_OK) {
// goto exit;
// }
uint8_t id_ecPublicKey[] = ID_ECPUBLICKEY;
xResult = SetASNTLV(tag, &id_ecPublicKey[0], sizeof(id_ecPublicKey), ecPubParams, &ecPubParams_size);
if (xResult != CKR_OK) {
goto exit;
}
tag = ASN_TAG_SEQUENCE;
xResult = SetASNTLV(tag, &ecPubParams[ecPubParams_size], sizeof(ecPubParams) - ecPubParams_size, key, keyLen);
if (xResult != CKR_OK) {
goto exit;
}
size_t totalLen = bufferSize_copy - *keyLen;
if (totalLen <= 127) {
if (*keyLen < 1) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 1;
key[*keyLen] = totalLen;
}
else if (totalLen <= 255) {
if (*keyLen < 2) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 2;
key[*keyLen] = 0x81;
key[*keyLen + 1] = totalLen;
}
else {
if (*keyLen < 3) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
*keyLen = *keyLen - 3;
key[*keyLen] = 0x82;
key[*keyLen + 1] = (totalLen & 0x00FF00) >> 8;
key[*keyLen + 2] = (totalLen & 0x00FF);
}
if (*keyLen < 1) {
return CKR_ARGUMENTS_BAD;
}
*keyLen = *keyLen - 1;
key[*keyLen] = ASN_TAG_SEQUENCE;
totalLen = bufferSize_copy - *keyLen;
memcpy(&key_buffer[0], &key[*keyLen], totalLen);
*keyLen = totalLen;
}
else {
xResult = CKR_ARGUMENTS_BAD;
}
exit:
return xResult;
}
CK_RV EcSignatureToRandS(uint8_t *signature, size_t *sigLen)
{
CK_RV xResult = CKR_FUNCTION_FAILED;
uint8_t rands[128] = {0};
int index = 0;
size_t i = 0;
size_t len = 0;
if (signature[index++] != 0x30)
goto exit;
if (signature[index++] != (*sigLen - 2))
goto exit;
if (signature[index++] != 0x02)
goto exit;
len = signature[index++];
if (len & 0x01) {
len--;
index++;
}
for (i = 0; i < len; i++) {
rands[i] = signature[index++];
}
if (signature[index++] != 0x02) {
goto exit;
}
len = signature[index++];
if (len & 0x01) {
len--;
index++;
}
len = len + i;
for (; i < len; i++) {
rands[i] = signature[index++];
}
memcpy(&signature[0], &rands[0], i);
*sigLen = i;
xResult = CKR_OK;
exit:
return xResult;
}
CK_RV EcRandSToSignature(uint8_t *rands, const size_t rands_len, uint8_t *output, size_t *outputLen)
{
CK_RV xResult = CKR_FUNCTION_FAILED;
uint8_t signature[256] = {0};
size_t signatureLen = sizeof(signature);
size_t componentLen = (rands_len) / 2;
uint8_t tag = ASN_TAG_INT;
xResult = SetASNTLV(tag, &rands[componentLen], componentLen, signature, &signatureLen);
if (xResult != CKR_OK) {
goto exit;
}
xResult = SetASNTLV(tag, &rands[0], componentLen, signature, &signatureLen);
if (xResult != CKR_OK) {
goto exit;
}
size_t totalLen = sizeof(signature) - signatureLen;
if (totalLen <= 127) {
if (signatureLen < 1) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
signatureLen = signatureLen - 1;
signature[signatureLen] = totalLen;
}
else if (totalLen <= 255) {
if (signatureLen < 2) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
signatureLen = signatureLen - 2;
signature[signatureLen] = 0x81;
signature[signatureLen + 1] = totalLen;
}
else {
if (signatureLen < 3) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
signatureLen = signatureLen - 3;
signature[signatureLen] = 0x82;
signature[signatureLen + 1] = (totalLen & 0x00FF00) >> 8;
signature[signatureLen + 2] = (totalLen & 0x00FF);
}
if (signatureLen < 1) {
return CKR_ARGUMENTS_BAD;
}
signatureLen = signatureLen - 1;
signature[signatureLen] = ASN_TAG_SEQUENCE;
totalLen = sizeof(signature) - signatureLen;
memcpy(&output[0], &signature[signatureLen], totalLen);
*outputLen = totalLen;
xResult = CKR_OK;
exit:
return xResult;
}
CK_RV EcPublickeyGetEcParams(uint8_t *input, size_t *dataLen)
{
CK_RV xResult = CKR_FUNCTION_FAILED;
size_t index = 0;
uint8_t data[1024] = {0};
int len = 0;
memcpy(&data[0], input, *dataLen);
uint8_t tag = data[index++];
if (tag != ASN_TAG_SEQUENCE) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
len = data[index++];
if ((len & 0x80) == 0x80) {
if ((len & 0x7F) == 0x01) {
len = data[index++];
}
else if ((len & 0x7F) == 0x02) {
len = (data[index] << 8) | data[index + 1];
index = index + 2;
}
}
if (index > *dataLen) {
goto exit;
}
tag = data[index++];
if (tag != ASN_TAG_SEQUENCE) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
len = data[index++];
if ((len & 0x80) == 0x80) {
if ((len & 0x7F) == 0x01) {
len = data[index++];
}
else if ((len & 0x7F) == 0x02) {
len = (data[index] << 8) | data[index + 1];
index = index + 2;
}
}
if (index > *dataLen) {
goto exit;
}
tag = data[index++];
if (tag != ASN_TAG_OBJ_IDF) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
len = data[index++];
if ((len & 0x80) == 0x80) {
if ((len & 0x7F) == 0x01) {
len = data[index++];
}
else if ((len & 0x7F) == 0x02) {
len = (data[index] << 8) | data[index + 1];
index = index + 2;
}
}
index = index + len;
if (index > *dataLen) {
goto exit;
}
tag = data[index];
if (tag != ASN_TAG_OBJ_IDF) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
len = data[index + 1];
if ((len & 0x80) == 0x80) {
if ((len & 0x7F) == 0x01) {
len = data[index + 2];
len++;
}
else if ((len & 0x7F) == 0x02) {
len = (data[index + 2] << 8) | data[index + 3];
len = len + 2;
}
}
len = len + 2;
if ((index + len) > *dataLen) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
memcpy(&input[0], &data[index], len);
*dataLen = len;
xResult = CKR_OK;
exit:
return xResult;
}
CK_RV parseCertificateGetAttribute(
uint32_t xObject, CK_ATTRIBUTE_TYPE attributeType, uint8_t *pData, CK_ULONG *ulAttrLength)
{
CK_RV xResult = CKR_FUNCTION_FAILED;
sss_status_t status = kStatus_SSS_Fail;
sss_object_t sss_object = {0};
sss_digest_t digestCtx = {0};
sss_algorithm_t digest_algorithm = kAlgorithm_SSS_SHA1;
uint8_t data[2048] = {0};
size_t dataLen = sizeof(data);
size_t KeyBitLen = 0;
mbedtls_x509_crt certificate;
mbedtls_pk_context *pk;
uint8_t pubdata[2048] = {0};
size_t pubdataLen = sizeof(data);
size_t i = 0;
/* NOTE: MUTEX LOCK IS NOT USED HERE BECAUSE THIS FUNCTION IS CALLED ONLY WHEN WE HAVE ALREADY LOCKED THE MUTEX */
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
return xResult;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
return xResult;
}
if (kStatus_SSS_Success !=
sss_key_store_get_key(&pex_sss_demo_boot_ctx->ks, &sss_object, &data[0], &dataLen, &KeyBitLen)) {
return xResult;
}
mbedtls_x509_crt_init(&certificate);
if (0 != mbedtls_x509_crt_parse(&certificate, (const unsigned char *)data, dataLen)) {
LOG_E("Unable to parse certificate");
return xResult;
}
xResult = CKR_OK;
switch (attributeType) {
case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
if ((certificate.issuer_raw.tag != certificate.subject_raw.tag) ||
(certificate.issuer_raw.len != certificate.subject_raw.len) ||
(memcmp((void *)certificate.issuer_raw.p, (void *)certificate.subject_raw.p, certificate.subject_raw.len) !=
0)) {
xResult = CKR_ATTRIBUTE_SENSITIVE;
}
else {
pk = &certificate.pk;
int len = mbedtls_pk_write_pubkey_der(pk, pubdata, pubdataLen);
if (len < 0) {
xResult = CKR_FUNCTION_FAILED;
break;
}
if ((int)(*ulAttrLength) < len) {
LOG_E("Buffer too small");
xResult = CKR_BUFFER_TOO_SMALL;
break;
}
memcpy(pData, &pubdata[pubdataLen - len], len);
*ulAttrLength = len;
}
break;
case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
pk = &certificate.pk;
int len = mbedtls_pk_write_pubkey_der(pk, pubdata, pubdataLen);
if (len < 0) {
xResult = CKR_FUNCTION_FAILED;
break;
}
if ((int)(*ulAttrLength) < len) {
LOG_E("Buffer too small");
xResult = CKR_BUFFER_TOO_SMALL;
break;
}
memcpy(pData, &pubdata[pubdataLen - len], len);
*ulAttrLength = len;
break;
default:
LOG_W("Attribute required : 0x%08lx\n", attributeType);
xResult = CKR_ATTRIBUTE_SENSITIVE;
}
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
xResult = CKR_FUNCTION_FAILED;
uint8_t *pTLV = &pData[0];
ENSURE_OR_GO_EXIT(*pTLV == 0x30);
/*
* Public key will be of the following format
* 30 ZZ
* 30 XX
* KEY_PARAMETERS
* 03 YY
* PUBLIC_KEY
*/
size_t tagLen = 0, bufindex = 0;
int ret = asn_1_parse_tlv(pTLV, &tagLen, &bufindex); /* Parse initial sequence */
ENSURE_OR_GO_EXIT(ret == 0);
pTLV = pTLV + bufindex;
ENSURE_OR_GO_EXIT(*pTLV == 0x30);
bufindex = 0;
ret = asn_1_parse_tlv(pTLV, &tagLen, &bufindex); /* Parse key parameters */
ENSURE_OR_GO_EXIT(ret == 0);
/* Parse next tag */
ASN1_SKIP_TO_NEXT_TAG(pTLV, tagLen)
ENSURE_OR_GO_EXIT(*pTLV == 0x03);
bufindex = 0;
ret = asn_1_parse_tlv(pTLV, &tagLen, &bufindex);
ENSURE_OR_GO_EXIT(ret == 0);
pTLV += bufindex;
if (*pTLV == 0x00) {
pTLV++;
tagLen--;
}
xResult = CKR_OK;
status = sss_digest_context_init(&digestCtx, &pex_sss_demo_boot_ctx->session, digest_algorithm, kMode_SSS_Digest);
if (status != kStatus_SSS_Success) {
return CKR_DEVICE_ERROR;
}
status = sss_digest_init(&digestCtx);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
return CKR_DEVICE_ERROR;
}
while (tagLen > 500) {
status = sss_digest_update(&digestCtx, &pTLV[0 + i * 500], 500);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
return CKR_DEVICE_ERROR;
}
i++;
tagLen -= 500;
}
status = sss_digest_update(&digestCtx, &pTLV[0 + i * 500], tagLen);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
return CKR_DEVICE_ERROR;
}
*ulAttrLength = 20 /* SHA-1 data length */;
status = sss_digest_finish(&digestCtx, &pData[0], (size_t *)ulAttrLength);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
return CKR_DEVICE_ERROR;
}
sss_digest_context_free(&digestCtx);
exit:
return xResult;
}
/*-----------------------------------------------------------*/
/*
* PKCS#11 module implementation.
*/
/**
* @brief PKCS#11 interface functions implemented by this Cryptoki module.
*/
CK_FUNCTION_LIST prvP11FunctionList = {{CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR},
C_Initialize,
C_Finalize,
C_GetInfo,
C_GetFunctionList,
C_GetSlotList,
C_GetSlotInfo,
C_GetTokenInfo,
C_GetMechanismList,
C_GetMechanismInfo,
C_InitToken,
C_InitPIN,
C_SetPIN,
C_OpenSession,
C_CloseSession,
C_CloseAllSessions,
C_GetSessionInfo,
C_GetOperationState,
C_SetOperationState,
C_Login,
C_Logout,
C_CreateObject,
C_CopyObject,
C_DestroyObject,
C_GetObjectSize,
C_GetAttributeValue,
C_SetAttributeValue,
C_FindObjectsInit,
C_FindObjects,
C_FindObjectsFinal,
C_EncryptInit,
C_Encrypt,
C_EncryptUpdate,
C_EncryptFinal,
C_DecryptInit,
C_Decrypt,
C_DecryptUpdate,
C_DecryptFinal,
C_DigestInit,
C_Digest,
C_DigestUpdate,
C_DigestKey,
C_DigestFinal,
C_SignInit,
C_Sign,
C_SignUpdate,
C_SignFinal,
C_SignRecoverInit,
C_SignRecover,
C_VerifyInit,
C_Verify,
C_VerifyUpdate,
C_VerifyFinal,
C_VerifyRecoverInit,
C_VerifyRecover,
C_DigestEncryptUpdate,
C_DecryptDigestUpdate,
C_SignEncryptUpdate,
C_DecryptVerifyUpdate,
C_GenerateKey,
C_GenerateKeyPair,
C_WrapKey,
C_UnwrapKey,
C_DeriveKey,
C_SeedRandom,
C_GenerateRandom,
C_GetFunctionStatus,
C_CancelFunction,
C_WaitForSlotEvent};
CK_DEFINE_FUNCTION(CK_RV, C_DigestFinal)
(CK_SESSION_HANDLE xSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
if (pxSession == NULL) {
xResult = CKR_SESSION_HANDLE_INVALID;
}
else if (pxSession->xOperationInProgress == pkcs11NO_OPERATION) {
xResult = CKR_OPERATION_NOT_INITIALIZED;
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
}
else if (!pulDigestLen) {
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
xResult = CKR_ARGUMENTS_BAD;
}
if (xResult == CKR_OK) {
#if SSS_HAVE_ALT_SSS
LOCK_MUTEX_FOR_RTOS
{
size_t outputLen = 0;
switch (pxSession->xOperationInProgress) {
case CKM_SHA_1:
outputLen = 20;
break;
case CKM_SHA224:
outputLen = 28;
break;
case CKM_SHA256:
outputLen = 32;
break;
case CKM_SHA384:
outputLen = 48;
break;
case CKM_SHA512:
outputLen = 64;
break;
default:
xResult = CKR_FUNCTION_FAILED;
break;
}
if (xResult != CKR_OK) {
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
sss_digest_context_free(&pxSession->digest_ctx);
UNLOCK_MUTEX_FOR_RTOS_RET(xResult)
// return xResult;
}
if (pDigest) {
if (*pulDigestLen < outputLen) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
uint8_t digest[64] = {0};
size_t digestLen = sizeof(digest);
sss_status_t sss_status = kStatus_SSS_Fail;
sss_status = sss_digest_finish(&pxSession->digest_ctx, digest, &digestLen);
sss_digest_context_free(&pxSession->digest_ctx);
if (sss_status != kStatus_SSS_Success) {
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
xResult = CKR_FUNCTION_FAILED;
}
else {
memcpy(pDigest, digest, digestLen);
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
}
}
}
*pulDigestLen = outputLen;
UNLOCK_MUTEX_FOR_RTOS_RET(xResult)
// return xResult;
}
#else
if (pDigest == NULL) {
/* Supply the required buffer size. */
*pulDigestLen = pkcs11SHA256_DIGEST_LENGTH;
}
else {
if (*pulDigestLen < pkcs11SHA256_DIGEST_LENGTH) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
if (0 != mbedtls_sha256_finish_ret(&pxSession->xSHA256Context, pDigest)) {
xResult = CKR_FUNCTION_FAILED;
}
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
}
}
#endif
}
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_DigestUpdate)
(CK_SESSION_HANDLE xSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
if (pxSession == NULL) {
xResult = CKR_SESSION_HANDLE_INVALID;
}
else if (pxSession->xOperationInProgress == pkcs11NO_OPERATION) {
xResult = CKR_OPERATION_NOT_INITIALIZED;
}
if (xResult == CKR_OK) {
pxSession->digestUpdateCalled = CK_TRUE;
#if SSS_HAVE_ALT_SSS
sss_status_t sss_status = kStatus_SSS_Fail;
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_digest_update(&pxSession->digest_ctx, pPart, ulPartLen);
if (sss_status != kStatus_SSS_Success) {
sss_digest_context_free(&pxSession->digest_ctx);
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
xResult = CKR_FUNCTION_FAILED;
}
UNLOCK_MUTEX_FOR_RTOS
}
// &pxSession->digest_ctx
#else
if (0 != mbedtls_sha256_update_ret(&pxSession->xSHA256Context, pPart, ulPartLen)) {
xResult = CKR_FUNCTION_FAILED;
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
}
#endif
}
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_DigestInit)
(CK_SESSION_HANDLE xSession, CK_MECHANISM_PTR pMechanism)
{
CK_RV xResult = CKR_OK;
// return CKR_DEVICE_ERROR;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
if (pxSession == NULL) {
xResult = CKR_SESSION_HANDLE_INVALID;
return xResult;
}
if (NULL == pMechanism) {
xResult = CKR_ARGUMENTS_BAD;
return xResult;
}
else if (pxSession->xOperationInProgress != pkcs11NO_OPERATION) {
xResult = CKR_SESSION_HANDLE_INVALID;
return xResult;
}
#if SSS_HAVE_ALT_SSS
sss_status_t sss_status = kStatus_SSS_Fail;
sss_algorithm_t algorithm = kAlgorithm_None;
pxSession->xOperationInProgress = pMechanism->mechanism;
xResult = ParseDigestMechanism(pxSession, &algorithm);
if (xResult != CKR_OK) {
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_digest_context_init(
&pxSession->digest_ctx, &pex_sss_demo_boot_ctx->session, algorithm, kMode_SSS_Digest);
if (sss_status != kStatus_SSS_Success) {
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
sss_status = sss_digest_init(&pxSession->digest_ctx);
if (sss_status != kStatus_SSS_Success) {
pxSession->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
UNLOCK_MUTEX_FOR_RTOS
}
#else
if (pMechanism->mechanism != CKM_SHA256) {
xResult = CKR_MECHANISM_INVALID;
}
/*
* Initialize the requested hash type
*/
if (xResult == CKR_OK) {
mbedtls_sha256_init(&pxSession->xSHA256Context);
if (0 != mbedtls_sha256_starts_ret(&pxSession->xSHA256Context, 0)) {
xResult = CKR_FUNCTION_FAILED;
}
else {
pxSession->xOperationInProgress = pMechanism->mechanism;
}
}
#endif
if (xResult == CKR_OK) {
pxSession->digestUpdateCalled = CK_FALSE;
}
return xResult;
}
/**
* @brief Generate cryptographically random bytes.
*/
CK_DEFINE_FUNCTION(CK_RV, C_GenerateRandom)
(CK_SESSION_HANDLE xSession, CK_BYTE_PTR pucRandomData, CK_ULONG ulRandomLen)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
/*lint !e9072 It's OK to have different parameter name. */
// return CKR_DEVICE_ERROR;
#if SSS_HAVE_ALT_SSS
(void)(xSession);
#else
P11SessionPtr_t pxSessionObj = prvSessionPointerFromHandle(xSession);
#endif
if( ( NULL == pucRandomData )/* ||
( ulRandomLen == 0 )*/ )
{
xResult = CKR_ARGUMENTS_BAD;
return xResult;
}
if (ulRandomLen == 0) {
return CKR_OK;
}
else {
#if SSS_HAVE_ALT_SSS
LOCK_MUTEX_FOR_RTOS
{
sss_status_t sss_status = kStatus_SSS_Fail;
sss_rng_context_t sss_rng_ctx;
sss_status = sss_rng_context_init(&sss_rng_ctx, &pex_sss_demo_boot_ctx->session /* Session */);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
sss_status = sss_rng_get_random(&sss_rng_ctx, pucRandomData, ulRandomLen);
sss_rng_context_free(&sss_rng_ctx);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
UNLOCK_MUTEX_FOR_RTOS
}
#else
if (0 != mbedtls_ctr_drbg_random(&pxSessionObj->xMbedDrbgCtx, pucRandomData, ulRandomLen)) {
xResult = CKR_FUNCTION_FAILED;
}
#endif
}
// UNLOCK_MUTEX_FOR_RTOS_RET(xResult)
return xResult;
}
/**
* @brief Verify the digital signature of the specified data using the public
* key attached to this session.
*/
CK_DEFINE_FUNCTION(CK_RV, C_Verify)
(CK_SESSION_HANDLE xSession, CK_BYTE_PTR pucData, CK_ULONG ulDataLen, CK_BYTE_PTR pucSignature, CK_ULONG ulSignatureLen)
{
/*lint !e9072 It's OK to have different parameter name. */
/* pkcs11tb*/
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSessionObj = prvSessionPointerFromHandle(xSession);
#if SSS_HAVE_ALT_A71CH
(void)(pxSessionObj);
U8 index = 0;
HLSE_OBJECT_HANDLE handles[5];
HLSE_MECHANISM_INFO mechInfo;
U16 handleNum = 3;
U16 err;
#endif
#if SSS_HAVE_ALT_SSS
sss_status_t status;
sss_object_t object;
sss_asymmetric_t asymmCtx;
sss_algorithm_t algorithm;
sss_algorithm_t digest_algorithm;
#endif
/*
* Check parameters.
*/
if ((NULL == pucData) || (NULL == pucSignature)) {
xResult = CKR_ARGUMENTS_BAD;
return xResult;
}
#if SSS_HAVE_ALT_A71CH
err = HLSE_EnumerateObjects(HLSE_PUBLIC_KEY, handles, &handleNum);
if ((err != HLSE_SW_OK) || (handleNum <= index)) {
xResult = CKR_ARGUMENTS_BAD;
return xResult;
}
memset(&mechInfo, 0, sizeof(mechInfo));
mechInfo.mechanism = HLSE_ECDSA_VERIFY;
err = HLSE_VerifySignature(&mechInfo, handles[0], (U8 *)pucData, ulDataLen, (U8 *)pucSignature, ulSignatureLen);
if (err != HLSE_SW_OK) {
xResult = CKR_SIGNATURE_INVALID;
}
#endif
#if SSS_HAVE_ALT_SSS
xResult = ParseSignMechanism(pxSessionObj, &algorithm);
if (xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
if (pxSessionObj->xOperationInProgress == CKM_ECDSA) {
switch (ulDataLen) {
case 20:
algorithm = kAlgorithm_SSS_ECDSA_SHA1;
break;
case 28:
algorithm = kAlgorithm_SSS_ECDSA_SHA224;
break;
case 32:
algorithm = kAlgorithm_SSS_ECDSA_SHA256;
break;
case 48:
algorithm = kAlgorithm_SSS_ECDSA_SHA384;
break;
case 64:
algorithm = kAlgorithm_SSS_ECDSA_SHA512;
break;
default:
if (ulDataLen < 20) {
/* ECDSA Always needs a hash value. Hash value should be deduced from
* input size. In case the input size is less than any supported hash
* value, we will pad the data with 0s and default to kAlgorithm_SSS_SHA256
*/
algorithm = kAlgorithm_SSS_ECDSA_SHA256;
break;
}
else {
return CKR_DATA_LEN_RANGE;
}
}
}
uint8_t data[2048] = {0};
size_t dataLen = sizeof(data);
if (pxSessionObj->xOperationInProgress != CKM_RSA_PKCS_PSS && pxSessionObj->xOperationInProgress != CKM_ECDSA &&
pxSessionObj->xOperationInProgress != CKM_RSA_PKCS) {
sss_digest_t digestCtx;
size_t i = 0;
xResult = GetSSSAlgorithm(algorithm, &digest_algorithm);
if (xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
LOCK_MUTEX_FOR_RTOS
{
status = sss_digest_context_init(
&digestCtx, &pex_sss_demo_boot_ctx->session, digest_algorithm, kMode_SSS_Digest);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
status = sss_digest_init(&digestCtx);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
while (ulDataLen > 500) {
status = sss_digest_update(&digestCtx, &pucData[0 + i * 500], 500);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
i++;
ulDataLen -= 500;
}
status = sss_digest_update(&digestCtx, &pucData[0 + i * 500], ulDataLen);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
status = sss_digest_finish(&digestCtx, &data[0], &dataLen);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
sss_digest_context_free(&digestCtx);
UNLOCK_MUTEX_FOR_RTOS
}
}
else {
memcpy(&data[0], pucData, ulDataLen);
dataLen = ulDataLen;
if (algorithm == kAlgorithm_SSS_ECDSA_SHA256 && ulDataLen < 20) {
dataLen = 32;
}
}
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&object, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_key_object_init Failed...");
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
status = sss_key_object_get_handle(&object, (uint32_t)pxSessionObj->xOperationKeyHandle);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_key_object_get_handle Failed...");
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
status = sss_asymmetric_context_init(
&asymmCtx, &pex_sss_demo_boot_ctx->session, &object, algorithm, kMode_SSS_Verify);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_asymmetric_context_init verify context Failed...");
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
uint8_t buff[2048] = {0};
size_t buffLen = sizeof(buff);
if (asymmCtx.keyObject->cipherType == kSSS_CipherType_EC_NIST_P) {
xResult = EcRandSToSignature((uint8_t *)pucSignature, (size_t)ulSignatureLen, &buff[0], &buffLen);
}
else {
memcpy(&buff[0], pucSignature, ulSignatureLen);
buffLen = ulSignatureLen;
}
if (xResult == CKR_OK) {
status = sss_asymmetric_verify_digest(&asymmCtx, &data[0], dataLen, buff, buffLen);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_asymmetric_verify_digest Failed... %08x", status);
xResult = CKR_SIGNATURE_INVALID;
}
}
sss_asymmetric_context_free(&asymmCtx);
UNLOCK_MUTEX_FOR_RTOS
}
#endif
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_Sign)
(CK_SESSION_HANDLE xSession,
CK_BYTE_PTR pucData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pucSignature,
CK_ULONG_PTR pulSignatureLen)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSessionObj = prvSessionPointerFromHandle(xSession);
if (!pucData) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
xResult = CKR_ARGUMENTS_BAD;
return xResult;
}
if (!pulSignatureLen) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
xResult = CKR_ARGUMENTS_BAD;
return xResult;
}
sss_status_t status;
sss_object_t object;
sss_asymmetric_t asymmCtx;
sss_algorithm_t algorithm;
sss_algorithm_t digest_algorithm;
xResult = ParseSignMechanism(pxSessionObj, &algorithm);
// printf("\nParsed algorithm = %d\n", algorithm);
if (xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
if (pxSessionObj->xOperationInProgress == CKM_ECDSA) {
switch (ulDataLen) {
case 20:
algorithm = kAlgorithm_SSS_ECDSA_SHA1;
break;
case 28:
algorithm = kAlgorithm_SSS_ECDSA_SHA224;
break;
case 32:
algorithm = kAlgorithm_SSS_ECDSA_SHA256;
break;
case 48:
algorithm = kAlgorithm_SSS_ECDSA_SHA384;
break;
case 64:
algorithm = kAlgorithm_SSS_ECDSA_SHA512;
break;
default:
if (ulDataLen < 20) {
/* ECDSA Always needs a hash value. Hash value should be deduced from
* input size. In case the input size is less than any supported hash
* value, we will pad the data with 0s and default to kAlgorithm_SSS_SHA256
*/
algorithm = kAlgorithm_SSS_ECDSA_SHA256;
break;
}
else {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_DATA_LEN_RANGE;
}
}
}
if (pxSessionObj->xOperationInProgress == CKM_RSA_PKCS) {
uint16_t keySizeBytes = 0;
#if SSS_HAVE_APPLET_SE05X_IOT
xResult = read_object_size_with_lock((uint32_t)pxSessionObj->xOperationKeyHandle, &keySizeBytes);
if (xResult != CKR_OK) {
return xResult;
}
#endif
xResult = (keySizeBytes >= (ulDataLen + 11)) ? CKR_OK : CKR_MECHANISM_INVALID;
if (xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
}
uint8_t data[2048] = {0};
size_t dataLen = sizeof(data);
if (pxSessionObj->xOperationInProgress == CKM_RSA_PKCS_PSS || pxSessionObj->xOperationInProgress == CKM_ECDSA ||
pxSessionObj->xOperationInProgress == CKM_RSA_PKCS) {
if ((algorithm == kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA1) ||
/* (algorithm == kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA1) ||*/ (algorithm == kAlgorithm_SSS_ECDSA_SHA1)) {
//Check input size
if (ulDataLen != 20) {
// pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
/* FIXME:PKCS11 Spec states that operation should be terminated in this case.
AWS PKCS11 testbench states that Operation should not be terminated.
*/
return CKR_DATA_LEN_RANGE;
}
}
else if ((algorithm == kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA224) ||
/* (algorithm == kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA224) ||*/
(algorithm == kAlgorithm_SSS_ECDSA_SHA224)) {
//Check input size
if (ulDataLen != 28) {
// pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
/* FIXME:PKCS11 Spec states that operation should be terminated in this case.
AWS PKCS11 testbench states that Operation should not be terminated.
*/
return CKR_DATA_LEN_RANGE;
}
}
else if ((algorithm == kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA256) ||
/* (algorithm == kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA256) ||*/
(algorithm == kAlgorithm_SSS_ECDSA_SHA256)) {
//Check input size
if (ulDataLen != 32) {
if (algorithm == kAlgorithm_SSS_ECDSA_SHA256 && ulDataLen < 20) {
/* Nothing to do */
}
else {
// pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
/* FIXME:PKCS11 Spec states that operation should be terminated in this case.
AWS PKCS11 testbench states that Operation should not be terminated.
*/
return CKR_DATA_LEN_RANGE;
}
}
}
else if ((algorithm == kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA384) ||
/* (algorithm == kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA384) ||*/
(algorithm == kAlgorithm_SSS_ECDSA_SHA384)) {
//Check input size
if (ulDataLen != 48) {
// pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
/* FIXME:PKCS11 Spec states that operation should be terminated in this case.
AWS PKCS11 testbench states that Operation should not be terminated.
*/
return CKR_DATA_LEN_RANGE;
}
}
else if ((algorithm == kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA512) ||
/* (algorithm == kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA512) ||*/
(algorithm == kAlgorithm_SSS_ECDSA_SHA512)) {
//Check input size
if (ulDataLen != 64) {
// pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
/* FIXME:PKCS11 Spec states that operation should be terminated in this case.
AWS PKCS11 testbench states that Operation should not be terminated.
*/
return CKR_DATA_LEN_RANGE;
}
}
memcpy(&data[0], pucData, ulDataLen);
dataLen = ulDataLen;
if (algorithm == kAlgorithm_SSS_ECDSA_SHA256 && ulDataLen < 20) {
dataLen = 32;
}
}
else {
sss_digest_t digestCtx;
size_t i = 0;
xResult = GetSSSAlgorithm(algorithm, &digest_algorithm);
if (xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
LOCK_MUTEX_FOR_RTOS
{
status = sss_digest_context_init(
&digestCtx, &pex_sss_demo_boot_ctx->session, digest_algorithm, kMode_SSS_Digest);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
status = sss_digest_init(&digestCtx);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
while (ulDataLen > 500) {
status = sss_digest_update(&digestCtx, &pucData[0 + i * 500], 500);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
i++;
ulDataLen -= 500;
}
status = sss_digest_update(&digestCtx, &pucData[0 + i * 500], ulDataLen);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
status = sss_digest_finish(&digestCtx, &data[0], &dataLen);
if (status != kStatus_SSS_Success) {
sss_digest_context_free(&digestCtx);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_DEVICE_ERROR);
}
sss_digest_context_free(&digestCtx);
UNLOCK_MUTEX_FOR_RTOS
}
// dataLen = 0;
}
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&object, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_key_object_init Failed...");
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
status = sss_key_object_get_handle(&object, (uint32_t)pxSessionObj->xOperationKeyHandle);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_key_object_get_handle Failed...");
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
status =
sss_asymmetric_context_init(&asymmCtx, &pex_sss_demo_boot_ctx->session, &object, algorithm, kMode_SSS_Sign);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_asymmetric_context_ sign init Failed...");
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
/* Do Signing */
uint8_t signature[512] = {0};
size_t sigLen = sizeof(signature);
status = sss_asymmetric_sign_digest(&asymmCtx, &data[0], dataLen, &signature[0], &sigLen);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_asymmetric_sign_digest Failed...");
xResult = CKR_FUNCTION_FAILED;
}
if (xResult == CKR_OK) {
if (asymmCtx.keyObject->cipherType == kSSS_CipherType_EC_NIST_P) {
xResult = EcSignatureToRandS(signature, &sigLen);
}
if (xResult == CKR_OK) {
if (pucSignature) {
if (*pulSignatureLen < sigLen) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
memcpy(pucSignature, &signature[0], sigLen);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
}
}
*pulSignatureLen = sigLen;
}
}
sss_asymmetric_context_free(&asymmCtx);
UNLOCK_MUTEX_FOR_RTOS
}
return xResult;
}
/**
* @brief Free resources attached to an object handle.
*/
CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject)
(CK_SESSION_HANDLE xSession, CK_OBJECT_HANDLE xObject)
{ /*lint !e9072 It's OK to have different parameter name. */
(void)(xSession);
// printf("\n\n%s\n\n", __FUNCTION__);
sss_status_t sss_status = kStatus_SSS_Fail;
sss_object_t object = {0};
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_key_object_init(&object, &pex_sss_demo_boot_ctx->ks);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
sss_status = sss_key_object_get_handle(&object, (uint32_t)xObject);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
sss_status = sss_key_store_erase_key(&pex_sss_demo_boot_ctx->ks, &object);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
// return CKR_FUNCTION_FAILED;
}
UNLOCK_MUTEX_FOR_RTOS
}
return CKR_OK;
}
#if SSS_HAVE_ALT_A71CH
static U16 HLSE_Create_token(
uint32_t keyId, HLSE_OBJECT_TYPE objType, void *buff, unsigned long bufflen, HLSE_OBJECT_HANDLE handle_object)
{
HLSE_OBJECT_INDEX index = keyId;
HLSE_ATTRIBUTE attr[3];
unsigned short templateSize = 3;
attr[0].type = HLSE_ATTR_OBJECT_TYPE;
attr[0].value = &objType;
attr[0].valueLen = sizeof(objType);
attr[1].type = HLSE_ATTR_OBJECT_INDEX;
attr[1].value = &index;
attr[1].valueLen = sizeof(index);
attr[2].type = HLSE_ATTR_OBJECT_VALUE;
attr[2].value = buff;
attr[2].valueLen = bufflen;
return HLSE_CreateObject(attr, templateSize, &handle_object);
}
#endif
#if SSS_HAVE_ALT_SSS
static sss_status_t sss_create_token(sss_key_store_t *keystore,
sss_object_t *CreateObject,
U32 ObjectId,
sss_key_part_t KeyPart,
sss_cipher_type_t CipherType,
U8 *buffer,
U32 bufferLen,
U32 bitLen)
{
sss_status_t status = kStatus_SSS_Fail;
uint8_t output[4096] = {0};
size_t olen = sizeof(output);
int a = convertpemtoder((unsigned char *)buffer, (size_t)bufferLen, &output[0], &olen);
if (a == 0) {
//Data was in PEM format. Nothing to be done.
}
else {
memcpy(&output[0], buffer, bufferLen);
olen = bufferLen;
}
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(CreateObject, keystore);
if (status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(status)
}
status = sss_key_object_allocate_handle(
CreateObject, ObjectId, KeyPart, CipherType, olen, kKeyObject_Mode_Persistent);
if (status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(status)
}
status = sss_key_store_set_key(keystore, CreateObject, output, olen, bitLen, NULL, 0);
if (status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(status)
}
UNLOCK_MUTEX_FOR_RTOS
}
return status;
}
#if SSS_HAVE_APPLET_SE05X_IOT
static smStatus_t read_id_list(uint32_t *idlist, size_t *idlistlen)
{
uint8_t pmore = kSE05x_MoreIndicator_NA;
uint8_t list[1024];
size_t listlen = sizeof(list);
size_t i, k = 0;
smStatus_t retStatus = SM_NOT_OK;
uint16_t outputOffset = 0;
sss_se05x_session_t *pSession = (sss_se05x_session_t *)&pex_sss_demo_boot_ctx->session;
pSe05xSession_t session_ctx = &pSession->s_ctx;
LOCK_MUTEX_FOR_RTOS
{
do {
retStatus = Se05x_API_ReadIDList(session_ctx, outputOffset, 0xFF, &pmore, list, &listlen);
if (retStatus != SM_OK) {
UNLOCK_MUTEX_FOR_RTOS_RET(retStatus)
// return retStatus;
}
outputOffset = (uint16_t)listlen;
// for (i = 0; i < listlen; i += 4) {
// #if LOG_INFO_ENABLED
// uint32_t id = 0 | (list[i + 0] << (3 * 8)) | (list[i + 1] << (2 * 8)) | (list[i + 2] << (1 * 8)) |
// (list[i + 3] << (0 * 8));
// LOG_I("Found object Id - %08X", id);
// #endif
// }
} while (pmore == kSE05x_MoreIndicator_MORE);
UNLOCK_MUTEX_FOR_RTOS
}
for (i = 0; ((i < listlen) && (k < *idlistlen)); i += 4) {
idlist[k] = 0 | (list[i + 0] << (3 * 8)) | (list[i + 1] << (2 * 8)) | (list[i + 2] << (1 * 8)) |
(list[i + 3] << (0 * 8));
k++;
}
*idlistlen = k;
return SM_OK;
}
#endif
#endif
#if SSS_HAVE_APPLET_SE05X_IOT
static CK_RV read_object_size_with_lock(uint32_t keyId, uint16_t *keyLen)
{
CK_RV xResult = CKR_FUNCTION_FAILED;
smStatus_t sm_status = SM_NOT_OK;
sss_status_t sss_status = kStatus_SSS_Fail;
sss_object_t sss_object = {0};
sss_se05x_session_t *se05x_session = (sss_se05x_session_t *)&pex_sss_demo_boot_ctx->session;
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
xResult = CKR_KEY_HANDLE_INVALID;
sss_status = sss_key_object_get_handle(&sss_object, keyId);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
xResult = CKR_FUNCTION_FAILED;
sm_status = Se05x_API_ReadSize(&se05x_session->s_ctx, keyId, keyLen);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sm_status == SM_OK);
xResult = CKR_OK;
UNLOCK_MUTEX_FOR_RTOS
}
exit:
return xResult;
}
static CK_RV read_object_size(uint32_t keyId, uint16_t *keyLen)
{
CK_RV xResult = CKR_FUNCTION_FAILED;
smStatus_t sm_status = SM_NOT_OK;
sss_status_t sss_status = kStatus_SSS_Fail;
sss_object_t sss_object = {0};
sss_se05x_session_t *se05x_session = (sss_se05x_session_t *)&pex_sss_demo_boot_ctx->session;
sss_status = sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks);
ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
xResult = CKR_KEY_HANDLE_INVALID;
sss_status = sss_key_object_get_handle(&sss_object, keyId);
ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
xResult = CKR_FUNCTION_FAILED;
sm_status = Se05x_API_ReadSize(&se05x_session->s_ctx, keyId, keyLen);
ENSURE_OR_GO_EXIT(sm_status == SM_OK);
xResult = CKR_OK;
exit:
return xResult;
}
static uint8_t CheckIfKeyIdExists(uint32_t keyId, pSe05xSession_t session_ctx)
{
smStatus_t retStatus = SM_NOT_OK;
SE05x_Result_t IdExists = 0;
uint8_t exists = 0;
LOCK_MUTEX_FOR_RTOS
{
retStatus = Se05x_API_CheckObjectExists(session_ctx, keyId, &IdExists);
if (retStatus == SM_OK) {
if (IdExists == kSE05x_Result_SUCCESS) {
// LOG_D("Key Id 0x%X exists", keyId);
exists = 1;
}
}
else {
LOG_E("Error in Se05x_API_CheckObjectExists");
}
UNLOCK_MUTEX_FOR_RTOS
}
return exists;
}
#endif
/**
* Extend the byte array \p pStore with 0x00 byte(s). This is typically required when
* a big integer has - previously - been stripped from its (superfluous) sign bits.
* The caller must ensure \p expectedLength is bigger than \p actualLength
* @param[in,out] pStore Array representation of big number, to be zero sign extended.
* Size of corresponding buffer must be at least \p expectedLength
* @param[in] actualLength Length of incoming array \p pStore
* @param[in] expectedLength Zero sign extend until this length.
*
* @retval SW_OK In case of successfull execution
* @retval ERR_API_ERROR Requested adjustment would result in truncation
*/
U16 axZeroSignExtend(U8 *pStore, U16 actualLength, U16 expectedLength)
{
U16 sw = SW_OK;
int numExtraByte = (int)expectedLength - (int)actualLength;
if (numExtraByte == 0) {
// Do nothing
}
else if (numExtraByte < 0) {
// Flag an API error
sw = ERR_API_ERROR;
}
else {
memmove(pStore + numExtraByte, pStore, actualLength);
memset(pStore, 0x00, numExtraByte);
}
return sw;
}
// #if SSS_HAVE_ALT_A71CH
// /**
// * Extract the public key - as a byte array in uncompress format - from an ECC key
// * @param[in] pKey Reference to ECC key.
// * @param[in,out] pPublicKeyData IN: Buffer to contain public key; OUT: Public key
// * @param[out] pPublicKeyLen Length of public key \p pPublicKeyData retrieved
// * @param[in] maxPublicKeyLen Size of buffer (\p pPublicKeyData) provided to contain public key
// */
// U16 HOSTCRYPTO_GetPublicKey(EC_KEY *pKey, U8 *pPublicKeyData, U16 *pPublicKeyLen, U16 maxPublicKeyLen)
// {
// int res;
// size_t keylen = 0;
// mbedtls_ecp_keypair * pEcCtx = mbedtls_pk_ec( *pKey );
// res = mbedtls_ecp_check_pubkey( &(pEcCtx->grp), &(pEcCtx->Q) );
// if ((res != 0) || (pPublicKeyData == NULL) || (pPublicKeyLen == NULL))
// {
// return ERR_CRYPTO_ENGINE_FAILED;
// }
// res = mbedtls_ecp_point_write_binary(&(pEcCtx->grp),&(pEcCtx->Q),MBEDTLS_ECP_PF_UNCOMPRESSED,&keylen,pPublicKeyData,maxPublicKeyLen);
// *pPublicKeyLen = (U16)keylen;
// if ((*pPublicKeyLen == 0) || (res != 0))
// {
// return ERR_CRYPTO_ENGINE_FAILED;
// }
// return SW_OK;
// }
// /**
// * Extract the private key - as a byte array restored to nominal key size by sign extension - from an ECC key (in an mbed TLS specific format)
// * @param[in] pKey Reference to ECC key.
// * @param[in,out] pPrivateKeyData IN: Buffer to contain private key; OUT: Private key
// * @param[out] pPrivateKeyLen Length of private key \p pPrivateKeyData retrieved
// * @param[in] maxPrivateKeyLen Size of buffer (\p pPrivateKeyData) provided to contain private key
// */
// U16 HOSTCRYPTO_GetPrivateKey(EC_KEY *pKey, U8 *pPrivateKeyData, U16 *pPrivateKeyLen, U16 maxPrivateKeyLen)
// {
// int significantBytes = 0;
// int keyLen = 0;
// U16 res = SW_OK;
// U8 keyArray[256];
// const mbedtls_ecp_curve_info *p_curve_info = NULL;
// mbedtls_ecp_keypair * pEcCtx = mbedtls_pk_ec( *pKey );
// /*TODO check sign extension part */
// res = mbedtls_ecp_check_privkey( &(pEcCtx->grp), &(pEcCtx->d));
// if ((res != 0) || (pPrivateKeyData == NULL) || (pPrivateKeyLen == NULL))
// {
// return ERR_CRYPTO_ENGINE_FAILED;
// }
// significantBytes = mbedtls_mpi_size( &(pEcCtx->d) );
// p_curve_info = mbedtls_ecp_curve_info_from_grp_id( pEcCtx->grp.id );
// keyLen = ((p_curve_info->bit_size + 7))/8;
// if (keyLen > maxPrivateKeyLen)
// {
// return ERR_BUF_TOO_SMALL;
// }
// res = mbedtls_mpi_write_binary(&(pEcCtx->d),keyArray,keyLen);
// if (res == 0)
// {
// // Extend byte array with leading 0x00 byte in case private key had
// // been truncated because the MSB were not significant
// if (significantBytes > 0)
// {
// res = axZeroSignExtend(keyArray, (U16)significantBytes, (U16)keyLen);
// if (res == SW_OK)
// {
// memcpy(pPrivateKeyData, keyArray, keyLen);
// *pPrivateKeyLen = (U16)keyLen;
// }
// else
// {
// *pPrivateKeyLen = 0;
// }
// }
// else
// {
// *pPrivateKeyLen = 0;
// res = ERR_GENERAL_ERROR;
// }
// }
// else
// {
// res = ERR_CRYPTO_ENGINE_FAILED;
// }
// return res;
// }
// #endif // SSS_HAVE_ALT_A71CH
/**
* @brief Provides import and storage of a single client certificate and
* associated private key.
*/
CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)
(CK_SESSION_HANDLE xSession, CK_ATTRIBUTE_PTR pxTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR pxObject)
{
/*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
#if SSS_HAVE_ALT_A71CH
HLSE_OBJECT_HANDLE HLSE_Handle_Create_obj = 0x0;
U16 err = 0;
#endif
int ret;
U8 buff[4096];
mbedtls_pk_context pk;
CK_ULONG Valueindex = 0;
uint32_t keyId = 0xffffffff;
CK_ULONG i = 0;
CK_ULONG classIndex = 0;
size_t buff_len = sizeof(buff);
#if SSS_HAVE_ALT_SSS
CK_ULONG keyidindex;
CK_ULONG labelIndex = 0;
CK_BBOOL foundKeyId = CK_FALSE;
sss_status_t status;
sss_cipher_type_t cipherType = kSSS_CipherType_RSA;
size_t keybitlen = 0;
#endif
/* Unreferenced variables.*/
// ( void ) ( xSession );
/*
* Check parameters.
*/
if ((pkcs11CREATEOBJECT_MINIMUM_ATTRIBUTE_COUNT > ulCount) || (NULL == pxTemplate) || (NULL == pxObject)) {
return CKR_ARGUMENTS_BAD;
}
if (ulCount == -1) {
return CKR_ARGUMENTS_BAD;
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_CLASS, &classIndex);
if (xResult != CKR_OK) {
return xResult;
}
/*Find the key id as it's needed while provisiong keys and certificate*/
#if SSS_HAVE_ALT_SSS
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_SSS_ID, &keyidindex);
if (xResult == CKR_OK) {
foundKeyId = CK_TRUE;
}
xResult = CKR_OK;
#endif
/*
* Handle the object by class.
*/
if (CKR_OK == xResult) {
switch (*((uint32_t *)pxTemplate[classIndex].pValue)) {
case CKO_CERTIFICATE:
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_VALUE, &i);
if (xResult != CKR_OK) {
return xResult;
}
memcpy(buff, pxTemplate[i].pValue, pxTemplate[i].ulValueLen);
buff_len = (size_t)pxTemplate[i].ulValueLen;
#if SSS_HAVE_ALT_A71CH
err = HLSE_Create_token(
keyId, HLSE_CERTIFICATE, pxTemplate[i].pValue, pxTemplate[i].ulValueLen, HLSE_Handle_Create_obj);
if (err != HLSE_SW_OK) {
xResult = CKR_DEVICE_ERROR;
return xResult;
}
pxObject = (CK_OBJECT_HANDLE_PTR)&HLSE_Handle_Create_obj;
#endif
#if SSS_HAVE_ALT_SSS
if (0 != pxTemplate[i].ulValueLen) {
if (!foundKeyId) {
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_LABEL, &labelIndex);
if (xResult != CKR_OK) {
/* CKA_LABEL was not provided. Generate a random keyId */
xResult = LabelToKeyId((unsigned char *)"", 0, &keyId);
if (xResult != CKR_OK) {
return xResult;
}
}
else {
xResult =
LabelToKeyId(pxTemplate[labelIndex].pValue, pxTemplate[labelIndex].ulValueLen, &keyId);
if (xResult != CKR_OK) {
return xResult;
}
}
}
mbedtls_x509_crt certificate;
mbedtls_x509_crt_init(&certificate);
ret = mbedtls_x509_crt_parse(&certificate, (const unsigned char *)buff, buff_len);
mbedtls_x509_crt_free(&certificate);
if (ret != 0) {
LOG_E(
"Certificate parsing failed ! mbedtls_x509_crt_parse "
"returned %d",
ret);
return CKR_ARGUMENTS_BAD;
}
status = sss_create_token(&pex_sss_demo_boot_ctx->ks,
&pex_sss_demo_tls_ctx->dev_cert,
keyId,
kSSS_KeyPart_Default,
kSSS_CipherType_Binary,
buff,
buff_len,
buff_len * 8);
if (status != kStatus_SSS_Success) {
xResult = CKR_DEVICE_ERROR;
return xResult;
}
*pxObject = keyId;
}
#endif
break;
case CKO_PRIVATE_KEY:
/*Parses the private key in PEM format and converts it to DER format.
* This is required because as SE shall require a key pair for storing keys*/
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_VALUE, &Valueindex);
if (xResult != CKR_OK) {
uint8_t key[4096];
size_t keyLen = sizeof(key);
xResult = CreateRawPrivateKey(pxTemplate, ulCount, &key[0], &keyLen);
if (xResult != CKR_OK) {
return xResult;
}
mbedtls_pk_init(&pk);
ret = mbedtls_pk_parse_key(&pk, key, keyLen, NULL, 0);
if (ret != 0) {
xResult = CKR_ARGUMENTS_BAD;
return xResult;
}
memset(buff, 0, sizeof(buff));
memcpy(buff, key, keyLen);
buff_len = (size_t)keyLen;
}
else {
mbedtls_pk_init(&pk);
if (0 != pxTemplate[Valueindex].ulValueLen) {
ret = mbedtls_pk_parse_key(
&pk, pxTemplate[Valueindex].pValue, pxTemplate[Valueindex].ulValueLen, NULL, 0);
if (ret != 0) {
uint8_t key[1024] = {0};
size_t keyLen = sizeof(key);
xResult = CreateRawPrivateKey(pxTemplate, ulCount, &key[0], &keyLen);
if (xResult != CKR_OK) {
break;
}
ret = mbedtls_pk_parse_key(&pk, key, keyLen, NULL, 0);
if (ret != 0) {
xResult = CKR_ARGUMENTS_BAD;
break;
}
memset(buff, 0, sizeof(buff));
memcpy(buff, key, keyLen);
buff_len = (size_t)keyLen;
}
else {
memset(buff, 0, sizeof(buff));
memcpy(buff, pxTemplate[Valueindex].pValue, pxTemplate[Valueindex].ulValueLen);
buff_len = (size_t)pxTemplate[Valueindex].ulValueLen;
}
}
}
#if SSS_HAVE_ALT_A71CH
err = HLSE_Create_token(keyId, HLSE_KEY_PAIR, buff, buff_len, HLSE_Handle_Create_obj);
if (err != HLSE_SW_OK) {
xResult = CKR_DEVICE_ERROR;
return xResult;
}
pxObject = (CK_OBJECT_HANDLE_PTR)&HLSE_Handle_Create_obj;
#endif
#if SSS_HAVE_ALT_SSS
if (!foundKeyId) {
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_LABEL, &labelIndex);
if (xResult != CKR_OK) {
/* CKA_LABEL was not provided. Generate a random keyId */
xResult = LabelToKeyId((unsigned char *)"", 0, &keyId);
if (xResult != CKR_OK) {
return xResult;
}
}
else {
xResult = LabelToKeyId(pxTemplate[labelIndex].pValue, pxTemplate[labelIndex].ulValueLen, &keyId);
if (xResult != CKR_OK) {
return xResult;
}
}
}
CK_KEY_TYPE key_type = CKK_RSA;
CK_ULONG index = 0;
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_KEY_TYPE, &index);
if (xResult != CKR_OK) {
return xResult;
}
memcpy(&key_type, pxTemplate[index].pValue, pxTemplate[index].ulValueLen);
if (key_type == CKK_RSA) {
cipherType = kSSS_CipherType_RSA;
mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(pk);
keybitlen = pk_rsa->len * 8;
}
else if (key_type == CKK_EC) { /*CKK_EC also means CKK_ECDSA both enum values are same*/
//Currently only for NIST-P curves
#if CKK_EC != CKK_ECDSA
#error "Assumed to be equal"
#endif
cipherType = kSSS_CipherType_EC_NIST_P;
mbedtls_ecp_keypair *pk_ec = mbedtls_pk_ec(pk);
switch (pk_ec->grp.id) {
case MBEDTLS_ECP_DP_SECP192R1:
keybitlen = 192;
break;
case MBEDTLS_ECP_DP_SECP224R1:
keybitlen = 224;
break;
case MBEDTLS_ECP_DP_SECP256R1:
keybitlen = 256;
break;
case MBEDTLS_ECP_DP_SECP384R1:
keybitlen = 384;
break;
case MBEDTLS_ECP_DP_SECP521R1:
keybitlen = 521;
break;
default:
return CKR_ARGUMENTS_BAD;
}
}
else {
return CKR_ARGUMENTS_BAD;
}
status = sss_create_token(&pex_sss_demo_boot_ctx->ks,
&pex_sss_demo_tls_ctx->obj,
keyId,
kSSS_KeyPart_Pair,
cipherType,
buff,
buff_len,
keybitlen);
if (status != kStatus_SSS_Success) {
xResult = CKR_DEVICE_ERROR;
return xResult;
}
*pxObject = keyId;
#endif
break;
case CKO_PUBLIC_KEY:
/*Parses the public key in PEM format and converts it to DER format.
* This is required because as HLSE understands DER only*/
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_VALUE, &Valueindex);
if (xResult != CKR_OK) {
uint8_t key[2048];
size_t keyLen = sizeof(key);
xResult = CreateRawPublicKey(pxTemplate, ulCount, &key[0], &keyLen);
if (xResult != CKR_OK) {
return xResult;
}
mbedtls_pk_init(&pk);
ret = mbedtls_pk_parse_public_key(&pk, &key[0], keyLen);
if (ret != 0) {
xResult = CKR_ARGUMENTS_BAD;
break;
}
memset(buff, 0, sizeof(buff));
memcpy(buff, &key[0], keyLen);
buff_len = keyLen;
}
else {
mbedtls_pk_init(&pk);
ret =
mbedtls_pk_parse_public_key(&pk, pxTemplate[Valueindex].pValue, pxTemplate[Valueindex].ulValueLen);
if (ret != 0) {
xResult = CKR_ARGUMENTS_BAD;
break;
}
memset(buff, 0, sizeof(buff));
memcpy(buff, pxTemplate[Valueindex].pValue, pxTemplate[Valueindex].ulValueLen);
buff_len = (size_t)pxTemplate[Valueindex].ulValueLen;
}
#if SSS_HAVE_ALT_A71CH
err = HLSE_Create_token(keyId, HLSE_PUBLIC_KEY, buff, buff_len, HLSE_Handle_Create_obj);
if (err != HLSE_SW_OK) {
xResult = CKR_DEVICE_ERROR;
return xResult;
}
pxObject = (CK_OBJECT_HANDLE_PTR)&HLSE_Handle_Create_obj;
#endif
#if SSS_HAVE_ALT_SSS
if (!foundKeyId) {
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_LABEL, &labelIndex);
if (xResult != CKR_OK) {
/* CKA_LABEL was not provided. Generate a random keyId */
xResult = LabelToKeyId((unsigned char *)"", 0, &keyId);
if (xResult != CKR_OK) {
return xResult;
}
}
else {
xResult = LabelToKeyId(pxTemplate[labelIndex].pValue, pxTemplate[labelIndex].ulValueLen, &keyId);
if (xResult != CKR_OK) {
return xResult;
}
}
}
mbedtls_pk_type_t pk_type = MBEDTLS_PK_NONE;
pk_type = pk.pk_info->type;
switch (pk_type) {
case MBEDTLS_PK_RSA:
cipherType = kSSS_CipherType_RSA;
mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(pk);
keybitlen = pk_rsa->len * 8;
break;
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECDSA:
cipherType = kSSS_CipherType_EC_NIST_P;
mbedtls_ecp_keypair *pk_ec = mbedtls_pk_ec(pk);
switch (pk_ec->grp.id) {
case MBEDTLS_ECP_DP_SECP192R1:
keybitlen = 192;
break;
case MBEDTLS_ECP_DP_SECP224R1:
keybitlen = 224;
break;
case MBEDTLS_ECP_DP_SECP256R1:
keybitlen = 256;
break;
case MBEDTLS_ECP_DP_SECP384R1:
keybitlen = 384;
break;
case MBEDTLS_ECP_DP_SECP521R1:
keybitlen = 521;
break;
default:
return CKR_ARGUMENTS_BAD;
}
break;
default:
return CKR_ARGUMENTS_BAD;
}
status = sss_create_token(&pex_sss_demo_boot_ctx->ks,
&pex_sss_demo_tls_ctx->pub_obj,
keyId,
kSSS_KeyPart_Public,
cipherType,
buff,
buff_len,
keybitlen);
if (status != kStatus_SSS_Success) {
xResult = CKR_DEVICE_ERROR;
return xResult;
}
*pxObject = keyId;
#endif
break;
case CKO_SECRET_KEY:
#if SSS_HAVE_ALT_A71CH
xResult = CKR_ARGUMENTS_BAD;
#endif
#if SSS_HAVE_ALT_SSS
if (!foundKeyId) {
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_LABEL, &labelIndex);
if (xResult != CKR_OK) {
/* CKA_LABEL was not provided. Generate a random keyId */
xResult = LabelToKeyId((unsigned char *)"", 0, &keyId);
if (xResult != CKR_OK) {
return xResult;
}
}
else {
xResult = LabelToKeyId(pxTemplate[labelIndex].pValue, pxTemplate[labelIndex].ulValueLen, &keyId);
if (xResult != CKR_OK) {
return xResult;
}
}
}
xResult = GetAttributeParameterIndex(pxTemplate, ulCount, CKA_VALUE, &i);
if (xResult != CKR_OK) {
return xResult;
}
if (0 != pxTemplate[i].ulValueLen) {
sss_object_t secretObject = {0};
status = sss_create_token(&pex_sss_demo_boot_ctx->ks,
&secretObject,
keyId,
kSSS_KeyPart_Default,
kSSS_CipherType_AES,
(uint8_t *)pxTemplate[i].pValue,
pxTemplate[i].ulValueLen,
pxTemplate[i].ulValueLen * 8);
if (status != kStatus_SSS_Success) {
LOG_E("Secret Object init failed");
break;
}
*pxObject = keyId;
}
#endif
break;
default:
xResult = CKR_ARGUMENTS_BAD;
break;
}
}
return xResult;
}
/**
* @brief Query the list of interface function pointers.
*/
CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionList)
(CK_FUNCTION_LIST_PTR_PTR ppxFunctionList)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
if (NULL == ppxFunctionList) {
xResult = CKR_ARGUMENTS_BAD;
}
else {
*ppxFunctionList = &prvP11FunctionList;
}
return xResult;
}
/**
* @brief Initialize the Cryptoki module for use.
*/
CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pvInitArgs)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV status = CKR_OK;
if (cryptokiInitialized) {
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
}
// printf("\n\n%s\n\n", __FUNCTION__);
// typedef struct CK_C_INITIALIZE_ARGS {
// CK_CREATEMUTEX CreateMutex;
// CK_DESTROYMUTEX DestroyMutex;
// CK_LOCKMUTEX LockMutex;
// CK_UNLOCKMUTEX UnlockMutex;
// CK_FLAGS flags;
// CK_VOID_PTR pReserved;
// } CK_C_INITIALIZE_ARGS;
if (pvInitArgs) {
CK_C_INITIALIZE_ARGS_PTR initArgs = (CK_C_INITIALIZE_ARGS_PTR)(pvInitArgs);
if (initArgs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
// //Library should not create OS threads. If this is not possible, return CKR_NEED_TO_CREATE_THREADS
#if (__GNUC__ && !AX_EMBEDDED)
return CKR_NEED_TO_CREATE_THREADS;
#endif
#if defined(USE_RTOS) && USE_RTOS == 1
return CKR_NEED_TO_CREATE_THREADS;
#endif
}
if (initArgs->flags & CKF_OS_LOCKING_OK) {
// Application will call from multiple threads. Library should use locks.
if ((initArgs->CreateMutex) && (initArgs->DestroyMutex) && (initArgs->LockMutex) &&
(initArgs->UnlockMutex)) {
//If mutex pointers are not null, library can use either OS locking or provided functions
// return CKR_GENERAL_ERROR;
}
else if (!(initArgs->CreateMutex) && !(initArgs->DestroyMutex) && !(initArgs->LockMutex) &&
!(initArgs->UnlockMutex)) {
//If mutex pointers are null, library must use OS locking.
// return CKR_CANT_LOCK;
}
}
else {
return CKR_CANT_LOCK;
// //If mutex pointers are null, application would not access the library simultaneously.
// //If mutex pointers are not null, library should use provided functions to create threads.
// CKR_CANT_LOCK
// // status = CKR_ARGUMENTS_BAD;
// // return status;
}
}
if (!mutex_initialised) {
#if defined(USE_RTOS) && USE_RTOS == 1
// memset(&xSemaphore, 0, sizeof(SemaphoreHandle_t));
xSemaphore = xSemaphoreCreateMutex();
if (xSemaphore == NULL) {
status = CKR_CANT_LOCK;
goto exit;
}
#endif
#if (__GNUC__ && !AX_EMBEDDED)
int ret = EBUSY;
while (ret == EBUSY) {
ret = pthread_mutex_init(&gSessionlock, NULL);
}
if (ret != 0) {
LOG_E("Could not initialize mutex");
status = CKR_CANT_LOCK;
goto exit;
}
while (ret == EBUSY) {
ret = pthread_mutex_init(&gFilelock, NULL);
}
// ret = pthread_mutex_init(&gSessionlock, NULL);
#endif
mutex_initialised = true;
}
cryptokiInitialized = true;
#if ((defined(USE_RTOS) && USE_RTOS == 1) || ((__GNUC__ && !AX_EMBEDDED)))
exit:
#endif
return status;
}
/**
* @brief Un-initialize the Cryptoki module.
*/
CK_DEFINE_FUNCTION(CK_RV, C_Finalize)(CK_VOID_PTR pvReserved)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
if (NULL != pvReserved) {
return CKR_ARGUMENTS_BAD;
}
if (!cryptokiInitialized) {
return CKR_CRYPTOKI_NOT_INITIALIZED;
}
if (mutex_initialised) {
#if defined(USE_RTOS) && USE_RTOS == 1
vSemaphoreDelete(xSemaphore);
#endif
mutex_initialised = false;
}
cryptokiInitialized = false;
return xResult;
}
/**
* @brief Query the value of the specified cryptographic object attribute.
*/
CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)
(CK_SESSION_HANDLE xSession, CK_OBJECT_HANDLE xObject, CK_ATTRIBUTE_PTR pxTemplate, CK_ULONG ulCount)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
// LOG_I("%s : 0x%08X", __FUNCTION__, (uint32_t) xObject);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
CK_VOID_PTR pvAttr = NULL;
CK_ULONG ulAttrLength = 0;
CK_ULONG xP11KeyType, iAttrib, objectClass;
CK_BBOOL supported = CK_FALSE;
if (!pxTemplate) {
return CKR_ARGUMENTS_BAD;
}
/*
* Enumerate the requested attributes.
*/
LOCK_MUTEX_FOR_RTOS
{
for (iAttrib = 0; iAttrib < ulCount && CKR_OK == xResult; iAttrib++) {
/*
* Get the attribute data and size.
*/
ulAttrLength = 0;
size_t size = 0;
CK_BBOOL infoUnavailable = CK_FALSE;
sss_object_t sss_object = {0};
uint8_t data[2048] = {0};
size_t dataLen = sizeof(data);
size_t KeyBitLen = 2048;
uint8_t *rsaE = NULL;
size_t rsaElen;
uint8_t *rsaN = NULL;
size_t rsaNlen;
uint16_t outKeyIndex;
size_t pubKeyLen;
char label[80];
uint32_t keyId = 0;
CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
// LOG_I("Attribute required : 0x%08lx\n", pxTemplate[ iAttrib ].type);
switch (pxTemplate[iAttrib].type) {
/* Common key attributes */
case CKA_ID:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
keyId = sss_object.keyId;
pvAttr = &keyId;
ulAttrLength = sizeof(keyId);
break;
case CKA_CERTIFICATE_TYPE:
ulAttrLength = sizeof(cert_type);
pvAttr = &cert_type;
break;
case CKA_LABEL:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
keyId = sss_object.keyId;
snprintf(label, sizeof(label), "sss:%08X", (unsigned int)keyId);
ulAttrLength = strlen(label);
pvAttr = (char *)&label[0];
break;
case CKA_ALWAYS_AUTHENTICATE:
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
break;
case CKA_TOKEN:
supported = CK_TRUE; /* Object is always on token */
ulAttrLength = sizeof(supported);
pvAttr = &(supported);
break;
case CKA_KEY_TYPE:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
switch (sss_object.cipherType) {
case kSSS_CipherType_RSA:
case kSSS_CipherType_RSA_CRT:
xP11KeyType = CKK_RSA;
break;
case kSSS_CipherType_EC_NIST_P:
xP11KeyType = CKK_EC;
break;
case kSSS_CipherType_AES:
case kSSS_CipherType_DES:
xP11KeyType = CKK_AES;
break;
default:
xResult = CKR_ATTRIBUTE_VALUE_INVALID;
break;
}
ulAttrLength = sizeof(xP11KeyType);
pvAttr = &xP11KeyType;
break;
case CKA_VALUE:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
switch (sss_object.cipherType) {
case kSSS_CipherType_Binary:
if (kStatus_SSS_Success !=
sss_key_store_get_key(
&pex_sss_demo_boot_ctx->ks, &sss_object, &data[0], &dataLen, &KeyBitLen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
pvAttr = (void *)&data[0];
ulAttrLength = dataLen;
break;
case kSSS_CipherType_RSA:
case kSSS_CipherType_EC_NIST_P:
if (sss_object.objectType == kSSS_KeyPart_Pair || sss_object.objectType == kSSS_KeyPart_Private) {
ulAttrLength = 0;
xResult = CKR_ATTRIBUTE_SENSITIVE;
break;
}
if (kStatus_SSS_Success !=
sss_key_store_get_key(
&pex_sss_demo_boot_ctx->ks, &sss_object, &data[0], &dataLen, &KeyBitLen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
pvAttr = (void *)&data[0];
ulAttrLength = dataLen;
break;
default:
ulAttrLength = 0;
xResult = CKR_ARGUMENTS_BAD;
break;
}
break;
case CKA_VALUE_LEN:
pvAttr = NULL;
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
#if SSS_HAVE_APPLET_SE05X_IOT
xResult = read_object_size(xObject, &outKeyIndex);
if (xResult != CKR_OK) {
break;
}
size = (size_t)outKeyIndex;
pvAttr = (void *)&size;
ulAttrLength = sizeof(size_t);
#endif
break;
case CKA_MODULUS_BITS:
case CKA_PRIME_BITS:
/*
* Key strength size query, handled the same for RSA or ECDSA
* in this port.
*/
pvAttr = NULL;
ulAttrLength = 0;
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (((pxTemplate[iAttrib].type == CKA_MODULUS_BITS) &&
(sss_object.cipherType != kSSS_CipherType_RSA_CRT &&
sss_object.cipherType != kSSS_CipherType_RSA)) ||
((pxTemplate[iAttrib].type == CKA_PRIME_BITS) &&
sss_object.cipherType != kSSS_CipherType_EC_NIST_P)) {
xResult = CKR_ARGUMENTS_BAD;
break;
}
#if SSS_HAVE_APPLET_SE05X_IOT
xResult = read_object_size(xObject, &outKeyIndex);
if (xResult != CKR_OK) {
break;
}
#else
outKeyIndex = 32;
#endif
size = (size_t)outKeyIndex * 8;
pvAttr = (void *)&size;
ulAttrLength = sizeof(size_t);
break;
case CKA_VENDOR_DEFINED:
/*
* Return the key context for application-layer use.
*/
ulAttrLength = sizeof(pxSession->pxCurrentKey->xMbedPkCtx);
pvAttr = &pxSession->pxCurrentKey->xMbedPkCtx;
break;
case CKA_MODULUS:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success !=
sss_key_store_get_key(&pex_sss_demo_boot_ctx->ks, &sss_object, &data[0], &dataLen, &KeyBitLen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success !=
sss_util_asn1_rsa_parse_public(&data[0], dataLen, &rsaN, &rsaNlen, &rsaE, &rsaElen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
ulAttrLength = rsaNlen;
/* TODO: Why was this done??? */
// ulAttrLength = rsaNlen + 1;
pvAttr = (void *)rsaN;
break;
case CKA_PUBLIC_EXPONENT:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success !=
sss_key_store_get_key(&pex_sss_demo_boot_ctx->ks, &sss_object, &data[0], &dataLen, &KeyBitLen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success !=
sss_util_asn1_rsa_parse_public(&data[0], dataLen, &rsaN, &rsaNlen, &rsaE, &rsaElen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
ulAttrLength = rsaElen;
pvAttr = (void *)rsaE;
break;
case CKA_EC_PARAMS:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success !=
sss_key_store_get_key(&pex_sss_demo_boot_ctx->ks, &sss_object, &data[0], &dataLen, &KeyBitLen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
xResult = EcPublickeyGetEcParams(&data[0], &dataLen);
ulAttrLength = dataLen;
pvAttr = &data[0];
break;
case CKA_EC_POINT:
KeyBitLen = 256;
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success !=
sss_key_store_get_key(&pex_sss_demo_boot_ctx->ks, &sss_object, &data[0], &dataLen, &KeyBitLen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success !=
sss_util_pkcs8_asn1_get_ec_public_key_index(&data[0], dataLen, &outKeyIndex, &pubKeyLen)) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (pubKeyLen <= 127) {
if (outKeyIndex < 1) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
outKeyIndex = outKeyIndex - 1;
data[outKeyIndex] = pubKeyLen;
pubKeyLen++;
}
else if (pubKeyLen <= 255) {
if (outKeyIndex < 2) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
outKeyIndex = outKeyIndex - 2;
data[outKeyIndex] = 0x81;
data[outKeyIndex + 1] = pubKeyLen;
pubKeyLen = pubKeyLen + 2;
}
else {
if (outKeyIndex < 3) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
outKeyIndex = outKeyIndex - 3;
data[outKeyIndex] = 0x82;
data[outKeyIndex + 1] = (pubKeyLen & 0x00FF00) >> 8;
data[outKeyIndex + 2] = (pubKeyLen & 0x00FF);
pubKeyLen = pubKeyLen + 3;
}
pubKeyLen++;
if (outKeyIndex < 1) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
outKeyIndex = outKeyIndex - 1;
data[outKeyIndex] = ASN_TAG_OCTETSTRING;
ulAttrLength = pubKeyLen;
pvAttr = &data[outKeyIndex];
break;
case CKA_CLASS:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (sss_object.objectType == kSSS_KeyPart_Private || sss_object.objectType == kSSS_KeyPart_Pair) {
objectClass = CKO_PRIVATE_KEY;
pvAttr = &objectClass;
ulAttrLength = sizeof(objectClass);
}
else if (sss_object.objectType == kSSS_KeyPart_Public) {
objectClass = CKO_PUBLIC_KEY;
pvAttr = &objectClass;
ulAttrLength = sizeof(objectClass);
}
else if (sss_object.objectType == kSSS_KeyPart_Default) {
if (sss_object.cipherType == kSSS_CipherType_Binary) {
objectClass = CKO_CERTIFICATE;
pvAttr = &objectClass;
ulAttrLength = sizeof(objectClass);
}
else {
objectClass = CKO_SECRET_KEY;
pvAttr = &objectClass;
ulAttrLength = sizeof(objectClass);
}
}
else {
ulAttrLength = CK_UNAVAILABLE_INFORMATION;
xResult = CKR_ATTRIBUTE_SENSITIVE;
infoUnavailable = CK_TRUE;
}
break;
case CKA_ENCRYPT:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (sss_object.objectType == kSSS_KeyPart_Public) {
if (sss_object.cipherType == kSSS_CipherType_RSA_CRT ||
sss_object.cipherType == kSSS_CipherType_RSA) {
supported = CK_TRUE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
}
else if (sss_object.objectType == kSSS_KeyPart_Default) {
if (sss_object.cipherType == kSSS_CipherType_AES) {
supported = CK_TRUE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
break;
case CKA_DECRYPT:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (sss_object.objectType == kSSS_KeyPart_Private || sss_object.objectType == kSSS_KeyPart_Pair) {
if (sss_object.cipherType == kSSS_CipherType_RSA_CRT ||
sss_object.cipherType == kSSS_CipherType_RSA) {
supported = CK_TRUE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
}
else if (sss_object.objectType == kSSS_KeyPart_Default) {
if (sss_object.cipherType == kSSS_CipherType_AES) {
supported = CK_TRUE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
break;
case CKA_SIGN:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (sss_object.objectType == kSSS_KeyPart_Private || sss_object.objectType == kSSS_KeyPart_Pair) {
if (sss_object.cipherType == kSSS_CipherType_RSA_CRT ||
sss_object.cipherType == kSSS_CipherType_RSA ||
sss_object.cipherType == kSSS_CipherType_EC_NIST_P) {
supported = CK_TRUE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
break;
case CKA_VERIFY:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (sss_object.objectType == kSSS_KeyPart_Public) {
if (sss_object.cipherType == kSSS_CipherType_RSA_CRT ||
sss_object.cipherType == kSSS_CipherType_RSA ||
sss_object.cipherType == kSSS_CipherType_EC_NIST_P) {
supported = CK_TRUE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
}
else {
supported = CK_FALSE;
pvAttr = &supported;
ulAttrLength = sizeof(supported);
}
break;
case CKA_WRAP:
case CKA_UNWRAP:
case CKA_SIGN_RECOVER:
case CKA_VERIFY_RECOVER:
supported = CK_FALSE;
ulAttrLength = sizeof(supported);
pvAttr = &(supported);
break;
case CKA_DERIVE:
if (kStatus_SSS_Success != (sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (kStatus_SSS_Success != (sss_key_object_get_handle(&sss_object, xObject))) {
ulAttrLength = 0;
xResult = CKR_FUNCTION_FAILED;
break;
}
if (sss_object.objectType == kSSS_KeyPart_Pair && sss_object.cipherType == kSSS_CipherType_EC_NIST_P) {
supported = CK_TRUE;
ulAttrLength = sizeof(supported);
pvAttr = &(supported);
}
else {
supported = CK_FALSE;
ulAttrLength = sizeof(supported);
pvAttr = &(supported);
}
break;
case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
ulAttrLength = sizeof(data);
xResult =
parseCertificateGetAttribute((uint32_t)xObject, pxTemplate[iAttrib].type, &data[0], &ulAttrLength);
if (xResult != CKR_OK) {
pvAttr = NULL;
ulAttrLength = 0;
}
else {
pvAttr = &data[0];
}
break;
default:
LOG_W("Attribute required : 0x%08lx\n", pxTemplate[iAttrib].type);
ulAttrLength = CK_UNAVAILABLE_INFORMATION;
infoUnavailable = CK_TRUE;
xResult = CKR_ATTRIBUTE_SENSITIVE;
break;
}
if (CKR_OK == xResult) {
/*
* Copy out the data and size.
*/
if (NULL != pxTemplate[iAttrib].pValue && !infoUnavailable) {
if (pxTemplate[iAttrib].ulValueLen < ulAttrLength) {
xResult = CKR_BUFFER_TOO_SMALL;
ulAttrLength = CK_UNAVAILABLE_INFORMATION;
}
else {
memcpy(pxTemplate[iAttrib].pValue, pvAttr, ulAttrLength);
}
}
}
pxTemplate[iAttrib].ulValueLen = ulAttrLength;
if (rsaN) {
SSS_FREE(rsaN);
}
if (rsaE) {
SSS_FREE(rsaE);
}
}
UNLOCK_MUTEX_FOR_RTOS
}
return xResult;
}
/**
* @brief Begin an enumeration sequence for the objects of the specified type.
*/
CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)
(CK_SESSION_HANDLE xSession, CK_ATTRIBUTE_PTR pxTemplate, CK_ULONG ulCount)
{ /*lint !e9072 It's OK to have different parameter name. */
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
// printf("\n\n%s\n\n", __FUNCTION__);
// ( void ) ( ulCount );
/*
* Allow filtering on a single object class attribute.
*/
pxSession->xFindObjectInit = CK_TRUE;
pxSession->xFindObjectComplete = CK_FALSE;
pxSession->xFindObjectClass = pkcs11INVALID_OBJECT_CLASS; /* Invalid Class */
pxSession->xFindObjectKeyType = pkcs11INVALID_KEY_TYPE; /* Invalid Key Type */
if (!pxTemplate) {
pxSession->labelPresent = CK_FALSE;
pxSession->keyIdPresent = CK_FALSE;
pxSession->xFindObjectClass = pkcs11INVALID_OBJECT_CLASS; /* Invalid Class */
pxSession->xFindObjectKeyType = pkcs11INVALID_KEY_TYPE; /* Invalid Key Type */
pxSession->xFindObjectTotalFound = 0;
return CKR_OK;
// return CKR_ARGUMENTS_BAD;
}
int classIndex = 0;
CK_BBOOL foundClass = CK_FALSE;
CK_ULONG i = 0;
for (i = 0; i < ulCount; i++) {
if (pxTemplate[i].type == CKA_LABEL) {
pxSession->labelPresent = CK_TRUE;
snprintf(pxSession->label, sizeof(pxSession->label), "%s", (char *)pxTemplate[i].pValue);
// pxSession->label = (unsigned char *) pxTemplate[i].pValue;
// memcpy(pxSession->label, pxTemplate[i].pValue, strlen((char *)pxTemplate[i].pValue));
// memcpy(pxSession->label, pxTemplate[i].pValue, pxTemplate[i].ulValueLen);
pxSession->labelLen = pxTemplate[i].ulValueLen;
// printf("\nFound label\n");
}
else if (pxTemplate[i].type == CKA_CLASS) {
classIndex = i;
foundClass = CK_TRUE;
}
else if (pxTemplate[i].type == CKA_SSS_ID) {
pxSession->keyIdPresent = CK_TRUE;
pxSession->keyId = *((uint32_t *)(pxTemplate[i].pValue));
}
else if (pxTemplate[i].type == CKA_KEY_TYPE) {
memcpy(&pxSession->xFindObjectKeyType, pxTemplate[i].pValue, sizeof(CK_KEY_TYPE));
}
// keyIdPresent
}
if (foundClass) {
// if(pxTemplate[0].type == CKA_CLASS) {
memcpy(&pxSession->xFindObjectClass, pxTemplate[classIndex].pValue, sizeof(CK_OBJECT_CLASS));
// }
}
return CKR_OK;
}
/**
* @brief Query the objects of the requested type.
*/
CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)
(CK_SESSION_HANDLE xSession, CK_OBJECT_HANDLE_PTR pxObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
BaseType_t xDone = pdFALSE;
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
uint32_t keyId = 0x0;
/*
* Check parameters.
*/
if ((CK_BBOOL)CK_FALSE == pxSession->xFindObjectInit) {
xResult = CKR_OPERATION_NOT_INITIALIZED;
xDone = pdTRUE;
return xResult;
}
if ((pdFALSE == xDone) && (0u == ulMaxObjectCount)) {
xResult = CKR_ARGUMENTS_BAD;
xDone = pdTRUE;
return xResult;
}
if ((pdFALSE == xDone) && (!pxObject || !pulObjectCount)) {
xResult = CKR_ARGUMENTS_BAD;
xDone = pdTRUE;
return xResult;
}
if ((pdFALSE == xDone) && ((CK_BBOOL)CK_TRUE == pxSession->xFindObjectComplete)) {
*pulObjectCount = 0;
xResult = CKR_OK;
xDone = pdTRUE;
return xResult;
}
/*
* Load the default private key and certificate.
*/
if ((pdFALSE == xDone) && pxSession->labelPresent) {
if (pxSession->labelLen == 0) {
*pulObjectCount = 0;
xResult = CKR_FUNCTION_FAILED;
}
else {
if (pxSession->xFindObjectTotalFound == 1) {
*pulObjectCount = 0;
}
else {
xResult = LabelToKeyId((unsigned char *)pxSession->label, pxSession->labelLen, &keyId);
if (xResult == CKR_OK) {
sss_status_t status = kStatus_SSS_Fail;
sss_object_t object = {0};
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&object, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
xResult = CKR_FUNCTION_FAILED;
}
else {
status = sss_key_object_get_handle(&object, keyId);
if (status != kStatus_SSS_Success) {
*pulObjectCount = 0;
// xResult = CKR_FUNCTION_FAILED;
}
else {
*pxObject = keyId;
*pulObjectCount = 1;
pxSession->xFindObjectTotalFound = 1;
}
}
UNLOCK_MUTEX_FOR_RTOS
}
}
}
}
xDone = pdTRUE;
}
else if ((pdFALSE == xDone) && pxSession->keyIdPresent) {
keyId = pxSession->keyId;
sss_status_t status = kStatus_SSS_Fail;
sss_object_t object = {0};
if (pxSession->xFindObjectTotalFound == 1) {
*pulObjectCount = 0;
}
else {
LOCK_MUTEX_FOR_RTOS
{
status = sss_key_object_init(&object, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
xResult = CKR_FUNCTION_FAILED;
}
else {
status = sss_key_object_get_handle(&object, keyId);
if (status != kStatus_SSS_Success) {
*pulObjectCount = 0;
// xResult = CKR_FUNCTION_FAILED;
}
else {
*pxObject = keyId;
*pulObjectCount = 1;
pxSession->xFindObjectTotalFound = 1;
}
}
UNLOCK_MUTEX_FOR_RTOS
}
}
xDone = pdTRUE;
}
else if ((pdFALSE == xDone)) {
#if SSS_HAVE_ALT_SSS && SSS_HAVE_APPLET_SE05X_IOT
uint32_t object_list[40];
size_t object_list_size = sizeof(object_list) / sizeof(object_list[0]);
smStatus_t sm_status = read_id_list(object_list, &object_list_size);
if (sm_status != SM_OK) {
xResult = CKR_FUNCTION_FAILED;
xDone = pdTRUE;
return xResult;
}
size_t i = 0;
uint32_t skipped = 0;
CK_OBJECT_HANDLE_PTR ckObjects = (CK_OBJECT_HANDLE_PTR)SSS_MALLOC(sizeof(CK_OBJECT_HANDLE) * ulMaxObjectCount);
*pulObjectCount = 0;
LOCK_MUTEX_FOR_RTOS
{
for (i = 0; ((i < object_list_size) && (*pulObjectCount < ulMaxObjectCount)); i++) {
uint32_t id = object_list[i];
sss_object_t object;
sss_status_t status = sss_key_object_init(&object, &pex_sss_demo_boot_ctx->ks);
if (status != kStatus_SSS_Success) {
LOG_E("Object init failed. Should not reach here");
continue;
}
status = sss_key_object_get_handle(&object, id);
if (status != kStatus_SSS_Success) {
LOG_E("Object get handle failed. Should not reach here");
continue;
}
if (pxSession->xFindObjectClass == pkcs11INVALID_OBJECT_CLASS &&
pxSession->xFindObjectKeyType == pkcs11INVALID_KEY_TYPE) {
if (skipped < pxSession->xFindObjectTotalFound) {
skipped++;
continue;
}
memcpy(&ckObjects[*pulObjectCount], &id, sizeof(id));
(*pulObjectCount)++;
}
else if (pxSession->xFindObjectClass != pkcs11INVALID_OBJECT_CLASS &&
pxSession->xFindObjectKeyType == pkcs11INVALID_KEY_TYPE) {
if ((object.cipherType == kSSS_CipherType_Binary &&
pxSession->xFindObjectClass == CKO_CERTIFICATE) ||
(object.objectType == kSSS_KeyPart_Pair && pxSession->xFindObjectClass == CKO_PRIVATE_KEY) ||
(object.objectType == kSSS_KeyPart_Public && pxSession->xFindObjectClass == CKO_PUBLIC_KEY)) {
if (skipped < pxSession->xFindObjectTotalFound) {
skipped++;
continue;
}
memcpy(&ckObjects[*pulObjectCount], &id, sizeof(id));
(*pulObjectCount)++;
}
}
else if (pxSession->xFindObjectClass == pkcs11INVALID_OBJECT_CLASS &&
pxSession->xFindObjectKeyType != pkcs11INVALID_KEY_TYPE) {
if ((object.cipherType == kSSS_CipherType_AES && pxSession->xFindObjectKeyType == CKK_AES) ||
(object.cipherType == kSSS_CipherType_DES && pxSession->xFindObjectKeyType == CKK_DES) ||
(object.cipherType == kSSS_CipherType_DES && pxSession->xFindObjectKeyType == CKK_DES2) ||
(object.cipherType == kSSS_CipherType_DES && pxSession->xFindObjectKeyType == CKK_DES3) ||
(object.cipherType == kSSS_CipherType_RSA && pxSession->xFindObjectKeyType == CKK_RSA) ||
(object.cipherType == kSSS_CipherType_RSA_CRT && pxSession->xFindObjectKeyType == CKK_RSA) ||
(object.cipherType == kSSS_CipherType_EC_NIST_P && pxSession->xFindObjectKeyType == CKK_EC)) {
if (skipped < pxSession->xFindObjectTotalFound) {
skipped++;
continue;
}
memcpy(&ckObjects[*pulObjectCount], &id, sizeof(id));
(*pulObjectCount)++;
}
}
else if (pxSession->xFindObjectClass != pkcs11INVALID_OBJECT_CLASS &&
pxSession->xFindObjectKeyType != pkcs11INVALID_KEY_TYPE) {
if ((object.objectType == kSSS_KeyPart_Pair && pxSession->xFindObjectClass == CKO_PRIVATE_KEY) ||
(object.objectType == kSSS_KeyPart_Public && pxSession->xFindObjectClass == CKO_PUBLIC_KEY)) {
if ((object.cipherType == kSSS_CipherType_AES && pxSession->xFindObjectKeyType == CKK_AES) ||
(object.cipherType == kSSS_CipherType_DES && pxSession->xFindObjectKeyType == CKK_DES) ||
(object.cipherType == kSSS_CipherType_DES && pxSession->xFindObjectKeyType == CKK_DES2) ||
(object.cipherType == kSSS_CipherType_DES && pxSession->xFindObjectKeyType == CKK_DES3) ||
(object.cipherType == kSSS_CipherType_RSA && pxSession->xFindObjectKeyType == CKK_RSA) ||
(object.cipherType == kSSS_CipherType_RSA_CRT &&
pxSession->xFindObjectKeyType == CKK_RSA) ||
(object.cipherType == kSSS_CipherType_EC_NIST_P &&
pxSession->xFindObjectKeyType == CKK_EC)) {
if (skipped < pxSession->xFindObjectTotalFound) {
skipped++;
continue;
}
memcpy(&ckObjects[*pulObjectCount], &id, sizeof(id));
(*pulObjectCount)++;
}
}
}
}
UNLOCK_MUTEX_FOR_RTOS
}
if (*pulObjectCount > 0) {
memcpy(pxObject, ckObjects, (sizeof(CK_OBJECT_HANDLE) * (*pulObjectCount)));
pxSession->xFindObjectTotalFound = pxSession->xFindObjectTotalFound + *pulObjectCount;
}
if (ckObjects) {
SSS_FREE(ckObjects);
}
#endif
xDone = pdTRUE;
}
return xResult;
}
/**
* @brief Terminate object enumeration.
*/
CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal)(CK_SESSION_HANDLE xSession)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
/*
* Check parameters.
*/
if ((CK_BBOOL)CK_FALSE == pxSession->xFindObjectInit) {
xResult = CKR_OPERATION_NOT_INITIALIZED;
}
else {
/*
* Clean-up find objects state.
*/
pxSession->labelPresent = CK_FALSE;
pxSession->keyIdPresent = CK_FALSE;
pxSession->xFindObjectInit = CK_FALSE;
pxSession->xFindObjectComplete = CK_FALSE;
pxSession->xFindObjectClass = 0;
pxSession->xFindObjectTotalFound = 0;
pxSession->xFindObjectKeyType = pkcs11INVALID_KEY_TYPE;
}
return xResult;
}
/**
* @brief Start a session for a cryptographic command sequence.
*/
CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)
(CK_SLOT_ID xSlotID, CK_FLAGS xFlags, CK_VOID_PTR pvApplication, CK_NOTIFY xNotify, CK_SESSION_HANDLE_PTR pxSession)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
P11SessionPtr_t pxSessionObj = NULL;
// printf("\n\n%s\n\n", __FUNCTION__);
// ( void ) ( xSlotID );
// ( void ) ( pvApplication );
// ( void ) ( xNotify );
/* Check arguments. */
if (!cryptokiInitialized) {
return CKR_CRYPTOKI_NOT_INITIALIZED;
}
if (NULL == pxSession) {
xResult = CKR_ARGUMENTS_BAD;
}
if (xSlotID != pkcs11SLOT_ID) {
return CKR_ARGUMENTS_BAD;
}
if (!(xFlags & CKF_SERIAL_SESSION)) {
return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
}
/*
* Make space for the context.
*/
#if defined(USE_RTOS) && USE_RTOS == 1
if (NULL == (pxSessionObj = (P11SessionPtr_t)pvPortMalloc(
sizeof(P11Session_t)))) /*lint !e9087 Allow casting void* to other types. */
{
xResult = CKR_HOST_MEMORY;
}
#else
if (NULL == (pxSessionObj = (P11SessionPtr_t)SSS_MALLOC(
sizeof(P11Session_t)))) /*lint !e9087 Allow casting void* to other types. */
{
xResult = CKR_HOST_MEMORY;
}
#endif
/*
* Assume that there's no performance tradeoff in loading the default key
* now, since that's the principal use case for opening a session in this
* provider anyway. This way, the private key can be used for seeding the RNG,
* especially if there's no hardware-based alternative.
*/
if (CKR_OK == xResult) {
memset(pxSessionObj, 0, sizeof(P11Session_t));
}
/*
* Initialize RNG.
*/
if (CKR_OK == xResult) {
memset(&pxSessionObj->xMbedEntropyContext, 0, sizeof(pxSessionObj->xMbedEntropyContext));
}
if (CKR_OK == xResult) {
/*
* Assign the session.
*/
pxSessionObj->ulState = 0u != (xFlags & CKF_RW_SESSION) ? CKS_RW_PUBLIC_SESSION : CKS_RO_PUBLIC_SESSION;
pxSessionObj->xOpened = CK_TRUE;
/*
* Return the session.
*/
*pxSession = (CK_SESSION_HANDLE)pxSessionObj; /*lint !e923 Allow casting pointer to integer type for handle. */
}
if ((NULL != pxSessionObj) && (CKR_OK != xResult)) {
SSS_FREE(pxSessionObj);
return CKR_FUNCTION_FAILED;
}
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
/*Lock for session open - required because multiple session_open will be attempted*/
#if (__GNUC__ && !AX_EMBEDDED)
pthread_mutex_lock(&gSessionlock);
#endif
#ifdef PKCS11_SESSION_OPEN
LOCK_MUTEX_FOR_RTOS
{
if (CKR_OK == xResult) {
// if(pex_sss_demo_boot_ctx->session.subsystem == kType_SSS_SubSystem_NONE){
if (sessionCount == 0) {
sss_status_t sss_status = kStatus_SSS_Fail;
const char *portName = g_port_name;
SM_Close(NULL, 0);
/* If portname is given in ENV */
sss_status = ex_sss_boot_connectstring(0, NULL, &portName);
sss_status = ex_sss_boot_open(pex_sss_demo_boot_ctx, portName);
if (sss_status != kStatus_SSS_Success) {
LOG_E("Session Open Failed");
xResult = CKR_GENERAL_ERROR;
goto error;
}
#if EX_SSS_BOOT_DO_ERASE
sss_status = ex_sss_boot_factory_reset(pex_sss_demo_boot_ctx);
if (sss_status != kStatus_SSS_Success) {
LOG_E("Factory Reset failed");
}
#endif
sss_status = ex_sss_key_store_and_object_init(pex_sss_demo_boot_ctx);
if (sss_status != kStatus_SSS_Success) {
LOG_E("Keystore Init Failed");
xResult = CKR_FUNCTION_FAILED;
goto error;
}
pex_sss_demo_tls_ctx->pHost_ks = &pex_sss_demo_boot_ctx->host_ks;
sss_status = sss_key_object_init(&pex_sss_demo_tls_ctx->obj, &pex_sss_demo_boot_ctx->ks);
if (sss_status != kStatus_SSS_Success) {
LOG_E("Object init failed");
}
sss_status = sss_key_object_init(&pex_sss_demo_tls_ctx->dev_cert, &pex_sss_demo_boot_ctx->ks);
if (sss_status != kStatus_SSS_Success) {
LOG_E("Cert Object init failed");
}
sss_status = sss_key_object_init(&pex_sss_demo_tls_ctx->interCaCert, &pex_sss_demo_boot_ctx->ks);
if (sss_status != kStatus_SSS_Success) {
LOG_E("IntermCA Object init failed");
}
sss_status = sss_key_object_init(&pex_sss_demo_tls_ctx->pub_obj, &pex_sss_demo_boot_ctx->ks);
if (sss_status != kStatus_SSS_Success) {
LOG_E("Pub Object init failed");
}
UNLOCK_MUTEX_FOR_RTOS
goto exit;
error:
if (pxSessionObj) {
SSS_FREE(pxSessionObj);
}
if (pex_sss_demo_boot_ctx->session.subsystem != kType_SSS_SubSystem_NONE) {
ex_sss_session_close(pex_sss_demo_boot_ctx);
}
}
}
UNLOCK_MUTEX_FOR_RTOS
}
exit:
#endif
if (xResult == CKR_OK) {
sessionCount++;
}
/*Unlock for session open - required because multiple session_open will be attempted*/
#if (__GNUC__ && !AX_EMBEDDED)
pthread_mutex_unlock(&gSessionlock);
LOG_I("Destroyed mutex");
#endif
return xResult;
}
/**
* @brief Terminate a session and release resources.
*/
CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)(CK_SESSION_HANDLE xSession)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
// printf("\n\n%s\n\n", __FUNCTION__);
if (NULL != pxSession) {
/*
* Tear down the session.
*/
/* PKCS11TB macro is required because in one of the PKCS 11 test case causes hard fault
* since no buffer is allocated for certificate_buf and it causes hard fault when freeing
* TODO: not deallocate memory when buffer is not allocated */
#if (defined(PKCS11TB) && (PKCS11TB == 0))
if (NULL != pxSession->pxCurrentKey->certificate_buf) {
#if defined(USE_RTOS) && USE_RTOS == 1
vPortFree(pxSession->pxCurrentKey->certificate_buf);
#else
SSS_FREE(pxSession->pxCurrentKey->certificate_buf);
#endif
}
#endif
#if defined(USE_RTOS) && USE_RTOS == 1
vPortFree(pxSession);
#else
SSS_FREE(pxSession);
#endif
/*Lock for session open - required because multiple session_open will be attempted*/
#if (__GNUC__ && !AX_EMBEDDED)
pthread_mutex_lock(&gSessionlock);
#endif
if (CKR_OK == xResult) {
#ifdef PKCS11_SESSION_OPEN //SSS_HAVE_ALT_SSS || SSS_HAVE_ALT_A71CH
// static const char *g_port_name;
// printf("\nIn session close");
if (sessionCount == 1) {
// printf("\nsessionCount = 1");
// sss_status_t sss_status = kStatus_SSS_Fail;
LOCK_MUTEX_FOR_RTOS
{
sss_key_object_free(&pex_sss_demo_tls_ctx->obj);
sss_key_object_free(&pex_sss_demo_tls_ctx->dev_cert);
sss_key_object_free(&pex_sss_demo_tls_ctx->interCaCert);
sss_key_object_free(&pex_sss_demo_tls_ctx->pub_obj);
ex_sss_session_close(pex_sss_demo_boot_ctx);
UNLOCK_MUTEX_FOR_RTOS
}
}
#endif
}
}
else {
xResult = CKR_SESSION_HANDLE_INVALID;
}
if (xResult == CKR_OK) {
sessionCount--;
}
/*Unlock for session open - required because multiple session_open will be attempted*/
#if (__GNUC__ && !AX_EMBEDDED)
pthread_mutex_unlock(&gSessionlock);
LOG_I("Destroyted mutex");
LOG_I("SessionCount = %d", sessionCount);
#endif
return xResult;
}
/**
* @brief Cleans up a key structure.
*/
// static int convertdertopemformat(const unsigned char * int_ca_cert_der, int len_der, unsigned char * int_ca_cert_pem, int dst_buf_len, U16 *outlength)
// {
// int ret;
// size_t len_out;
// const char start[]= "-----BEGIN CERTIFICATE-----\n";
// const char end[]= "\n-----END CERTIFICATE-----\n";
// strcpy((char *)int_ca_cert_pem,start);
// ret = mbedtls_base64_encode(&int_ca_cert_pem[sizeof(start) - 1],dst_buf_len-sizeof(start)-sizeof(end)-1,&len_out,int_ca_cert_der,len_der);
// if (ret == 0)
// {
// strcpy((char *) &int_ca_cert_pem[sizeof(start) - 1 + len_out],end);
// *outlength = len_out + sizeof(start) + sizeof(end) - 1;
// }
// else
// {
// *outlength = 0;
// ret = 1;
// }
// return ret;
// }
#if SSS_HAVE_ALT_SSS
static int convertpemtoder(const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen)
{
int ret;
const unsigned char *s1, *s2, *end = input + ilen;
size_t len = 0;
s1 = (unsigned char *)strstr((const char *)input, "-----BEGIN");
if (s1 == NULL)
return (-1);
s2 = (unsigned char *)strstr((const char *)input, "-----END");
if (s2 == NULL)
return (-1);
s1 += 10;
while (s1 < end && *s1 != '-')
s1++;
while (s1 < end && *s1 == '-')
s1++;
if (*s1 == '\r')
s1++;
if (*s1 == '\n')
s1++;
if (s2 <= s1 || s2 > end)
return (-1);
ret = mbedtls_base64_decode(NULL, 0, &len, (const unsigned char *)s1, s2 - s1);
if (ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER)
return (ret);
if (len > *olen)
return (-1);
if ((ret = mbedtls_base64_decode(output, len, &len, (const unsigned char *)s1, s2 - s1)) != 0) {
return (ret);
}
*olen = len;
return (0);
}
#endif
#if AX_EMBEDDED
BaseType_t PKCS11_PAL_SaveFile(char *pcFileName, uint8_t *pucData, uint32_t ulDataSize)
{
return false;
}
#endif /* AX_EMBEDDED */
/**
* @brief Begin a digital signature verification session.
*/
CK_DEFINE_FUNCTION(CK_RV, C_VerifyInit)
(CK_SESSION_HANDLE xSession, CK_MECHANISM_PTR pxMechanism, CK_OBJECT_HANDLE xKey)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
// pxSession->xOperationInProgress = pxMechanism->mechanism;
/*lint !e9072 It's OK to have different parameter name. */
// ( void ) ( xSession );
// ( void ) ( xKey );
if (NULL == pxMechanism) {
xResult = CKR_ARGUMENTS_BAD;
}
else if (pxSession->xOperationInProgress != pkcs11NO_OPERATION) {
xResult = CKR_SESSION_HANDLE_INVALID;
}
else {
pxSession->xOperationInProgress = pxMechanism->mechanism;
pxSession->xOperationKeyHandle = xKey;
if (pxMechanism->pParameter) {
pxSession->mechParameter = pxMechanism->pParameter;
pxSession->mechParameterLen = pxMechanism->ulParameterLen;
}
else {
pxSession->mechParameterLen = 0;
}
}
return xResult;
}
CK_RV ParseSignMechanism(P11SessionPtr_t pxSession, sss_algorithm_t *algorithm)
{
CK_RV xResult = CKR_OK;
switch (pxSession->xOperationInProgress) {
case CKM_RSA_PKCS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_V1_5_NO_HASH;
break;
case CKM_RSA_PKCS_PSS:
/*Also need the details about hash algorithm used*/
if (!pxSession->mechParameterLen) {
xResult = CKR_ARGUMENTS_BAD;
break;
}
CK_RSA_PKCS_PSS_PARAMS_PTR param = (CK_RSA_PKCS_PSS_PARAMS_PTR)pxSession->mechParameter;
switch (param->hashAlg) {
case CKM_SHA_1:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA1;
break;
case CKM_SHA224:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA224;
break;
case CKM_SHA256:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA256;
break;
case CKM_SHA384:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA384;
break;
case CKM_SHA512:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA512;
break;
default:
xResult = CKR_MECHANISM_INVALID;
break;
}
break;
case CKM_SHA1_RSA_PKCS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA1;
break;
case CKM_SHA1_RSA_PKCS_PSS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA1;
break;
case CKM_SHA256_RSA_PKCS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA256;
break;
case CKM_SHA256_RSA_PKCS_PSS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA256;
break;
case CKM_SHA384_RSA_PKCS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA384;
break;
case CKM_SHA384_RSA_PKCS_PSS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA384;
break;
case CKM_SHA512_RSA_PKCS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA512;
break;
case CKM_SHA512_RSA_PKCS_PSS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA512;
break;
case CKM_SHA224_RSA_PKCS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_V1_5_SHA224;
break;
case CKM_SHA224_RSA_PKCS_PSS:
*algorithm = kAlgorithm_SSS_RSASSA_PKCS1_PSS_MGF1_SHA224;
break;
case CKM_ECDSA:
/* We will use algorithm according to digest size.
* Should be checked from where this function is called
*/
break;
case CKM_ECDSA_SHA1:
*algorithm = kAlgorithm_SSS_ECDSA_SHA1;
break;
default:
xResult = CKR_MECHANISM_INVALID;
break;
}
return xResult;
}
CK_RV ParseEncryptionMechanism(P11SessionPtr_t pxSession, sss_algorithm_t *algorithm)
{
/* typedef struct CK_RSA_PKCS_OAEP_PARAMS {
CK_MECHANISM_TYPE hashAlg;
CK_RSA_PKCS_MGF_TYPE mgf;
CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
CK_VOID_PTR pSourceData;
CK_ULONG ulSourceDataLen;
} CK_RSA_PKCS_OAEP_PARAMS;*/
CK_RV xResult = CKR_OK;
switch (pxSession->xOperationInProgress) {
case CKM_RSA_PKCS:
case CKM_SHA1_RSA_PKCS:
case CKM_SHA256_RSA_PKCS:
case CKM_SHA384_RSA_PKCS:
case CKM_SHA512_RSA_PKCS:
case CKM_SHA224_RSA_PKCS:
*algorithm = kAlgorithm_SSS_RSAES_PKCS1_V1_5;
break;
case CKM_RSA_PKCS_OAEP:
/* Also need the details about hash algorithm used */
/* TODO: Also see how to use source, pSourceData, ulSourceDataLen
* in RSA_PKCS_OAEP_PARAMS
*/
if (!pxSession->mechParameterLen) {
xResult = CKR_ARGUMENTS_BAD;
break;
}
CK_RSA_PKCS_OAEP_PARAMS_PTR param = (CK_RSA_PKCS_OAEP_PARAMS_PTR)pxSession->mechParameter;
switch (param->hashAlg) {
case CKM_SHA_1:
if (param->mgf == CKG_MGF1_SHA1) {
*algorithm = kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA1;
}
else {
xResult = CKR_MECHANISM_INVALID;
}
break;
case CKM_SHA224:
xResult = CKR_MECHANISM_INVALID;
/**algorithm = kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA224;*/
break;
case CKM_SHA256:
xResult = CKR_MECHANISM_INVALID;
/**algorithm = kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA256;*/
break;
case CKM_SHA384:
xResult = CKR_MECHANISM_INVALID;
/**algorithm = kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA384;*/
break;
case CKM_SHA512:
xResult = CKR_MECHANISM_INVALID;
/**algorithm = kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA512;*/
break;
default:
xResult = CKR_MECHANISM_INVALID;
break;
}
break;
// *algorithm = kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA1;
break;
case CKM_AES_ECB:
*algorithm = kAlgorithm_SSS_AES_ECB;
break;
case CKM_AES_CBC:
*algorithm = kAlgorithm_SSS_AES_CBC;
break;
case CKM_AES_CTR:
*algorithm = kAlgorithm_SSS_AES_CTR;
break;
default:
xResult = CKR_MECHANISM_INVALID;
break;
}
return xResult;
}
CK_RV ParseDigestMechanism(P11SessionPtr_t pxSession, sss_algorithm_t *algorithm)
{
CK_RV xResult = CKR_OK;
switch (pxSession->xOperationInProgress) {
case CKM_SHA_1:
*algorithm = kAlgorithm_SSS_SHA1;
break;
case CKM_SHA224:
*algorithm = kAlgorithm_SSS_SHA224;
break;
case CKM_SHA256:
*algorithm = kAlgorithm_SSS_SHA256;
break;
case CKM_SHA384:
*algorithm = kAlgorithm_SSS_SHA384;
break;
case CKM_SHA512:
*algorithm = kAlgorithm_SSS_SHA512;
break;
default:
xResult = CKR_MECHANISM_INVALID;
break;
}
return xResult;
}
/**
* @brief Begin a digital signature generation session.
*/
CK_DEFINE_FUNCTION(CK_RV, C_SignInit)
(CK_SESSION_HANDLE xSession, CK_MECHANISM_PTR pxMechanism, CK_OBJECT_HANDLE xKey)
{
CK_RV xResult = CKR_OK;
// LOG_I("KeyId = %ld", (uint32_t) xKey);
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(xSession);
// pxSession->xOperationInProgress = pxMechanism->mechanism;
/*lint !e9072 It's OK to have different parameter name. */
// ( void ) ( xSession );
// ( void ) ( xKey );
if (NULL == pxMechanism) {
xResult = CKR_ARGUMENTS_BAD;
}
else if (pxSession->xOperationInProgress != pkcs11NO_OPERATION) {
xResult = CKR_SESSION_HANDLE_INVALID;
}
else {
pxSession->xOperationInProgress = pxMechanism->mechanism;
pxSession->xOperationKeyHandle = xKey;
if (pxMechanism->pParameter) {
pxSession->mechParameter = pxMechanism->pParameter;
pxSession->mechParameterLen = pxMechanism->ulParameterLen;
}
else {
pxSession->mechParameterLen = 0;
}
}
return xResult;
}
/**
* @brief Query the list of slots. A single default slot is implemented.
*/
CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)
(CK_BBOOL xTokenPresent, CK_SLOT_ID_PTR pxSlotList, CK_ULONG_PTR pulCount)
{ /*lint !e9072 It's OK to have different parameter name. */
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
// ( void ) ( xTokenPresent );
if (NULL == pulCount) {
xResult = CKR_ARGUMENTS_BAD;
}
else if (NULL == pxSlotList) {
*pulCount = 1;
}
else {
// if( 0u == *pulCount )
if (*pulCount < 1) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
pxSlotList[0] = (CK_ULONG)pkcs11SLOT_ID;
*pulCount = 1;
}
}
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_CopyObject)
(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phNewObject)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_Decrypt)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedData,
CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDataLen)
{
CK_RV xResult = CKR_OK;
// return CKR_ARGUMENTS_BAD;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSessionObj = prvSessionPointerFromHandle(hSession);
if (!pEncryptedData) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_ARGUMENTS_BAD;
}
// sss_status_t status;
// sss_asymmetric_t asymmCtx;
sss_algorithm_t algorithm = kAlgorithm_None;
// sss_algorithm_t digest_algorithm = kAlgorithm_None;
xResult = ParseEncryptionMechanism(pxSessionObj, &algorithm);
// printf("\nEncrypt Mechanism = %08x\n", pxSessionObj->xOperationInProgress);
if (xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
if (algorithm == kAlgorithm_None) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_MECHANISM_INVALID;
}
if ((algorithm == kAlgorithm_SSS_RSAES_PKCS1_V1_5) || (algorithm == kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA1)) {
/*RSA Encryption*/
xResult = AsymmetricDecrypt(pxSessionObj, algorithm, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
}
else {
/*Symmetric Encryption*/
xResult = SymmetricDecrypt(pxSessionObj, algorithm, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
}
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_DecryptFinal)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_DecryptInit)
(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(hSession);
if (NULL == pMechanism) {
xResult = CKR_ARGUMENTS_BAD;
}
else if (pxSession->xOperationInProgress != pkcs11NO_OPERATION) {
xResult = CKR_SESSION_HANDLE_INVALID;
}
else {
pxSession->xOperationInProgress = pMechanism->mechanism;
pxSession->xOperationKeyHandle = hKey;
if (pMechanism->pParameter) {
pxSession->mechParameter = pMechanism->pParameter;
pxSession->mechParameterLen = pMechanism->ulParameterLen;
}
else {
pxSession->mechParameterLen = 0;
}
}
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_DecryptUpdate)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_DeriveKey)
(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hBaseKey,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulAttributeCount,
CK_OBJECT_HANDLE_PTR phKey)
{
// printf("\n\n%s\n\n", __FUNCTION__);
CK_RV xResult = CKR_FUNCTION_NOT_SUPPORTED;
#if SSS_HAVE_APPLET_SE05X_IOT
uint32_t keyId = (uint32_t)hBaseKey;
sss_se05x_session_t *se05x_session = (sss_se05x_session_t *)&pex_sss_demo_boot_ctx->session;
sss_algorithm_t algorithm = kAlgorithm_SSS_ECDH;
sss_mode_t mode = kMode_SSS_ComputeSharedSecret;
sss_object_t privKeyObj = {0};
sss_object_t pubKeyObj = {0};
sss_object_t derivedObject = {0};
sss_status_t sss_status = kStatus_SSS_Fail;
uint16_t keySize = 0;
uint8_t tag = 0x00;
uint8_t publicKeyBuffer[160] = {0};
size_t publicKeyBufferLen = sizeof(publicKeyBuffer);
uint8_t ecKeyParameters[30] = {0};
size_t ecKeyParametersLen = sizeof(ecKeyParameters);
uint8_t id_ecPublicKey[] = ID_ECPUBLICKEY;
CK_ULONG attributeIndex = 0;
uint32_t derivedKeyId = 0;
size_t derivedKeyLen = 0;
sss_derive_key_t ctx_derive_key = {0};
CK_MECHANISM_TYPE mechType = pMechanism->mechanism;
if (mechType != CKM_ECDH1_DERIVE) {
/*
* We support ECDH and HKDF mechanisms for key derivation.
* As per PKCS#11 v2.40, HKDF mechanism is not supported by
* PKCS#11. CKM_HKDF_DERIVE is added in PKCS#11 v3.0
*/
return CKR_MECHANISM_INVALID;
}
if (mechType == CKM_ECDH1_DERIVE) {
if (!pMechanism->ulParameterLen) {
return CKR_ARGUMENTS_BAD;
}
if (!pMechanism->pParameter) {
return CKR_ARGUMENTS_BAD;
}
CK_ECDH1_DERIVE_PARAMS_PTR p_ecdh1Params = (CK_ECDH1_DERIVE_PARAMS_PTR)pMechanism->pParameter;
if (!p_ecdh1Params->ulPublicDataLen || !p_ecdh1Params->pPublicData) {
return CKR_ARGUMENTS_BAD;
}
if ((p_ecdh1Params->kdf != CKD_SHA1_KDF) && (p_ecdh1Params->kdf != CKD_SHA224_KDF) &&
(p_ecdh1Params->kdf != CKD_SHA256_KDF) && (p_ecdh1Params->kdf != CKD_SHA384_KDF) &&
(p_ecdh1Params->kdf != CKD_SHA512_KDF) && (p_ecdh1Params->kdf != CKD_NULL)) {
return CKR_ARGUMENTS_BAD;
}
if (!CheckIfKeyIdExists(keyId, &se05x_session->s_ctx)) {
return CKR_KEY_HANDLE_INVALID;
}
if ((GetAttributeParameterIndex(pTemplate, ulAttributeCount, CKA_CLASS, &attributeIndex) != CKR_OK) ||
(*((CK_OBJECT_CLASS_PTR)pTemplate[attributeIndex].pValue) != CKO_SECRET_KEY)) {
return CKR_ARGUMENTS_BAD;
}
if ((GetAttributeParameterIndex(pTemplate, ulAttributeCount, CKA_KEY_TYPE, &attributeIndex) != CKR_OK) ||
(*((CK_KEY_TYPE *)pTemplate[attributeIndex].pValue) != CKK_AES)) {
return CKR_ARGUMENTS_BAD;
}
if ((GetAttributeParameterIndex(pTemplate, ulAttributeCount, CKA_VALUE_LEN, &attributeIndex) != CKR_OK) ||
((*((size_t *)pTemplate[attributeIndex].pValue) != 16) &&
(*((size_t *)pTemplate[attributeIndex].pValue) != 24) &&
(*((size_t *)pTemplate[attributeIndex].pValue) != 32))) {
return CKR_ARGUMENTS_BAD;
}
derivedKeyLen = *((size_t *)pTemplate[attributeIndex].pValue);
if (GetAttributeParameterIndex(pTemplate, ulAttributeCount, CKA_LABEL, &attributeIndex) != CKR_OK) {
/* Label not passed. Create random keyID */
xResult = LabelToKeyId((unsigned char *)"", 0, &derivedKeyId);
}
else {
xResult =
LabelToKeyId(pTemplate[attributeIndex].pValue, pTemplate[attributeIndex].ulValueLen, &derivedKeyId);
}
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_key_object_init(&privKeyObj, &pex_sss_demo_boot_ctx->ks);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_key_object_get_handle(&privKeyObj, keyId);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
xResult = read_object_size(keyId, &keySize);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(xResult == CKR_OK);
// ENSURE_OR_GO_EXIT(xResult == CKR_OK);
UNLOCK_MUTEX_FOR_RTOS
}
if (privKeyObj.cipherType != kSSS_CipherType_EC_NIST_P) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
/* Create complete key */
tag = ASN_TAG_OBJ_IDF;
if (keySize == 24) {
xResult = SetASNTLV(tag,
(uint8_t *)MBEDTLS_OID_EC_GRP_SECP192R1,
sizeof(MBEDTLS_OID_EC_GRP_SECP192R1) - 1,
ecKeyParameters,
&ecKeyParametersLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
}
else if (keySize == 28) {
xResult = SetASNTLV(tag,
(uint8_t *)MBEDTLS_OID_EC_GRP_SECP224R1,
sizeof(MBEDTLS_OID_EC_GRP_SECP224R1) - 1,
ecKeyParameters,
&ecKeyParametersLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
}
else if (keySize == 32) {
xResult = SetASNTLV(tag,
(uint8_t *)MBEDTLS_OID_EC_GRP_SECP256R1,
sizeof(MBEDTLS_OID_EC_GRP_SECP256R1) - 1,
ecKeyParameters,
&ecKeyParametersLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
}
else if (keySize == 48) {
xResult = SetASNTLV(tag,
(uint8_t *)MBEDTLS_OID_EC_GRP_SECP384R1,
sizeof(MBEDTLS_OID_EC_GRP_SECP384R1) - 1,
ecKeyParameters,
&ecKeyParametersLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
}
else if (keySize == 65 || keySize == 66) {
xResult = SetASNTLV(tag,
(uint8_t *)MBEDTLS_OID_EC_GRP_SECP521R1,
sizeof(MBEDTLS_OID_EC_GRP_SECP521R1) - 1,
ecKeyParameters,
&ecKeyParametersLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
}
else {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
xResult = SetASNTLV(tag, id_ecPublicKey, sizeof(id_ecPublicKey), ecKeyParameters, &ecKeyParametersLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
uint8_t ecPoint[70] = {0};
uint8_t *p_ecPoint = &ecPoint[0];
int i = 0;
if (p_ecdh1Params->pPublicData[i++] != ASN_TAG_OCTETSTRING) {
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
size_t len = p_ecdh1Params->pPublicData[i++];
if ((len & 0x80) == 0x80) {
if ((len & 0x7F) == 0x01) {
len = p_ecdh1Params->pPublicData[i++];
}
else if ((len & 0x7F) == 0x02) {
len = (p_ecdh1Params->pPublicData[i] << 8) | (p_ecdh1Params->pPublicData[i + 1]);
i = i + 2;
}
else {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
}
if (p_ecdh1Params->pPublicData[i] != 0x00) {
p_ecPoint++;
memcpy(p_ecPoint, &p_ecdh1Params->pPublicData[i], len);
len++;
}
else {
memcpy(p_ecPoint, &p_ecdh1Params->pPublicData[i], len);
}
tag = ASN_TAG_BITSTRING;
xResult = SetASNTLV(tag, &ecPoint[0], len, publicKeyBuffer, &publicKeyBufferLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
tag = ASN_TAG_SEQUENCE;
xResult = SetASNTLV(tag,
&ecKeyParameters[ecKeyParametersLen],
sizeof(ecKeyParameters) - ecKeyParametersLen,
publicKeyBuffer,
&publicKeyBufferLen);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
len = sizeof(publicKeyBuffer) - publicKeyBufferLen;
if (len <= 127) {
if (publicKeyBufferLen < 1) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
publicKeyBufferLen = publicKeyBufferLen - 1;
publicKeyBuffer[publicKeyBufferLen] = len;
}
else if (len <= 255) {
if (publicKeyBufferLen < 2) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
publicKeyBufferLen = publicKeyBufferLen - 2;
publicKeyBuffer[publicKeyBufferLen] = 0x81;
publicKeyBuffer[publicKeyBufferLen + 1] = len;
}
else {
if (publicKeyBufferLen < 3) {
xResult = CKR_FUNCTION_FAILED;
goto exit;
}
publicKeyBufferLen = publicKeyBufferLen - 3;
publicKeyBuffer[publicKeyBufferLen] = 0x82;
publicKeyBuffer[publicKeyBufferLen + 1] = (len & 0x00FF00) >> 8;
publicKeyBuffer[publicKeyBufferLen + 2] = (len & 0x00FF);
}
if (publicKeyBufferLen < 1) {
return CKR_ARGUMENTS_BAD;
}
publicKeyBufferLen = publicKeyBufferLen - 1;
publicKeyBuffer[publicKeyBufferLen] = ASN_TAG_SEQUENCE;
/*
* key = &publicKeyBuffer[publicKeyBufferLen]
* size = sizeof(publicKeyBuffer) - publicKeyBufferLen
*/
/* Import the public key now */
uint32_t publicKeyId = 0;
xResult = LabelToKeyId((unsigned char *)"", 0, &publicKeyId);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
xResult = CKR_FUNCTION_FAILED;
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_key_object_init(&pubKeyObj, &pex_sss_demo_boot_ctx->ks);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_key_object_allocate_handle(&pubKeyObj,
publicKeyId,
kSSS_KeyPart_Public,
privKeyObj.cipherType,
keySize * 8,
kKeyObject_Mode_Persistent);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_key_store_set_key(&pex_sss_demo_boot_ctx->ks,
&pubKeyObj,
&publicKeyBuffer[publicKeyBufferLen],
sizeof(publicKeyBuffer) - publicKeyBufferLen,
keySize * 8,
NULL,
0);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
UNLOCK_MUTEX_FOR_RTOS
}
/* Start process for derivation now */
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_key_object_init(&derivedObject, &pex_sss_demo_boot_ctx->host_ks);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_key_object_allocate_handle(&derivedObject,
derivedKeyId,
kSSS_KeyPart_Default,
kSSS_CipherType_AES,
derivedKeyLen * 8,
kKeyObject_Mode_Persistent);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_derive_key_context_init(
&ctx_derive_key, &pex_sss_demo_boot_ctx->session, &privKeyObj, algorithm, mode);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_derive_key_dh(&ctx_derive_key, &pubKeyObj, &derivedObject);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
uint8_t derivedKey[32] = {0};
size_t derivedKeySize = sizeof(derivedKey);
size_t derivedKeyBitLen = derivedKeyLen * 8;
sss_status = sss_key_store_get_key(
&pex_sss_demo_boot_ctx->host_ks, &derivedObject, derivedKey, &derivedKeySize, &derivedKeyBitLen);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_key_object_init(&derivedObject, &pex_sss_demo_boot_ctx->ks);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_key_object_allocate_handle(&derivedObject,
derivedKeyId,
kSSS_KeyPart_Default,
kSSS_CipherType_AES,
derivedKeyLen * 8,
kKeyObject_Mode_Persistent);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
sss_status = sss_key_store_set_key(
&pex_sss_demo_boot_ctx->ks, &derivedObject, derivedKey, derivedKeySize, derivedKeyBitLen, NULL, 0);
UNLOCK_MUTEX_FOR_RTOS_EXIT_ON_FAIL(sss_status == kStatus_SSS_Success);
// ENSURE_OR_GO_EXIT(sss_status == kStatus_SSS_Success);
UNLOCK_MUTEX_FOR_RTOS
}
xResult = CKR_OK;
*phKey = derivedKeyId;
}
exit:
if (pubKeyObj.keyStore) {
LOCK_MUTEX_FOR_RTOS
{
sss_key_store_erase_key(pubKeyObj.keyStore, &pubKeyObj);
UNLOCK_MUTEX_FOR_RTOS
}
}
#endif
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_Digest)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
if (!pData) {
return CKR_ARGUMENTS_BAD;
}
P11SessionPtr_t pxSessionObj = prvSessionPointerFromHandle(hSession);
sss_algorithm_t algorithm;
xResult = ParseDigestMechanism(pxSessionObj, &algorithm);
if (xResult != CKR_OK) {
return xResult;
}
#if SSS_HAVE_ALT_SSS
uint8_t *input = (uint8_t *)SSS_MALLOC(ulDataLen * sizeof(uint8_t));
memset(input, 0, (ulDataLen * sizeof(uint8_t)));
sss_status_t status = kStatus_SSS_Fail;
uint8_t output[64] = {0};
size_t inputLen = ulDataLen;
size_t outputLen = sizeof(output);
LOCK_MUTEX_FOR_RTOS
{
if (pxSessionObj->digestUpdateCalled == CK_TRUE) {
xResult = CKR_FUNCTION_FAILED;
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS
goto cleanup;
}
switch (pxSessionObj->xOperationInProgress) {
case CKM_SHA_1:
outputLen = 20;
break;
case CKM_SHA224:
outputLen = 28;
break;
case CKM_SHA256:
outputLen = 32;
break;
case CKM_SHA384:
outputLen = 48;
break;
case CKM_SHA512:
outputLen = 64;
break;
default:
xResult = CKR_FUNCTION_FAILED;
break;
}
if (xResult == CKR_FUNCTION_FAILED) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
UNLOCK_MUTEX_FOR_RTOS
goto cleanup;
}
if (pDigest) {
if (*pulDigestLen < outputLen) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
memcpy(input, pData, inputLen);
status = sss_digest_update(&pxSessionObj->digest_ctx, input, inputLen);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
xResult = CKR_DEVICE_ERROR;
UNLOCK_MUTEX_FOR_RTOS
goto cleanup;
}
status = sss_digest_finish(&pxSessionObj->digest_ctx, &output[0], &outputLen);
if (status != kStatus_SSS_Success) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
xResult = CKR_DEVICE_ERROR;
UNLOCK_MUTEX_FOR_RTOS
goto cleanup;
}
memcpy(pDigest, &output[0], outputLen);
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
}
}
*pulDigestLen = outputLen;
UNLOCK_MUTEX_FOR_RTOS
}
cleanup:
if (input) {
SSS_FREE(input);
}
#endif
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_DigestKey)
(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_Encrypt)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pEncryptedData,
CK_ULONG_PTR pulEncryptedDataLen)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSessionObj = prvSessionPointerFromHandle(hSession);
if (!pData) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_ARGUMENTS_BAD;
}
// sss_status_t status;
sss_algorithm_t algorithm = kAlgorithm_None;
xResult = ParseEncryptionMechanism(pxSessionObj, &algorithm);
// printf("\nEncrypt Mechanism = %08x\n", pxSessionObj->xOperationInProgress);
if (xResult != CKR_OK) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return xResult;
}
if (algorithm == kAlgorithm_None) {
pxSessionObj->xOperationInProgress = pkcs11NO_OPERATION;
return CKR_MECHANISM_INVALID;
}
if ((algorithm == kAlgorithm_SSS_RSAES_PKCS1_V1_5) || (algorithm == kAlgorithm_SSS_RSAES_PKCS1_OAEP_SHA1)) {
/*RSA Encryption*/
xResult = AsymmetricEncrypt(pxSessionObj, algorithm, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen);
}
else {
/*Symmetric Encryption*/
xResult = SymmetricEncrypt(pxSessionObj, algorithm, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen);
}
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_EncryptFinal)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_EncryptInit)
(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
CK_RV xResult = CKR_OK;
// printf("\n\n%s\n\n", __FUNCTION__);
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(hSession);
if (NULL == pMechanism) {
xResult = CKR_ARGUMENTS_BAD;
}
else if (pxSession->xOperationInProgress != pkcs11NO_OPERATION) {
xResult = CKR_SESSION_HANDLE_INVALID;
}
else {
pxSession->xOperationInProgress = pMechanism->mechanism;
pxSession->xOperationKeyHandle = hKey;
if (pMechanism->pParameter) {
pxSession->mechParameter = pMechanism->pParameter;
pxSession->mechParameterLen = pMechanism->ulParameterLen;
}
else {
pxSession->mechParameterLen = 0;
}
}
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_EncryptUpdate)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_GenerateKey)
(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phKey)
{
// printf("\n\n%s\n\n", __FUNCTION__);
/*
Attribute.CLASS: ObjectClass.SECRET_KEY,
Attribute.ID: id or b'',
Attribute.LABEL: label or '',
Attribute.TOKEN: store,
Attribute.PRIVATE: True,
Attribute.SENSITIVE: True,
Attribute.ENCRYPT: MechanismFlag.ENCRYPT & capabilities,
Attribute.DECRYPT: MechanismFlag.DECRYPT & capabilities,
Attribute.WRAP: MechanismFlag.WRAP & capabilities,
Attribute.UNWRAP: MechanismFlag.UNWRAP & capabilities,
Attribute.SIGN: MechanismFlag.SIGN & capabilities,
Attribute.VERIFY: MechanismFlag.VERIFY & capabilities,
Attribute.DERIVE: MechanismFlag.DERIVE & capabilities,
template_[Attribute.VALUE_LEN] = key_length // 8 # In bytes
*/
CK_RV xResult = CKR_FUNCTION_NOT_SUPPORTED;
#if SSS_HAVE_ALT_SSS
sss_status_t sss_status = kStatus_SSS_Fail;
sss_rng_context_t sss_rng_ctx;
uint32_t keyId = 0x0;
size_t keyLen = 0;
sss_cipher_type_t cipherType = kSSS_CipherType_NONE;
CK_ULONG attributeIndex = 0;
CK_OBJECT_CLASS ck_object = pkcs11INVALID_OBJECT_CLASS;
// LOG_I("Mechanism = %zu", *pMechanism);
CK_MECHANISM mech = *pMechanism;
xResult = GetAttributeParameterIndex(pTemplate, ulCount, CKA_CLASS, &attributeIndex);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
/* Ensure that CK_OBJECT_CLASS is CKO_SECRET_KEY */
ck_object = *((CK_OBJECT_CLASS_PTR)pTemplate[attributeIndex].pValue);
ENSURE_OR_GO_EXIT(ck_object == CKO_SECRET_KEY);
if (mech.mechanism == CKM_AES_KEY_GEN) {
xResult = GetAttributeParameterIndex(pTemplate, ulCount, CKA_VALUE_LEN, &attributeIndex);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
keyLen = *((size_t *)pTemplate[attributeIndex].pValue);
if ((keyLen != 16) && (keyLen != 24) && (keyLen != 32)) {
LOG_E("Unsupported key length %d", keyLen);
xResult = CKR_ARGUMENTS_BAD;
goto exit;
}
cipherType = kSSS_CipherType_AES;
}
else if (mech.mechanism == CKM_DES2_KEY_GEN) {
keyLen = 16; /* Fixed length for DES key */
cipherType = kSSS_CipherType_DES;
}
else if (mech.mechanism == CKM_DES3_KEY_GEN) {
keyLen = 24; /* Fixed length for DES key */
cipherType = kSSS_CipherType_DES;
}
xResult = GetAttributeParameterIndex(pTemplate, ulCount, CKA_LABEL, &attributeIndex);
if (xResult != CKR_OK) {
/* CKA_LABEL was not provided. Generate a random keyId */
xResult = LabelToKeyId((unsigned char *)"", 0, &keyId);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
}
else {
xResult = LabelToKeyId(pTemplate[attributeIndex].pValue, pTemplate[attributeIndex].ulValueLen, &keyId);
ENSURE_OR_GO_EXIT(xResult == CKR_OK);
}
xResult = CKR_DEVICE_ERROR;
/* Generate random data */
uint8_t randomKey[64] = {0};
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_rng_context_init(&sss_rng_ctx, &pex_sss_demo_boot_ctx->session);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS
goto exit;
}
sss_status = sss_rng_get_random(&sss_rng_ctx, randomKey, keyLen);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS
goto exit;
}
UNLOCK_MUTEX_FOR_RTOS
}
/* Import secret key */
sss_object_t sss_object = {0};
sss_status = sss_create_token(&pex_sss_demo_boot_ctx->ks,
&sss_object,
keyId,
kSSS_KeyPart_Default,
cipherType,
randomKey,
keyLen,
keyLen * 8);
if (sss_status == kStatus_SSS_Success) {
xResult = CKR_OK;
*phKey = keyId;
LOG_I("Generated KeyID = %d", keyId);
}
exit:
#endif
return xResult;
// return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_GenerateKeyPair)
(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_ATTRIBUTE_PTR pPublicKeyTemplate,
CK_ULONG ulPublicKeyAttributeCount,
CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
CK_ULONG ulPrivateKeyAttributeCount,
CK_OBJECT_HANDLE_PTR phPublicKey,
CK_OBJECT_HANDLE_PTR phPrivateKey)
{
// printf("\n\n%s\n\n", __FUNCTION__);
CK_RV xResult = CKR_OK;
P11SessionPtr_t pxSession = prvSessionPointerFromHandle(hSession);
size_t KeyBitLen = 0;
CK_ULONG privateLabelIndex = 0;
CK_ULONG publicLabelIndex = 0;
uint32_t privKeyId = 0;
uint32_t pubKeyId = 0;
sss_status_t sss_status = kStatus_SSS_Fail;
sss_object_t sss_object = {0};
CK_BBOOL skipPublicKey = CK_FALSE;
CK_BBOOL privLabelExists = CK_FALSE;
if (pxSession == NULL) {
xResult = CKR_SESSION_HANDLE_INVALID;
return xResult;
}
if (!pMechanism) {
return CKR_ARGUMENTS_BAD;
}
sss_cipher_type_t cipherType = kSSS_CipherType_Binary;
switch (pMechanism->mechanism) {
// case CKM_ECDSA_KEY_PAIR_GEN:
case CKM_EC_KEY_PAIR_GEN:
cipherType = kSSS_CipherType_EC_NIST_P;
break;
case CKM_RSA_PKCS_KEY_PAIR_GEN:
cipherType = kSSS_CipherType_RSA;
break;
default:
return CKR_MECHANISM_INVALID;
}
if (cipherType == kSSS_CipherType_EC_NIST_P) {
CK_ULONG ec_params_index = 0;
xResult =
GetAttributeParameterIndex(pPublicKeyTemplate, ulPublicKeyAttributeCount, CKA_EC_PARAMS, &ec_params_index);
if (xResult != CKR_OK) {
return xResult;
}
uint8_t ec_params[40] = {""};
memcpy(ec_params, pPublicKeyTemplate[ec_params_index].pValue, pPublicKeyTemplate[ec_params_index].ulValueLen);
uint8_t tag = ASN_TAG_OBJ_IDF;
uint8_t oid[20] = {0};
size_t oidLen = sizeof(oid);
xResult = SetASNTLV(
tag, (uint8_t *)MBEDTLS_OID_EC_GRP_SECP192R1, sizeof(MBEDTLS_OID_EC_GRP_SECP192R1) - 1, oid, &oidLen);
if (xResult != CKR_OK) {
return xResult;
}
if (memcmp(&oid[oidLen], &ec_params[0], sizeof(oid) - oidLen) == 0) {
KeyBitLen = 192;
goto cont;
}
oidLen = sizeof(oid);
xResult = SetASNTLV(
tag, (uint8_t *)MBEDTLS_OID_EC_GRP_SECP224R1, sizeof(MBEDTLS_OID_EC_GRP_SECP224R1) - 1, oid, &oidLen);
if (xResult != CKR_OK) {
return xResult;
}
if (memcmp(&oid[oidLen], &ec_params[0], sizeof(oid) - oidLen) == 0) {
KeyBitLen = 224;
goto cont;
}
oidLen = sizeof(oid);
xResult = SetASNTLV(
tag, (uint8_t *)MBEDTLS_OID_EC_GRP_SECP256R1, sizeof(MBEDTLS_OID_EC_GRP_SECP256R1) - 1, oid, &oidLen);
if (xResult != CKR_OK) {
return xResult;
}
if (memcmp(&oid[oidLen], &ec_params[0], sizeof(oid) - oidLen) == 0) {
KeyBitLen = 256;
goto cont;
}
oidLen = sizeof(oid);
xResult = SetASNTLV(
tag, (uint8_t *)MBEDTLS_OID_EC_GRP_SECP384R1, sizeof(MBEDTLS_OID_EC_GRP_SECP384R1) - 1, oid, &oidLen);
if (xResult != CKR_OK) {
return xResult;
}
if (memcmp(&oid[oidLen], &ec_params[0], sizeof(oid) - oidLen) == 0) {
KeyBitLen = 384;
goto cont;
}
oidLen = sizeof(oid);
xResult = SetASNTLV(
tag, (uint8_t *)MBEDTLS_OID_EC_GRP_SECP521R1, sizeof(MBEDTLS_OID_EC_GRP_SECP521R1) - 1, oid, &oidLen);
if (xResult != CKR_OK) {
return xResult;
}
if (memcmp(&oid[oidLen], &ec_params[0], sizeof(oid) - oidLen) == 0) {
KeyBitLen = 521;
goto cont;
}
return CKR_ARGUMENTS_BAD;
}
else if (cipherType == kSSS_CipherType_RSA) {
CK_ULONG rsa_params_index = 0;
xResult = GetAttributeParameterIndex(
pPublicKeyTemplate, ulPublicKeyAttributeCount, CKA_MODULUS_BITS, &rsa_params_index);
if (xResult != CKR_OK) {
return xResult;
}
CK_ULONG modulusBits = 0;
memcpy(
&modulusBits, pPublicKeyTemplate[rsa_params_index].pValue, pPublicKeyTemplate[rsa_params_index].ulValueLen);
KeyBitLen = (size_t)modulusBits;
if ((KeyBitLen != 1024) && (KeyBitLen != 2048) && (KeyBitLen != 3072) && (KeyBitLen != 4096)) {
return CKR_ARGUMENTS_BAD;
}
}
cont:
xResult =
GetAttributeParameterIndex(pPrivateKeyTemplate, ulPrivateKeyAttributeCount, CKA_LABEL, &privateLabelIndex);
if (xResult != CKR_OK) {
/* CKA_LABEL was not provided. Generate a random keyId */
xResult = LabelToKeyId((unsigned char *)"", 0, &privKeyId);
if (xResult != CKR_OK) {
return xResult;
}
}
else {
privLabelExists = CK_TRUE;
xResult = LabelToKeyId(pPrivateKeyTemplate[privateLabelIndex].pValue,
pPrivateKeyTemplate[privateLabelIndex].ulValueLen,
&privKeyId);
if (xResult != CKR_OK) {
return xResult;
}
}
xResult = GetAttributeParameterIndex(pPublicKeyTemplate, ulPublicKeyAttributeCount, CKA_LABEL, &publicLabelIndex);
if (xResult != CKR_OK) {
/* CKA_LABEL was not provided. Generate a random keyId */
xResult = LabelToKeyId((unsigned char *)"", 0, &pubKeyId);
if (xResult != CKR_OK) {
return xResult;
}
}
else {
if (privLabelExists) {
if (pPrivateKeyTemplate[privateLabelIndex].ulValueLen == pPublicKeyTemplate[publicLabelIndex].ulValueLen &&
pPrivateKeyTemplate[privateLabelIndex].ulValueLen != 0) {
if (strncmp((const char *)pPrivateKeyTemplate[privateLabelIndex].pValue,
(const char *)pPublicKeyTemplate[publicLabelIndex].pValue,
(size_t)pPrivateKeyTemplate[privateLabelIndex].ulValueLen) == 0) {
skipPublicKey = CK_TRUE;
}
}
}
xResult = LabelToKeyId(
pPublicKeyTemplate[publicLabelIndex].pValue, pPublicKeyTemplate[publicLabelIndex].ulValueLen, &pubKeyId);
if (xResult != CKR_OK) {
return xResult;
}
}
LOCK_MUTEX_FOR_RTOS
{
sss_status = sss_key_object_init(&sss_object, &pex_sss_demo_boot_ctx->ks);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
sss_status = sss_key_object_allocate_handle(
&sss_object, privKeyId, kSSS_KeyPart_Pair, cipherType, KeyBitLen * 8, kKeyObject_Mode_Persistent);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
sss_status = sss_key_store_generate_key(&pex_sss_demo_boot_ctx->ks, &sss_object, KeyBitLen, NULL);
if (sss_status != kStatus_SSS_Success) {
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
if (!skipPublicKey) {
uint8_t public[2048] = {0};
size_t public_len = sizeof(public);
sss_status =
sss_key_store_get_key(&pex_sss_demo_boot_ctx->ks, &sss_object, public, &public_len, &KeyBitLen);
if (sss_status != kStatus_SSS_Success) {
sss_status = sss_key_store_erase_key(&pex_sss_demo_boot_ctx->ks, &sss_object);
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
sss_object_t sss_pub_object = {0};
sss_status = sss_key_object_init(&sss_pub_object, &pex_sss_demo_boot_ctx->ks);
if (sss_status != kStatus_SSS_Success) {
sss_status = sss_key_store_erase_key(&pex_sss_demo_boot_ctx->ks, &sss_object);
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
sss_status = sss_key_object_allocate_handle(
&sss_pub_object, pubKeyId, kSSS_KeyPart_Public, cipherType, KeyBitLen * 8, kKeyObject_Mode_Persistent);
if (sss_status != kStatus_SSS_Success) {
sss_status = sss_key_store_erase_key(&pex_sss_demo_boot_ctx->ks, &sss_object);
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
sss_status = sss_key_store_set_key(
&pex_sss_demo_boot_ctx->ks, &sss_pub_object, public, public_len, KeyBitLen, NULL, 0);
if (sss_status != kStatus_SSS_Success) {
sss_status = sss_key_store_erase_key(&pex_sss_demo_boot_ctx->ks, &sss_object);
UNLOCK_MUTEX_FOR_RTOS_RET(CKR_FUNCTION_FAILED)
}
}
else {
pubKeyId = privKeyId;
}
UNLOCK_MUTEX_FOR_RTOS
}
*phPublicKey = pubKeyId;
*phPrivateKey = privKeyId;
return CKR_OK;
// return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(CK_INFO_PTR pInfo)
{
// printf("\n\n%s\n\n", __FUNCTION__);
/*typedef struct CK_INFO {
// manufacturerID and libraryDecription have been changed from
// CK_CHAR to CK_UTF8CHAR for v2.10
CK_VERSION cryptokiVersion; // Cryptoki interface ver
CK_UTF8CHAR manufacturerID[32]; // blank padded
CK_FLAGS flags; // must be zero
CK_UTF8CHAR libraryDescription[32]; // blank padded
CK_VERSION libraryVersion; // version of library
} CK_INFO;
*/
if (!pInfo) {
LOG_E("Null pointer");
return CKR_ARGUMENTS_BAD;
}
pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
memset(&pInfo->manufacturerID[0], ' ', sizeof(pInfo->manufacturerID));
memset(&pInfo->libraryDescription[0], ' ', sizeof(pInfo->libraryDescription));
pInfo->flags = 0;
// { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
return CKR_OK;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)
(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo)
{
// printf("\n\n%s\n\n", __FUNCTION__);
// /* CK_MECHANISM_INFO provides information about a particular
// * mechanism */
// typedef struct CK_MECHANISM_INFO {
// CK_ULONG ulMinKeySize;
// CK_ULONG ulMaxKeySize;
// CK_FLAGS flags;
// } CK_MECHANISM_INFO;
// /* The flags are defined as follows:
// * Bit Flag Mask Meaning */
// #define CKF_HW 0x00000001UL /* performed by HW */
// /* Specify whether or not a mechanism can be used for a particular task */
// #define CKF_ENCRYPT 0x00000100UL
// #define CKF_DECRYPT 0x00000200UL
// #define CKF_DIGEST 0x00000400UL
// #define CKF_SIGN 0x00000800UL
//// #define CKF_SIGN_RECOVER 0x00001000UL
// #define CKF_VERIFY 0x00002000UL
//// #define CKF_VERIFY_RECOVER 0x00004000UL
// #define CKF_GENERATE 0x00008000UL
// #define CKF_GENERATE_KEY_PAIR 0x00010000UL
//// #define CKF_WRAP 0x00020000UL
//// #define CKF_UNWRAP 0x00040000UL
//// #define CKF_DERIVE 0x00080000UL
CK_RV xResult = CKR_MECHANISM_INVALID;
CK_MECHANISM_INFO mech_info = {.ulMinKeySize = 0, .ulMaxKeySize = 0, .flags = CKF_HW};
if (type == CKM_RSA_PKCS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA1_RSA_PKCS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA224_RSA_PKCS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA256_RSA_PKCS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA384_RSA_PKCS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA512_RSA_PKCS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_RSA_PKCS_PSS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA1_RSA_PKCS_PSS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA224_RSA_PKCS_PSS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA256_RSA_PKCS_PSS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA384_RSA_PKCS_PSS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_SHA512_RSA_PKCS_PSS) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_RSA_PKCS_OAEP) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_ENCRYPT | CKF_DECRYPT;
xResult = CKR_OK;
}
else if (type == CKM_AES_ECB) {
mech_info.ulMinKeySize = 128;
mech_info.ulMaxKeySize = 256;
mech_info.flags = mech_info.flags | CKF_ENCRYPT | CKF_DECRYPT;
xResult = CKR_OK;
}
else if (type == CKM_AES_CBC) {
mech_info.ulMinKeySize = 128;
mech_info.ulMaxKeySize = 256;
mech_info.flags = mech_info.flags | CKF_ENCRYPT | CKF_DECRYPT;
xResult = CKR_OK;
}
else if (type == CKM_AES_CTR) {
mech_info.ulMinKeySize = 128;
mech_info.ulMaxKeySize = 256;
mech_info.flags = mech_info.flags | CKF_ENCRYPT | CKF_DECRYPT;
xResult = CKR_OK;
}
else if (type == CKM_SHA_1) {
mech_info.ulMinKeySize = 0;
mech_info.ulMaxKeySize = 0;
mech_info.flags = mech_info.flags | CKF_DIGEST;
xResult = CKR_OK;
}
else if (type == CKM_SHA224) {
mech_info.ulMinKeySize = 0;
mech_info.ulMaxKeySize = 0;
mech_info.flags = mech_info.flags | CKF_DIGEST;
xResult = CKR_OK;
}
else if (type == CKM_SHA256) {
mech_info.ulMinKeySize = 0;
mech_info.ulMaxKeySize = 0;
mech_info.flags = mech_info.flags | CKF_DIGEST;
xResult = CKR_OK;
}
else if (type == CKM_SHA384) {
mech_info.ulMinKeySize = 0;
mech_info.ulMaxKeySize = 0;
mech_info.flags = mech_info.flags | CKF_DIGEST;
xResult = CKR_OK;
}
else if (type == CKM_SHA512) {
mech_info.ulMinKeySize = 0;
mech_info.ulMaxKeySize = 0;
mech_info.flags = mech_info.flags | CKF_DIGEST;
xResult = CKR_OK;
}
else if (type == CKM_ECDSA) {
mech_info.ulMinKeySize = 192;
mech_info.ulMaxKeySize = 521;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_ECDSA_SHA1) {
mech_info.ulMinKeySize = 192;
mech_info.ulMaxKeySize = 521;
mech_info.flags = mech_info.flags | CKF_SIGN | CKF_VERIFY;
xResult = CKR_OK;
}
else if (type == CKM_EC_KEY_PAIR_GEN) {
mech_info.ulMinKeySize = 192;
mech_info.ulMaxKeySize = 521;
mech_info.flags = mech_info.flags | CKF_GENERATE_KEY_PAIR | CKF_EC_NAMEDCURVE;
xResult = CKR_OK;
}
else if (type == CKM_RSA_PKCS_KEY_PAIR_GEN) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_GENERATE_KEY_PAIR;
xResult = CKR_OK;
}
else if (type == CKM_AES_KEY_GEN) {
mech_info.ulMinKeySize = 128;
mech_info.ulMaxKeySize = 256;
mech_info.flags = mech_info.flags | CKF_GENERATE;
xResult = CKR_OK;
}
else if (type == CKM_DES2_KEY_GEN) {
mech_info.ulMinKeySize = 128;
mech_info.ulMaxKeySize = 128;
mech_info.flags = mech_info.flags | CKF_GENERATE;
xResult = CKR_OK;
}
else if (type == CKM_ECDH1_DERIVE) {
mech_info.ulMinKeySize = 128;
mech_info.ulMaxKeySize = 256;
mech_info.flags = mech_info.flags | CKF_DERIVE;
xResult = CKR_OK;
}
else if (type == CKM_RSA_X_509) {
mech_info.ulMinKeySize = 1024;
mech_info.ulMaxKeySize = 4096;
mech_info.flags = mech_info.flags | CKF_VERIFY;
xResult = CKR_OK;
}
if (xResult == CKR_OK) {
memcpy(pInfo, &mech_info, sizeof(CK_MECHANISM_INFO));
}
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismList)
(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount)
{
// printf("\n\n%s\n\n", __FUNCTION__);
CK_RV xResult = CKR_OK;
if (!pulCount) {
return CKR_ARGUMENTS_BAD;
}
CK_MECHANISM_TYPE mechanisms[] = {/* RSA Algorithms */
CKM_RSA_PKCS,
CKM_SHA1_RSA_PKCS,
CKM_SHA224_RSA_PKCS,
CKM_SHA256_RSA_PKCS,
CKM_SHA384_RSA_PKCS,
CKM_SHA512_RSA_PKCS,
CKM_RSA_PKCS_PSS,
CKM_SHA1_RSA_PKCS_PSS,
CKM_SHA224_RSA_PKCS_PSS,
CKM_SHA256_RSA_PKCS_PSS,
CKM_SHA384_RSA_PKCS_PSS,
CKM_SHA512_RSA_PKCS_PSS,
CKM_RSA_PKCS_OAEP,
/* AES Algorithms */
CKM_AES_ECB,
CKM_AES_CBC,
CKM_AES_CTR,
/* Digest algorithms */
CKM_SHA_1,
CKM_SHA224,
CKM_SHA256,
CKM_SHA384,
CKM_SHA512,
/* ECDSA */
CKM_ECDSA,
CKM_ECDSA_SHA1,
/* Key Generation algorithms */
CKM_EC_KEY_PAIR_GEN,
CKM_RSA_PKCS_KEY_PAIR_GEN,
CKM_AES_KEY_GEN,
CKM_DES2_KEY_GEN,
CKM_DES3_KEY_GEN,
/* Key Derivation algorithms */
CKM_ECDH1_DERIVE};
if (pMechanismList) {
if (*pulCount < sizeof(mechanisms)) {
xResult = CKR_BUFFER_TOO_SMALL;
}
else {
memcpy(pMechanismList, &mechanisms[0], sizeof(mechanisms));
}
}
*pulCount = sizeof(mechanisms);
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetSlotInfo)
(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
{
// printf("\n\n%s\n\n", __FUNCTION__);
// typedef struct CK_SLOT_INFO {
// /* slotDescription and manufacturerID have been changed from
// * CK_CHAR to CK_UTF8CHAR for v2.10 */
// CK_UTF8CHAR slotDescription[64]; /* blank padded */
// CK_UTF8CHAR manufacturerID[32]; /* blank padded */
// CK_FLAGS flags;
// CK_VERSION hardwareVersion; /* version of hardware */
// CK_VERSION firmwareVersion; /* version of firmware */
// } CK_SLOT_INFO;
if (slotID != 1) {
return CKR_SLOT_ID_INVALID;
}
memset(&pInfo->slotDescription[0], ' ', sizeof(pInfo->slotDescription));
memset(&pInfo->manufacturerID[0], ' ', sizeof(pInfo->manufacturerID));
pInfo->flags = CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
#if SSS_HAVE_APPLET_SE05X_IOT
pInfo->hardwareVersion.major = APPLET_SE050_VER_MAJOR;
pInfo->hardwareVersion.minor = APPLET_SE050_VER_MINOR;
#endif
CK_VERSION libVersion = PKCS11_LIBRARY_VERSION;
memcpy(&pInfo->firmwareVersion, &libVersion, sizeof(CK_VERSION));
memcpy(&pInfo->manufacturerID, "NXP", sizeof("NXP"));
return CKR_OK;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)
(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
{
// printf("\n\n%s\n\n", __FUNCTION__);
// typedef struct CK_TOKEN_INFO {
// /* label, manufacturerID, and model have been changed from
// * CK_CHAR to CK_UTF8CHAR for v2.10 */
// CK_UTF8CHAR label[32]; /* blank padded */
// CK_UTF8CHAR manufacturerID[32]; /* blank padded */
// CK_UTF8CHAR model[16]; /* blank padded */
// CK_CHAR serialNumber[16]; /* blank padded */
// CK_FLAGS flags; /* see below */
// CK_ULONG ulMaxSessionCount; /* max open sessions */
// CK_ULONG ulSessionCount; /* sess. now open */
// CK_ULONG ulMaxRwSessionCount; max R/W sessions
// CK_ULONG ulRwSessionCount; /* R/W sess. now open */
// CK_ULONG ulMaxPinLen; /* in bytes */
// CK_ULONG ulMinPinLen; /* in bytes */
// CK_ULONG ulTotalPublicMemory; /* in bytes */
// CK_ULONG ulFreePublicMemory; /* in bytes */
// CK_ULONG ulTotalPrivateMemory; /* in bytes */
// CK_ULONG ulFreePrivateMemory; /* in bytes */
// CK_VERSION hardwareVersion; /* version of hardware */
// CK_VERSION firmwareVersion; /* version of firmware */
// CK_CHAR utcTime[16]; /* time */
// } CK_TOKEN_INFO;
// memset(&pInfo->label[0], ' ', sizeof(pInfo->label));
CK_TOKEN_INFO tokenInfo = {0};
unsigned char label[] = PKCS11_TOKEN_LABEL;
unsigned char manufacturer[] = PKCS11_MANUFACTURER;
memset(tokenInfo.label, ' ', sizeof(tokenInfo.label));
memset(tokenInfo.manufacturerID, ' ', sizeof(tokenInfo.manufacturerID));
memset(tokenInfo.model, ' ', sizeof(tokenInfo.model));
memset(tokenInfo.serialNumber, ' ', sizeof(tokenInfo.serialNumber));
memcpy(tokenInfo.label, label, sizeof(label));
memcpy(tokenInfo.manufacturerID, manufacturer, sizeof(manufacturer));
tokenInfo.ulMaxSessionCount = 1;
tokenInfo.ulMaxRwSessionCount = 1;
tokenInfo.ulMaxPinLen = 10;
tokenInfo.ulMinPinLen = 0;
#if SSS_HAVE_APPLET_SE05X_IOT
tokenInfo.hardwareVersion.major = APPLET_SE050_VER_MAJOR;
tokenInfo.hardwareVersion.minor = APPLET_SE050_VER_MINOR;
#endif
CK_VERSION libVersion = PKCS11_LIBRARY_VERSION;
memcpy(&tokenInfo.firmwareVersion, &libVersion, sizeof(CK_VERSION));
tokenInfo.flags = CKF_RNG | CKF_TOKEN_INITIALIZED;
memcpy(pInfo, &tokenInfo, sizeof(CK_TOKEN_INFO));
return CKR_OK;
}
CK_DEFINE_FUNCTION(CK_RV, C_Login)
(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
// /* Security Officer */
// #define CKU_SO 0UL
// /* Normal user */
// #define CKU_USER 1UL
// /* Context specific */
// #define CKU_CONTEXT_SPECIFIC 2UL
// return CKR_GENERAL_ERROR;
return CKR_OK;
}
CK_DEFINE_FUNCTION(CK_RV, C_Logout)(CK_SESSION_HANDLE hSession)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_OK;
}
CK_DEFINE_FUNCTION(CK_RV, C_SeedRandom)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_OK;
}
CK_DEFINE_FUNCTION(CK_RV, C_SetAttributeValue)
(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_SignFinal)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_SignUpdate)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_UnwrapKey)
(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hUnwrappingKey,
CK_BYTE_PTR pWrappedKey,
CK_ULONG ulWrappedKeyLen,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulAttributeCount,
CK_OBJECT_HANDLE_PTR phKey)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_VerifyFinal)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_VerifyUpdate)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_WrapKey)
(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hWrappingKey,
CK_OBJECT_HANDLE hKey,
CK_BYTE_PTR pWrappedKey,
CK_ULONG_PTR pulWrappedKeyLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_InitToken)
(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_InitPIN)
(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_SetPIN)
(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_CloseAllSessions)(CK_SLOT_ID slotID)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)
(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
{
// printf("\n\n%s\n\n", __FUNCTION__);
CK_RV xResult = CKR_SESSION_CLOSED;
#if (__GNUC__ && !AX_EMBEDDED)
pthread_mutex_lock(&gSessionlock);
#endif
LOCK_MUTEX_FOR_RTOS
{
CK_SESSION_INFO session_info = {
.slotID = pkcs11SLOT_ID, .state = CKS_RW_PUBLIC_SESSION, .flags = CKF_RW_SESSION, .ulDeviceError = 0};
#if defined(USE_RTOS) && USE_RTOS == 1
#elif (__GNUC__ && !AX_EMBEDDED)
#else
session_info.flags = session_info.flags | CKF_SERIAL_SESSION;
#endif
if (sessionCount) {
memcpy(pInfo, &session_info, sizeof(CK_SESSION_INFO));
xResult = CKR_OK;
}
UNLOCK_MUTEX_FOR_RTOS
}
#if (__GNUC__ && !AX_EMBEDDED)
pthread_mutex_unlock(&gSessionlock);
#endif
return xResult;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetOperationState)
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_SetOperationState)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pOperationState,
CK_ULONG ulOperationStateLen,
CK_OBJECT_HANDLE hEncryptionKey,
CK_OBJECT_HANDLE hAuthenticationKey)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetObjectSize)
(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_SignRecoverInit)
(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_SignRecover)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pSignature,
CK_ULONG_PTR pulSignatureLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_VerifyRecoverInit)
(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_VerifyRecover)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature,
CK_ULONG ulSignatureLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDataLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_DigestEncryptUpdate)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_DecryptDigestUpdate)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_SignEncryptUpdate)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_DecryptVerifyUpdate)
(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionStatus)(CK_SESSION_HANDLE hSession)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_PARALLEL;
}
CK_DEFINE_FUNCTION(CK_RV, C_CancelFunction)(CK_SESSION_HANDLE hSession)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_PARALLEL;
}
CK_DEFINE_FUNCTION(CK_RV, C_WaitForSlotEvent)
(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
{
// printf("\n\n%s\n\n", __FUNCTION__);
return CKR_FUNCTION_NOT_SUPPORTED;
}
#endif /* TGT_A71CH */