blob: e99601a1a1d1168c6734503afb7f42ed9b7a3487 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This is the Chaps client. Essentially it forwards all PKCS #11 calls to the
// Chaps Daemon (chapsd) via D-Bus.
#include <string>
#include <vector>
#include <base/basictypes.h>
#include <base/logging.h>
#include <base/synchronization/waitable_event.h>
#include "chaps/attributes.h"
#include "chaps/chaps.h"
#include "chaps/chaps_proxy.h"
#include "chaps/chaps_utility.h"
#include "chaps/isolate.h"
#include "pkcs11/cryptoki.h"
using base::WaitableEvent;
using std::string;
using std::vector;
static const CK_BYTE kChapsLibraryVersionMajor = 0;
static const CK_BYTE kChapsLibraryVersionMinor = 1;
// The global proxy instance. This is valid only when g_is_initialized is true.
static chaps::ChapsInterface* g_proxy = NULL;
// Set to true when using a mock proxy.
static bool g_is_using_mock = false;
// Set to true when C_Initialize has been called successfully.
// When not using a mock proxy this is synonymous with (g_proxy != NULL).
static bool g_is_initialized = false;
// Set to the user's isolate credential (if it exists) in C_Initialize in order
// to provide access to the user's private slots.
static chromeos::SecureBlob* g_user_isolate = NULL;
// Tear down helper.
static void TearDown() {
if (g_is_initialized && !g_is_using_mock && g_proxy) {
delete g_proxy;
delete g_user_isolate;
}
g_is_initialized = false;
}
// This function implements the output handling convention described in
// PKCS #11 section 11.2. This method handles the following cases:
// 1) Caller passes a NULL buffer.
// 2) Caller passes a buffer that's too small.
// 3) Caller passes a buffer that is large enough.
// Parameters:
// result - The result of the operation as returned by chapsd. This will be
// clobbered if an error occurs, otherwise it is returned as is.
// output - The output of the operation as provided by chapsd. This should
// always fit in the caller-supplied output buffer.
// output_length - The output length as provided by chapsd. This is used
// when no data, only the length has been provided by chapsd.
// out_buffer - The caller-supplied output buffer; this may be NULL.
// out_buffer_length - The caller-supplied output buffer length, in bytes.
// This will be updated with the actual output length.
static CK_RV HandlePKCS11Output(CK_RV result,
const vector<uint8_t>& output,
uint64_t output_length,
CK_BYTE_PTR out_buffer,
CK_ULONG_PTR out_buffer_length) {
if (result == CKR_OK && out_buffer) {
if (output.size() > *out_buffer_length)
return CKR_GENERAL_ERROR;
*out_buffer_length = output.size();
memcpy(out_buffer, &output.front(), output.size());
} else {
*out_buffer_length = static_cast<CK_ULONG>(output_length);
if (result == CKR_BUFFER_TOO_SMALL)
result = CKR_OK;
}
return result;
}
namespace chaps {
// Helpers to support a mock proxy and isolate credential (useful in testing).
EXPORT_SPEC void EnableMockProxy(ChapsInterface* proxy,
chromeos::SecureBlob* isolate_credential,
bool is_initialized) {
g_proxy = proxy;
g_user_isolate = isolate_credential;
g_is_using_mock = true;
g_is_initialized = is_initialized;
}
EXPORT_SPEC void DisableMockProxy() {
// We don't own the mock proxy.
g_proxy = NULL;
g_user_isolate = NULL;
g_is_using_mock = false;
g_is_initialized = false;
}
} // namespace chaps
// The following functions are PKCS #11 entry points. They are intentionally
// in the root namespace and are declared 'extern "C"' in pkcs11.h.
// PKCS #11 v2.20 section 11.4 page 102.
// Connects to the D-Bus service.
CK_RV C_Initialize(CK_VOID_PTR pInitArgs) {
if (g_is_initialized)
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
// Validate args (if any).
if (pInitArgs) {
CK_C_INITIALIZE_ARGS_PTR args =
reinterpret_cast<CK_C_INITIALIZE_ARGS_PTR>(pInitArgs);
LOG_CK_RV_AND_RETURN_IF(args->pReserved, CKR_ARGUMENTS_BAD);
// If one of the following is NULL, they all must be NULL.
if ((!args->CreateMutex || !args->DestroyMutex ||
!args->LockMutex || !args->UnlockMutex) &&
(args->CreateMutex || args->DestroyMutex ||
args->LockMutex || args->UnlockMutex)) {
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
}
// We require OS locking.
if (((args->flags & CKF_OS_LOCKING_OK) == 0) && args->CreateMutex) {
LOG_CK_RV_AND_RETURN(CKR_CANT_LOCK);
}
}
// If we're not using a mock proxy instance we need to create one.
if (!g_is_using_mock) {
scoped_ptr<chaps::ChapsProxyImpl> proxy(new chaps::ChapsProxyImpl());
CHECK(proxy.get());
if (!proxy->Init())
LOG_CK_RV_AND_RETURN(CKR_GENERAL_ERROR);
g_proxy = proxy.release();
g_user_isolate = new chromeos::SecureBlob();
chaps::IsolateCredentialManager isolate_manager;
if (!isolate_manager.GetCurrentUserIsolateCredential(g_user_isolate))
*g_user_isolate = isolate_manager.GetDefaultIsolateCredential();
}
CHECK(g_proxy);
CHECK(g_user_isolate);
g_is_initialized = true;
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.4 page 104.
// Closes the D-Bus service connection.
CK_RV C_Finalize(CK_VOID_PTR pReserved) {
LOG_CK_RV_AND_RETURN_IF(pReserved, CKR_ARGUMENTS_BAD);
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
TearDown();
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.4 page 105.
// Provide library info locally.
// TODO(dkrahn): i18n of strings - crosbug.com/20637
CK_RV C_GetInfo(CK_INFO_PTR pInfo) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pInfo, CKR_ARGUMENTS_BAD);
pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
chaps::CopyStringToCharBuffer("Chromium OS",
pInfo->manufacturerID,
arraysize(pInfo->manufacturerID));
pInfo->flags = 0;
chaps::CopyStringToCharBuffer("Chaps Client Library",
pInfo->libraryDescription,
arraysize(pInfo->libraryDescription));
pInfo->libraryVersion.major = kChapsLibraryVersionMajor;
pInfo->libraryVersion.minor = kChapsLibraryVersionMinor;
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.4 page 106.
CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {
static CK_VERSION version = {2, 20};
static CK_FUNCTION_LIST functionList = {
version,
// Let pkcs11f.h populate the function pointers in order.
#define CK_PKCS11_FUNCTION_INFO(func) &func,
// We want only the function names, not the arguments.
#undef CK_NEED_ARG_LIST
#include "pkcs11/pkcs11f.h"
#undef CK_PKCS11_FUNCTION_INFO
};
*ppFunctionList = &functionList;
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.5 page 106.
CK_RV C_GetSlotList(CK_BBOOL tokenPresent,
CK_SLOT_ID_PTR pSlotList,
CK_ULONG_PTR pulCount) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pulCount, CKR_ARGUMENTS_BAD);
vector<uint64_t> slot_list;
CK_RV result = g_proxy->GetSlotList(*g_user_isolate,
(tokenPresent != CK_FALSE), &slot_list);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
size_t max_copy = static_cast<size_t>(*pulCount);
*pulCount = static_cast<CK_ULONG>(slot_list.size());
if (!pSlotList)
return CKR_OK;
LOG_CK_RV_AND_RETURN_IF(slot_list.size() > max_copy, CKR_BUFFER_TOO_SMALL);
for (size_t i = 0; i < slot_list.size(); ++i) {
pSlotList[i] = slot_list[i];
}
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.5 page 108.
CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pInfo, CKR_ARGUMENTS_BAD);
vector<uint8_t> slot_description;
vector<uint8_t> manufacturer_id;
CK_RV result = g_proxy->GetSlotInfo(
*g_user_isolate,
slotID,
&slot_description,
&manufacturer_id,
chaps::PreservedCK_ULONG(&pInfo->flags),
static_cast<uint8_t*>(&pInfo->hardwareVersion.major),
static_cast<uint8_t*>(&pInfo->hardwareVersion.minor),
static_cast<uint8_t*>(&pInfo->firmwareVersion.major),
static_cast<uint8_t*>(&pInfo->firmwareVersion.minor));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
chaps::CopyVectorToCharBuffer(slot_description,
pInfo->slotDescription,
arraysize(pInfo->slotDescription));
chaps::CopyVectorToCharBuffer(manufacturer_id,
pInfo->manufacturerID,
arraysize(pInfo->manufacturerID));
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.5 page 109.
CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pInfo, CKR_ARGUMENTS_BAD);
vector<uint8_t> label;
vector<uint8_t> manufacturer_id;
vector<uint8_t> model;
vector<uint8_t> serial_number;
CK_RV result = g_proxy->GetTokenInfo(
*g_user_isolate,
slotID,
&label,
&manufacturer_id,
&model,
&serial_number,
chaps::PreservedCK_ULONG(&pInfo->flags),
chaps::PreservedCK_ULONG(&pInfo->ulMaxSessionCount),
chaps::PreservedCK_ULONG(&pInfo->ulSessionCount),
chaps::PreservedCK_ULONG(&pInfo->ulMaxRwSessionCount),
chaps::PreservedCK_ULONG(&pInfo->ulRwSessionCount),
chaps::PreservedCK_ULONG(&pInfo->ulMaxPinLen),
chaps::PreservedCK_ULONG(&pInfo->ulMinPinLen),
chaps::PreservedCK_ULONG(&pInfo->ulTotalPublicMemory),
chaps::PreservedCK_ULONG(&pInfo->ulFreePublicMemory),
chaps::PreservedCK_ULONG(&pInfo->ulTotalPrivateMemory),
chaps::PreservedCK_ULONG(&pInfo->ulFreePrivateMemory),
static_cast<uint8_t*>(&pInfo->hardwareVersion.major),
static_cast<uint8_t*>(&pInfo->hardwareVersion.minor),
static_cast<uint8_t*>(&pInfo->firmwareVersion.major),
static_cast<uint8_t*>(&pInfo->firmwareVersion.minor));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
chaps::CopyVectorToCharBuffer(label,
pInfo->label,
arraysize(pInfo->label));
chaps::CopyVectorToCharBuffer(manufacturer_id,
pInfo->manufacturerID,
arraysize(pInfo->manufacturerID));
chaps::CopyVectorToCharBuffer(model,
pInfo->model,
arraysize(pInfo->model));
chaps::CopyVectorToCharBuffer(serial_number,
pInfo->serialNumber,
arraysize(pInfo->serialNumber));
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.5 page 110.
// Currently, slot events via D-Bus are not supported because no slot events
// occur with TPM-based tokens. We want this call to behave properly so we'll
// block the calling thread (if not CKF_DONT_BLOCK) until C_Finalize is called.
CK_RV C_WaitForSlotEvent(CK_FLAGS flags,
CK_SLOT_ID_PTR pSlot,
CK_VOID_PTR pReserved) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pSlot, CKR_ARGUMENTS_BAD);
// Currently, all supported tokens are not removable - i.e. no slot events.
if (CKF_DONT_BLOCK & flags)
return CKR_NO_EVENT;
// Block until C_Finalize. A simple mechanism is used here because any
// synchronization primitive will be a problem if C_Finalize is called in a
// signal handler.
while (g_is_initialized) {
const useconds_t kPollInterval = 3000000; // 3 seconds
usleep(kPollInterval);
}
return CKR_CRYPTOKI_NOT_INITIALIZED;
}
// PKCS #11 v2.20 section 11.5 page 111.
CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
CK_MECHANISM_TYPE_PTR pMechanismList,
CK_ULONG_PTR pulCount) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pulCount, CKR_ARGUMENTS_BAD);
vector<uint64_t> mechanism_list;
CK_RV result = g_proxy->GetMechanismList(*g_user_isolate,
slotID, &mechanism_list);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
// Copy the mechanism list to caller-supplied memory.
size_t max_copy = static_cast<size_t>(*pulCount);
*pulCount = static_cast<CK_ULONG>(mechanism_list.size());
if (!pMechanismList)
return CKR_OK;
LOG_CK_RV_AND_RETURN_IF(mechanism_list.size() > max_copy,
CKR_BUFFER_TOO_SMALL);
for (size_t i = 0; i < mechanism_list.size(); ++i) {
pMechanismList[i] = static_cast<CK_MECHANISM_TYPE>(mechanism_list[i]);
}
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.5 page 112.
CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
CK_MECHANISM_TYPE type,
CK_MECHANISM_INFO_PTR pInfo) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pInfo, CKR_ARGUMENTS_BAD);
vector<uint64_t> mechanism_list;
CK_RV result = g_proxy->GetMechanismInfo(
*g_user_isolate,
slotID,
type,
chaps::PreservedCK_ULONG(&pInfo->ulMinKeySize),
chaps::PreservedCK_ULONG(&pInfo->ulMaxKeySize),
chaps::PreservedCK_ULONG(&pInfo->flags));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.5 page 113.
CK_RV C_InitToken(CK_SLOT_ID slotID,
CK_UTF8CHAR_PTR pPin,
CK_ULONG ulPinLen,
CK_UTF8CHAR_PTR pLabel) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pLabel, CKR_ARGUMENTS_BAD);
string pin = chaps::ConvertCharBufferToString(pPin, ulPinLen);
vector<uint8_t> label =
chaps::ConvertByteBufferToVector(pLabel, chaps::kTokenLabelSize);
string* pin_ptr = (!pPin) ? NULL : &pin;
CK_RV result = g_proxy->InitToken(*g_user_isolate, slotID, pin_ptr, label);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.5 page 115.
CK_RV C_InitPIN(CK_SESSION_HANDLE hSession,
CK_UTF8CHAR_PTR pPin,
CK_ULONG ulPinLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
string pin = chaps::ConvertCharBufferToString(pPin, ulPinLen);
string* pin_ptr = (!pPin) ? NULL : &pin;
CK_RV result = g_proxy->InitPIN(*g_user_isolate, hSession, pin_ptr);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.5 page 116.
CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
CK_UTF8CHAR_PTR pOldPin,
CK_ULONG ulOldLen,
CK_UTF8CHAR_PTR pNewPin,
CK_ULONG ulNewLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
string old_pin = chaps::ConvertCharBufferToString(pOldPin, ulOldLen);
string* old_pin_ptr = (!pOldPin) ? NULL : &old_pin;
string new_pin = chaps::ConvertCharBufferToString(pNewPin, ulNewLen);
string* new_pin_ptr = (!pNewPin) ? NULL : &new_pin;
CK_RV result = g_proxy->SetPIN(*g_user_isolate, hSession, old_pin_ptr,
new_pin_ptr);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.6 page 117.
CK_RV C_OpenSession(CK_SLOT_ID slotID,
CK_FLAGS flags,
CK_VOID_PTR pApplication,
CK_NOTIFY Notify,
CK_SESSION_HANDLE_PTR phSession) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!phSession, CKR_ARGUMENTS_BAD);
// pApplication and Notify are intentionally ignored. We don't support
// notification callbacks and the PKCS #11 specification does not require us
// to. See PKCS #11 v2.20 section 11.17 for details.
CK_RV result = g_proxy->OpenSession(*g_user_isolate, slotID, flags,
chaps::PreservedCK_ULONG(phSession));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.6 page 118.
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
CK_RV result = g_proxy->CloseSession(*g_user_isolate, hSession);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.6 page 120.
CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
CK_RV result = g_proxy->CloseAllSessions(*g_user_isolate, slotID);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.6 page 120.
CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pInfo, CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->GetSessionInfo(
*g_user_isolate,
hSession,
chaps::PreservedCK_ULONG(&pInfo->slotID),
chaps::PreservedCK_ULONG(&pInfo->state),
chaps::PreservedCK_ULONG(&pInfo->flags),
chaps::PreservedCK_ULONG(&pInfo->ulDeviceError));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.6 page 121.
CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pOperationState,
CK_ULONG_PTR pulOperationStateLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pulOperationStateLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> operation_state;
CK_RV result = g_proxy->GetOperationState(*g_user_isolate, hSession,
&operation_state);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
// Copy the data and length to caller-supplied memory.
size_t max_copy = static_cast<size_t>(*pulOperationStateLen);
*pulOperationStateLen = static_cast<CK_ULONG>(operation_state.size());
if (!pOperationState)
return CKR_OK;
LOG_CK_RV_AND_RETURN_IF(operation_state.size() > max_copy,
CKR_BUFFER_TOO_SMALL);
memcpy(pOperationState, &operation_state.front(), operation_state.size());
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.6 page 123.
CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pOperationState,
CK_ULONG ulOperationStateLen,
CK_OBJECT_HANDLE hEncryptionKey,
CK_OBJECT_HANDLE hAuthenticationKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pOperationState, CKR_ARGUMENTS_BAD);
vector<uint8_t> operation_state =
chaps::ConvertByteBufferToVector(pOperationState,
ulOperationStateLen);
CK_RV result = g_proxy->SetOperationState(*g_user_isolate,
hSession,
operation_state,
hEncryptionKey,
hAuthenticationKey);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.6 page 125.
CK_RV C_Login(CK_SESSION_HANDLE hSession,
CK_USER_TYPE userType,
CK_UTF8CHAR_PTR pPin,
CK_ULONG ulPinLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
string pin = chaps::ConvertCharBufferToString(pPin, ulPinLen);
string* pin_ptr = (!pPin) ? NULL : &pin;
CK_RV result = g_proxy->Login(*g_user_isolate, hSession, userType, pin_ptr);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.6 page 127.
CK_RV C_Logout(CK_SESSION_HANDLE hSession) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
CK_RV result = g_proxy->Logout(*g_user_isolate, hSession);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.7 page 128.
CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phObject) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (pTemplate == NULL_PTR || phObject == NULL_PTR)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
chaps::Attributes attributes(pTemplate, ulCount);
vector<uint8_t> serialized_attributes;
if (!attributes.Serialize(&serialized_attributes))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
CK_RV result = g_proxy->CreateObject(
*g_user_isolate,
hSession,
serialized_attributes,
chaps::PreservedCK_ULONG(phObject));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.7 page 130.
CK_RV C_CopyObject(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phNewObject) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (pTemplate == NULL_PTR || phNewObject == NULL_PTR)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
chaps::Attributes attributes(pTemplate, ulCount);
vector<uint8_t> serialized_attributes;
if (!attributes.Serialize(&serialized_attributes))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
CK_RV result = g_proxy->CopyObject(
*g_user_isolate,
hSession,
hObject,
serialized_attributes,
chaps::PreservedCK_ULONG(phNewObject));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.7 page 131.
CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
CK_RV result = g_proxy->DestroyObject(*g_user_isolate, hSession, hObject);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.7 page 132.
CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ULONG_PTR pulSize) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pulSize, CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->GetObjectSize(*g_user_isolate,
hSession,
hObject,
chaps::PreservedCK_ULONG(pulSize));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.7 page 133.
CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pTemplate, CKR_ARGUMENTS_BAD);
chaps::Attributes attributes(pTemplate, ulCount);
vector<uint8_t> serialized_attributes_in;
if (!attributes.Serialize(&serialized_attributes_in))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
vector<uint8_t> serialized_attributes_out;
CK_RV result = g_proxy->GetAttributeValue(*g_user_isolate,
hSession,
hObject,
serialized_attributes_in,
&serialized_attributes_out);
// There are a few errors that can be returned while information about one or
// more attributes has been provided. We need to continue in these cases.
if (result != CKR_OK &&
result != CKR_ATTRIBUTE_TYPE_INVALID &&
result != CKR_ATTRIBUTE_SENSITIVE &&
result != CKR_BUFFER_TOO_SMALL)
LOG_CK_RV_AND_RETURN(result);
// Chapsd ensures the value is serialized correctly; we can assert.
CHECK(attributes.ParseAndFill(serialized_attributes_out));
VLOG(1) << __func__ << " - " << chaps::CK_RVToString(result);
return result;
}
// PKCS #11 v2.20 section 11.7 page 135.
CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pTemplate, CKR_ARGUMENTS_BAD);
chaps::Attributes attributes(pTemplate, ulCount);
vector<uint8_t> serialized_attributes;
if (!attributes.Serialize(&serialized_attributes))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
CK_RV result = g_proxy->SetAttributeValue(*g_user_isolate,
hSession,
hObject,
serialized_attributes);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.7 page 136.
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pTemplate && ulCount > 0, CKR_ARGUMENTS_BAD);
chaps::Attributes attributes(pTemplate, ulCount);
vector<uint8_t> serialized_attributes;
if (!attributes.Serialize(&serialized_attributes))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
CK_RV result = g_proxy->FindObjectsInit(*g_user_isolate, hSession,
serialized_attributes);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.7 page 137.
CK_RV C_FindObjects(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE_PTR phObject,
CK_ULONG ulMaxObjectCount,
CK_ULONG_PTR pulObjectCount) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!phObject || !pulObjectCount, CKR_ARGUMENTS_BAD);
vector<uint64_t> object_list;
CK_RV result = g_proxy->FindObjects(*g_user_isolate, hSession,
ulMaxObjectCount, &object_list);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
LOG_CK_RV_AND_RETURN_IF(object_list.size() > ulMaxObjectCount,
CKR_GENERAL_ERROR);
*pulObjectCount = static_cast<CK_ULONG>(object_list.size());
for (size_t i = 0; i < object_list.size(); i++) {
phObject[i] = static_cast<CK_OBJECT_HANDLE>(object_list[i]);
}
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.7 page 138.
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
CK_RV result = g_proxy->FindObjectsFinal(*g_user_isolate, hSession);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.8 page 139.
CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pMechanism, CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->EncryptInit(
*g_user_isolate,
hSession,
pMechanism->mechanism,
chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen),
hKey);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.8 page 140.
CK_RV C_Encrypt(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pEncryptedData,
CK_ULONG_PTR pulEncryptedDataLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if ((!pData && ulDataLen > 0) || !pulEncryptedDataLen)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pEncryptedData ? static_cast<uint64_t>(*pulEncryptedDataLen) : 0;
CK_RV result = g_proxy->Encrypt(*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pData,
ulDataLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pEncryptedData,
pulEncryptedDataLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.8 page 141.
CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pPart || !pulEncryptedPartLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pEncryptedPart ? static_cast<uint64_t>(*pulEncryptedPartLen) : 0;
CK_RV result = g_proxy->EncryptUpdate(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pPart, ulPartLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pEncryptedPart,
pulEncryptedPartLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.8 page 141.
CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pLastEncryptedPart,
CK_ULONG_PTR pulLastEncryptedPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pulLastEncryptedPartLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pLastEncryptedPart ? static_cast<uint64_t>(*pulLastEncryptedPartLen) : 0;
CK_RV result = g_proxy->EncryptFinal(*g_user_isolate,
hSession,
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pLastEncryptedPart,
pulLastEncryptedPartLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.9 page 144.
CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pMechanism, CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->DecryptInit(
*g_user_isolate,
hSession,
pMechanism->mechanism,
chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen),
hKey);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.9 page 145.
CK_RV C_Decrypt(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedData,
CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDataLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if ((!pEncryptedData && ulEncryptedDataLen > 0) || !pulDataLen)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length = pData ? static_cast<uint64_t>(*pulDataLen) : 0;
CK_RV result = g_proxy->Decrypt(*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(
pEncryptedData,
ulEncryptedDataLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pData,
pulDataLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.9 page 146.
CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pEncryptedPart || !pulPartLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length = pPart ? static_cast<uint64_t>(*pulPartLen) : 0;
CK_RV result = g_proxy->DecryptUpdate(*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(
pEncryptedPart,
ulEncryptedPartLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pPart,
pulPartLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.9 page 146.
CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pLastPart,
CK_ULONG_PTR pulLastPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pulLastPartLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pLastPart ? static_cast<uint64_t>(*pulLastPartLen) : 0;
CK_RV result = g_proxy->DecryptFinal(*g_user_isolate,
hSession,
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pLastPart,
pulLastPartLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.10 page 148.
CK_RV C_DigestInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pMechanism, CKR_ARGUMENTS_BAD);
vector<uint8_t> parameter = chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen);
CK_RV result = g_proxy->DigestInit(*g_user_isolate,
hSession,
pMechanism->mechanism,
parameter);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.10 page 149.
CK_RV C_Digest(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pDigest,
CK_ULONG_PTR pulDigestLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if ((!pData && ulDataLen > 0) || !pulDigestLen)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length = pDigest ? static_cast<uint64_t>(*pulDigestLen) : 0;
CK_RV result = g_proxy->Digest(*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pData,
ulDataLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pDigest,
pulDigestLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.10 page 150.
CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pPart, CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->DigestUpdate(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pPart, ulPartLen));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.10 page 150.
CK_RV C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
CK_RV result = g_proxy->DigestKey(*g_user_isolate, hSession, hKey);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.10 page 151.
CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pDigest,
CK_ULONG_PTR pulDigestLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pulDigestLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length = pDigest ? static_cast<uint64_t>(*pulDigestLen) : 0;
CK_RV result = g_proxy->DigestFinal(*g_user_isolate,
hSession,
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pDigest,
pulDigestLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.11 page 152.
CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pMechanism, CKR_ARGUMENTS_BAD);
vector<uint8_t> parameter = chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen);
CK_RV result = g_proxy->SignInit(*g_user_isolate,
hSession,
pMechanism->mechanism,
parameter,
hKey);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.11 page 153.
CK_RV C_Sign (CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pSignature,
CK_ULONG_PTR pulSignatureLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if ((!pData && ulDataLen > 0) || !pulSignatureLen)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pSignature ? static_cast<uint64_t>(*pulSignatureLen) : 0;
CK_RV result = g_proxy->Sign(*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pData,
ulDataLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pSignature,
pulSignatureLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.11 page 154.
CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pPart, CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->SignUpdate(*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pPart,
ulPartLen));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.11 page 154.
CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature,
CK_ULONG_PTR pulSignatureLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pulSignatureLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pSignature ? static_cast<uint64_t>(*pulSignatureLen) : 0;
CK_RV result = g_proxy->SignFinal(*g_user_isolate,
hSession,
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pSignature,
pulSignatureLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.11 page 155.
CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pMechanism, CKR_ARGUMENTS_BAD);
vector<uint8_t> parameter = chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen);
CK_RV result = g_proxy->SignRecoverInit(*g_user_isolate,
hSession,
pMechanism->mechanism,
parameter,
hKey);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.11 page 156.
CK_RV C_SignRecover(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pSignature,
CK_ULONG_PTR pulSignatureLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if ((!pData && ulDataLen > 0) || !pulSignatureLen)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pSignature ? static_cast<uint64_t>(*pulSignatureLen) : 0;
CK_RV result = g_proxy->SignRecover(*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pData,
ulDataLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pSignature,
pulSignatureLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.12 page 157.
CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pMechanism, CKR_ARGUMENTS_BAD);
vector<uint8_t> parameter = chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen);
CK_RV result = g_proxy->VerifyInit(*g_user_isolate,
hSession,
pMechanism->mechanism,
parameter,
hKey);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.12 page 158.
CK_RV C_Verify(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pSignature,
CK_ULONG ulSignatureLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!pSignature || (!pData && ulDataLen > 0))
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->Verify(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pData, ulDataLen),
chaps::ConvertByteBufferToVector(pSignature, ulSignatureLen));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.12 page 159.
CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pPart, CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->VerifyUpdate(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pPart, ulPartLen));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.12 page 159.
CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature,
CK_ULONG ulSignatureLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pSignature, CKR_ARGUMENTS_BAD);
CK_RV result = g_proxy->VerifyFinal(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pSignature, ulSignatureLen));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.12 page 161.
CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pMechanism, CKR_ARGUMENTS_BAD);
vector<uint8_t> parameter = chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen);
CK_RV result = g_proxy->VerifyRecoverInit(
*g_user_isolate,
hSession,
pMechanism->mechanism,
parameter,
hKey);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.12 page 161.
CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature,
CK_ULONG ulSignatureLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDataLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!pSignature || !pulDataLen)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length = pData ? static_cast<uint64_t>(*pulDataLen) : 0;
CK_RV result = g_proxy->VerifyRecover(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pSignature, ulSignatureLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pData,
pulDataLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.13 page 163.
CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pPart || !pulEncryptedPartLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pEncryptedPart ? static_cast<uint64_t>(*pulEncryptedPartLen) : 0;
CK_RV result = g_proxy->DigestEncryptUpdate(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pPart, ulPartLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pEncryptedPart,
pulEncryptedPartLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.13 page 165.
CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pEncryptedPart || !pulPartLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length = pPart ? static_cast<uint64_t>(*pulPartLen) : 0;
CK_RV result = g_proxy->DecryptDigestUpdate(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pEncryptedPart, ulEncryptedPartLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pPart,
pulPartLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.13 page 169.
CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pPart || !pulEncryptedPartLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pEncryptedPart ? static_cast<uint64_t>(*pulEncryptedPartLen) : 0;
CK_RV result = g_proxy->SignEncryptUpdate(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pPart, ulPartLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pEncryptedPart,
pulEncryptedPartLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.13 page 171.
CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
LOG_CK_RV_AND_RETURN_IF(!pEncryptedPart || !pulPartLen, CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length = pPart ? static_cast<uint64_t>(*pulPartLen) : 0;
CK_RV result = g_proxy->DecryptVerifyUpdate(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pEncryptedPart, ulEncryptedPartLen),
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pPart,
pulPartLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.14 page 175.
CK_RV C_GenerateKey(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phKey) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!pMechanism || (!pTemplate && ulCount > 0) || !phKey)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
chaps::Attributes attributes(pTemplate, ulCount);
vector<uint8_t> serialized;
if (!attributes.Serialize(&serialized))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
CK_RV result = g_proxy->GenerateKey(
*g_user_isolate,
hSession,
pMechanism->mechanism,
chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen),
serialized,
chaps::PreservedCK_ULONG(phKey));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.14 page 176.
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) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!pMechanism ||
(!pPublicKeyTemplate && ulPublicKeyAttributeCount > 0) ||
(!pPrivateKeyTemplate && ulPrivateKeyAttributeCount > 0) ||
!phPublicKey ||
!phPrivateKey)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
chaps::Attributes public_attributes(pPublicKeyTemplate,
ulPublicKeyAttributeCount);
chaps::Attributes private_attributes(pPrivateKeyTemplate,
ulPrivateKeyAttributeCount);
vector<uint8_t> public_serialized, private_serialized;
if (!public_attributes.Serialize(&public_serialized) ||
!private_attributes.Serialize(&private_serialized))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
CK_RV result = g_proxy->GenerateKeyPair(
*g_user_isolate,
hSession,
pMechanism->mechanism,
chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen),
public_serialized,
private_serialized,
chaps::PreservedCK_ULONG(phPublicKey),
chaps::PreservedCK_ULONG(phPrivateKey));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.14 page 178.
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) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!pMechanism || !pulWrappedKeyLen)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint64_t data_out_length;
uint64_t max_out_length =
pWrappedKey ? static_cast<uint64_t>(*pulWrappedKeyLen) : 0;
uint32_t result = g_proxy->WrapKey(
*g_user_isolate,
hSession,
pMechanism->mechanism,
chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen),
hWrappingKey,
hKey,
max_out_length,
&data_out_length,
&data_out);
result = HandlePKCS11Output(result,
data_out,
data_out_length,
pWrappedKey,
pulWrappedKeyLen);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.14 page 180.
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) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!pMechanism || !pWrappedKey || !phKey)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
chaps::Attributes attributes(pTemplate, ulAttributeCount);
vector<uint8_t> serialized;
if (!attributes.Serialize(&serialized))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
uint32_t result = g_proxy->UnwrapKey(
*g_user_isolate,
hSession,
pMechanism->mechanism,
chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen),
hUnwrappingKey,
chaps::ConvertByteBufferToVector(pWrappedKey, ulWrappedKeyLen),
serialized,
chaps::PreservedCK_ULONG(phKey));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.14 page 182.
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) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!pMechanism || !phKey)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
chaps::Attributes attributes(pTemplate, ulAttributeCount);
vector<uint8_t> serialized;
if (!attributes.Serialize(&serialized))
LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
uint32_t result = g_proxy->DeriveKey(
*g_user_isolate,
hSession,
pMechanism->mechanism,
chaps::ConvertByteBufferToVector(
reinterpret_cast<CK_BYTE_PTR>(pMechanism->pParameter),
pMechanism->ulParameterLen),
hBaseKey,
serialized,
chaps::PreservedCK_ULONG(phKey));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.15 page 184.
CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSeed,
CK_ULONG ulSeedLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!pSeed || ulSeedLen == 0)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
uint32_t result = g_proxy->SeedRandom(
*g_user_isolate,
hSession,
chaps::ConvertByteBufferToVector(pSeed, ulSeedLen));
LOG_CK_RV_AND_RETURN_IF_ERR(result);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.15 page 184.
CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR RandomData,
CK_ULONG ulRandomLen) {
LOG_CK_RV_AND_RETURN_IF(!g_is_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
if (!RandomData || ulRandomLen == 0)
LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
vector<uint8_t> data_out;
uint32_t result = g_proxy->GenerateRandom(*g_user_isolate, hSession,
ulRandomLen, &data_out);
LOG_CK_RV_AND_RETURN_IF_ERR(result);
LOG_CK_RV_AND_RETURN_IF(data_out.size() != ulRandomLen, CKR_GENERAL_ERROR);
memcpy(RandomData, &data_out.front(), ulRandomLen);
VLOG(1) << __func__ << " - CKR_OK";
return CKR_OK;
}
// PKCS #11 v2.20 section 11.16 page 185.
CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
return CKR_FUNCTION_NOT_PARALLEL;
}
// PKCS #11 v2.20 section 11.16 page 186.
CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession) {
return CKR_FUNCTION_NOT_PARALLEL;
}