aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/prov
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/prov')
-rw-r--r--src/lib/prov/openssl/openssl_rc4.cpp11
-rw-r--r--src/lib/prov/pkcs11/info.txt48
-rw-r--r--src/lib/prov/pkcs11/p11.cpp769
-rw-r--r--src/lib/prov/pkcs11/p11.h2861
-rw-r--r--src/lib/prov/pkcs11/p11_ecc_key.cpp137
-rw-r--r--src/lib/prov/pkcs11/p11_ecc_key.h228
-rw-r--r--src/lib/prov/pkcs11/p11_ecdh.cpp141
-rw-r--r--src/lib/prov/pkcs11/p11_ecdh.h122
-rw-r--r--src/lib/prov/pkcs11/p11_ecdsa.cpp229
-rw-r--r--src/lib/prov/pkcs11/p11_ecdsa.h127
-rw-r--r--src/lib/prov/pkcs11/p11_mechanism.cpp250
-rw-r--r--src/lib/prov/pkcs11/p11_mechanism.h108
-rw-r--r--src/lib/prov/pkcs11/p11_module.cpp41
-rw-r--r--src/lib/prov/pkcs11/p11_module.h79
-rw-r--r--src/lib/prov/pkcs11/p11_object.cpp217
-rw-r--r--src/lib/prov/pkcs11/p11_object.h743
-rw-r--r--src/lib/prov/pkcs11/p11_randomgenerator.cpp31
-rw-r--r--src/lib/prov/pkcs11/p11_randomgenerator.h70
-rw-r--r--src/lib/prov/pkcs11/p11_rsa.cpp377
-rw-r--r--src/lib/prov/pkcs11/p11_rsa.h212
-rw-r--r--src/lib/prov/pkcs11/p11_session.cpp89
-rw-r--r--src/lib/prov/pkcs11/p11_session.h105
-rw-r--r--src/lib/prov/pkcs11/p11_slot.cpp60
-rw-r--r--src/lib/prov/pkcs11/p11_slot.h79
-rw-r--r--src/lib/prov/pkcs11/p11_x509.cpp37
-rw-r--r--src/lib/prov/pkcs11/p11_x509.h115
-rw-r--r--src/lib/prov/pkcs11/pkcs11.h264
-rw-r--r--src/lib/prov/pkcs11/pkcs11f.h938
-rw-r--r--src/lib/prov/pkcs11/pkcs11t.h2002
-rw-r--r--src/lib/prov/tpm/tpm.h24
30 files changed, 10499 insertions, 15 deletions
diff --git a/src/lib/prov/openssl/openssl_rc4.cpp b/src/lib/prov/openssl/openssl_rc4.cpp
index e36535e08..d6246e4ab 100644
--- a/src/lib/prov/openssl/openssl_rc4.cpp
+++ b/src/lib/prov/openssl/openssl_rc4.cpp
@@ -12,6 +12,7 @@
#include <botan/internal/algo_registry.h>
#include <botan/internal/openssl.h>
#include <botan/parsing.h>
+#include <botan/exceptn.h>
#include <openssl/rc4.h>
namespace Botan {
@@ -45,6 +46,16 @@ class OpenSSL_RC4 : public StreamCipher
explicit OpenSSL_RC4(size_t skip = 0) : m_skip(skip) { clear(); }
~OpenSSL_RC4() { clear(); }
+
+ void set_iv(const byte*, size_t) override
+ {
+ throw Exception("RC4 does not support an IV");
+ }
+
+ void seek(u64bit) override
+ {
+ throw Exception("RC4 does not support seeking");
+ }
private:
void cipher(const byte in[], byte out[], size_t length) override
{
diff --git a/src/lib/prov/pkcs11/info.txt b/src/lib/prov/pkcs11/info.txt
new file mode 100644
index 000000000..2715c7cda
--- /dev/null
+++ b/src/lib/prov/pkcs11/info.txt
@@ -0,0 +1,48 @@
+define PKCS11 20160219
+
+load_on vendor
+
+<requires>
+dyn_load
+rng
+pk_pad
+</requires>
+
+<header:internal>
+p11_mechanism.h
+</header:internal>
+
+<header:external>
+pkcs11.h
+pkcs11f.h
+pkcs11t.h
+</header:external>
+
+<header:public>
+p11.h
+p11_ecc_key.h
+p11_ecdh.h
+p11_ecdsa.h
+p11_module.h
+p11_object.h
+p11_randomgenerator.h
+p11_rsa.h
+p11_session.h
+p11_slot.h
+p11_x509.h
+</header:public>
+
+<source>
+p11.cpp
+p11_ecc_key.cpp
+p11_ecdh.cpp
+p11_ecdsa.cpp
+p11_mechanism.cpp
+p11_module.cpp
+p11_object.cpp
+p11_randomgenerator.cpp
+p11_rsa.cpp
+p11_session.cpp
+p11_slot.cpp
+p11_x509.cpp
+</source> \ No newline at end of file
diff --git a/src/lib/prov/pkcs11/p11.cpp b/src/lib/prov/pkcs11/p11.cpp
new file mode 100644
index 000000000..d338438d3
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11.cpp
@@ -0,0 +1,769 @@
+/*
+* PKCS#11
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11.h>
+#include <botan/p11_session.h>
+
+#include <cstdint>
+#include <string>
+#include <functional>
+
+namespace Botan {
+namespace PKCS11 {
+
+ReturnValue* ThrowException = reinterpret_cast< ReturnValue* >(-1);
+
+namespace {
+/// @param function_result Return value of the PKCS11 module function
+/// @param returnValue if (`ThrowException`) is passed the function throws an exception, otherwise if a non-NULL pointer is passed:
+/// return_value receives the return value of the PKCS#11 function and no exception is thrown.
+/// @return true if function call was successful, false otherwise
+bool handle_return_value(const CK_RV function_result, ReturnValue* return_value)
+ {
+ if(return_value == ThrowException)
+ {
+ if(static_cast< ReturnValue >(function_result) != ReturnValue::OK)
+ {
+ // caller wants exception
+ throw PKCS11_ReturnError(static_cast< ReturnValue >(function_result));
+ }
+ }
+ else if(return_value != nullptr)
+ {
+ // caller wants return value
+ *return_value = static_cast< ReturnValue >(function_result);
+ }
+
+ return static_cast< ReturnValue >(function_result) == ReturnValue::OK;
+ }
+}
+
+void initialize_token(Slot& slot, const std::string& label, const secure_string& so_pin, const secure_string& pin)
+ {
+ slot.initialize(label, so_pin);
+ set_pin(slot, so_pin, pin);
+ }
+
+void change_pin(Slot& slot, const secure_string& old_pin, const secure_string& new_pin)
+ {
+ Session session(slot, false);
+ session.login(UserType::User, old_pin);
+ session.set_pin(old_pin, new_pin);
+ }
+
+void change_so_pin(Slot& slot, const secure_string& old_so_pin, const secure_string& new_so_pin)
+ {
+ Session session(slot, false);
+ session.login(UserType::SO, old_so_pin);
+ session.set_pin(old_so_pin, new_so_pin);
+ }
+
+void set_pin(Slot& slot, const secure_string& so_pin, const secure_string& pin)
+ {
+ Session session(slot, false);
+ session.login(UserType::SO, so_pin);
+ session.init_pin(pin);
+ }
+
+LowLevel::LowLevel(FunctionListPtr ptr) :
+ m_func_list_ptr(ptr)
+ {
+ if(m_func_list_ptr == nullptr)
+ {
+ throw Invalid_Argument("Invalid PKCS#11 function list ptr");
+ }
+ }
+
+LowLevel::~LowLevel() BOTAN_NOEXCEPT
+{}
+
+/****************************** General purpose functions ******************************/
+
+bool LowLevel::C_Initialize(VoidPtr init_args,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Initialize(init_args), return_value);
+ }
+
+bool LowLevel::C_Finalize(VoidPtr reserved,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Finalize(reserved), return_value);
+ }
+
+bool LowLevel::C_GetInfo(Info* info_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetInfo(info_ptr), return_value);
+ }
+
+bool LowLevel::C_GetFunctionList(Dynamically_Loaded_Library& pkcs11_module, FunctionListPtr* function_list_ptr_ptr,
+ ReturnValue* return_value)
+ {
+ using get_function_list = CK_RV(*)(FunctionListPtr*);
+
+ get_function_list get_function_list_ptr = pkcs11_module.resolve<get_function_list>("C_GetFunctionList");
+
+ return handle_return_value(get_function_list_ptr(function_list_ptr_ptr), return_value);
+ }
+
+/****************************** Slot and token management functions ******************************/
+
+bool LowLevel::C_GetSlotList(Bbool token_present,
+ SlotId* slot_list_ptr,
+ Ulong* count_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetSlotList(token_present, slot_list_ptr, count_ptr), return_value);
+ }
+
+bool LowLevel::C_GetSlotList(bool token_present,
+ std::vector<SlotId>& slot_ids,
+ ReturnValue* return_value) const
+ {
+ slot_ids.clear();
+
+ // first get available slots
+ Ulong number_slots = 0;
+
+ bool success = C_GetSlotList(token_present, nullptr, &number_slots, return_value);
+
+ if(!success || !number_slots)
+ {
+ return success;
+ }
+
+ // get actual slot ids
+ slot_ids.resize(number_slots);
+ return C_GetSlotList(token_present, slot_ids.data(), &number_slots, return_value);
+ }
+
+bool LowLevel::C_GetSlotInfo(SlotId slot_id,
+ SlotInfo* info_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetSlotInfo(slot_id, info_ptr), return_value);
+ }
+
+bool LowLevel::C_GetTokenInfo(SlotId slot_id,
+ TokenInfo* info_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetTokenInfo(slot_id, info_ptr), return_value);
+ }
+
+bool LowLevel::C_WaitForSlotEvent(Flags flags,
+ SlotId* slot_ptr,
+ VoidPtr reserved,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_WaitForSlotEvent(flags, slot_ptr, reserved), return_value);
+ }
+
+bool LowLevel::C_GetMechanismList(SlotId slot_id,
+ MechanismType* mechanism_list_ptr,
+ Ulong* count_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetMechanismList(slot_id,
+ reinterpret_cast< CK_MECHANISM_TYPE_PTR >(mechanism_list_ptr), count_ptr), return_value);
+ }
+
+bool LowLevel::C_GetMechanismList(SlotId slot_id,
+ std::vector<MechanismType>& mechanisms,
+ ReturnValue* return_value) const
+ {
+ mechanisms.clear();
+
+ // first get number of mechanisms
+ Ulong number_mechanisms = 0;
+
+ bool success = C_GetMechanismList(slot_id, nullptr, &number_mechanisms, return_value);
+
+ if(!success || !number_mechanisms)
+ {
+ return success;
+ }
+
+ // get actual mechanisms
+ mechanisms.resize(number_mechanisms);
+ return C_GetMechanismList(slot_id, reinterpret_cast< MechanismType* >(mechanisms.data()), &number_mechanisms,
+ return_value);
+ }
+
+bool LowLevel::C_GetMechanismInfo(SlotId slot_id,
+ MechanismType type,
+ MechanismInfo* info_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetMechanismInfo(slot_id, static_cast< CK_MECHANISM_TYPE >(type),
+ info_ptr), return_value);
+ }
+
+bool LowLevel::C_InitToken(SlotId slot_id,
+ Utf8Char* so_pin_ptr,
+ Ulong so_pin_len,
+ Utf8Char* label_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_InitToken(slot_id, so_pin_ptr, so_pin_len, label_ptr), return_value);
+ }
+
+bool LowLevel::C_InitPIN(SessionHandle session,
+ Utf8Char* pin_ptr,
+ Ulong pin_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_InitPIN(session, pin_ptr, pin_len), return_value);
+ }
+
+bool LowLevel::C_SetPIN(SessionHandle session,
+ Utf8Char* old_pin_ptr,
+ Ulong old_len,
+ Utf8Char* new_pin_ptr,
+ Ulong new_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SetPIN(session, old_pin_ptr, old_len, new_pin_ptr, new_len),
+ return_value);
+ }
+
+/****************************** Session management ******************************/
+
+bool LowLevel::C_OpenSession(SlotId slot_id,
+ Flags flags,
+ VoidPtr application,
+ Notify notify,
+ SessionHandle* session_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_OpenSession(slot_id, flags, application, notify, session_ptr),
+ return_value);
+ }
+
+bool LowLevel::C_CloseSession(SessionHandle session,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_CloseSession(session), return_value);
+ }
+
+bool LowLevel::C_CloseAllSessions(SlotId slot_id,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_CloseAllSessions(slot_id), return_value);
+ }
+
+bool LowLevel::C_GetSessionInfo(SessionHandle session,
+ SessionInfo* info_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetSessionInfo(session, info_ptr), return_value);
+ }
+
+bool LowLevel::C_GetOperationState(SessionHandle session,
+ Byte* operation_state_ptr,
+ Ulong* operation_state_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetOperationState(session, operation_state_ptr, operation_state_len_ptr),
+ return_value);
+ }
+
+bool LowLevel::C_SetOperationState(SessionHandle session,
+ Byte* operation_state_ptr,
+ Ulong operation_state_len,
+ ObjectHandle encryption_key,
+ ObjectHandle authentication_key,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SetOperationState(session, operation_state_ptr, operation_state_len,
+ encryption_key, authentication_key), return_value);
+ }
+
+bool LowLevel::C_Login(SessionHandle session,
+ UserType user_type,
+ Utf8Char* pin_ptr,
+ Ulong pin_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Login(session, static_cast< CK_USER_TYPE >(user_type), pin_ptr, pin_len),
+ return_value);
+ }
+
+bool LowLevel::C_Logout(SessionHandle session,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Logout(session), return_value);
+ }
+
+/****************************** Object management functions ******************************/
+
+bool LowLevel::C_CreateObject(SessionHandle session,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ObjectHandle* object_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_CreateObject(session, attribute_template_ptr, count, object_ptr),
+ return_value);
+ }
+
+bool LowLevel::C_CopyObject(SessionHandle session,
+ ObjectHandle object,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ObjectHandle* new_object_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_CopyObject(session, object, attribute_template_ptr, count,
+ new_object_ptr), return_value);
+ }
+
+bool LowLevel::C_DestroyObject(SessionHandle session,
+ ObjectHandle object,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DestroyObject(session, object), return_value);
+ }
+
+bool LowLevel::C_GetObjectSize(SessionHandle session,
+ ObjectHandle object,
+ Ulong* size_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetObjectSize(session, object, size_ptr), return_value);
+ }
+
+bool LowLevel::C_GetAttributeValue(SessionHandle session,
+ ObjectHandle object,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetAttributeValue(session, object, attribute_template_ptr, count),
+ return_value);
+ }
+
+bool LowLevel::C_SetAttributeValue(SessionHandle session,
+ ObjectHandle object,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SetAttributeValue(session, object, attribute_template_ptr, count),
+ return_value);
+ }
+
+bool LowLevel::C_FindObjectsInit(SessionHandle session,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_FindObjectsInit(session, attribute_template_ptr, count), return_value);
+ }
+
+bool LowLevel::C_FindObjects(SessionHandle session,
+ ObjectHandle* object_ptr,
+ Ulong max_object_count,
+ Ulong* object_count_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_FindObjects(session, object_ptr, max_object_count, object_count_ptr),
+ return_value);
+ }
+
+bool LowLevel::C_FindObjectsFinal(SessionHandle session,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_FindObjectsFinal(session), return_value);
+ }
+
+/****************************** Encryption functions ******************************/
+
+bool LowLevel::C_EncryptInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_EncryptInit(session, mechanism_ptr, key), return_value);
+ }
+
+bool LowLevel::C_Encrypt(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* encrypted_data_ptr,
+ Ulong* encrypted_data_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Encrypt(session, data_ptr, data_len, encrypted_data_ptr,
+ encrypted_data_len_ptr), return_value);
+ }
+
+bool LowLevel::C_EncryptUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ Byte* encrypted_part_ptr,
+ Ulong* encrypted_part_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_EncryptUpdate(session, part_ptr, part_len, encrypted_part_ptr,
+ encrypted_part_len_ptr), return_value);
+ }
+
+bool LowLevel::C_EncryptFinal(SessionHandle session,
+ Byte* last_encrypted_part_ptr,
+ Ulong* last_encrypted_part_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_EncryptFinal(session, last_encrypted_part_ptr,
+ last_encrypted_part_len_ptr), return_value);
+ }
+
+/****************************** Decryption functions ******************************/
+
+bool LowLevel::C_DecryptInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DecryptInit(session, mechanism_ptr, key), return_value);
+ }
+
+bool LowLevel::C_Decrypt(SessionHandle session,
+ Byte* encrypted_data_ptr,
+ Ulong encrypted_data_len,
+ Byte* data_ptr,
+ Ulong* data_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Decrypt(session, encrypted_data_ptr, encrypted_data_len, data_ptr,
+ data_len_ptr), return_value);
+ }
+
+bool LowLevel::C_DecryptUpdate(SessionHandle session,
+ Byte* encrypted_part_ptr,
+ Ulong encrypted_part_len,
+ Byte* part_ptr,
+ Ulong* part_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DecryptUpdate(session, encrypted_part_ptr, encrypted_part_len, part_ptr,
+ part_len_ptr), return_value);
+ }
+
+bool LowLevel::C_DecryptFinal(SessionHandle session,
+ Byte* last_part_ptr,
+ Ulong* last_part_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DecryptFinal(session, last_part_ptr, last_part_len_ptr), return_value);
+ }
+
+/****************************** Message digesting functions ******************************/
+
+bool LowLevel::C_DigestInit(SessionHandle session,
+ Mechanism* mechanism,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DigestInit(session, mechanism), return_value);
+ }
+
+bool LowLevel::C_Digest(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* digest_ptr,
+ Ulong* digest_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Digest(session, data_ptr, data_len, digest_ptr, digest_len_ptr),
+ return_value);
+ }
+
+bool LowLevel::C_DigestUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DigestUpdate(session, part_ptr, part_len), return_value);
+ }
+
+bool LowLevel::C_DigestKey(SessionHandle session,
+ ObjectHandle key,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DigestKey(session, key), return_value);
+ }
+
+bool LowLevel::C_DigestFinal(SessionHandle session,
+ Byte* digest_ptr,
+ Ulong* digest_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DigestFinal(session, digest_ptr, digest_len_ptr), return_value);
+ }
+
+/****************************** Signing and MACing functions ******************************/
+
+bool LowLevel::C_SignInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SignInit(session, mechanism_ptr, key), return_value);
+ }
+
+bool LowLevel::C_Sign(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* signature_ptr,
+ Ulong* signature_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Sign(session, data_ptr, data_len, signature_ptr, signature_len_ptr),
+ return_value);
+ }
+
+bool LowLevel::C_SignUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SignUpdate(session, part_ptr, part_len), return_value);
+ }
+
+bool LowLevel::C_SignFinal(SessionHandle session,
+ Byte* signature_ptr,
+ Ulong* signature_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SignFinal(session, signature_ptr, signature_len_ptr), return_value);
+ }
+
+bool LowLevel::C_SignRecoverInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SignRecoverInit(session, mechanism_ptr, key), return_value);
+ }
+
+bool LowLevel::C_SignRecover(SessionHandle session,
+ Byte* data,
+ Ulong data_len,
+ Byte* signature,
+ Ulong* signature_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SignRecover(session, data, data_len, signature, signature_len),
+ return_value);
+ }
+
+/****************************** Functions for verifying signatures and MACs ******************************/
+
+bool LowLevel::C_VerifyInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_VerifyInit(session, mechanism_ptr, key), return_value);
+ }
+
+bool LowLevel::C_Verify(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* signature_ptr,
+ Ulong signature_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_Verify(session, data_ptr, data_len, signature_ptr, signature_len),
+ return_value);
+ }
+
+bool LowLevel::C_VerifyUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_VerifyUpdate(session, part_ptr, part_len), return_value);
+ }
+
+bool LowLevel::C_VerifyFinal(SessionHandle session,
+ Byte* signature_ptr,
+ Ulong signature_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_VerifyFinal(session, signature_ptr, signature_len), return_value);
+ }
+
+bool LowLevel::C_VerifyRecoverInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_VerifyRecoverInit(session, mechanism_ptr, key), return_value);
+ }
+
+bool LowLevel::C_VerifyRecover(SessionHandle session,
+ Byte* signature_ptr,
+ Ulong signature_len,
+ Byte* data_ptr,
+ Ulong* data_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_VerifyRecover(session, signature_ptr, signature_len, data_ptr,
+ data_len_ptr), return_value);
+ }
+
+/****************************** Dual-purpose cryptographic functions ******************************/
+
+bool LowLevel::C_DigestEncryptUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ Byte* encrypted_part_ptr,
+ Ulong* encrypted_part_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DigestEncryptUpdate(session, part_ptr, part_len, encrypted_part_ptr,
+ encrypted_part_len_ptr), return_value);
+ }
+
+bool LowLevel::C_DecryptDigestUpdate(SessionHandle session,
+ Byte* encrypted_part_ptr,
+ Ulong encrypted_part_len,
+ Byte* part_ptr,
+ Ulong* part_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DecryptDigestUpdate(session, encrypted_part_ptr, encrypted_part_len,
+ part_ptr, part_len_ptr), return_value);
+ }
+
+bool LowLevel::C_SignEncryptUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ Byte* encrypted_part_ptr,
+ Ulong* encrypted_part_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SignEncryptUpdate(session, part_ptr, part_len, encrypted_part_ptr,
+ encrypted_part_len_ptr), return_value);
+ }
+
+bool LowLevel::C_DecryptVerifyUpdate(SessionHandle session,
+ Byte* encrypted_part_ptr,
+ Ulong encrypted_part_len,
+ Byte* part_ptr,
+ Ulong* part_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DecryptVerifyUpdate(session, encrypted_part_ptr, encrypted_part_len,
+ part_ptr, part_len_ptr), return_value);
+ }
+
+/****************************** Key management functions ******************************/
+
+bool LowLevel::C_GenerateKey(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ObjectHandle* key_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GenerateKey(session, mechanism_ptr, attribute_template_ptr, count,
+ key_ptr), return_value);
+ }
+
+bool LowLevel::C_GenerateKeyPair(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ Attribute* public_key_template_ptr,
+ Ulong public_key_attribute_count,
+ Attribute* private_key_template_ptr,
+ Ulong private_key_attribute_count,
+ ObjectHandle* public_key_ptr,
+ ObjectHandle* private_key_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GenerateKeyPair(session, mechanism_ptr, public_key_template_ptr,
+ public_key_attribute_count, private_key_template_ptr,
+ private_key_attribute_count, public_key_ptr, private_key_ptr), return_value);
+ }
+
+bool LowLevel::C_WrapKey(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle wrapping_key,
+ ObjectHandle key,
+ Byte* wrapped_key_ptr,
+ Ulong* wrapped_key_len_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_WrapKey(session, mechanism_ptr, wrapping_key, key, wrapped_key_ptr,
+ wrapped_key_len_ptr), return_value);
+ }
+
+bool LowLevel::C_UnwrapKey(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle unwrapping_key,
+ Byte* wrapped_key_ptr,
+ Ulong wrapped_key_len,
+ Attribute* attribute_template_ptr,
+ Ulong attribute_count,
+ ObjectHandle* key_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_UnwrapKey(session, mechanism_ptr, unwrapping_key, wrapped_key_ptr,
+ wrapped_key_len, attribute_template_ptr,
+ attribute_count, key_ptr), return_value);
+ }
+
+bool LowLevel::C_DeriveKey(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle base_key,
+ Attribute* attribute_template_ptr,
+ Ulong attribute_count,
+ ObjectHandle* key_ptr,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_DeriveKey(session, mechanism_ptr, base_key, attribute_template_ptr,
+ attribute_count, key_ptr), return_value);
+ }
+
+/****************************** Random number generation functions ******************************/
+
+bool LowLevel::C_SeedRandom(SessionHandle session,
+ Byte* seed_ptr,
+ Ulong seed_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_SeedRandom(session, seed_ptr, seed_len), return_value);
+ }
+
+bool LowLevel::C_GenerateRandom(SessionHandle session,
+ Byte* random_data_ptr,
+ Ulong random_len,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GenerateRandom(session, random_data_ptr, random_len), return_value);
+ }
+
+/****************************** Parallel function management functions ******************************/
+
+bool LowLevel::C_GetFunctionStatus(SessionHandle session,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_GetFunctionStatus(session), return_value);
+ }
+
+bool LowLevel::C_CancelFunction(SessionHandle session,
+ ReturnValue* return_value) const
+ {
+ return handle_return_value(m_func_list_ptr->C_CancelFunction(session), return_value);
+ }
+
+}
+
+}
diff --git a/src/lib/prov/pkcs11/p11.h b/src/lib/prov/pkcs11/p11.h
new file mode 100644
index 000000000..c18c07d59
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11.h
@@ -0,0 +1,2861 @@
+/*
+* PKCS#11
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_H__
+#define BOTAN_P11_H__
+
+#include <botan/secmem.h>
+#include <botan/exceptn.h>
+#include <botan/dyn_load.h>
+
+#include <vector>
+#include <string>
+#include <map>
+
+#define BOTAN_PKCS11_RSA_PRIO 90
+#define BOTAN_PKCS11_ECDSA_PRIO 90
+#define BOTAN_PKCS11_ECDH_PRIO 90
+
+#define CK_PTR *
+
+#if defined(_MSC_VER)
+#define CK_DECLARE_FUNCTION(returnType, name) \
+ returnType __declspec(dllimport) name
+#else
+#define CK_DECLARE_FUNCTION(returnType, name) \
+ returnType name
+#endif
+
+#if defined(_MSC_VER)
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ returnType __declspec(dllimport) (* name)
+#else
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ returnType (* name)
+#endif
+
+#define CK_CALLBACK_FUNCTION(returnType, name) \
+ returnType (* name)
+
+#ifndef NULL_PTR
+ #define NULL_PTR nullptr
+#endif
+
+#if defined(_MSC_VER)
+ #pragma pack(push, cryptoki, 1)
+#endif
+
+#include "pkcs11.h"
+
+#if defined(_MSC_VER)
+ #pragma pack(pop, cryptoki)
+#endif
+
+static_assert(CRYPTOKI_VERSION_MAJOR == 2 && CRYPTOKI_VERSION_MINOR == 40,
+ "The Botan PKCS#11 module was implemented against PKCS#11 v2.40. Please use the correct PKCS#11 headers.");
+
+namespace Botan {
+namespace PKCS11 {
+
+using secure_string = secure_vector<byte>;
+
+enum class AttributeType : CK_ATTRIBUTE_TYPE
+ {
+ Class = CKA_CLASS,
+ Token = CKA_TOKEN,
+ Private = CKA_PRIVATE,
+ Label = CKA_LABEL,
+ Application = CKA_APPLICATION,
+ Value = CKA_VALUE,
+ ObjectId = CKA_OBJECT_ID,
+ CertificateType = CKA_CERTIFICATE_TYPE,
+ Issuer = CKA_ISSUER,
+ SerialNumber = CKA_SERIAL_NUMBER,
+ AcIssuer = CKA_AC_ISSUER,
+ Owner = CKA_OWNER,
+ AttrTypes = CKA_ATTR_TYPES,
+ Trusted = CKA_TRUSTED,
+ CertificateCategory = CKA_CERTIFICATE_CATEGORY,
+ JavaMidpSecurityDomain = CKA_JAVA_MIDP_SECURITY_DOMAIN,
+ Url = CKA_URL,
+ HashOfSubjectPublicKey = CKA_HASH_OF_SUBJECT_PUBLIC_KEY,
+ HashOfIssuerPublicKey = CKA_HASH_OF_ISSUER_PUBLIC_KEY,
+ NameHashAlgorithm = CKA_NAME_HASH_ALGORITHM,
+ CheckValue = CKA_CHECK_VALUE,
+ KeyType = CKA_KEY_TYPE,
+ Subject = CKA_SUBJECT,
+ Id = CKA_ID,
+ Sensitive = CKA_SENSITIVE,
+ Encrypt = CKA_ENCRYPT,
+ Decrypt = CKA_DECRYPT,
+ Wrap = CKA_WRAP,
+ Unwrap = CKA_UNWRAP,
+ Sign = CKA_SIGN,
+ SignRecover = CKA_SIGN_RECOVER,
+ Verify = CKA_VERIFY,
+ VerifyRecover = CKA_VERIFY_RECOVER,
+ Derive = CKA_DERIVE,
+ StartDate = CKA_START_DATE,
+ EndDate = CKA_END_DATE,
+ Modulus = CKA_MODULUS,
+ ModulusBits = CKA_MODULUS_BITS,
+ PublicExponent = CKA_PUBLIC_EXPONENT,
+ PrivateExponent = CKA_PRIVATE_EXPONENT,
+ Prime1 = CKA_PRIME_1,
+ Prime2 = CKA_PRIME_2,
+ Exponent1 = CKA_EXPONENT_1,
+ Exponent2 = CKA_EXPONENT_2,
+ Coefficient = CKA_COEFFICIENT,
+ PublicKeyInfo = CKA_PUBLIC_KEY_INFO,
+ Prime = CKA_PRIME,
+ Subprime = CKA_SUBPRIME,
+ Base = CKA_BASE,
+ PrimeBits = CKA_PRIME_BITS,
+ SubprimeBits = CKA_SUBPRIME_BITS,
+ SubPrimeBits = CKA_SUB_PRIME_BITS,
+ ValueBits = CKA_VALUE_BITS,
+ ValueLen = CKA_VALUE_LEN,
+ Extractable = CKA_EXTRACTABLE,
+ Local = CKA_LOCAL,
+ NeverExtractable = CKA_NEVER_EXTRACTABLE,
+ AlwaysSensitive = CKA_ALWAYS_SENSITIVE,
+ KeyGenMechanism = CKA_KEY_GEN_MECHANISM,
+ Modifiable = CKA_MODIFIABLE,
+ Copyable = CKA_COPYABLE,
+ Destroyable = CKA_DESTROYABLE,
+ EcdsaParams = CKA_ECDSA_PARAMS,
+ EcParams = CKA_EC_PARAMS,
+ EcPoint = CKA_EC_POINT,
+ SecondaryAuth = CKA_SECONDARY_AUTH,
+ AuthPinFlags = CKA_AUTH_PIN_FLAGS,
+ AlwaysAuthenticate = CKA_ALWAYS_AUTHENTICATE,
+ WrapWithTrusted = CKA_WRAP_WITH_TRUSTED,
+ WrapTemplate = CKA_WRAP_TEMPLATE,
+ UnwrapTemplate = CKA_UNWRAP_TEMPLATE,
+ DeriveTemplate = CKA_DERIVE_TEMPLATE,
+ OtpFormat = CKA_OTP_FORMAT,
+ OtpLength = CKA_OTP_LENGTH,
+ OtpTimeInterval = CKA_OTP_TIME_INTERVAL,
+ OtpUserFriendlyMode = CKA_OTP_USER_FRIENDLY_MODE,
+ OtpChallengeRequirement = CKA_OTP_CHALLENGE_REQUIREMENT,
+ OtpTimeRequirement = CKA_OTP_TIME_REQUIREMENT,
+ OtpCounterRequirement = CKA_OTP_COUNTER_REQUIREMENT,
+ OtpPinRequirement = CKA_OTP_PIN_REQUIREMENT,
+ OtpCounter = CKA_OTP_COUNTER,
+ OtpTime = CKA_OTP_TIME,
+ OtpUserIdentifier = CKA_OTP_USER_IDENTIFIER,
+ OtpServiceIdentifier = CKA_OTP_SERVICE_IDENTIFIER,
+ OtpServiceLogo = CKA_OTP_SERVICE_LOGO,
+ OtpServiceLogoType = CKA_OTP_SERVICE_LOGO_TYPE,
+ Gostr3410Params = CKA_GOSTR3410_PARAMS,
+ Gostr3411Params = CKA_GOSTR3411_PARAMS,
+ Gost28147Params = CKA_GOST28147_PARAMS,
+ HwFeatureType = CKA_HW_FEATURE_TYPE,
+ ResetOnInit = CKA_RESET_ON_INIT,
+ HasReset = CKA_HAS_RESET,
+ PixelX = CKA_PIXEL_X,
+ PixelY = CKA_PIXEL_Y,
+ Resolution = CKA_RESOLUTION,
+ CharRows = CKA_CHAR_ROWS,
+ CharColumns = CKA_CHAR_COLUMNS,
+ Color = CKA_COLOR,
+ BitsPerPixel = CKA_BITS_PER_PIXEL,
+ CharSets = CKA_CHAR_SETS,
+ EncodingMethods = CKA_ENCODING_METHODS,
+ MimeTypes = CKA_MIME_TYPES,
+ MechanismType = CKA_MECHANISM_TYPE,
+ RequiredCmsAttributes = CKA_REQUIRED_CMS_ATTRIBUTES,
+ DefaultCmsAttributes = CKA_DEFAULT_CMS_ATTRIBUTES,
+ SupportedCmsAttributes = CKA_SUPPORTED_CMS_ATTRIBUTES,
+ AllowedMechanisms = CKA_ALLOWED_MECHANISMS,
+ VendorDefined = CKA_VENDOR_DEFINED,
+ };
+
+enum class CertificateType : CK_CERTIFICATE_TYPE
+ {
+ X509 = CKC_X_509,
+ X509AttrCert = CKC_X_509_ATTR_CERT,
+ Wtls = CKC_WTLS,
+ VendorDefined = CKC_VENDOR_DEFINED,
+ };
+
+/// Indicates if a stored certificate is a user certificate for which the corresponding private key is available
+/// on the token ("token user"), a CA certificate ("authority"), or another end-entity certificate ("other entity").
+enum class CertificateCategory : CK_ULONG
+ {
+ Unspecified = CK_CERTIFICATE_CATEGORY_UNSPECIFIED,
+ TokenUser = CK_CERTIFICATE_CATEGORY_TOKEN_USER,
+ Authority = CK_CERTIFICATE_CATEGORY_AUTHORITY,
+ OtherEntity = CK_CERTIFICATE_CATEGORY_OTHER_ENTITY
+ };
+
+enum class KeyDerivation : CK_ULONG
+ {
+ Null = CKD_NULL,
+ Sha1Kdf = CKD_SHA1_KDF,
+ Sha1KdfAsn1 = CKD_SHA1_KDF_ASN1,
+ Sha1KdfConcatenate = CKD_SHA1_KDF_CONCATENATE,
+ Sha224Kdf = CKD_SHA224_KDF,
+ Sha256Kdf = CKD_SHA256_KDF,
+ Sha384Kdf = CKD_SHA384_KDF,
+ Sha512Kdf = CKD_SHA512_KDF,
+ CpdiversifyKdf = CKD_CPDIVERSIFY_KDF,
+ };
+
+enum class Flag : CK_FLAGS
+ {
+ None = 0,
+ TokenPresent = CKF_TOKEN_PRESENT,
+ RemovableDevice = CKF_REMOVABLE_DEVICE,
+ HwSlot = CKF_HW_SLOT,
+ Rng = CKF_RNG,
+ WriteProtected = CKF_WRITE_PROTECTED,
+ LoginRequired = CKF_LOGIN_REQUIRED,
+ UserPinInitialized = CKF_USER_PIN_INITIALIZED,
+ RestoreKeyNotNeeded = CKF_RESTORE_KEY_NOT_NEEDED,
+ ClockOnToken = CKF_CLOCK_ON_TOKEN,
+ ProtectedAuthenticationPath = CKF_PROTECTED_AUTHENTICATION_PATH,
+ DualCryptoOperations = CKF_DUAL_CRYPTO_OPERATIONS,
+ TokenInitialized = CKF_TOKEN_INITIALIZED,
+ SecondaryAuthentication = CKF_SECONDARY_AUTHENTICATION,
+ UserPinCountLow = CKF_USER_PIN_COUNT_LOW,
+ UserPinFinalTry = CKF_USER_PIN_FINAL_TRY,
+ UserPinLocked = CKF_USER_PIN_LOCKED,
+ UserPinToBeChanged = CKF_USER_PIN_TO_BE_CHANGED,
+ SoPinCountLow = CKF_SO_PIN_COUNT_LOW,
+ SoPinFinalTry = CKF_SO_PIN_FINAL_TRY,
+ SoPinLocked = CKF_SO_PIN_LOCKED,
+ SoPinToBeChanged = CKF_SO_PIN_TO_BE_CHANGED,
+ ErrorState = CKF_ERROR_STATE,
+ RwSession = CKF_RW_SESSION,
+ SerialSession = CKF_SERIAL_SESSION,
+ ArrayAttribute = CKF_ARRAY_ATTRIBUTE,
+ Hw = CKF_HW,
+ Encrypt = CKF_ENCRYPT,
+ Decrypt = CKF_DECRYPT,
+ Digest = CKF_DIGEST,
+ Sign = CKF_SIGN,
+ SignRecover = CKF_SIGN_RECOVER,
+ Verify = CKF_VERIFY,
+ VerifyRecover = CKF_VERIFY_RECOVER,
+ Generate = CKF_GENERATE,
+ GenerateKeyPair = CKF_GENERATE_KEY_PAIR,
+ Wrap = CKF_WRAP,
+ Unwrap = CKF_UNWRAP,
+ Derive = CKF_DERIVE,
+ EcFP = CKF_EC_F_P,
+ EcF2m = CKF_EC_F_2M,
+ EcEcparameters = CKF_EC_ECPARAMETERS,
+ EcNamedcurve = CKF_EC_NAMEDCURVE,
+ EcUncompress = CKF_EC_UNCOMPRESS,
+ EcCompress = CKF_EC_COMPRESS,
+ Extension = CKF_EXTENSION,
+ LibraryCantCreateOsThreads = CKF_LIBRARY_CANT_CREATE_OS_THREADS,
+ OsLockingOk = CKF_OS_LOCKING_OK,
+ DontBlock = CKF_DONT_BLOCK,
+ NextOtp = CKF_NEXT_OTP,
+ ExcludeTime = CKF_EXCLUDE_TIME,
+ ExcludeCounter = CKF_EXCLUDE_COUNTER,
+ ExcludeChallenge = CKF_EXCLUDE_CHALLENGE,
+ ExcludePin = CKF_EXCLUDE_PIN,
+ UserFriendlyOtp = CKF_USER_FRIENDLY_OTP,
+ };
+
+inline Flag operator | (Flag a, Flag b)
+ {
+ return static_cast< Flag >(static_cast< CK_FLAGS >(a) | static_cast< CK_FLAGS >(b));
+ }
+
+enum class MGF : CK_RSA_PKCS_MGF_TYPE
+ {
+ Mgf1Sha1 = CKG_MGF1_SHA1,
+ Mgf1Sha256 = CKG_MGF1_SHA256,
+ Mgf1Sha384 = CKG_MGF1_SHA384,
+ Mgf1Sha512 = CKG_MGF1_SHA512,
+ Mgf1Sha224 = CKG_MGF1_SHA224,
+ };
+
+enum class HardwareType : CK_HW_FEATURE_TYPE
+ {
+ MonotonicCounter = CKH_MONOTONIC_COUNTER,
+ Clock = CKH_CLOCK,
+ UserInterface = CKH_USER_INTERFACE,
+ VendorDefined = CKH_VENDOR_DEFINED,
+ };
+
+enum class KeyType : CK_KEY_TYPE
+ {
+ Rsa = CKK_RSA,
+ Dsa = CKK_DSA,
+ Dh = CKK_DH,
+ Ecdsa = CKK_ECDSA,
+ Ec = CKK_EC,
+ X942Dh = CKK_X9_42_DH,
+ Kea = CKK_KEA,
+ GenericSecret = CKK_GENERIC_SECRET,
+ Rc2 = CKK_RC2,
+ Rc4 = CKK_RC4,
+ Des = CKK_DES,
+ Des2 = CKK_DES2,
+ Des3 = CKK_DES3,
+ Cast = CKK_CAST,
+ Cast3 = CKK_CAST3,
+ Cast5 = CKK_CAST5,
+ Cast128 = CKK_CAST128,
+ Rc5 = CKK_RC5,
+ Idea = CKK_IDEA,
+ Skipjack = CKK_SKIPJACK,
+ Baton = CKK_BATON,
+ Juniper = CKK_JUNIPER,
+ Cdmf = CKK_CDMF,
+ Aes = CKK_AES,
+ Blowfish = CKK_BLOWFISH,
+ Twofish = CKK_TWOFISH,
+ Securid = CKK_SECURID,
+ Hotp = CKK_HOTP,
+ Acti = CKK_ACTI,
+ Camellia = CKK_CAMELLIA,
+ Aria = CKK_ARIA,
+ Md5Hmac = CKK_MD5_HMAC,
+ Sha1Hmac = CKK_SHA_1_HMAC,
+ Ripemd128Hmac = CKK_RIPEMD128_HMAC,
+ Ripemd160Hmac = CKK_RIPEMD160_HMAC,
+ Sha256Hmac = CKK_SHA256_HMAC,
+ Sha384Hmac = CKK_SHA384_HMAC,
+ Sha512Hmac = CKK_SHA512_HMAC,
+ Sha224Hmac = CKK_SHA224_HMAC,
+ Seed = CKK_SEED,
+ Gostr3410 = CKK_GOSTR3410,
+ Gostr3411 = CKK_GOSTR3411,
+ Gost28147 = CKK_GOST28147,
+ VendorDefined = CKK_VENDOR_DEFINED,
+ };
+
+enum class MechanismType : CK_MECHANISM_TYPE
+ {
+ RsaPkcsKeyPairGen = CKM_RSA_PKCS_KEY_PAIR_GEN,
+ RsaPkcs = CKM_RSA_PKCS,
+ Rsa9796 = CKM_RSA_9796,
+ RsaX509 = CKM_RSA_X_509,
+ Md2RsaPkcs = CKM_MD2_RSA_PKCS,
+ Md5RsaPkcs = CKM_MD5_RSA_PKCS,
+ Sha1RsaPkcs = CKM_SHA1_RSA_PKCS,
+ Ripemd128RsaPkcs = CKM_RIPEMD128_RSA_PKCS,
+ Ripemd160RsaPkcs = CKM_RIPEMD160_RSA_PKCS,
+ RsaPkcsOaep = CKM_RSA_PKCS_OAEP,
+ RsaX931KeyPairGen = CKM_RSA_X9_31_KEY_PAIR_GEN,
+ RsaX931 = CKM_RSA_X9_31,
+ Sha1RsaX931 = CKM_SHA1_RSA_X9_31,
+ RsaPkcsPss = CKM_RSA_PKCS_PSS,
+ Sha1RsaPkcsPss = CKM_SHA1_RSA_PKCS_PSS,
+ DsaKeyPairGen = CKM_DSA_KEY_PAIR_GEN,
+ Dsa = CKM_DSA,
+ DsaSha1 = CKM_DSA_SHA1,
+ DsaSha224 = CKM_DSA_SHA224,
+ DsaSha256 = CKM_DSA_SHA256,
+ DsaSha384 = CKM_DSA_SHA384,
+ DsaSha512 = CKM_DSA_SHA512,
+ DhPkcsKeyPairGen = CKM_DH_PKCS_KEY_PAIR_GEN,
+ DhPkcsDerive = CKM_DH_PKCS_DERIVE,
+ X942DhKeyPairGen = CKM_X9_42_DH_KEY_PAIR_GEN,
+ X942DhDerive = CKM_X9_42_DH_DERIVE,
+ X942DhHybridDerive = CKM_X9_42_DH_HYBRID_DERIVE,
+ X942MqvDerive = CKM_X9_42_MQV_DERIVE,
+ Sha256RsaPkcs = CKM_SHA256_RSA_PKCS,
+ Sha384RsaPkcs = CKM_SHA384_RSA_PKCS,
+ Sha512RsaPkcs = CKM_SHA512_RSA_PKCS,
+ Sha256RsaPkcsPss = CKM_SHA256_RSA_PKCS_PSS,
+ Sha384RsaPkcsPss = CKM_SHA384_RSA_PKCS_PSS,
+ Sha512RsaPkcsPss = CKM_SHA512_RSA_PKCS_PSS,
+ Sha224RsaPkcs = CKM_SHA224_RSA_PKCS,
+ Sha224RsaPkcsPss = CKM_SHA224_RSA_PKCS_PSS,
+ Sha512224 = CKM_SHA512_224,
+ Sha512224Hmac = CKM_SHA512_224_HMAC,
+ Sha512224HmacGeneral = CKM_SHA512_224_HMAC_GENERAL,
+ Sha512224KeyDerivation = CKM_SHA512_224_KEY_DERIVATION,
+ Sha512256 = CKM_SHA512_256,
+ Sha512256Hmac = CKM_SHA512_256_HMAC,
+ Sha512256HmacGeneral = CKM_SHA512_256_HMAC_GENERAL,
+ Sha512256KeyDerivation = CKM_SHA512_256_KEY_DERIVATION,
+ Sha512T = CKM_SHA512_T,
+ Sha512THmac = CKM_SHA512_T_HMAC,
+ Sha512THmacGeneral = CKM_SHA512_T_HMAC_GENERAL,
+ Sha512TKeyDerivation = CKM_SHA512_T_KEY_DERIVATION,
+ Rc2KeyGen = CKM_RC2_KEY_GEN,
+ Rc2Ecb = CKM_RC2_ECB,
+ Rc2Cbc = CKM_RC2_CBC,
+ Rc2Mac = CKM_RC2_MAC,
+ Rc2MacGeneral = CKM_RC2_MAC_GENERAL,
+ Rc2CbcPad = CKM_RC2_CBC_PAD,
+ Rc4KeyGen = CKM_RC4_KEY_GEN,
+ Rc4 = CKM_RC4,
+ DesKeyGen = CKM_DES_KEY_GEN,
+ DesEcb = CKM_DES_ECB,
+ DesCbc = CKM_DES_CBC,
+ DesMac = CKM_DES_MAC,
+ DesMacGeneral = CKM_DES_MAC_GENERAL,
+ DesCbcPad = CKM_DES_CBC_PAD,
+ Des2KeyGen = CKM_DES2_KEY_GEN,
+ Des3KeyGen = CKM_DES3_KEY_GEN,
+ Des3Ecb = CKM_DES3_ECB,
+ Des3Cbc = CKM_DES3_CBC,
+ Des3Mac = CKM_DES3_MAC,
+ Des3MacGeneral = CKM_DES3_MAC_GENERAL,
+ Des3CbcPad = CKM_DES3_CBC_PAD,
+ Des3CmacGeneral = CKM_DES3_CMAC_GENERAL,
+ Des3Cmac = CKM_DES3_CMAC,
+ CdmfKeyGen = CKM_CDMF_KEY_GEN,
+ CdmfEcb = CKM_CDMF_ECB,
+ CdmfCbc = CKM_CDMF_CBC,
+ CdmfMac = CKM_CDMF_MAC,
+ CdmfMacGeneral = CKM_CDMF_MAC_GENERAL,
+ CdmfCbcPad = CKM_CDMF_CBC_PAD,
+ DesOfb64 = CKM_DES_OFB64,
+ DesOfb8 = CKM_DES_OFB8,
+ DesCfb64 = CKM_DES_CFB64,
+ DesCfb8 = CKM_DES_CFB8,
+ Md2 = CKM_MD2,
+ Md2Hmac = CKM_MD2_HMAC,
+ Md2HmacGeneral = CKM_MD2_HMAC_GENERAL,
+ Md5 = CKM_MD5,
+ Md5Hmac = CKM_MD5_HMAC,
+ Md5HmacGeneral = CKM_MD5_HMAC_GENERAL,
+ Sha1 = CKM_SHA_1,
+ Sha1Hmac = CKM_SHA_1_HMAC,
+ Sha1HmacGeneral = CKM_SHA_1_HMAC_GENERAL,
+ Ripemd128 = CKM_RIPEMD128,
+ Ripemd128Hmac = CKM_RIPEMD128_HMAC,
+ Ripemd128HmacGeneral = CKM_RIPEMD128_HMAC_GENERAL,
+ Ripemd160 = CKM_RIPEMD160,
+ Ripemd160Hmac = CKM_RIPEMD160_HMAC,
+ Ripemd160HmacGeneral = CKM_RIPEMD160_HMAC_GENERAL,
+ Sha256 = CKM_SHA256,
+ Sha256Hmac = CKM_SHA256_HMAC,
+ Sha256HmacGeneral = CKM_SHA256_HMAC_GENERAL,
+ Sha224 = CKM_SHA224,
+ Sha224Hmac = CKM_SHA224_HMAC,
+ Sha224HmacGeneral = CKM_SHA224_HMAC_GENERAL,
+ Sha384 = CKM_SHA384,
+ Sha384Hmac = CKM_SHA384_HMAC,
+ Sha384HmacGeneral = CKM_SHA384_HMAC_GENERAL,
+ Sha512 = CKM_SHA512,
+ Sha512Hmac = CKM_SHA512_HMAC,
+ Sha512HmacGeneral = CKM_SHA512_HMAC_GENERAL,
+ SecuridKeyGen = CKM_SECURID_KEY_GEN,
+ Securid = CKM_SECURID,
+ HotpKeyGen = CKM_HOTP_KEY_GEN,
+ Hotp = CKM_HOTP,
+ Acti = CKM_ACTI,
+ ActiKeyGen = CKM_ACTI_KEY_GEN,
+ CastKeyGen = CKM_CAST_KEY_GEN,
+ CastEcb = CKM_CAST_ECB,
+ CastCbc = CKM_CAST_CBC,
+ CastMac = CKM_CAST_MAC,
+ CastMacGeneral = CKM_CAST_MAC_GENERAL,
+ CastCbcPad = CKM_CAST_CBC_PAD,
+ Cast3KeyGen = CKM_CAST3_KEY_GEN,
+ Cast3Ecb = CKM_CAST3_ECB,
+ Cast3Cbc = CKM_CAST3_CBC,
+ Cast3Mac = CKM_CAST3_MAC,
+ Cast3MacGeneral = CKM_CAST3_MAC_GENERAL,
+ Cast3CbcPad = CKM_CAST3_CBC_PAD,
+ Cast5KeyGen = CKM_CAST5_KEY_GEN,
+ Cast128KeyGen = CKM_CAST128_KEY_GEN,
+ Cast5Ecb = CKM_CAST5_ECB,
+ Cast128Ecb = CKM_CAST128_ECB,
+ Cast5Cbc = CKM_CAST5_CBC,
+ Cast128Cbc = CKM_CAST128_CBC,
+ Cast5Mac = CKM_CAST5_MAC,
+ Cast128Mac = CKM_CAST128_MAC,
+ Cast5MacGeneral = CKM_CAST5_MAC_GENERAL,
+ Cast128MacGeneral = CKM_CAST128_MAC_GENERAL,
+ Cast5CbcPad = CKM_CAST5_CBC_PAD,
+ Cast128CbcPad = CKM_CAST128_CBC_PAD,
+ Rc5KeyGen = CKM_RC5_KEY_GEN,
+ Rc5Ecb = CKM_RC5_ECB,
+ Rc5Cbc = CKM_RC5_CBC,
+ Rc5Mac = CKM_RC5_MAC,
+ Rc5MacGeneral = CKM_RC5_MAC_GENERAL,
+ Rc5CbcPad = CKM_RC5_CBC_PAD,
+ IdeaKeyGen = CKM_IDEA_KEY_GEN,
+ IdeaEcb = CKM_IDEA_ECB,
+ IdeaCbc = CKM_IDEA_CBC,
+ IdeaMac = CKM_IDEA_MAC,
+ IdeaMacGeneral = CKM_IDEA_MAC_GENERAL,
+ IdeaCbcPad = CKM_IDEA_CBC_PAD,
+ GenericSecretKeyGen = CKM_GENERIC_SECRET_KEY_GEN,
+ ConcatenateBaseAndKey = CKM_CONCATENATE_BASE_AND_KEY,
+ ConcatenateBaseAndData = CKM_CONCATENATE_BASE_AND_DATA,
+ ConcatenateDataAndBase = CKM_CONCATENATE_DATA_AND_BASE,
+ XorBaseAndData = CKM_XOR_BASE_AND_DATA,
+ ExtractKeyFromKey = CKM_EXTRACT_KEY_FROM_KEY,
+ Ssl3PreMasterKeyGen = CKM_SSL3_PRE_MASTER_KEY_GEN,
+ Ssl3MasterKeyDerive = CKM_SSL3_MASTER_KEY_DERIVE,
+ Ssl3KeyAndMacDerive = CKM_SSL3_KEY_AND_MAC_DERIVE,
+ Ssl3MasterKeyDeriveDh = CKM_SSL3_MASTER_KEY_DERIVE_DH,
+ TlsPreMasterKeyGen = CKM_TLS_PRE_MASTER_KEY_GEN,
+ TlsMasterKeyDerive = CKM_TLS_MASTER_KEY_DERIVE,
+ TlsKeyAndMacDerive = CKM_TLS_KEY_AND_MAC_DERIVE,
+ TlsMasterKeyDeriveDh = CKM_TLS_MASTER_KEY_DERIVE_DH,
+ TlsPrf = CKM_TLS_PRF,
+ Ssl3Md5Mac = CKM_SSL3_MD5_MAC,
+ Ssl3Sha1Mac = CKM_SSL3_SHA1_MAC,
+ Md5KeyDerivation = CKM_MD5_KEY_DERIVATION,
+ Md2KeyDerivation = CKM_MD2_KEY_DERIVATION,
+ Sha1KeyDerivation = CKM_SHA1_KEY_DERIVATION,
+ Sha256KeyDerivation = CKM_SHA256_KEY_DERIVATION,
+ Sha384KeyDerivation = CKM_SHA384_KEY_DERIVATION,
+ Sha512KeyDerivation = CKM_SHA512_KEY_DERIVATION,
+ Sha224KeyDerivation = CKM_SHA224_KEY_DERIVATION,
+ PbeMd2DesCbc = CKM_PBE_MD2_DES_CBC,
+ PbeMd5DesCbc = CKM_PBE_MD5_DES_CBC,
+ PbeMd5CastCbc = CKM_PBE_MD5_CAST_CBC,
+ PbeMd5Cast3Cbc = CKM_PBE_MD5_CAST3_CBC,
+ PbeMd5Cast5Cbc = CKM_PBE_MD5_CAST5_CBC,
+ PbeMd5Cast128Cbc = CKM_PBE_MD5_CAST128_CBC,
+ PbeSha1Cast5Cbc = CKM_PBE_SHA1_CAST5_CBC,
+ PbeSha1Cast128Cbc = CKM_PBE_SHA1_CAST128_CBC,
+ PbeSha1Rc4128 = CKM_PBE_SHA1_RC4_128,
+ PbeSha1Rc440 = CKM_PBE_SHA1_RC4_40,
+ PbeSha1Des3EdeCbc = CKM_PBE_SHA1_DES3_EDE_CBC,
+ PbeSha1Des2EdeCbc = CKM_PBE_SHA1_DES2_EDE_CBC,
+ PbeSha1Rc2128Cbc = CKM_PBE_SHA1_RC2_128_CBC,
+ PbeSha1Rc240Cbc = CKM_PBE_SHA1_RC2_40_CBC,
+ Pkcs5Pbkd2 = CKM_PKCS5_PBKD2,
+ PbaSha1WithSha1Hmac = CKM_PBA_SHA1_WITH_SHA1_HMAC,
+ WtlsPreMasterKeyGen = CKM_WTLS_PRE_MASTER_KEY_GEN,
+ WtlsMasterKeyDerive = CKM_WTLS_MASTER_KEY_DERIVE,
+ WtlsMasterKeyDeriveDhEcc = CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC,
+ WtlsPrf = CKM_WTLS_PRF,
+ WtlsServerKeyAndMacDerive = CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE,
+ WtlsClientKeyAndMacDerive = CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE,
+ Tls10MacServer = CKM_TLS10_MAC_SERVER,
+ Tls10MacClient = CKM_TLS10_MAC_CLIENT,
+ Tls12Mac = CKM_TLS12_MAC,
+ Tls12Kdf = CKM_TLS12_KDF,
+ Tls12MasterKeyDerive = CKM_TLS12_MASTER_KEY_DERIVE,
+ Tls12KeyAndMacDerive = CKM_TLS12_KEY_AND_MAC_DERIVE,
+ Tls12MasterKeyDeriveDh = CKM_TLS12_MASTER_KEY_DERIVE_DH,
+ Tls12KeySafeDerive = CKM_TLS12_KEY_SAFE_DERIVE,
+ TlsMac = CKM_TLS_MAC,
+ TlsKdf = CKM_TLS_KDF,
+ KeyWrapLynks = CKM_KEY_WRAP_LYNKS,
+ KeyWrapSetOaep = CKM_KEY_WRAP_SET_OAEP,
+ CmsSig = CKM_CMS_SIG,
+ KipDerive = CKM_KIP_DERIVE,
+ KipWrap = CKM_KIP_WRAP,
+ KipMac = CKM_KIP_MAC,
+ CamelliaKeyGen = CKM_CAMELLIA_KEY_GEN,
+ CamelliaEcb = CKM_CAMELLIA_ECB,
+ CamelliaCbc = CKM_CAMELLIA_CBC,
+ CamelliaMac = CKM_CAMELLIA_MAC,
+ CamelliaMacGeneral = CKM_CAMELLIA_MAC_GENERAL,
+ CamelliaCbcPad = CKM_CAMELLIA_CBC_PAD,
+ CamelliaEcbEncryptData = CKM_CAMELLIA_ECB_ENCRYPT_DATA,
+ CamelliaCbcEncryptData = CKM_CAMELLIA_CBC_ENCRYPT_DATA,
+ CamelliaCtr = CKM_CAMELLIA_CTR,
+ AriaKeyGen = CKM_ARIA_KEY_GEN,
+ AriaEcb = CKM_ARIA_ECB,
+ AriaCbc = CKM_ARIA_CBC,
+ AriaMac = CKM_ARIA_MAC,
+ AriaMacGeneral = CKM_ARIA_MAC_GENERAL,
+ AriaCbcPad = CKM_ARIA_CBC_PAD,
+ AriaEcbEncryptData = CKM_ARIA_ECB_ENCRYPT_DATA,
+ AriaCbcEncryptData = CKM_ARIA_CBC_ENCRYPT_DATA,
+ SeedKeyGen = CKM_SEED_KEY_GEN,
+ SeedEcb = CKM_SEED_ECB,
+ SeedCbc = CKM_SEED_CBC,
+ SeedMac = CKM_SEED_MAC,
+ SeedMacGeneral = CKM_SEED_MAC_GENERAL,
+ SeedCbcPad = CKM_SEED_CBC_PAD,
+ SeedEcbEncryptData = CKM_SEED_ECB_ENCRYPT_DATA,
+ SeedCbcEncryptData = CKM_SEED_CBC_ENCRYPT_DATA,
+ SkipjackKeyGen = CKM_SKIPJACK_KEY_GEN,
+ SkipjackEcb64 = CKM_SKIPJACK_ECB64,
+ SkipjackCbc64 = CKM_SKIPJACK_CBC64,
+ SkipjackOfb64 = CKM_SKIPJACK_OFB64,
+ SkipjackCfb64 = CKM_SKIPJACK_CFB64,
+ SkipjackCfb32 = CKM_SKIPJACK_CFB32,
+ SkipjackCfb16 = CKM_SKIPJACK_CFB16,
+ SkipjackCfb8 = CKM_SKIPJACK_CFB8,
+ SkipjackWrap = CKM_SKIPJACK_WRAP,
+ SkipjackPrivateWrap = CKM_SKIPJACK_PRIVATE_WRAP,
+ SkipjackRelayx = CKM_SKIPJACK_RELAYX,
+ KeaKeyPairGen = CKM_KEA_KEY_PAIR_GEN,
+ KeaKeyDerive = CKM_KEA_KEY_DERIVE,
+ KeaDerive = CKM_KEA_DERIVE,
+ FortezzaTimestamp = CKM_FORTEZZA_TIMESTAMP,
+ BatonKeyGen = CKM_BATON_KEY_GEN,
+ BatonEcb128 = CKM_BATON_ECB128,
+ BatonEcb96 = CKM_BATON_ECB96,
+ BatonCbc128 = CKM_BATON_CBC128,
+ BatonCounter = CKM_BATON_COUNTER,
+ BatonShuffle = CKM_BATON_SHUFFLE,
+ BatonWrap = CKM_BATON_WRAP,
+ EcdsaKeyPairGen = CKM_ECDSA_KEY_PAIR_GEN,
+ EcKeyPairGen = CKM_EC_KEY_PAIR_GEN,
+ Ecdsa = CKM_ECDSA,
+ EcdsaSha1 = CKM_ECDSA_SHA1,
+ EcdsaSha224 = CKM_ECDSA_SHA224,
+ EcdsaSha256 = CKM_ECDSA_SHA256,
+ EcdsaSha384 = CKM_ECDSA_SHA384,
+ EcdsaSha512 = CKM_ECDSA_SHA512,
+ Ecdh1Derive = CKM_ECDH1_DERIVE,
+ Ecdh1CofactorDerive = CKM_ECDH1_COFACTOR_DERIVE,
+ EcmqvDerive = CKM_ECMQV_DERIVE,
+ EcdhAesKeyWrap = CKM_ECDH_AES_KEY_WRAP,
+ RsaAesKeyWrap = CKM_RSA_AES_KEY_WRAP,
+ JuniperKeyGen = CKM_JUNIPER_KEY_GEN,
+ JuniperEcb128 = CKM_JUNIPER_ECB128,
+ JuniperCbc128 = CKM_JUNIPER_CBC128,
+ JuniperCounter = CKM_JUNIPER_COUNTER,
+ JuniperShuffle = CKM_JUNIPER_SHUFFLE,
+ JuniperWrap = CKM_JUNIPER_WRAP,
+ Fasthash = CKM_FASTHASH,
+ AesKeyGen = CKM_AES_KEY_GEN,
+ AesEcb = CKM_AES_ECB,
+ AesCbc = CKM_AES_CBC,
+ AesMac = CKM_AES_MAC,
+ AesMacGeneral = CKM_AES_MAC_GENERAL,
+ AesCbcPad = CKM_AES_CBC_PAD,
+ AesCtr = CKM_AES_CTR,
+ AesGcm = CKM_AES_GCM,
+ AesCcm = CKM_AES_CCM,
+ AesCts = CKM_AES_CTS,
+ AesCmac = CKM_AES_CMAC,
+ AesCmacGeneral = CKM_AES_CMAC_GENERAL,
+ AesXcbcMac = CKM_AES_XCBC_MAC,
+ AesXcbcMac96 = CKM_AES_XCBC_MAC_96,
+ AesGmac = CKM_AES_GMAC,
+ BlowfishKeyGen = CKM_BLOWFISH_KEY_GEN,
+ BlowfishCbc = CKM_BLOWFISH_CBC,
+ TwofishKeyGen = CKM_TWOFISH_KEY_GEN,
+ TwofishCbc = CKM_TWOFISH_CBC,
+ BlowfishCbcPad = CKM_BLOWFISH_CBC_PAD,
+ TwofishCbcPad = CKM_TWOFISH_CBC_PAD,
+ DesEcbEncryptData = CKM_DES_ECB_ENCRYPT_DATA,
+ DesCbcEncryptData = CKM_DES_CBC_ENCRYPT_DATA,
+ Des3EcbEncryptData = CKM_DES3_ECB_ENCRYPT_DATA,
+ Des3CbcEncryptData = CKM_DES3_CBC_ENCRYPT_DATA,
+ AesEcbEncryptData = CKM_AES_ECB_ENCRYPT_DATA,
+ AesCbcEncryptData = CKM_AES_CBC_ENCRYPT_DATA,
+ Gostr3410KeyPairGen = CKM_GOSTR3410_KEY_PAIR_GEN,
+ Gostr3410 = CKM_GOSTR3410,
+ Gostr3410WithGostr3411 = CKM_GOSTR3410_WITH_GOSTR3411,
+ Gostr3410KeyWrap = CKM_GOSTR3410_KEY_WRAP,
+ Gostr3410Derive = CKM_GOSTR3410_DERIVE,
+ Gostr3411 = CKM_GOSTR3411,
+ Gostr3411Hmac = CKM_GOSTR3411_HMAC,
+ Gost28147KeyGen = CKM_GOST28147_KEY_GEN,
+ Gost28147Ecb = CKM_GOST28147_ECB,
+ Gost28147 = CKM_GOST28147,
+ Gost28147Mac = CKM_GOST28147_MAC,
+ Gost28147KeyWrap = CKM_GOST28147_KEY_WRAP,
+ DsaParameterGen = CKM_DSA_PARAMETER_GEN,
+ DhPkcsParameterGen = CKM_DH_PKCS_PARAMETER_GEN,
+ X942DhParameterGen = CKM_X9_42_DH_PARAMETER_GEN,
+ DsaProbablisticParameterGen = CKM_DSA_PROBABLISTIC_PARAMETER_GEN,
+ DsaShaweTaylorParameterGen = CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN,
+ AesOfb = CKM_AES_OFB,
+ AesCfb64 = CKM_AES_CFB64,
+ AesCfb8 = CKM_AES_CFB8,
+ AesCfb128 = CKM_AES_CFB128,
+ AesCfb1 = CKM_AES_CFB1,
+ AesKeyWrap = CKM_AES_KEY_WRAP,
+ AesKeyWrapPad = CKM_AES_KEY_WRAP_PAD,
+ RsaPkcsTpm11 = CKM_RSA_PKCS_TPM_1_1,
+ RsaPkcsOaepTpm11 = CKM_RSA_PKCS_OAEP_TPM_1_1,
+ VendorDefined = CKM_VENDOR_DEFINED,
+ };
+
+enum class Notification : CK_NOTIFICATION
+ {
+ Surrender = CKN_SURRENDER,
+ OtpChanged = CKN_OTP_CHANGED,
+ };
+
+enum class ObjectClass : CK_OBJECT_CLASS
+ {
+ Data = CKO_DATA,
+ Certificate = CKO_CERTIFICATE,
+ PublicKey = CKO_PUBLIC_KEY,
+ PrivateKey = CKO_PRIVATE_KEY,
+ SecretKey = CKO_SECRET_KEY,
+ HwFeature = CKO_HW_FEATURE,
+ DomainParameters = CKO_DOMAIN_PARAMETERS,
+ Mechanism = CKO_MECHANISM,
+ OtpKey = CKO_OTP_KEY,
+ VendorDefined = CKO_VENDOR_DEFINED,
+ };
+
+enum class PseudoRandom : CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE
+ {
+ Pkcs5Pbkd2HmacSha1 = CKP_PKCS5_PBKD2_HMAC_SHA1,
+ Pkcs5Pbkd2HmacGostr3411 = CKP_PKCS5_PBKD2_HMAC_GOSTR3411,
+ Pkcs5Pbkd2HmacSha224 = CKP_PKCS5_PBKD2_HMAC_SHA224,
+ Pkcs5Pbkd2HmacSha256 = CKP_PKCS5_PBKD2_HMAC_SHA256,
+ Pkcs5Pbkd2HmacSha384 = CKP_PKCS5_PBKD2_HMAC_SHA384,
+ Pkcs5Pbkd2HmacSha512 = CKP_PKCS5_PBKD2_HMAC_SHA512,
+ Pkcs5Pbkd2HmacSha512224 = CKP_PKCS5_PBKD2_HMAC_SHA512_224,
+ Pkcs5Pbkd2HmacSha512256 = CKP_PKCS5_PBKD2_HMAC_SHA512_256,
+ };
+
+enum class SessionState : CK_STATE
+ {
+ RoPublicSession = CKS_RO_PUBLIC_SESSION,
+ RoUserFunctions = CKS_RO_USER_FUNCTIONS,
+ RwPublicSession = CKS_RW_PUBLIC_SESSION,
+ RwUserFunctions = CKS_RW_USER_FUNCTIONS,
+ RwSoFunctions = CKS_RW_SO_FUNCTIONS,
+ };
+
+enum class ReturnValue : CK_RV
+ {
+ OK = CKR_OK,
+ Cancel = CKR_CANCEL,
+ HostMemory = CKR_HOST_MEMORY,
+ SlotIdInvalid = CKR_SLOT_ID_INVALID,
+ GeneralError = CKR_GENERAL_ERROR,
+ FunctionFailed = CKR_FUNCTION_FAILED,
+ ArgumentsBad = CKR_ARGUMENTS_BAD,
+ NoEvent = CKR_NO_EVENT,
+ NeedToCreateThreads = CKR_NEED_TO_CREATE_THREADS,
+ CantLock = CKR_CANT_LOCK,
+ AttributeReadOnly = CKR_ATTRIBUTE_READ_ONLY,
+ AttributeSensitive = CKR_ATTRIBUTE_SENSITIVE,
+ AttributeTypeInvalid = CKR_ATTRIBUTE_TYPE_INVALID,
+ AttributeValueInvalid = CKR_ATTRIBUTE_VALUE_INVALID,
+ ActionProhibited = CKR_ACTION_PROHIBITED,
+ DataInvalid = CKR_DATA_INVALID,
+ DataLenRange = CKR_DATA_LEN_RANGE,
+ DeviceError = CKR_DEVICE_ERROR,
+ DeviceMemory = CKR_DEVICE_MEMORY,
+ DeviceRemoved = CKR_DEVICE_REMOVED,
+ EncryptedDataInvalid = CKR_ENCRYPTED_DATA_INVALID,
+ EncryptedDataLenRange = CKR_ENCRYPTED_DATA_LEN_RANGE,
+ FunctionCanceled = CKR_FUNCTION_CANCELED,
+ FunctionNotParallel = CKR_FUNCTION_NOT_PARALLEL,
+ FunctionNotSupported = CKR_FUNCTION_NOT_SUPPORTED,
+ KeyHandleInvalid = CKR_KEY_HANDLE_INVALID,
+ KeySizeRange = CKR_KEY_SIZE_RANGE,
+ KeyTypeInconsistent = CKR_KEY_TYPE_INCONSISTENT,
+ KeyNotNeeded = CKR_KEY_NOT_NEEDED,
+ KeyChanged = CKR_KEY_CHANGED,
+ KeyNeeded = CKR_KEY_NEEDED,
+ KeyIndigestible = CKR_KEY_INDIGESTIBLE,
+ KeyFunctionNotPermitted = CKR_KEY_FUNCTION_NOT_PERMITTED,
+ KeyNotWrappable = CKR_KEY_NOT_WRAPPABLE,
+ KeyUnextractable = CKR_KEY_UNEXTRACTABLE,
+ MechanismInvalid = CKR_MECHANISM_INVALID,
+ MechanismParamInvalid = CKR_MECHANISM_PARAM_INVALID,
+ ObjectHandleInvalid = CKR_OBJECT_HANDLE_INVALID,
+ OperationActive = CKR_OPERATION_ACTIVE,
+ OperationNotInitialized = CKR_OPERATION_NOT_INITIALIZED,
+ PinIncorrect = CKR_PIN_INCORRECT,
+ PinInvalid = CKR_PIN_INVALID,
+ PinLenRange = CKR_PIN_LEN_RANGE,
+ PinExpired = CKR_PIN_EXPIRED,
+ PinLocked = CKR_PIN_LOCKED,
+ SessionClosed = CKR_SESSION_CLOSED,
+ SessionCount = CKR_SESSION_COUNT,
+ SessionHandleInvalid = CKR_SESSION_HANDLE_INVALID,
+ SessionParallelNotSupported = CKR_SESSION_PARALLEL_NOT_SUPPORTED,
+ SessionReadOnly = CKR_SESSION_READ_ONLY,
+ SessionExists = CKR_SESSION_EXISTS,
+ SessionReadOnlyExists = CKR_SESSION_READ_ONLY_EXISTS,
+ SessionReadWriteSoExists = CKR_SESSION_READ_WRITE_SO_EXISTS,
+ SignatureInvalid = CKR_SIGNATURE_INVALID,
+ SignatureLenRange = CKR_SIGNATURE_LEN_RANGE,
+ TemplateIncomplete = CKR_TEMPLATE_INCOMPLETE,
+ TemplateInconsistent = CKR_TEMPLATE_INCONSISTENT,
+ TokenNotPresent = CKR_TOKEN_NOT_PRESENT,
+ TokenNotRecognized = CKR_TOKEN_NOT_RECOGNIZED,
+ TokenWriteProtected = CKR_TOKEN_WRITE_PROTECTED,
+ UnwrappingKeyHandleInvalid = CKR_UNWRAPPING_KEY_HANDLE_INVALID,
+ UnwrappingKeySizeRange = CKR_UNWRAPPING_KEY_SIZE_RANGE,
+ UnwrappingKeyTypeInconsistent = CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
+ UserAlreadyLoggedIn = CKR_USER_ALREADY_LOGGED_IN,
+ UserNotLoggedIn = CKR_USER_NOT_LOGGED_IN,
+ UserPinNotInitialized = CKR_USER_PIN_NOT_INITIALIZED,
+ UserTypeInvalid = CKR_USER_TYPE_INVALID,
+ UserAnotherAlreadyLoggedIn = CKR_USER_ANOTHER_ALREADY_LOGGED_IN,
+ UserTooManyTypes = CKR_USER_TOO_MANY_TYPES,
+ WrappedKeyInvalid = CKR_WRAPPED_KEY_INVALID,
+ WrappedKeyLenRange = CKR_WRAPPED_KEY_LEN_RANGE,
+ WrappingKeyHandleInvalid = CKR_WRAPPING_KEY_HANDLE_INVALID,
+ WrappingKeySizeRange = CKR_WRAPPING_KEY_SIZE_RANGE,
+ WrappingKeyTypeInconsistent = CKR_WRAPPING_KEY_TYPE_INCONSISTENT,
+ RandomSeedNotSupported = CKR_RANDOM_SEED_NOT_SUPPORTED,
+ RandomNoRng = CKR_RANDOM_NO_RNG,
+ DomainParamsInvalid = CKR_DOMAIN_PARAMS_INVALID,
+ CurveNotSupported = CKR_CURVE_NOT_SUPPORTED,
+ BufferTooSmall = CKR_BUFFER_TOO_SMALL,
+ SavedStateInvalid = CKR_SAVED_STATE_INVALID,
+ InformationSensitive = CKR_INFORMATION_SENSITIVE,
+ StateUnsaveable = CKR_STATE_UNSAVEABLE,
+ CryptokiNotInitialized = CKR_CRYPTOKI_NOT_INITIALIZED,
+ CryptokiAlreadyInitialized = CKR_CRYPTOKI_ALREADY_INITIALIZED,
+ MutexBad = CKR_MUTEX_BAD,
+ MutexNotLocked = CKR_MUTEX_NOT_LOCKED,
+ NewPinMode = CKR_NEW_PIN_MODE,
+ NextOtp = CKR_NEXT_OTP,
+ ExceededMaxIterations = CKR_EXCEEDED_MAX_ITERATIONS,
+ FipsSelfTestFailed = CKR_FIPS_SELF_TEST_FAILED,
+ LibraryLoadFailed = CKR_LIBRARY_LOAD_FAILED,
+ PinTooWeak = CKR_PIN_TOO_WEAK,
+ PublicKeyInvalid = CKR_PUBLIC_KEY_INVALID,
+ FunctionRejected = CKR_FUNCTION_REJECTED,
+ VendorDefined = CKR_VENDOR_DEFINED,
+ };
+
+enum class UserType : CK_USER_TYPE
+ {
+ SO = CKU_SO,
+ User = CKU_USER,
+ ContextSpecific = CKU_CONTEXT_SPECIFIC,
+ };
+
+enum class PublicPointEncoding : uint32_t
+ {
+ Raw,
+ Der
+ };
+
+using FunctionListPtr = CK_FUNCTION_LIST_PTR;
+using VoidPtr = CK_VOID_PTR;
+using C_InitializeArgs = CK_C_INITIALIZE_ARGS;
+using CreateMutex = CK_CREATEMUTEX;
+using DestroyMutex = CK_DESTROYMUTEX;
+using LockMutex = CK_LOCKMUTEX;
+using UnlockMutex = CK_UNLOCKMUTEX;
+using Flags = CK_FLAGS;
+using Info = CK_INFO;
+using Bbool = CK_BBOOL;
+using SlotId = CK_SLOT_ID;
+using Ulong = CK_ULONG;
+using SlotInfo = CK_SLOT_INFO;
+using TokenInfo = CK_TOKEN_INFO;
+using Mechanism = CK_MECHANISM;
+using MechanismInfo = CK_MECHANISM_INFO;
+using Utf8Char = CK_UTF8CHAR;
+using Notify = CK_NOTIFY;
+using SessionHandle = CK_SESSION_HANDLE;
+using SessionInfo = CK_SESSION_INFO;
+using Attribute = CK_ATTRIBUTE;
+using ObjectHandle = CK_OBJECT_HANDLE;
+using Byte = CK_BYTE;
+using RsaPkcsOaepParams = CK_RSA_PKCS_OAEP_PARAMS;
+using RsaPkcsPssParams = CK_RSA_PKCS_PSS_PARAMS;
+using Ecdh1DeriveParams = CK_ECDH1_DERIVE_PARAMS;
+using Date = CK_DATE;
+
+BOTAN_DLL extern ReturnValue* ThrowException;
+
+const Bbool True = CK_TRUE;
+const Bbool False = CK_FALSE;
+
+inline Flags flags(Flag flags)
+ {
+ return static_cast<Flags>(flags);
+ }
+
+class Slot;
+
+/**
+* Initializes a token
+* @param slot The slot with the attached token that should be initialized
+* @param label The token label
+* @param so_pin PIN of the security officer. Will be set if the token is uninitialized other this has to be the current SO_PIN
+* @param pin The user PIN that will be set
+*/
+BOTAN_DLL void initialize_token(Slot& slot, const std::string& label, const secure_string& so_pin,
+ const secure_string& pin);
+
+/**
+* Change PIN with old PIN to new PIN
+* @param slot The slot with the attached token
+* @param old_pin The old user PIN
+* @param new_pin The new user PIN
+*/
+
+BOTAN_DLL void change_pin(Slot& slot, const secure_string& old_pin, const secure_string& new_pin);
+
+/**
+* Change SO_PIN with old SO_PIN to new SO_PIN
+* @param slot The slot with the attached token
+* @param old_so_pin The old SO_PIN
+* @param new_so_pin The new SO_PIN
+*/
+BOTAN_DLL void change_so_pin(Slot& slot, const secure_string& old_so_pin, const secure_string& new_so_pin);
+
+/**
+* Sets user PIN with SO_PIN
+* @param slot The slot with the attached token
+* @param so_pin PIN of the security officer
+* @param pin The user PIN that should be set
+*/
+BOTAN_DLL void set_pin(Slot& slot, const secure_string& so_pin, const secure_string& pin);
+
+/// Provides access to all PKCS#11 functions
+class BOTAN_DLL LowLevel
+ {
+ public:
+
+ /// @param ptr the functon list pointer to use. Can be retrieved via `LowLevel::C_GetFunctionList`
+ explicit LowLevel(FunctionListPtr ptr);
+
+ ~LowLevel() BOTAN_NOEXCEPT;
+
+ /****************************** General purpose functions ******************************/
+
+ /**
+ * C_Initialize initializes the Cryptoki library.
+ * @param init_args if this is not nullptr, it gets cast to (`C_InitializeArgs`) and dereferenced
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CantLock \li CryptokiAlreadyInitialized
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li NeedToCreateThreads \li OK
+ * @return true on success, false otherwise
+ */
+ bool C_Initialize(VoidPtr init_args,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Finalize indicates that an application is done with the Cryptoki library.
+ * @param reserved reserved. Should be nullptr
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * @return true on success, false otherwise
+ */
+ bool C_Finalize(VoidPtr reserved,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetInfo returns general information about Cryptoki.
+ * @param info_ptr location that receives information
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * @return true on success, false otherwise
+ */
+ bool C_GetInfo(Info* info_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetFunctionList returns the function list.
+ * @param pkcs11_module The PKCS#11 module
+ * @param function_list_ptr_ptr receives pointer to function list
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK
+ * @return true on success, false otherwise
+ */
+ static bool C_GetFunctionList(Dynamically_Loaded_Library& pkcs11_module, FunctionListPtr* function_list_ptr_ptr,
+ ReturnValue* return_value = ThrowException);
+
+ /****************************** Slot and token management functions ******************************/
+
+ /**
+ * C_GetSlotList obtains a list of slots in the system.
+ * @param token_present only slots with tokens
+ * @param slot_list_ptr receives array of slot IDs
+ * @param count_ptr receives number of slots
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK
+ * @return true on success, false otherwise
+ */
+ bool C_GetSlotList(Bbool token_present,
+ SlotId* slot_list_ptr,
+ Ulong* count_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetSlotList obtains a list of slots in the system.
+ * @param token_present only slots with tokens
+ * @param slot_ids receives vector of slot IDs
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK
+ * @return true on success, false otherwise
+ */
+ bool C_GetSlotList(bool token_present,
+ std::vector<SlotId>& slot_ids,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetSlotInfo obtains information about a particular slot in the system.
+ * @param slot_id the ID of the slot
+ * @param info_ptr receives the slot information
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li SlotIdInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_GetSlotInfo(SlotId slot_id,
+ SlotInfo* info_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetTokenInfo obtains information about a particular token in the system.
+ * @param slot_id ID of the token's slot
+ * @param info_ptr receives the token information
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li SlotIdInvalid
+ * \li TokenNotPresent \li TokenNotRecognized \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_GetTokenInfo(SlotId slot_id,
+ TokenInfo* info_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_WaitForSlotEvent waits for a slot event (token insertion, removal, etc.) to occur.
+ * @param flags blocking/nonblocking flag
+ * @param slot_ptr location that receives the slot ID
+ * @param reserved reserved. Should be NULL_PTR
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li FunctionFailed
+ * \li GeneralError \li HostMemory \li NoEvent
+ * \li OK
+ * @return true on success, false otherwise
+ */
+ bool C_WaitForSlotEvent(Flags flags,
+ SlotId* slot_ptr,
+ VoidPtr reserved,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetMechanismList obtains a list of mechanism types supported by a token.
+ * @param slot_id ID of token's slot
+ * @param mechanism_list_ptr gets mech. array
+ * @param count_ptr gets # of mechs.
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li BufferTooSmall \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li SlotIdInvalid \li TokenNotPresent \li TokenNotRecognized
+ * \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_GetMechanismList(SlotId slot_id,
+ MechanismType* mechanism_list_ptr,
+ Ulong* count_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetMechanismList obtains a list of mechanism types supported by a token.
+ * @param slot_id ID of token's slot
+ * @param mechanisms receives vector of supported mechanisms
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li BufferTooSmall \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li SlotIdInvalid \li TokenNotPresent \li TokenNotRecognized
+ * \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_GetMechanismList(SlotId slot_id,
+ std::vector<MechanismType>& mechanisms,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetMechanismInfo obtains information about a particular mechanism possibly supported by a token.
+ * @param slot_id ID of the token's slot
+ * @param type type of mechanism
+ * @param info_ptr receives mechanism info
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li MechanismInvalid \li OK
+ * \li SlotIdInvalid \li TokenNotPresent \li TokenNotRecognized
+ * \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_GetMechanismInfo(SlotId slot_id,
+ MechanismType type,
+ MechanismInfo* info_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_InitToken initializes a token.
+ * @param slot_id ID of the token's slot
+ * @param so_pin_ptr the SO's initial PIN
+ * @param so_pin_len length in bytes of the SO_PIN
+ * @param label_ptr 32-byte token label (blank padded)
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li PinIncorrect \li PinLocked \li SessionExists
+ * \li SlotIdInvalid \li TokenNotPresent \li TokenNotRecognized
+ * \li TokenWriteProtected \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_InitToken(SlotId slot_id,
+ Utf8Char* so_pin_ptr,
+ Ulong so_pin_len,
+ Utf8Char* label_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_InitToken initializes a token.
+ * @param slot_id ID of the token's slot
+ * @param so_pin the SO's initial PIN
+ * @param label token label (at max 32 bytes long)
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li PinIncorrect \li PinLocked \li SessionExists
+ * \li SlotIdInvalid \li TokenNotPresent \li TokenNotRecognized
+ * \li TokenWriteProtected \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_InitToken(SlotId slot_id,
+ const std::vector<byte, TAlloc>& so_pin,
+ const std::string& label,
+ ReturnValue* return_value = ThrowException) const
+ {
+ std::string padded_label = label;
+ if(label.size() < 32)
+ {
+ padded_label.insert(padded_label.end(), 32 - label.size(), ' ');
+ }
+
+ return C_InitToken(slot_id, reinterpret_cast< Utf8Char* >(const_cast< byte* >(so_pin.data())),
+ so_pin.size(), reinterpret_cast< Utf8Char* >(const_cast< char* >(padded_label.c_str())), return_value);
+ }
+
+ /**
+ * C_InitPIN initializes the normal user's PIN.
+ * @param session the session's handle
+ * @param pin_ptr the normal user's PIN
+ * @param pin_len length in bytes of the PIN
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li PinInvalid \li PinLenRange \li SessionClosed
+ * \li SessionReadOnly \li SessionHandleInvalid \li TokenWriteProtected
+ * \li UserNotLoggedIn \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_InitPIN(SessionHandle session,
+ Utf8Char* pin_ptr,
+ Ulong pin_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_InitPIN initializes the normal user's PIN.
+ * @param session the session's handle
+ * @param pin the normal user's PIN
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li PinInvalid \li PinLenRange \li SessionClosed
+ * \li SessionReadOnly \li SessionHandleInvalid \li TokenWriteProtected
+ * \li UserNotLoggedIn \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_InitPIN(SessionHandle session,
+ const std::vector<byte, TAlloc>& pin,
+ ReturnValue* return_value = ThrowException) const
+ {
+ return C_InitPIN(session, reinterpret_cast< Utf8Char* >(const_cast< byte* >(pin.data())), pin.size(), return_value);
+ }
+
+ /**
+ * C_SetPIN modifies the PIN of the user who is logged in.
+ * @param session the session's handle
+ * @param old_pin_ptr the old PIN
+ * @param old_len length of the old PIN
+ * @param new_pin_ptr the new PIN
+ * @param new_len length of the new PIN
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li PinIncorrect \li PinInvalid \li PinLenRange
+ * \li PinLocked \li SessionClosed \li SessionHandleInvalid
+ * \li SessionReadOnly \li TokenWriteProtected \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_SetPIN(SessionHandle session,
+ Utf8Char* old_pin_ptr,
+ Ulong old_len,
+ Utf8Char* new_pin_ptr,
+ Ulong new_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_SetPIN modifies the PIN of the user who is logged in.
+ * @param session the session's handle
+ * @param old_pin the old PIN
+ * @param new_pin the new PIN
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li PinIncorrect \li PinInvalid \li PinLenRange
+ * \li PinLocked \li SessionClosed \li SessionHandleInvalid
+ * \li SessionReadOnly \li TokenWriteProtected \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_SetPIN(SessionHandle session,
+ const std::vector<byte, TAlloc>& old_pin,
+ const std::vector<byte, TAlloc>& new_pin,
+ ReturnValue* return_value = ThrowException) const
+ {
+ return C_SetPIN(session,
+ reinterpret_cast< Utf8Char* >(const_cast< byte* >(old_pin.data())), old_pin.size(),
+ reinterpret_cast< Utf8Char* >(const_cast< byte* >(new_pin.data())), new_pin.size(),
+ return_value);
+ }
+
+
+ /****************************** Session management ******************************/
+
+ /**
+ * C_OpenSession opens a session between an application and a token.
+ * @param slot_id the slot's ID
+ * @param flags from CK_SESSION_INFO
+ * @param application passed to callback
+ * @param notify callback function
+ * @param session_ptr gets session handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li SessionCount
+ * \li SessionParallelNotSupported \li SessionReadWriteSoExists \li SlotIdInvalid
+ * \li TokenNotPresent \li TokenNotRecognized \li TokenWriteProtected
+ * \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_OpenSession(SlotId slot_id,
+ Flags flags,
+ VoidPtr application,
+ Notify notify,
+ SessionHandle* session_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_CloseSession closes a session between an application and a token.
+ * @param session the session's handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li SessionClosed
+ * \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_CloseSession(SessionHandle session,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_CloseAllSessions closes all sessions with a token.
+ * @param slot_id the token's slot
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li SlotIdInvalid
+ * \li TokenNotPresent
+ * @return true on success, false otherwise
+ */
+ bool C_CloseAllSessions(SlotId slot_id,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetSessionInfo obtains information about the session.
+ * @param session the session's handle
+ * @param info receives session info
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li SessionClosed
+ * \li SessionHandleInvalid \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_GetSessionInfo(SessionHandle session,
+ SessionInfo* info_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetOperationState obtains the state of the cryptographic operation in a session.
+ * @param session session's handle
+ * @param operation_state_ptr gets state
+ * @param operation_state_len_ptr gets state length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li BufferTooSmall \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * \li StateUnsaveable \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_GetOperationState(SessionHandle session,
+ Byte* operation_state_ptr,
+ Ulong* operation_state_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_SetOperationState restores the state of the cryptographic operation in a session.
+ * @param session session's handle
+ * @param operation_state_ptr holds state
+ * @param operation_state_len holds state length
+ * @param encryption_key en/decryption key
+ * @param authentication_key sign/verify key
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li KeyChanged \li KeyNeeded
+ * \li KeyNotNeeded \li OK \li SavedStateInvalid
+ * \li SessionClosed \li SessionHandleInvalid \li ArgumentsBad
+ * @return true on success, false otherwise
+ */
+ bool C_SetOperationState(SessionHandle session,
+ Byte* operation_state_ptr,
+ Ulong operation_state_len,
+ ObjectHandle encryption_key,
+ ObjectHandle authentication_key,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Login logs a user into a token.
+ * @param session the session's handle
+ * @param user_type the user type
+ * @param pin_ptr the user's PIN
+ * @param pin_len the length of the PIN
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li PinIncorrect
+ * \li PinLocked \li SessionClosed \li SessionHandleInvalid
+ * \li SessionReadOnlyExists \li UserAlreadyLoggedIn \li UserAnotherAlreadyLoggedIn
+ * \li UserPinNotInitialized \li UserTooManyTypes \li UserTypeInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_Login(SessionHandle session,
+ UserType user_type,
+ Utf8Char* pin_ptr,
+ Ulong pin_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Login logs a user into a token.
+ * @param session the session's handle
+ * @param user_type the user type
+ * @param pin the user or security officer's PIN
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li PinIncorrect
+ * \li PinLocked \li SessionClosed \li SessionHandleInvalid
+ * \li SessionReadOnlyExists \li UserAlreadyLoggedIn \li UserAnotherAlreadyLoggedIn
+ * \li UserPinNotInitialized \li UserTooManyTypes \li UserTypeInvalid
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_Login(SessionHandle session,
+ UserType user_type,
+ const std::vector<byte, TAlloc>& pin,
+ ReturnValue* return_value = ThrowException) const
+ {
+ return C_Login(session, user_type, reinterpret_cast< Utf8Char* >(const_cast< byte* >(pin.data())), pin.size(),
+ return_value);
+ }
+
+ /**
+ * C_Logout logs a user out from a token.
+ * @param session the session's handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_Logout(SessionHandle session,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Object management functions ******************************/
+
+ /**
+ * C_CreateObject creates a new object.
+ * @param session the session's handle
+ * @param attribute_template_ptr the object's template
+ * @param count attributes in template
+ * @param object_ptr gets new object's handle.
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li AttributeReadOnly \li AttributeTypeInvalid
+ * \li AttributeValueInvalid \li CryptokiNotInitialized \li CurveNotSupported
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li DomainParamsInvalid \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li PinExpired
+ * \li SessionClosed \li SessionHandleInvalid \li SessionReadOnly
+ * \li TemplateIncomplete \li TemplateInconsistent \li TokenWriteProtected
+ * \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_CreateObject(SessionHandle session,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ObjectHandle* object_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_CopyObject copies an object, creating a new object for the copy.
+ * @param session the session's handle
+ * @param object the object's handle
+ * @param attribute_template_ptr template for new object
+ * @param count attributes in template
+ * @param new_object_ptr receives handle of copy
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ActionProhibited \li ArgumentsBad \li AttributeReadOnly
+ * \li AttributeTypeInvalid \li AttributeValueInvalid \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li ObjectHandleInvalid \li OK \li PinExpired
+ * \li SessionClosed \li SessionHandleInvalid \li SessionReadOnly
+ * \li TemplateInconsistent \li TokenWriteProtected \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_CopyObject(SessionHandle session,
+ ObjectHandle object,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ObjectHandle* new_object_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_DestroyObject destroys an object.
+ * @param session the session's handle
+ * @param object the object's handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ActionProhibited \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionFailed
+ * \li GeneralError \li HostMemory \li ObjectHandleInvalid
+ * \li OK \li PinExpired \li SessionClosed
+ * \li SessionHandleInvalid \li SessionReadOnly \li TokenWriteProtected
+ * @return true on success, false otherwise
+ */
+ bool C_DestroyObject(SessionHandle session,
+ ObjectHandle object,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetObjectSize gets the size of an object in bytes.
+ * @param session the session's handle
+ * @param object the object's handle
+ * @param size_ptr receives size of object
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionFailed
+ * \li GeneralError \li HostMemory \li InformationSensitive
+ * \li ObjectHandleInvalid \li OK \li SessionClosed
+ * \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_GetObjectSize(SessionHandle session,
+ ObjectHandle object,
+ Ulong* size_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetAttributeValue obtains the value of one or more object attributes.
+ * @param session the session's handle
+ * @param object the object's handle
+ * @param attribute_template_ptr specifies attrs; gets vals
+ * @param count attributes in template
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li AttributeSensitive \li AttributeTypeInvalid
+ * \li BufferTooSmall \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionFailed
+ * \li GeneralError \li HostMemory \li ObjectHandleInvalid
+ * \li OK \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_GetAttributeValue(SessionHandle session,
+ ObjectHandle object,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GetAttributeValue obtains the value of one or more object attributes.
+ * @param session the session's handle
+ * @param object the object's handle
+ * @param attribute_values specifies attrs; gets vals
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li AttributeSensitive \li AttributeTypeInvalid
+ * \li BufferTooSmall \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionFailed
+ * \li GeneralError \li HostMemory \li ObjectHandleInvalid
+ * \li OK \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_GetAttributeValue(SessionHandle session,
+ ObjectHandle object,
+ std::map<AttributeType, std::vector<byte, TAlloc>>& attribute_values,
+ ReturnValue* return_value = ThrowException) const
+ {
+ std::vector<Attribute> getter_template;
+
+ for(const auto& entry : attribute_values)
+ {
+ getter_template.emplace_back(Attribute{ static_cast< CK_ATTRIBUTE_TYPE >(entry.first), nullptr, 0 });
+ }
+
+ bool success = C_GetAttributeValue(session, object, const_cast< Attribute* >(getter_template.data()),
+ getter_template.size(), return_value);
+
+ if(!success)
+ {
+ return success;
+ }
+
+ size_t i = 0;
+ for(auto& entry : attribute_values)
+ {
+ entry.second.clear();
+ entry.second.resize(getter_template.at(i).ulValueLen);
+ getter_template.at(i).pValue = const_cast< byte* >(entry.second.data());
+ i++;
+ }
+
+ return C_GetAttributeValue(session, object, const_cast< Attribute* >(getter_template.data()), getter_template.size(),
+ return_value);
+ }
+
+ /**
+ * C_SetAttributeValue modifies the value of one or more object attributes.
+ * @param session the session's handle
+ * @param object the object's handle
+ * @param attribute_template_ptr specifies attrs and values
+ * @param count attributes in template
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ActionProhibited \li ArgumentsBad \li AttributeReadOnly
+ * \li AttributeTypeInvalid \li AttributeValueInvalid \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li ObjectHandleInvalid \li OK \li SessionClosed
+ * \li SessionHandleInvalid \li SessionReadOnly \li TemplateInconsistent
+ * \li TokenWriteProtected \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_SetAttributeValue(SessionHandle session,
+ ObjectHandle object,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_SetAttributeValue modifies the value of one or more object attributes.
+ * @param session the session's handle
+ * @param object the object's handle
+ * @param attributes specifies attrs and values
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ActionProhibited \li ArgumentsBad \li AttributeReadOnly
+ * \li AttributeTypeInvalid \li AttributeValueInvalid \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li ObjectHandleInvalid \li OK \li SessionClosed
+ * \li SessionHandleInvalid \li SessionReadOnly \li TemplateInconsistent
+ * \li TokenWriteProtected \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_SetAttributeValue(SessionHandle session,
+ ObjectHandle object,
+ std::map<AttributeType, std::vector<byte, TAlloc>>& attribute_values,
+ ReturnValue* return_value = ThrowException) const
+ {
+ std::vector<Attribute> setter_template;
+
+ for(auto& entry : attribute_values)
+ {
+ setter_template.emplace_back(Attribute{ static_cast< CK_ATTRIBUTE_TYPE >(entry.first), entry.second.data(), static_cast<CK_ULONG>(entry.second.size()) });
+ }
+
+ return C_SetAttributeValue(session, object, const_cast< Attribute* >(setter_template.data()), setter_template.size(),
+ return_value);
+ }
+
+ /**
+ * C_FindObjectsInit initializes a search for token and session objects that match a template.
+ * @param session the session's handle
+ * @param attribute_template_ptr attribute values to match
+ * @param count attrs in search template
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li AttributeTypeInvalid \li AttributeValueInvalid
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationActive
+ * \li PinExpired \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_FindObjectsInit(SessionHandle session,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_FindObjects continues a search for token and session objects that match a template, obtaining additional object handles.
+ * @param session session's handle
+ * @param object gets obj. handles
+ * @param max_object_count max handles to get
+ * @param object_count actual # returned
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_FindObjects(SessionHandle session,
+ ObjectHandle* object_ptr,
+ Ulong max_object_count,
+ Ulong* object_count_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_FindObjectsFinal finishes a search for token and session objects.
+ * @param session the session's handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_FindObjectsFinal(SessionHandle session,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Encryption functions ******************************/
+
+ /**
+ * C_EncryptInit initializes an encryption operation.
+ * @param session the session's handle
+ * @param mechanism_ptr the encryption mechanism
+ * @param key handle of encryption key
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li KeyFunctionNotPermitted
+ * \li KeyHandleInvalid \li KeySizeRange \li KeyTypeInconsistent
+ * \li MechanismInvalid \li MechanismParamInvalid \li OK
+ * \li OperationActive \li PinExpired \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_EncryptInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Encrypt encrypts single-part data.
+ * @param session session's handle
+ * @param data_ptr the plaintext data
+ * @param encrypted_data_len_ptr bytes of plaintext
+ * @param encrypted_data gets ciphertext
+ * @param encrypted_data_len gets c-text size
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataInvalid \li DataLenRange \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_Encrypt(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* encrypted_data,
+ Ulong* encrypted_data_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Encrypt encrypts single-part data.
+ * @param session session's handle
+ * @param plaintext_data the plaintext data
+ * @param encrypted_data gets ciphertext
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataInvalid \li DataLenRange \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ template<typename TAllocA, typename TAllocB>
+ bool C_Encrypt(SessionHandle session,
+ const std::vector<byte, TAllocA>& plaintext_data,
+ std::vector<byte, TAllocB>& encrypted_data,
+ ReturnValue* return_value = ThrowException) const
+ {
+ Ulong encrypted_size = 0;
+ if(!C_Encrypt(session, const_cast<Byte*>((plaintext_data.data())), plaintext_data.size(), nullptr, &encrypted_size,
+ return_value))
+ {
+ return false;
+ }
+
+ encrypted_data.resize(encrypted_size);
+ return C_Encrypt(session, const_cast<Byte*>(plaintext_data.data()), plaintext_data.size(), encrypted_data.data(),
+ &encrypted_size, return_value);
+ }
+
+ /**
+ * C_EncryptUpdate continues a multiple-part encryption operation.
+ * @param session session's handle
+ * @param part_ptr the plaintext data
+ * @param part_len plaintext data len
+ * @param encrypted_part_ptr gets ciphertext
+ * @param encrypted_part_len_ptr gets c-text size
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_EncryptUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ Byte* encrypted_part_ptr,
+ Ulong* encrypted_part_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_EncryptFinal finishes a multiple-part encryption operation.
+ * @param session session handle
+ * @param last_encrypted_part_ptr last c-text
+ * @param last_encrypted_part_len_ptr gets last size
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_EncryptFinal(SessionHandle session,
+ Byte* last_encrypted_part_ptr,
+ Ulong* last_encrypted_part_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Decryption functions ******************************/
+
+ /**
+ * C_DecryptInit initializes a decryption operation.
+ * @param session the session's handle
+ * @param mechanism_ptr the decryption mechanism
+ * @param key handle of decryption key
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li KeyFunctionNotPermitted \li KeyHandleInvalid \li KeySizeRange
+ * \li KeyTypeInconsistent \li MechanismInvalid \li MechanismParamInvalid
+ * \li OK \li OperationActive \li PinExpired
+ * \li SessionClosed \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_DecryptInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Decrypt decrypts encrypted data in a single part.
+ * @param session session's handle
+ * @param encrypted_data_ptr ciphertext
+ * @param encrypted_data_len ciphertext length
+ * @param data_ptr gets plaintext
+ * @param data_len_ptr gets p-text size
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li EncryptedDataInvalid \li EncryptedDataLenRange \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_Decrypt(SessionHandle session,
+ Byte* encrypted_data_ptr,
+ Ulong encrypted_data_len,
+ Byte* data_ptr,
+ Ulong* data_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Decrypt decrypts encrypted data in a single part.
+ * @param session session's handle
+ * @param encrypted_data ciphertext
+ * @param decrypted_data gets plaintext
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li EncryptedDataInvalid \li EncryptedDataLenRange \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ template<typename TAllocA, typename TAllocB>
+ bool C_Decrypt(SessionHandle session,
+ const std::vector<byte, TAllocA>& encrypted_data,
+ std::vector<byte, TAllocB>& decrypted_data,
+ ReturnValue* return_value = ThrowException) const
+ {
+ Ulong decrypted_size = 0;
+ if(!C_Decrypt(session, const_cast<Byte*>((encrypted_data.data())), encrypted_data.size(), nullptr, &decrypted_size,
+ return_value))
+ {
+ return false;
+ }
+
+ decrypted_data.resize(decrypted_size);
+ return C_Decrypt(session, const_cast<Byte*>(encrypted_data.data()), encrypted_data.size(), decrypted_data.data(),
+ &decrypted_size, return_value);
+ }
+
+ /**
+ * C_DecryptUpdate continues a multiple-part decryption operation.
+ * @param session session's handle
+ * @param encrypted_part_ptr encrypted data
+ * @param encrypted_part_len input length
+ * @param part_ptr gets plaintext
+ * @param part_len_ptr p-text size
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li EncryptedDataInvalid \li EncryptedDataLenRange \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_DecryptUpdate(SessionHandle session,
+ Byte* encrypted_part_ptr,
+ Ulong encrypted_part_len,
+ Byte* part_ptr,
+ Ulong* part_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_DecryptFinal finishes a multiple-part decryption operation.
+ * @param session the session's handle
+ * @param last_part_ptr gets plaintext
+ * @param last_part_len_ptr p-text size
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li EncryptedDataInvalid \li EncryptedDataLenRange \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_DecryptFinal(SessionHandle session,
+ Byte* last_part_ptr,
+ Ulong* last_part_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Message digesting functions ******************************/
+
+ /**
+ * C_DigestInit initializes a message-digesting operation.
+ * @param session the session's handle
+ * @param mechanism_ptr the digesting mechanism
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li MechanismInvalid \li MechanismParamInvalid \li OK
+ * \li OperationActive \li PinExpired \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_DigestInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Digest digests data in a single part.
+ * @param session the session's handle
+ * @param data_ptr data to be digested
+ * @param data_len bytes of data to digest
+ * @param digest_ptr gets the message digest
+ * @param digest_len_ptr gets digest length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_Digest(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* digest_ptr,
+ Ulong* digest_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_DigestUpdate continues a multiple-part message-digesting operation.
+ * @param session the session's handle
+ * @param part_ptr data to be digested
+ * @param part_len bytes of data to be digested
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_DigestUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_DigestKey continues a multi-part message-digesting operation, by digesting the value of a secret key as part of the data already digested.
+ * @param session the session's handle
+ * @param key secret key to digest
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li KeyHandleInvalid
+ * \li KeyIndigestible \li KeySizeRange \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_DigestKey(SessionHandle session,
+ ObjectHandle key,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_DigestFinal finishes a multiple-part message-digesting operation.
+ * @param session the session's handle
+ * @param digest_ptr gets the message digest
+ * @param digest_len_ptr gets byte count of digest
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_DigestFinal(SessionHandle session,
+ Byte* digest_ptr,
+ Ulong* digest_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Signing and MACing functions ******************************/
+
+ /**
+ * C_SignInit initializes a signature (private key encryption) operation, where the signature is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param mechanism_ptr the signature mechanism
+ * @param key handle of signature key
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li KeyFunctionNotPermitted \li KeyHandleInvalid \li KeySizeRange
+ * \li KeyTypeInconsistent \li MechanismInvalid \li MechanismParamInvalid
+ * \li OK \li OperationActive \li PinExpired
+ * \li SessionClosed \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_SignInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Sign signs (encrypts with private key) data in a single part, where the signature is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param data_ptr the data to sign
+ * @param data_len count of bytes to sign
+ * @param signature_ptr gets the signature
+ * @param signature_len_ptr gets signature length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataInvalid \li DataLenRange \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn \li FunctionRejected
+ * @return true on success, false otherwise
+ */
+ bool C_Sign(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* signature_ptr,
+ Ulong* signature_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Sign signs (encrypts with private key) data in a single part, where the signature is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param data the data to sign
+ * @param signature gets the signature
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataInvalid \li DataLenRange \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn \li FunctionRejected
+ * @return true on success, false otherwise
+ */
+ template<typename TAllocA, typename TAllocB>
+ bool C_Sign(SessionHandle session,
+ const std::vector<byte, TAllocA>& data,
+ std::vector<byte, TAllocB>& signature,
+ ReturnValue* return_value = ThrowException) const
+ {
+ Ulong signature_size = 0;
+ if(!C_Sign(session, const_cast<Byte*>((data.data())), data.size(), nullptr, &signature_size, return_value))
+ {
+ return false;
+ }
+
+ signature.resize(signature_size);
+ return C_Sign(session, const_cast<Byte*>(data.data()), data.size(), signature.data(), &signature_size, return_value);
+ }
+
+ /**
+ * C_SignUpdate continues a multiple-part signature operation, where the signature is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param part_ptr the data to sign
+ * @param part_len count of bytes to sign
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DataLenRange
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_SignUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_SignUpdate continues a multiple-part signature operation, where the signature is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param part the data to sign
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DataLenRange
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_SignUpdate(SessionHandle session,
+ const std::vector<byte, TAlloc>& part,
+ ReturnValue* return_value = ThrowException) const
+ {
+ return C_SignUpdate(session, const_cast<Byte*>(part.data()), part.size(), return_value);
+ }
+
+ /**
+ * C_SignFinal finishes a multiple-part signature operation, returning the signature.
+ * @param session the session's handle
+ * @param signature_ptr gets the signature
+ * @param signature_len_ptr gets signature length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * \li UserNotLoggedIn \li FunctionRejected
+ * @return true on success, false otherwise
+ */
+ bool C_SignFinal(SessionHandle session,
+ Byte* signature_ptr,
+ Ulong* signature_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_SignFinal finishes a multiple-part signature operation, returning the signature.
+ * @param session the session's handle
+ * @param signature gets the signature
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * \li UserNotLoggedIn \li FunctionRejected
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_SignFinal(SessionHandle session,
+ std::vector<byte, TAlloc>& signature,
+ ReturnValue* return_value = ThrowException) const
+ {
+ Ulong signature_size = 0;
+ if(!C_SignFinal(session, nullptr, &signature_size, return_value))
+ {
+ return false;
+ }
+
+ signature.resize(signature_size);
+ return C_SignFinal(session, signature.data(), &signature_size, return_value);
+ }
+
+ /**
+ * C_SignRecoverInit initializes a signature operation, where the data can be recovered from the signature.
+ * @param session the session's handle
+ * @param mechanism_ptr the signature mechanism
+ * @param key handle of the signature key
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li KeyFunctionNotPermitted \li KeyHandleInvalid \li KeySizeRange
+ * \li KeyTypeInconsistent \li MechanismInvalid \li MechanismParamInvalid
+ * \li OK \li OperationActive \li PinExpired
+ * \li SessionClosed \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_SignRecoverInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_SignRecover signs data in a single operation, where the data can be recovered from the signature.
+ * @param session the session's handle
+ * @param data_ptr the data to sign
+ * @param data_len count of bytes to sign
+ * @param signature_ptr gets the signature
+ * @param signature_len_ptr gets signature length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataInvalid \li DataLenRange \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_SignRecover(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* signature_ptr,
+ Ulong* signature_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Functions for verifying signatures and MACs ******************************/
+
+ /**
+ * C_VerifyInit initializes a verification operation, where the signature is an appendix to the data, and plaintext cannot be recovered from the signature (e.g. DSA).
+ * @param session the session's handle
+ * @param mechanism_ptr the verification mechanism
+ * @param key verification key
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li KeyFunctionNotPermitted \li KeyHandleInvalid \li KeySizeRange
+ * \li KeyTypeInconsistent \li MechanismInvalid \li MechanismParamInvalid
+ * \li OK \li OperationActive \li PinExpired
+ * \li SessionClosed \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_VerifyInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Verify verifies a signature in a single-part operation, where the signature is an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param data_ptr signed data
+ * @param data_len length of signed data
+ * @param signature_ptr signature
+ * @param signature_len signature length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DataInvalid
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * \li SignatureInvalid \li SignatureLenRange
+ * @return true on success, false otherwise
+ */
+ bool C_Verify(SessionHandle session,
+ Byte* data_ptr,
+ Ulong data_len,
+ Byte* signature_ptr,
+ Ulong signature_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_Verify verifies a signature in a single-part operation, where the signature is an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param data signed data
+ * @param signature signature
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DataInvalid
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * \li SignatureInvalid \li SignatureLenRange
+ * @return true on success, false otherwise
+ */
+ template<typename TAllocA, typename TAllocB>
+ bool C_Verify(SessionHandle session,
+ const std::vector<byte, TAllocA>& data,
+ std::vector<byte, TAllocB>& signature,
+ ReturnValue* return_value = ThrowException) const
+ {
+ return C_Verify(session, const_cast<Byte*>(data.data()), data.size(), signature.data(), signature.size(), return_value);
+ }
+
+ /**
+ * C_VerifyUpdate continues a multiple-part verification operation, where the signature is an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param part_ptr signed data
+ * @param part_len length of signed data
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DataLenRange
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_VerifyUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_VerifyUpdate continues a multiple-part verification operation, where the signature is an appendix to the data, and plaintext cannot be recovered from the signature.
+ * @param session the session's handle
+ * @param part signed data
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DataLenRange
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ template<typename TAlloc>
+ bool C_VerifyUpdate(SessionHandle session,
+ std::vector<byte, TAlloc> part,
+ ReturnValue* return_value = ThrowException) const
+ {
+ return C_VerifyUpdate(session, part.data(), part.size(), return_value);
+ }
+
+ /**
+ * C_VerifyFinal finishes a multiple-part verification operation, checking the signature.
+ * @param session the session's handle
+ * @param signature_ptr signature to verify
+ * @param signature_len signature length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DataLenRange
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid \li SignatureInvalid
+ * \li SignatureLenRange
+ * @return true on success, false otherwise
+ */
+ bool C_VerifyFinal(SessionHandle session,
+ Byte* signature_ptr,
+ Ulong signature_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_VerifyRecoverInit initializes a signature verification operation, where the data is recovered from the signature.
+ * @param session the session's handle
+ * @param mechanism_ptr the verification mechanism
+ * @param key verification key
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li KeyFunctionNotPermitted \li KeyHandleInvalid \li KeySizeRange
+ * \li KeyTypeInconsistent \li MechanismInvalid \li MechanismParamInvalid
+ * \li OK \li OperationActive \li PinExpired
+ * \li SessionClosed \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_VerifyRecoverInit(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle key,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_VerifyRecover verifies a signature in a single-part operation, where the data is recovered from the signature.
+ * @param session the session's handle
+ * @param signature_ptr signature to verify
+ * @param signature_len signature length
+ * @param data_ptr gets signed data
+ * @param data_len_ptr gets signed data len
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataInvalid \li DataLenRange \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid \li SignatureLenRange \li SignatureInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_VerifyRecover(SessionHandle session,
+ Byte* signature_ptr,
+ Ulong signature_len,
+ Byte* data_ptr,
+ Ulong* data_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Dual-purpose cryptographic functions ******************************/
+
+ /**
+ * C_DigestEncryptUpdate continues a multiple-part digesting and encryption operation.
+ * @param session session's handle
+ * @param part_ptr the plaintext data
+ * @param part_len plaintext length
+ * @param encrypted_part_ptr gets ciphertext
+ * @param encrypted_part_len_ptr gets c-text length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_DigestEncryptUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ Byte* encrypted_part_ptr,
+ Ulong* encrypted_part_len_ptr,
+ ReturnValue* return_value = ThrowException) const ;
+
+ /**
+ * C_DecryptDigestUpdate continues a multiple-part decryption and digesting operation.
+ * @param session session's handle
+ * @param encrypted_part_ptr ciphertext
+ * @param encrypted_part_len ciphertext length
+ * @param part_ptr gets plaintext
+ * @param part_len_ptr gets plaintext len
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li EncryptedDataInvalid \li EncryptedDataLenRange \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationNotInitialized \li SessionClosed
+ * \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_DecryptDigestUpdate(SessionHandle session,
+ Byte* encrypted_part_ptr,
+ Ulong encrypted_part_len,
+ Byte* part_ptr,
+ Ulong* part_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_SignEncryptUpdate continues a multiple-part signing and encryption operation.
+ * @param session session's handle
+ * @param part_ptr the plaintext data
+ * @param part_len plaintext length
+ * @param encrypted_part_ptr gets ciphertext
+ * @param encrypted_part_len_ptr gets c-text length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li OK
+ * \li OperationNotInitialized \li SessionClosed \li SessionHandleInvalid
+ * \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_SignEncryptUpdate(SessionHandle session,
+ Byte* part_ptr,
+ Ulong part_len,
+ Byte* encrypted_part_ptr,
+ Ulong* encrypted_part_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_DecryptVerifyUpdate continues a multiple-part decryption and verify operation.
+ * @param session session's handle
+ * @param encrypted_part_ptr ciphertext
+ * @param encrypted_part_len ciphertext length
+ * @param part_ptr gets plaintext
+ * @param part_len_ptr gets p-text length
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DataLenRange \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li EncryptedDataInvalid \li EncryptedDataLenRange
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li OK \li OperationNotInitialized
+ * \li SessionClosed \li SessionHandleInvalid
+ * @return true on success, false otherwise
+ */
+ bool C_DecryptVerifyUpdate(SessionHandle session,
+ Byte* encrypted_part_ptr,
+ Ulong encrypted_part_len,
+ Byte* part_ptr,
+ Ulong* part_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Key management functions ******************************/
+
+ /**
+ * C_GenerateKey generates a secret key, creating a new key object.
+ * @param session the session's handle
+ * @param mechanism_ptr key generation mech.
+ * @param attribute_template_ptr template for new key
+ * @param count # of attrs in template
+ * @param key_ptr gets handle of new key
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li AttributeReadOnly \li AttributeTypeInvalid
+ * \li AttributeValueInvalid \li CryptokiNotInitialized \li CurveNotSupported
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li MechanismInvalid \li MechanismParamInvalid
+ * \li OK \li OperationActive \li PinExpired
+ * \li SessionClosed \li SessionHandleInvalid \li SessionReadOnly
+ * \li TemplateIncomplete \li TemplateInconsistent \li TokenWriteProtected
+ * \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_GenerateKey(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ Attribute* attribute_template_ptr,
+ Ulong count,
+ ObjectHandle* key_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GenerateKeyPair generates a public-key/private-key pair, creating new key objects.
+ * @param session session handle
+ * @param mechanism_ptr key-gen mech.
+ * @param public_key_template_ptr template for pub. key
+ * @param public_key_attribute_count # pub. attrs.
+ * @param private_key_template_ptr template for priv. key
+ * @param private_key_attribute_count # priv. attrs.
+ * @param public_key_ptr gets pub. key handle
+ * @param private_key_ptr gets priv. key handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li AttributeReadOnly \li AttributeTypeInvalid
+ * \li AttributeValueInvalid \li CryptokiNotInitialized \li CurveNotSupported
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li DomainParamsInvalid \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li MechanismInvalid
+ * \li MechanismParamInvalid \li OK \li OperationActive
+ * \li PinExpired \li SessionClosed \li SessionHandleInvalid
+ * \li SessionReadOnly \li TemplateIncomplete \li TemplateInconsistent
+ * \li TokenWriteProtected \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_GenerateKeyPair(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ Attribute* public_key_template_ptr,
+ Ulong public_key_attribute_count,
+ Attribute* private_key_template_ptr,
+ Ulong private_key_attribute_count,
+ ObjectHandle* public_key_ptr,
+ ObjectHandle* private_key_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_WrapKey wraps (i.e., encrypts) a key.
+ * @param session the session's handle
+ * @param mechanism_ptr the wrapping mechanism
+ * @param wrapping_key wrapping key
+ * @param key key to be wrapped
+ * @param wrapped_key_ptr gets wrapped key
+ * @param wrapped_key_len_ptr gets wrapped key size
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li BufferTooSmall \li CryptokiNotInitialized
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li FunctionCanceled \li FunctionFailed \li GeneralError
+ * \li HostMemory \li KeyHandleInvalid \li KeyNotWrappable
+ * \li KeySizeRange \li KeyUnextractable \li MechanismInvalid
+ * \li MechanismParamInvalid \li OK \li OperationActive
+ * \li PinExpired \li SessionClosed \li SessionHandleInvalid
+ * \li UserNotLoggedIn \li WrappingKeyHandleInvalid \li WrappingKeySizeRange
+ * \li WrappingKeyTypeInconsistent
+ * @return true on success, false otherwise
+ */
+ bool C_WrapKey(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle wrapping_key,
+ ObjectHandle key,
+ Byte* wrapped_key_ptr,
+ Ulong* wrapped_key_len_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object.
+ * @param session session's handle
+ * @param mechanism_ptr unwrapping mech.
+ * @param unwrapping_key unwrapping key
+ * @param wrapped_key_ptr the wrapped key
+ * @param wrapped_key_len wrapped key len
+ * @param attribute_template_ptr new key template
+ * @param attribute_count template length
+ * @param key_ptr gets new handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li AttributeReadOnly \li AttributeTypeInvalid
+ * \li AttributeValueInvalid \li BufferTooSmall \li CryptokiNotInitialized
+ * \li CurveNotSupported \li DeviceError \li DeviceMemory
+ * \li DeviceRemoved \li DomainParamsInvalid \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li MechanismInvalid \li MechanismParamInvalid \li OK
+ * \li OperationActive \li PinExpired \li SessionClosed
+ * \li SessionHandleInvalid \li SessionReadOnly \li TemplateIncomplete
+ * \li TemplateInconsistent \li TokenWriteProtected \li UnwrappingKeyHandleInvalid
+ * \li UnwrappingKeySizeRange \li UnwrappingKeyTypeInconsistent \li UserNotLoggedIn
+ * \li WrappedKeyInvalid \li WrappedKeyLenRange
+ * @return true on success, false otherwise
+ */
+ bool C_UnwrapKey(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle unwrapping_key,
+ Byte* wrapped_key_ptr,
+ Ulong wrapped_key_len,
+ Attribute* attribute_template_ptr,
+ Ulong attribute_count,
+ ObjectHandle* key_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_DeriveKey derives a key from a base key, creating a new key object.
+ * @param session session's handle
+ * @param mechanism_ptr key deriv. mech.
+ * @param base_key base key
+ * @param attribute_template_ptr new key template
+ * @param attribute_count template length
+ * @param key_ptr gets new handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li AttributeReadOnly \li AttributeTypeInvalid
+ * \li AttributeValueInvalid \li CryptokiNotInitialized \li CurveNotSupported
+ * \li DeviceError \li DeviceMemory \li DeviceRemoved
+ * \li DomainParamsInvalid \li FunctionCanceled \li FunctionFailed
+ * \li GeneralError \li HostMemory \li KeyHandleInvalid
+ * \li KeySizeRange \li KeyTypeInconsistent \li MechanismInvalid
+ * \li MechanismParamInvalid \li OK \li OperationActive
+ * \li PinExpired \li SessionClosed \li SessionHandleInvalid
+ * \li SessionReadOnly \li TemplateIncomplete \li TemplateInconsistent
+ * \li TokenWriteProtected \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_DeriveKey(SessionHandle session,
+ Mechanism* mechanism_ptr,
+ ObjectHandle base_key,
+ Attribute* attribute_template_ptr,
+ Ulong attribute_count,
+ ObjectHandle* key_ptr,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Random number generation functions ******************************/
+
+ /**
+ * C_SeedRandom mixes additional seed material into the token's random number generator.
+ * @param session the session's handle
+ * @param seed_ptr the seed material
+ * @param seed_len length of seed material
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationActive \li RandomSeedNotSupported
+ * \li RandomNoRng \li SessionClosed \li SessionHandleInvalid
+ * \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_SeedRandom(SessionHandle session,
+ Byte* seed_ptr,
+ Ulong seed_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_GenerateRandom generates random data.
+ * @param session the session's handle
+ * @param random_data_ptr receives the random data
+ * @param random_len # of bytes to generate
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li ArgumentsBad \li CryptokiNotInitialized \li DeviceError
+ * \li DeviceMemory \li DeviceRemoved \li FunctionCanceled
+ * \li FunctionFailed \li GeneralError \li HostMemory
+ * \li OK \li OperationActive \li RandomNoRng
+ * \li SessionClosed \li SessionHandleInvalid \li UserNotLoggedIn
+ * @return true on success, false otherwise
+ */
+ bool C_GenerateRandom(SessionHandle session,
+ Byte* random_data_ptr,
+ Ulong random_len,
+ ReturnValue* return_value = ThrowException) const;
+
+ /****************************** Parallel function management functions ******************************/
+
+ /**
+ * C_GetFunctionStatus is a legacy function; it obtains an updated status of a function running in parallel with an application.
+ * @param session the session's handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li FunctionFailed \li FunctionNotParallel
+ * \li GeneralError \li HostMemory \li SessionHandleInvalid
+ * \li SessionClosed
+ * @return true on success, false otherwise
+ */
+ bool C_GetFunctionStatus(SessionHandle session,
+ ReturnValue* return_value = ThrowException) const;
+
+ /**
+ * C_CancelFunction is a legacy function; it cancels a function running in parallel.
+ * @param session the session's handle
+ * @param return_value default value (`ThrowException`): throw exception on error.
+ * if a non-NULL pointer is passed: return_value receives the return value of the PKCS#11 function and no exception is thrown.
+ * At least the following PKCS#11 return values may be returned:
+ * \li CryptokiNotInitialized \li FunctionFailed \li FunctionNotParallel
+ * \li GeneralError \li HostMemory \li SessionHandleInvalid
+ * \li SessionClosed
+ * @return true on success, false otherwise
+ */
+ bool C_CancelFunction(SessionHandle session,
+ ReturnValue* return_value = ThrowException) const;
+
+ private:
+ const FunctionListPtr m_func_list_ptr;
+ };
+
+class PKCS11_Error : public Exception
+ {
+ public:
+ explicit PKCS11_Error(const std::string& what) :
+ Exception("PKCS11 error", what)
+ {
+ }
+ };
+
+class PKCS11_ReturnError : public PKCS11_Error
+ {
+ public:
+ explicit PKCS11_ReturnError(ReturnValue return_val) :
+ PKCS11_Error(std::to_string(static_cast< uint32_t >(return_val))),
+ m_return_val(return_val)
+ {}
+
+ inline ReturnValue get_return_value() const
+ {
+ return m_return_val;
+ }
+
+ private:
+ const ReturnValue m_return_val;
+ };
+
+}
+
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_ecc_key.cpp b/src/lib/prov/pkcs11/p11_ecc_key.cpp
new file mode 100644
index 000000000..0c3e879d9
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_ecc_key.cpp
@@ -0,0 +1,137 @@
+/*
+* PKCS#11 ECC
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_ecc_key.h>
+
+#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
+
+#include <botan/workfactor.h>
+#include <botan/ber_dec.h>
+
+namespace Botan {
+namespace PKCS11 {
+namespace {
+/// Converts a DER-encoded ANSI X9.62 ECPoint to PointGFp
+PointGFp decode_public_point(const secure_vector<byte>& ec_point_data, const CurveGFp& curve)
+ {
+ secure_vector<byte> ec_point;
+ BER_Decoder(ec_point_data).decode(ec_point, OCTET_STRING);
+ return OS2ECP(ec_point, curve);
+ }
+}
+
+EC_PublicKeyGenerationProperties::EC_PublicKeyGenerationProperties(const std::vector<byte>& ec_params)
+ : PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params)
+ {
+ add_binary(AttributeType::EcParams, m_ec_params);
+ }
+
+EC_PublicKeyImportProperties::EC_PublicKeyImportProperties(const std::vector<byte>& ec_params,
+ const std::vector<byte>& ec_point)
+ : PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_ec_point(ec_point)
+ {
+ add_binary(AttributeType::EcParams, m_ec_params);
+ add_binary(AttributeType::EcPoint, m_ec_point);
+ }
+
+PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, ObjectHandle handle)
+ : Object(session, handle)
+ {
+ secure_vector<byte> ec_parameters = get_attribute_value(AttributeType::EcParams);
+ m_domain_params = EC_Group(unlock(ec_parameters));
+ m_public_key = decode_public_point(get_attribute_value(AttributeType::EcPoint), m_domain_params.get_curve());
+ m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
+ }
+
+size_t PKCS11_EC_PublicKey::max_input_bits() const
+ {
+ return domain().get_order().bits();
+ }
+
+PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
+ : Object(session, props)
+ {
+ m_domain_params = EC_Group(props.ec_params());
+
+ secure_vector<byte> ec_point;
+ BER_Decoder(props.ec_point()).decode(ec_point, OCTET_STRING);
+ m_public_key = OS2ECP(ec_point, m_domain_params.get_curve());
+ m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
+ }
+
+EC_PrivateKeyImportProperties::EC_PrivateKeyImportProperties(const std::vector<byte>& ec_params, const BigInt& value)
+ : PrivateKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_value(value)
+ {
+ add_binary(AttributeType::EcParams, m_ec_params);
+ add_binary(AttributeType::Value, BigInt::encode(m_value));
+ }
+
+PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, ObjectHandle handle)
+ : Object(session, handle), m_domain_params(), m_public_key(), m_point_encoding(PublicPointEncoding::Der)
+ {
+ secure_vector<byte> ec_parameters = get_attribute_value(AttributeType::EcParams);
+ m_domain_params = EC_Group(unlock(ec_parameters));
+ }
+
+PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)
+ : Object(session, props)
+ {
+ m_domain_params = EC_Group(props.ec_params());
+ }
+
+PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const std::vector<byte>& ec_params,
+ const EC_PrivateKeyGenerationProperties& props)
+ : Object(session)
+ {
+ m_domain_params = EC_Group(ec_params);
+
+ EC_PublicKeyGenerationProperties pub_key_props(ec_params);
+ pub_key_props.set_verify(true);
+ pub_key_props.set_private(false);
+ pub_key_props.set_token(false); // don't create a persistent public key object
+
+ ObjectHandle pub_key_handle = 0;
+ m_handle = 0;
+ Mechanism mechanism = { CKM_EC_KEY_PAIR_GEN, nullptr, 0 };
+ session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
+ pub_key_props.data(), pub_key_props.count(), props.data(), props.count(),
+ &pub_key_handle, &m_handle);
+
+ Object public_key(session, pub_key_handle);
+ m_public_key = decode_public_point(public_key.get_attribute_value(AttributeType::EcPoint), m_domain_params.get_curve());
+ }
+
+size_t PKCS11_EC_PrivateKey::max_input_bits() const
+ {
+ return m_domain_params.get_order().bits();
+ }
+
+std::vector<byte> PKCS11_EC_PrivateKey::x509_subject_public_key() const
+ {
+ return unlock(EC2OSP(public_point(), PointGFp::COMPRESSED));
+ }
+
+size_t PKCS11_EC_PrivateKey::estimated_strength() const
+ {
+ return ecp_work_factor(domain().get_curve().get_p().bits());
+ }
+
+bool PKCS11_EC_PrivateKey::check_key(RandomNumberGenerator&, bool) const
+ {
+ return m_public_key.on_the_curve();
+ }
+
+AlgorithmIdentifier PKCS11_EC_PrivateKey::algorithm_identifier() const
+ {
+ return AlgorithmIdentifier(get_oid(), domain().DER_encode(EC_DOMPAR_ENC_EXPLICIT));
+ }
+}
+
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_ecc_key.h b/src/lib/prov/pkcs11/p11_ecc_key.h
new file mode 100644
index 000000000..3d10ae85e
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_ecc_key.h
@@ -0,0 +1,228 @@
+/*
+* PKCS#11 ECC
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_ECC_H__
+#define BOTAN_P11_ECC_H__
+
+#include <botan/build.h>
+#include <botan/p11_object.h>
+
+#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
+#include <botan/pk_keys.h>
+#include <botan/ecc_key.h>
+#include <botan/ec_group.h>
+#include <botan/rng.h>
+#include <botan/alg_id.h>
+#include <vector>
+
+namespace Botan {
+namespace PKCS11 {
+
+class Session;
+
+/// Properties for generating a PKCS#11 EC public key
+class BOTAN_DLL EC_PublicKeyGenerationProperties final : public PublicKeyProperties
+ {
+ public:
+ /// @param ec_params DER-encoding of an ANSI X9.62 Parameters value
+ EC_PublicKeyGenerationProperties(const std::vector<byte>& ec_params);
+
+ /// @return the DER-encoding of the ec parameters according to ANSI X9.62
+ inline const std::vector<byte>& ec_params() const
+ {
+ return m_ec_params;
+ }
+
+ private:
+ const std::vector<byte> m_ec_params;
+ };
+
+/// Properties for importing a PKCS#11 EC public key
+class BOTAN_DLL EC_PublicKeyImportProperties final : public PublicKeyProperties
+ {
+ public:
+ /**
+ * @param ec_params DER-encoding of an ANSI X9.62 Parameters value
+ * @param ec_point DER-encoding of ANSI X9.62 ECPoint value Q
+ */
+ EC_PublicKeyImportProperties(const std::vector<byte>& ec_params, const std::vector<byte>& ec_point);
+
+ /// @return the DER-encoding of the ec parameters according to ANSI X9.62
+ inline const std::vector<byte>& ec_params() const
+ {
+ return m_ec_params;
+ }
+
+ /// @return the DER-encoding of the ec public point according to ANSI X9.62
+ inline const std::vector<byte>& ec_point() const
+ {
+ return m_ec_point;
+ }
+
+ private:
+ const std::vector<byte> m_ec_params;
+ const std::vector<byte> m_ec_point;
+ };
+
+/// Represents a PKCS#11 EC public key
+class BOTAN_DLL PKCS11_EC_PublicKey : public virtual EC_PublicKey,
+ public Object
+ {
+ public:
+ static const ObjectClass Class = ObjectClass::PublicKey;
+
+ /**
+ * Creates a PKCS11_EC_PublicKey object from an existing PKCS#11 EC public key
+ * @param session the session to use
+ * @param handle the handle of the ecc public key
+ */
+ PKCS11_EC_PublicKey(Session& session, ObjectHandle handle);
+
+ /**
+ * Imports an EC public key
+ * @param session the session to use
+ * @param props the attributes of the public key
+ */
+ PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props);
+
+ size_t max_input_bits() const override;
+ };
+
+/// Properties for generating a PKCS#11 EC private key
+class BOTAN_DLL EC_PrivateKeyGenerationProperties final : public PrivateKeyProperties
+ {
+ public:
+ EC_PrivateKeyGenerationProperties()
+ : PrivateKeyProperties(KeyType::Ec)
+ {}
+ };
+
+/// Properties for importing a PKCS#11 EC private key
+class BOTAN_DLL EC_PrivateKeyImportProperties final : public PrivateKeyProperties
+ {
+ public:
+ /**
+ * @param ec_params DER-encoding of an ANSI X9.62 Parameters value
+ * @param value ANSI X9.62 private value d
+ */
+ EC_PrivateKeyImportProperties(const std::vector<byte>& ec_params, const BigInt& value);
+
+ /// @return the DER-encoding of the ec parameters according to ANSI X9.62
+ inline const std::vector<byte>& ec_params() const
+ {
+ return m_ec_params;
+ }
+
+ /// @return the value of the ec private key
+ inline const BigInt& value() const
+ {
+ return m_value;
+ }
+
+ private:
+ const std::vector<byte> m_ec_params;
+ const BigInt m_value;
+ };
+
+// note: don't inherit from PKCS11_EC_PublicKey: a private key object IS NOT A public key object on a smartcard (-> two different objects)
+// note: don't inherit from EC_PublicKey: the public key can not be extracted from a PKCS11-EC-PrivateKey (its only attributes are CKA_EC_PARAMS and CKA_VALUE)
+/// Represents a PKCS#11 EC private key
+class BOTAN_DLL PKCS11_EC_PrivateKey : public virtual Private_Key,
+ public Object
+ {
+ public:
+ static const ObjectClass Class = ObjectClass::PrivateKey;
+
+ /**
+ * Creates a PKCS11_EC_PrivateKey object from an existing PKCS#11 EC private key
+ * @param session the session to use
+ * @param handle the handle of the EC private key
+ */
+ PKCS11_EC_PrivateKey(Session& session, ObjectHandle handle);
+
+ /**
+ * Imports an EC private key
+ * @param session the session to use
+ * @param props the attributes of the private key
+ */
+ PKCS11_EC_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props);
+
+ /**
+ * Generates a PKCS#11 EC private key
+ * @param session the session to use
+ * @param ec_params DER-encoding of an ANSI X9.62 Parameters value
+ * @param props the attributes of the private key
+ * @note no persistent public key object will be created
+ */
+ PKCS11_EC_PrivateKey(Session& session, const std::vector<byte>& ec_params,
+ const EC_PrivateKeyGenerationProperties& props);
+
+ /// @returns the domain of the EC private key
+ inline const EC_Group& domain() const
+ {
+ return m_domain_params;
+ }
+
+ /**
+ * Sets the associated public point of this private key
+ * @param point the public point
+ * @param point_encoding encoding of the point (default DER-encoded)
+ */
+ void set_public_point(const PointGFp& point, PublicPointEncoding point_encoding = PublicPointEncoding::Der)
+ {
+ m_public_key = point;
+ m_point_encoding = point_encoding;
+ }
+
+ /**
+ * Gets the public_point
+ * @note: the public key must be set using `set_public_point`
+ * because it is not possible to infer the public key from a PKCS#11 EC private key
+ * @return the public point of the private key
+ * @throws Exception if the public point was not set using set_public_point()
+ */
+
+ const PointGFp& public_point() const
+ {
+ if(m_public_key.is_zero())
+ {
+ throw Exception("Public point not set. Inferring the public key from a PKCS#11 ec private key is not possible.");
+ }
+ return m_public_key;
+ }
+
+ /// @return the encoding format for the public point when it is passed to cryptoki functions as an argument
+ PublicPointEncoding point_encoding() const
+ {
+ return m_point_encoding;
+ }
+
+ // Private_Key methods
+
+ std::size_t max_input_bits() const override;
+
+ std::vector<byte> x509_subject_public_key() const override;
+
+ std::size_t estimated_strength() const override;
+
+ bool check_key(RandomNumberGenerator&, bool) const override;
+
+ AlgorithmIdentifier algorithm_identifier() const override;
+
+ private:
+ EC_Group m_domain_params;
+ PointGFp m_public_key;
+ PublicPointEncoding m_point_encoding;
+ };
+}
+
+}
+
+#endif
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_ecdh.cpp b/src/lib/prov/pkcs11/p11_ecdh.cpp
new file mode 100644
index 000000000..de24d6da4
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_ecdh.cpp
@@ -0,0 +1,141 @@
+/*
+* PKCS#11 ECDH
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_ecdh.h>
+
+#if defined(BOTAN_HAS_ECDH)
+
+#include <botan/internal/p11_mechanism.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/internal/algo_registry.h>
+#include <botan/internal/pk_utils.h>
+#include <botan/rng.h>
+
+namespace Botan {
+
+namespace PKCS11 {
+
+ECDH_PublicKey PKCS11_ECDH_PublicKey::export_key() const
+ {
+ return ECDH_PublicKey(domain(), public_point());
+ }
+
+ECDH_PrivateKey PKCS11_ECDH_PrivateKey::export_key() const
+ {
+ auto priv_key = get_attribute_value(AttributeType::Value);
+
+ Null_RNG rng;
+ return ECDH_PrivateKey(rng, domain(), BigInt::decode(priv_key));
+ }
+
+secure_vector<byte> PKCS11_ECDH_PrivateKey::pkcs8_private_key() const
+ {
+ return export_key().pkcs8_private_key();
+ }
+
+namespace {
+class PKCS11_ECDH_KA_Operation : public PK_Ops::Key_Agreement
+ {
+ public:
+ typedef PKCS11_EC_PrivateKey Key_Type;
+
+ static PKCS11_ECDH_KA_Operation* make_ecdh(const Spec& spec, bool use_cofactor)
+ {
+ try
+ {
+ if(auto* key = dynamic_cast< const PKCS11_EC_PrivateKey* >(&spec.key()))
+ {
+ return new PKCS11_ECDH_KA_Operation(*key, spec.padding(), use_cofactor);
+ }
+ }
+ catch(...)
+ {
+ }
+
+ return nullptr;
+ }
+
+ PKCS11_ECDH_KA_Operation(const PKCS11_EC_PrivateKey& key, const std::string& kdf, bool use_cofactor)
+ : PK_Ops::Key_Agreement(), m_key(key), m_mechanism(MechanismWrapper::create_ecdh_mechanism(kdf, use_cofactor))
+ {}
+
+
+ /// The encoding in V2.20 was not specified and resulted in different implementations choosing different encodings.
+ /// Applications relying only on a V2.20 encoding (e.g. the DER variant) other than the one specified now (raw) may not work with all V2.30 compliant tokens.
+ secure_vector<byte> agree(size_t key_len, const byte other_key[], size_t other_key_len, const byte salt[],
+ size_t salt_len) override
+ {
+ std::vector<byte> der_encoded_other_key;
+ if(m_key.point_encoding() == PublicPointEncoding::Der)
+ {
+ der_encoded_other_key = DER_Encoder().encode(other_key, other_key_len, OCTET_STRING).get_contents_unlocked();
+ m_mechanism.set_ecdh_other_key(der_encoded_other_key.data(), der_encoded_other_key.size());
+ }
+ else
+ {
+ m_mechanism.set_ecdh_other_key(other_key, other_key_len);
+ }
+
+ if(salt != nullptr && salt_len > 0)
+ {
+ m_mechanism.set_ecdh_salt(salt, salt_len);
+ }
+
+ ObjectHandle secret_handle = 0;
+ AttributeContainer attributes;
+ attributes.add_bool(AttributeType::Sensitive, false);
+ attributes.add_bool(AttributeType::Extractable, true);
+ attributes.add_numeric(AttributeType::Class, static_cast< CK_OBJECT_CLASS >(ObjectClass::SecretKey));
+ attributes.add_numeric(AttributeType::KeyType, static_cast< CK_KEY_TYPE >(KeyType::GenericSecret));
+ attributes.add_numeric(AttributeType::ValueLen, key_len);
+ m_key.module()->C_DeriveKey(m_key.session().handle(), m_mechanism.data(), m_key.handle(), attributes.data(),
+ attributes.count(), &secret_handle);
+
+ Object secret_object(m_key.session(), secret_handle);
+ secure_vector<byte> secret = secret_object.get_attribute_value(AttributeType::Value);
+ if(secret.size() < key_len)
+ {
+ throw PKCS11_Error("ECDH key derivation secret length is too short");
+ }
+ secret.resize(key_len);
+ return secret;
+ }
+
+ private:
+ const PKCS11_EC_PrivateKey& m_key;
+ MechanismWrapper m_mechanism;
+ };
+
+Algo_Registry<PK_Ops::Key_Agreement>::Add g_PKCS11_ECDH_KA_Operation_reg("ECDH",
+ std::bind(&PKCS11_ECDH_KA_Operation::make_ecdh, std::placeholders::_1, false), "pkcs11", BOTAN_PKCS11_ECDH_PRIO);
+
+Algo_Registry<PK_Ops::Key_Agreement>::Add g_PKCS11_ECDHC_KA_Operation_reg("ECDHC",
+ std::bind(&PKCS11_ECDH_KA_Operation::make_ecdh, std::placeholders::_1, true), "pkcs11", BOTAN_PKCS11_ECDH_PRIO);
+
+}
+
+PKCS11_ECDH_KeyPair generate_ecdh_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props,
+ const EC_PrivateKeyGenerationProperties& priv_props)
+ {
+ ObjectHandle pub_key_handle = 0;
+ ObjectHandle priv_key_handle = 0;
+
+ Mechanism mechanism = { static_cast< CK_MECHANISM_TYPE >(MechanismType::EcKeyPairGen), nullptr, 0 };
+
+ session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
+ pub_props.data(), pub_props.count(), priv_props.data(), priv_props.count(),
+ &pub_key_handle, &priv_key_handle);
+
+ return std::make_pair(PKCS11_ECDH_PublicKey(session, pub_key_handle), PKCS11_ECDH_PrivateKey(session, priv_key_handle));
+ }
+
+}
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_ecdh.h b/src/lib/prov/pkcs11/p11_ecdh.h
new file mode 100644
index 000000000..749a00d52
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_ecdh.h
@@ -0,0 +1,122 @@
+/*
+* PKCS#11 ECDH
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_ECDH_H__
+#define BOTAN_P11_ECDH_H__
+
+#include <botan/build.h>
+#if defined(BOTAN_HAS_ECDH)
+
+#include <botan/p11.h>
+#include <botan/p11_ecc_key.h>
+#include <botan/ecdh.h>
+
+#include <string>
+#include <vector>
+
+namespace Botan {
+namespace PKCS11 {
+class Session;
+
+/// Represents a PKCS#11 ECDH public key
+class BOTAN_DLL PKCS11_ECDH_PublicKey final : public PKCS11_EC_PublicKey
+ {
+ public:
+ /**
+ * Create a PKCS11_ECDH_PublicKey object from an existing PKCS#11 ECDH public key
+ * @param session the session to use
+ * @param handle the handle of the ECDH public key
+ */
+ PKCS11_ECDH_PublicKey(Session& session, ObjectHandle handle)
+ : EC_PublicKey(), PKCS11_EC_PublicKey(session, handle)
+ {}
+
+ /**
+ * Imports a ECDH public key
+ * @param session the session to use
+ * @param props the attributes of the public key
+ */
+ PKCS11_ECDH_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
+ : EC_PublicKey(), PKCS11_EC_PublicKey(session, props)
+ {}
+
+ inline std::string algo_name() const override
+ {
+ return "ECDH";
+ }
+
+ /// @return the exported ECDH public key
+ ECDH_PublicKey export_key() const;
+ };
+
+/// Represents a PKCS#11 ECDH private key
+class BOTAN_DLL PKCS11_ECDH_PrivateKey final : public virtual PKCS11_EC_PrivateKey, public virtual PK_Key_Agreement_Key
+ {
+ public:
+ /**
+ * Creates a PKCS11_ECDH_PrivateKey object from an existing PKCS#11 ECDH private key
+ * @param session the session to use
+ * @param handle the handle of the ECDH private key
+ */
+ PKCS11_ECDH_PrivateKey(Session& session, ObjectHandle handle)
+ : PKCS11_EC_PrivateKey(session, handle)
+ {}
+
+ /**
+ * Imports an ECDH private key
+ * @param session the session to use
+ * @param props the attributes of the private key
+ */
+ PKCS11_ECDH_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)
+ : PKCS11_EC_PrivateKey(session, props)
+ {}
+
+ /**
+ * Generates a PKCS#11 ECDH private key
+ * @param session the session to use
+ * @param ec_params DER-encoding of an ANSI X9.62 Parameters value
+ * @param props the attributes of the private key
+ * @note no persistent public key object will be created
+ */
+ PKCS11_ECDH_PrivateKey(Session& session, const std::vector<byte>& ec_params,
+ const EC_PrivateKeyGenerationProperties& props)
+ : PKCS11_EC_PrivateKey(session, ec_params, props)
+ {}
+
+ inline std::string algo_name() const override
+ {
+ return "ECDH";
+ }
+
+ inline std::vector<byte> public_value() const override
+ {
+ return unlock(EC2OSP(public_point(), PointGFp::UNCOMPRESSED));
+ }
+
+ /// @return the exported ECDH private key
+ ECDH_PrivateKey export_key() const;
+
+ secure_vector<byte> pkcs8_private_key() const override;
+ };
+
+using PKCS11_ECDH_KeyPair = std::pair<PKCS11_ECDH_PublicKey, PKCS11_ECDH_PrivateKey>;
+
+/**
+* PKCS#11 ECDH key pair generation
+* @param session the session that should be used for the key generation
+* @param pub_props the properties of the public key
+* @param priv_props the properties of the private key
+*/
+BOTAN_DLL PKCS11_ECDH_KeyPair generate_ecdh_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props,
+ const EC_PrivateKeyGenerationProperties& priv_props);
+}
+
+}
+
+#endif
+#endif
diff --git a/src/lib/prov/pkcs11/p11_ecdsa.cpp b/src/lib/prov/pkcs11/p11_ecdsa.cpp
new file mode 100644
index 000000000..078bc429d
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_ecdsa.cpp
@@ -0,0 +1,229 @@
+/*
+* PKCS#11 ECDSA
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_ecdsa.h>
+
+#if defined(BOTAN_HAS_ECDSA)
+
+#include <botan/internal/p11_mechanism.h>
+#include <botan/internal/algo_registry.h>
+#include <botan/internal/pk_utils.h>
+#include <botan/keypair.h>
+#include <botan/rng.h>
+
+namespace Botan {
+namespace PKCS11 {
+
+ECDSA_PublicKey PKCS11_ECDSA_PublicKey::export_key() const
+ {
+ return ECDSA_PublicKey(domain(), public_point());
+ }
+
+bool PKCS11_ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
+ {
+ if(!public_point().on_the_curve())
+ {
+ return false;
+ }
+
+
+ if(!strong)
+ {
+ return true;
+ }
+
+ return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)");
+ }
+
+ECDSA_PrivateKey PKCS11_ECDSA_PrivateKey::export_key() const
+ {
+ auto priv_key = get_attribute_value(AttributeType::Value);
+
+ Null_RNG rng;
+ return ECDSA_PrivateKey(rng, domain(), BigInt::decode(priv_key));
+ }
+
+secure_vector<byte> PKCS11_ECDSA_PrivateKey::pkcs8_private_key() const
+ {
+ return export_key().pkcs8_private_key();
+ }
+
+namespace {
+
+class PKCS11_ECDSA_Signature_Operation : public PK_Ops::Signature
+ {
+ public:
+ typedef PKCS11_EC_PrivateKey Key_Type;
+
+ PKCS11_ECDSA_Signature_Operation(const PKCS11_EC_PrivateKey& key, const std::string& emsa)
+ : PK_Ops::Signature(), m_key(key), m_order(key.domain().get_order()), m_mechanism(MechanismWrapper::create_ecdsa_mechanism(emsa))
+ {}
+
+ size_t message_parts() const override
+ {
+ return 2;
+ }
+
+ size_t message_part_size() const override
+ {
+ return m_order.bytes();
+ }
+
+ void update(const byte msg[], size_t msg_len) override
+ {
+ if(!m_initialized)
+ {
+ // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
+ m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
+ m_initialized = true;
+ m_first_message = secure_vector<byte>(msg, msg + msg_len);
+ return;
+ }
+
+ if(!m_first_message.empty())
+ {
+ // second call to update: start multiple-part operation
+ m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
+ m_first_message.clear();
+ }
+
+ m_key.module()->C_SignUpdate(m_key.session().handle(), const_cast<Byte*>(msg), msg_len);
+ }
+
+ secure_vector<byte> sign(RandomNumberGenerator&) override
+ {
+ secure_vector<byte> signature;
+ if(!m_first_message.empty())
+ {
+ // single call to update: perform single-part operation
+ m_key.module()->C_Sign(m_key.session().handle(), m_first_message, signature);
+ m_first_message.clear();
+ }
+ else
+ {
+ // multiple calls to update (or none): finish multiple-part operation
+ m_key.module()->C_SignFinal(m_key.session().handle(), signature);
+ }
+ m_initialized = false;
+ return signature;
+ }
+
+ private:
+ const PKCS11_EC_PrivateKey& m_key;
+ const BigInt& m_order;
+ MechanismWrapper m_mechanism;
+ secure_vector<byte> m_first_message;
+ bool m_initialized = false;
+ };
+
+
+class PKCS11_ECDSA_Verification_Operation : public PK_Ops::Verification
+ {
+ public:
+ typedef PKCS11_EC_PublicKey Key_Type;
+
+ PKCS11_ECDSA_Verification_Operation(const PKCS11_EC_PublicKey& key, const std::string& emsa)
+ : PK_Ops::Verification(), m_key(key), m_order(key.domain().get_order()), m_mechanism(MechanismWrapper::create_ecdsa_mechanism(emsa))
+ {}
+
+ size_t message_parts() const override
+ {
+ return 2;
+ }
+
+ size_t message_part_size() const override
+ {
+ return m_order.bytes();
+ }
+
+ size_t max_input_bits() const override
+ {
+ return m_order.bits();
+ }
+
+ void update(const byte msg[], size_t msg_len) override
+ {
+ if(!m_initialized)
+ {
+ // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
+ m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
+ m_initialized = true;
+ m_first_message = secure_vector<byte>(msg, msg + msg_len);
+ return;
+ }
+
+ if(!m_first_message.empty())
+ {
+ // second call to update: start multiple-part operation
+ m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
+ m_first_message.clear();
+ }
+
+ m_key.module()->C_VerifyUpdate(m_key.session().handle(), const_cast<Byte*>(msg), msg_len);
+ }
+
+ bool is_valid_signature(const byte sig[], size_t sig_len) override
+ {
+ ReturnValue return_value = ReturnValue::SignatureInvalid;
+ if(!m_first_message.empty())
+ {
+ // single call to update: perform single-part operation
+ m_key.module()->C_Verify(m_key.session().handle(), m_first_message.data(), m_first_message.size(),
+ const_cast<Byte*>(sig), sig_len, &return_value);
+ m_first_message.clear();
+ }
+ else
+ {
+ // multiple calls to update (or none): finish multiple-part operation
+ m_key.module()->C_VerifyFinal(m_key.session().handle(), const_cast<Byte*>(sig), sig_len, &return_value);
+ }
+ m_initialized = false;
+ if(return_value != ReturnValue::OK && return_value != ReturnValue::SignatureInvalid)
+ {
+ throw PKCS11_ReturnError(return_value);
+ }
+ return return_value == ReturnValue::OK;
+ }
+
+ private:
+ const PKCS11_EC_PublicKey& m_key;
+ const BigInt& m_order;
+ MechanismWrapper m_mechanism;
+ secure_vector<byte> m_first_message;
+ bool m_initialized = false;
+ };
+
+BOTAN_REGISTER_TYPE(PK_Ops::Signature, PKCS11_ECDSA_Signature_Operation, "ECDSA",
+ (make_pk_op<PK_Ops::Signature, PKCS11_ECDSA_Signature_Operation>), "pkcs11", BOTAN_PKCS11_ECDSA_PRIO);
+
+BOTAN_REGISTER_TYPE(PK_Ops::Verification, PKCS11_ECDSA_Verification_Operation, "ECDSA",
+ (make_pk_op<PK_Ops::Verification, PKCS11_ECDSA_Verification_Operation>), "pkcs11", BOTAN_PKCS11_ECDSA_PRIO);
+
+}
+
+PKCS11_ECDSA_KeyPair generate_ecdsa_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props,
+ const EC_PrivateKeyGenerationProperties& priv_props)
+ {
+ ObjectHandle pub_key_handle = 0;
+ ObjectHandle priv_key_handle = 0;
+
+ Mechanism mechanism = { static_cast<CK_MECHANISM_TYPE>(MechanismType::EcKeyPairGen), nullptr, 0 };
+
+ session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
+ pub_props.data(), pub_props.count(), priv_props.data(), priv_props.count(),
+ &pub_key_handle, &priv_key_handle);
+
+ return std::make_pair(PKCS11_ECDSA_PublicKey(session, pub_key_handle), PKCS11_ECDSA_PrivateKey(session,
+ priv_key_handle));
+ }
+
+}
+
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_ecdsa.h b/src/lib/prov/pkcs11/p11_ecdsa.h
new file mode 100644
index 000000000..d3d07a780
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_ecdsa.h
@@ -0,0 +1,127 @@
+/*
+* PKCS#11 ECDSA
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_ECDSA_H__
+#define BOTAN_P11_ECDSA_H__
+
+#include <botan/build.h>
+#if defined(BOTAN_HAS_ECDSA)
+
+#include <botan/p11_ecc_key.h>
+#include <botan/ecdsa.h>
+
+#include <string>
+
+namespace Botan {
+namespace PKCS11 {
+class Session;
+
+/// Represents a PKCS#11 ECDSA public key
+class BOTAN_DLL PKCS11_ECDSA_PublicKey final : public PKCS11_EC_PublicKey, public virtual ECDSA_PublicKey
+ {
+ public:
+ /**
+ * Creates a PKCS11_ECDSA_PublicKey object from an existing PKCS#11 ECDSA public key
+ * @param session the session to use
+ * @param handle the handle of the ECDSA public key
+ */
+ PKCS11_ECDSA_PublicKey(Session& session, ObjectHandle handle)
+ : EC_PublicKey(), PKCS11_EC_PublicKey(session, handle)
+ {}
+
+ /**
+ * Imports an ECDSA public key
+ * @param session the session to use
+ * @param props the attributes of the public key
+ */
+ PKCS11_ECDSA_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
+ : EC_PublicKey(), PKCS11_EC_PublicKey(session, props)
+ {}
+
+ inline std::string algo_name() const override
+ {
+ return "ECDSA";
+ }
+
+ inline std::size_t max_input_bits() const override
+ {
+ return domain().get_order().bits();
+ }
+
+ /// @return the exported ECDSA public key
+ ECDSA_PublicKey export_key() const;
+ };
+
+/// Represents a PKCS#11 ECDSA private key
+class BOTAN_DLL PKCS11_ECDSA_PrivateKey final : public PKCS11_EC_PrivateKey
+ {
+ public:
+ /**
+ * Creates a PKCS11_ECDSA_PrivateKey object from an existing PKCS#11 ECDSA private key
+ * @param session the session to use
+ * @param handle the handle of the ECDSA private key
+ */
+ PKCS11_ECDSA_PrivateKey(Session& session, ObjectHandle handle)
+ : PKCS11_EC_PrivateKey(session, handle)
+ {}
+
+ /**
+ * Imports a ECDSA private key
+ * @param session the session to use
+ * @param props the attributes of the private key
+ */
+ PKCS11_ECDSA_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)
+ : PKCS11_EC_PrivateKey(session, props)
+ {}
+
+ /**
+ * Generates a PKCS#11 ECDSA private key
+ * @param session the session to use
+ * @param ec_params DER-encoding of an ANSI X9.62 Parameters value
+ * @param props the attributes of the private key
+ * @note no persistent public key object will be created
+ */
+ PKCS11_ECDSA_PrivateKey(Session& session, const std::vector<byte>& ec_params,
+ const EC_PrivateKeyGenerationProperties& props)
+ : PKCS11_EC_PrivateKey(session, ec_params, props)
+ {}
+
+ inline std::string algo_name() const override
+ {
+ return "ECDSA";
+ }
+
+ inline size_t message_parts() const override
+ {
+ return 2;
+ }
+
+ /// @return the exported ECDSA private key
+ ECDSA_PrivateKey export_key() const;
+
+ secure_vector<byte> pkcs8_private_key() const override;
+
+ bool check_key(RandomNumberGenerator&, bool) const override;
+ };
+
+using PKCS11_ECDSA_KeyPair = std::pair<PKCS11_ECDSA_PublicKey, PKCS11_ECDSA_PrivateKey>;
+
+/**
+* ECDSA key pair generation
+* @param session the session that should be used for the key generation
+* @param pub_props the properties of the public key
+* @param priv_props the properties of the private key
+*/
+BOTAN_DLL PKCS11_ECDSA_KeyPair generate_ecdsa_keypair(Session& session,
+ const EC_PublicKeyGenerationProperties& pub_props, const EC_PrivateKeyGenerationProperties& priv_props);
+}
+
+}
+
+#endif
+#endif
diff --git a/src/lib/prov/pkcs11/p11_mechanism.cpp b/src/lib/prov/pkcs11/p11_mechanism.cpp
new file mode 100644
index 000000000..07ac00770
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_mechanism.cpp
@@ -0,0 +1,250 @@
+/*
+* PKCS#11 Mechanism
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/internal/p11_mechanism.h>
+#include <botan/scan_name.h>
+#include <botan/emsa.h>
+
+#include <tuple>
+
+namespace Botan {
+namespace PKCS11 {
+
+namespace {
+using PSS_Params = std::tuple<size_t, MechanismType, MGF>;
+
+// maps a PSS mechanism type to the number of bytes used for the salt, the mechanism type of the underlying hash algorithm and the MGF
+static const std::map<MechanismType, PSS_Params> PssOptions =
+ {
+ { MechanismType::RsaPkcsPss, PSS_Params(0, MechanismType::Sha1, MGF::Mgf1Sha1) },
+ { MechanismType::Sha1RsaPkcsPss, PSS_Params(20, MechanismType::Sha1, MGF::Mgf1Sha1) },
+ { MechanismType::Sha224RsaPkcsPss, PSS_Params(28, MechanismType::Sha224, MGF::Mgf1Sha224) },
+ { MechanismType::Sha256RsaPkcsPss, PSS_Params(32, MechanismType::Sha256, MGF::Mgf1Sha256) },
+ { MechanismType::Sha384RsaPkcsPss, PSS_Params(48, MechanismType::Sha384, MGF::Mgf1Sha384) },
+ { MechanismType::Sha512RsaPkcsPss, PSS_Params(64, MechanismType::Sha512, MGF::Mgf1Sha512) }
+ };
+
+struct MechanismData
+ {
+ explicit MechanismData(MechanismType _type)
+ : type(_type)
+ {}
+
+ virtual ~MechanismData() = default;
+
+ // the mechanism to perform
+ MechanismType type;
+ };
+
+struct RSA_SignMechanism : public MechanismData
+ {
+ explicit RSA_SignMechanism(MechanismType _type)
+ : MechanismData(_type), hash(static_cast<MechanismType>(0)), mgf(static_cast<MGF>(0)), salt_size(0)
+ {
+ auto pss_option = PssOptions.find(type);
+ if(pss_option != PssOptions.end())
+ {
+ hash = std::get<1>(pss_option->second);
+ mgf = std::get<2>(pss_option->second);
+ salt_size = std::get<0>(pss_option->second);
+ }
+ }
+
+ // hash algorithm used in the PSS encoding; if the signature mechanism does not include message hashing,
+ // then this value must be the mechanism used by the application to generate the message hash;
+ // if the signature mechanism includes hashing, then this value must match the hash algorithm indicated by the signature mechanism
+ MechanismType hash;
+
+ // mask generation function to use on the encoded block
+ MGF mgf;
+
+ // length, in bytes, of the salt value used in the PSS encoding; typical values are the length of the message hash and zero
+ size_t salt_size;
+ };
+
+// note: when updating this map, update the documentation for `MechanismWrapper::create_rsa_sign_mechanism`
+static std::map<std::string, RSA_SignMechanism> SignMechanisms =
+ {
+ { "Raw", RSA_SignMechanism(MechanismType::RsaX509) },
+
+ { "EMSA2(Raw)", RSA_SignMechanism(MechanismType::RsaX931) },
+ { "EMSA2(SHA-1)", RSA_SignMechanism(MechanismType::Sha1RsaX931) },
+
+ // RSASSA PKCS#1 v1.5
+ { "EMSA3(Raw)", RSA_SignMechanism(MechanismType::RsaPkcs) },
+ { "EMSA3(SHA-1)", RSA_SignMechanism(MechanismType::Sha1RsaPkcs) },
+ { "EMSA3(SHA-224)", RSA_SignMechanism(MechanismType::Sha224RsaPkcs) },
+ { "EMSA3(SHA-256)", RSA_SignMechanism(MechanismType::Sha256RsaPkcs) },
+ { "EMSA3(SHA-384)", RSA_SignMechanism(MechanismType::Sha384RsaPkcs) },
+ { "EMSA3(SHA-512)", RSA_SignMechanism(MechanismType::Sha512RsaPkcs) },
+
+ // RSASSA PKCS#1 PSS
+ { "EMSA4(Raw)", RSA_SignMechanism(MechanismType::RsaPkcsPss) },
+ { "EMSA4(SHA-1)", RSA_SignMechanism(MechanismType::Sha1RsaPkcsPss) },
+ { "EMSA4(SHA-224)", RSA_SignMechanism(MechanismType::Sha224RsaPkcsPss) },
+ { "EMSA4(SHA-256)", RSA_SignMechanism(MechanismType::Sha256RsaPkcsPss) },
+ { "EMSA4(SHA-384)", RSA_SignMechanism(MechanismType::Sha384RsaPkcsPss) },
+ { "EMSA4(SHA-512)", RSA_SignMechanism(MechanismType::Sha512RsaPkcsPss) },
+
+ { "ISO9796", RSA_SignMechanism(MechanismType::Rsa9796) }
+ };
+
+struct RSA_CryptMechanism : public MechanismData
+ {
+ RSA_CryptMechanism(MechanismType _type, size_t _padding_size, MechanismType _hash, MGF _mgf)
+ : MechanismData(_type), hash(_hash), mgf(_mgf), padding_size(_padding_size)
+ {}
+
+ RSA_CryptMechanism(MechanismType _type, size_t _padding_size)
+ : RSA_CryptMechanism(_type, _padding_size, static_cast<MechanismType>(0), static_cast<MGF>(0))
+ {}
+
+ // mechanism ID of the message digest algorithm used to calculate the digest of the encoding parameter
+ MechanismType hash;
+
+ // mask generation function to use on the encoded block
+ MGF mgf;
+
+ // number of bytes required for the padding
+ size_t padding_size;
+ };
+
+// note: when updating this map, update the documentation for `MechanismWrapper::create_rsa_crypt_mechanism`
+static const std::map<std::string, RSA_CryptMechanism> CryptMechanisms =
+ {
+ { "Raw", RSA_CryptMechanism(MechanismType::RsaX509, 0) },
+ { "EME-PKCS1-v1_5", RSA_CryptMechanism(MechanismType::RsaPkcs, 11) },
+ { "OAEP(SHA-1)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 20, MechanismType::Sha1, MGF::Mgf1Sha1) },
+ { "OAEP(SHA-224)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 28, MechanismType::Sha224, MGF::Mgf1Sha224) },
+ { "OAEP(SHA-256)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 32, MechanismType::Sha256, MGF::Mgf1Sha256) },
+ { "OAEP(SHA-384)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 48, MechanismType::Sha384, MGF::Mgf1Sha384) },
+ { "OAEP(SHA-512)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 64, MechanismType::Sha512, MGF::Mgf1Sha512) }
+ };
+
+// note: when updating this map, update the documentation for `MechanismWrapper::create_ecdsa_mechanism`
+static std::map<std::string, MechanismType> EcdsaHash =
+ {
+ { "Raw", MechanismType::Ecdsa },
+ { "SHA-160", MechanismType::EcdsaSha1 },
+ { "SHA-224", MechanismType::EcdsaSha224 },
+ { "SHA-256", MechanismType::EcdsaSha256 },
+ { "SHA-384", MechanismType::EcdsaSha384 },
+ { "SHA-512", MechanismType::EcdsaSha512 }
+ };
+
+// note: when updating this map, update the documentation for `MechanismWrapper::create_ecdh_mechanism`
+static std::map<std::string, KeyDerivation> EcdhHash =
+ {
+ { "Raw", KeyDerivation::Null },
+ { "SHA-160", KeyDerivation::Sha1Kdf },
+ { "SHA-224", KeyDerivation::Sha224Kdf },
+ { "SHA-256", KeyDerivation::Sha256Kdf },
+ { "SHA-384", KeyDerivation::Sha384Kdf },
+ { "SHA-512", KeyDerivation::Sha512Kdf }
+ };
+}
+
+MechanismWrapper::MechanismWrapper(MechanismType mechanism_type)
+ : m_mechanism( { static_cast<CK_MECHANISM_TYPE>(mechanism_type), nullptr, 0 }), m_parameters(nullptr)
+ {}
+
+MechanismWrapper MechanismWrapper::create_rsa_crypt_mechanism(const std::string& padding)
+ {
+ auto mechanism_info_it = CryptMechanisms.find(padding);
+ if(mechanism_info_it == CryptMechanisms.end())
+ {
+ // at this point it would be possible to support additional configurations that are not predefined above by parsing `padding`
+ throw Lookup_Error("PKCS#11 RSA encrypt/decrypt does not support EME " + padding);
+ }
+ RSA_CryptMechanism mechanism_info = mechanism_info_it->second;
+
+ MechanismWrapper mech(mechanism_info.type);
+ if(mechanism_info.type == MechanismType::RsaPkcsOaep)
+ {
+ mech.m_parameters = std::make_shared<MechanismParameters>();
+ mech.m_parameters->oaep_params.hashAlg = static_cast<CK_MECHANISM_TYPE>(mechanism_info.hash);
+ mech.m_parameters->oaep_params.mgf = static_cast<CK_RSA_PKCS_MGF_TYPE>(mechanism_info.mgf);
+ mech.m_parameters->oaep_params.source = CKZ_DATA_SPECIFIED;
+ mech.m_parameters->oaep_params.pSourceData = nullptr;
+ mech.m_parameters->oaep_params.ulSourceDataLen = 0;
+ mech.m_mechanism.pParameter = mech.m_parameters.get();
+ mech.m_mechanism.ulParameterLen = sizeof(RsaPkcsOaepParams);
+ }
+ mech.m_padding_size = mechanism_info.padding_size;
+ return mech;
+ }
+
+MechanismWrapper MechanismWrapper::create_rsa_sign_mechanism(const std::string& padding)
+ {
+ auto mechanism_info_it = SignMechanisms.find(padding);
+ if(mechanism_info_it == SignMechanisms.end())
+ {
+ // at this point it would be possible to support additional configurations that are not predefined above by parsing `padding`
+ throw Lookup_Error("PKCS#11 RSA sign/verify does not support EMSA " + padding);
+ }
+ RSA_SignMechanism mechanism_info = mechanism_info_it->second;
+
+ MechanismWrapper mech(mechanism_info.type);
+ if(PssOptions.find(mechanism_info.type) != PssOptions.end())
+ {
+ mech.m_parameters = std::make_shared<MechanismParameters>();
+ mech.m_parameters->pss_params.hashAlg = static_cast<CK_MECHANISM_TYPE>(mechanism_info.hash);
+ mech.m_parameters->pss_params.mgf = static_cast<CK_RSA_PKCS_MGF_TYPE>(mechanism_info.mgf);
+ mech.m_parameters->pss_params.sLen = mechanism_info.salt_size;
+ mech.m_mechanism.pParameter = mech.m_parameters.get();
+ mech.m_mechanism.ulParameterLen = sizeof(RsaPkcsPssParams);
+ }
+ return mech;
+ }
+
+MechanismWrapper MechanismWrapper::create_ecdsa_mechanism(const std::string& hash)
+ {
+ std::string hash_name = hash;
+
+ if(hash_name != "Raw")
+ {
+ hash_name = hash_for_emsa(hash);
+ }
+
+ auto mechanism_type = EcdsaHash.find(hash_name);
+ if(mechanism_type == EcdsaHash.end())
+ {
+ throw Lookup_Error("PKCS#11 ECDSA sign/verify does not support " + hash);
+ }
+ return MechanismWrapper(mechanism_type->second);
+ }
+
+MechanismWrapper MechanismWrapper::create_ecdh_mechanism(const std::string& kdf_name, bool use_cofactor)
+ {
+ std::string hash = kdf_name;
+
+ if(kdf_name != "Raw")
+ {
+ SCAN_Name kdf_hash(kdf_name);
+
+ if(kdf_hash.arg_count() > 0)
+ {
+ hash = kdf_hash.arg(0);
+ }
+ }
+
+ auto kdf = EcdhHash.find(hash);
+ if(kdf == EcdhHash.end())
+ {
+ throw Lookup_Error("PKCS#11 ECDH key derivation does not support KDF " + kdf_name);
+ }
+ MechanismWrapper mech(use_cofactor ? MechanismType::Ecdh1CofactorDerive : MechanismType::Ecdh1Derive);
+ mech.m_parameters = std::make_shared<MechanismParameters>();
+ mech.m_parameters->ecdh_params.kdf = static_cast<CK_EC_KDF_TYPE>(kdf->second);
+ mech.m_mechanism.pParameter = mech.m_parameters.get();
+ mech.m_mechanism.ulParameterLen = sizeof(Ecdh1DeriveParams);
+ return mech;
+ }
+
+}
+}
diff --git a/src/lib/prov/pkcs11/p11_mechanism.h b/src/lib/prov/pkcs11/p11_mechanism.h
new file mode 100644
index 000000000..5d8c826ee
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_mechanism.h
@@ -0,0 +1,108 @@
+/*
+* PKCS#11 Mechanism
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_MECHANISM_H__
+#define BOTAN_P11_MECHANISM_H__
+
+#include <botan/p11.h>
+
+#include <utility>
+#include <string>
+#include <memory>
+
+namespace Botan {
+namespace PKCS11 {
+
+/**
+* Simple class to build and hold the data for a CK_MECHANISM struct
+* for RSA (encryption/decryption, signature/verification)
+* and EC (ecdsa signature/verification, ecdh key derivation)
+*/
+class MechanismWrapper final
+ {
+ public:
+ /// @param mechanism_type the CK_MECHANISM_TYPE for the `mechanism` field of the CK_MECHANISM struct
+ explicit MechanismWrapper(MechanismType mechanism_type);
+
+ /**
+ * Creates the CK_MECHANISM data for RSA encryption/decryption
+ * @param padding supported paddings are Raw (X.509), EME-PKCS1-v1_5 (PKCS#1 v1.5) and OAEP (PKCS#1 OAEP)
+ */
+ static MechanismWrapper create_rsa_crypt_mechanism(const std::string& padding);
+
+ /**
+ * Creates the CK_MECHANISM data for RSA signature/verification
+ * @param padding supported paddings are Raw (X.509), EMSA3 (PKCS#1 v1.5), EMSA4 (PKCS#1 PSS),
+ * EMSA2 (ANSI X9.31) and ISO9796 (ISO/IEC 9796)
+ */
+ static MechanismWrapper create_rsa_sign_mechanism(const std::string& padding);
+
+ /**
+ * Creates the CK_MECHANISM data for ECDSA signature/verification
+ * @param hash the hash algorithm used to hash the data to sign.
+ * supported hash functions are Raw and SHA-160 to SHA-512
+ */
+ static MechanismWrapper create_ecdsa_mechanism(const std::string& hash);
+
+ /**
+ * Creates the CK_MECHANISM data for ECDH key derivation (CKM_ECDH1_DERIVE or CKM_ECDH1_COFACTOR_DERIVE)
+ * @param kdf_name the key derivation function to use. Supported KDFs are Raw and SHA-160 to SHA-512
+ * @param use_cofactor true if the cofactor key derivation mechanism should be used
+ */
+ static MechanismWrapper create_ecdh_mechanism(const std::string& kdf_name, bool use_cofactor);
+
+ /// Sets the salt for the ECDH mechanism parameters
+ inline void set_ecdh_salt(const byte salt[], size_t salt_len)
+ {
+ m_parameters->ecdh_params.pSharedData = const_cast<byte*>(salt);
+ m_parameters->ecdh_params.ulSharedDataLen = salt_len;
+ }
+
+ /// Sets the public key of the other party for the ECDH mechanism parameters
+ inline void set_ecdh_other_key(const byte other_key[], size_t other_key_len)
+ {
+ m_parameters->ecdh_params.pPublicData = const_cast<byte*>(other_key);
+ m_parameters->ecdh_params.ulPublicDataLen = other_key_len;
+ }
+
+ /// @return a pointer to the CK_MECHANISM struct that can be passed to the cryptoki functions
+ inline Mechanism* data() const
+ {
+ return const_cast<Mechanism*>(&m_mechanism);
+ }
+
+ /// @return the size of the padding in bytes (for encryption/decryption)
+ inline size_t padding_size() const
+ {
+ return m_padding_size;
+ }
+
+ /// Holds the mechanism parameters for OEAP, PSS and ECDH
+ union MechanismParameters
+ {
+ MechanismParameters()
+ {
+ std::memset(this, 0, sizeof(MechanismParameters));
+ }
+
+ RsaPkcsOaepParams oaep_params;
+ RsaPkcsPssParams pss_params;
+ Ecdh1DeriveParams ecdh_params;
+ };
+
+ private:
+ Mechanism m_mechanism;
+ std::shared_ptr<MechanismParameters> m_parameters;
+ size_t m_padding_size = 0;
+ };
+
+}
+
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_module.cpp b/src/lib/prov/pkcs11/p11_module.cpp
new file mode 100644
index 000000000..4ea3dc56d
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_module.cpp
@@ -0,0 +1,41 @@
+/*
+* PKCS#11 Module
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_module.h>
+
+namespace Botan {
+
+namespace PKCS11 {
+
+Module::Module(const std::string& file_path, C_InitializeArgs init_args)
+ : m_file_path(file_path)
+ {
+ reload(init_args);
+ }
+
+Module::~Module() BOTAN_NOEXCEPT
+ {
+ m_low_level->C_Finalize(nullptr, nullptr);
+ }
+
+void Module::reload(C_InitializeArgs init_args)
+ {
+ if(m_low_level)
+ {
+ m_low_level->C_Finalize(nullptr);
+ }
+
+ m_library.reset(new Dynamically_Loaded_Library(m_file_path));
+ LowLevel::C_GetFunctionList(*m_library, &m_func_list);
+ m_low_level.reset(new LowLevel(m_func_list));
+
+ m_low_level->C_Initialize(&init_args);
+ }
+
+}
+}
diff --git a/src/lib/prov/pkcs11/p11_module.h b/src/lib/prov/pkcs11/p11_module.h
new file mode 100644
index 000000000..990458a4d
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_module.h
@@ -0,0 +1,79 @@
+/*
+* PKCS#11 Module
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_MODULE_H__
+#define BOTAN_P11_MODULE_H__
+
+#include <string>
+#include <memory>
+
+#include <botan/p11.h>
+#include <botan/dyn_load.h>
+
+namespace Botan {
+namespace PKCS11 {
+
+/**
+* Loads the PKCS#11 shared library
+* Calls C_Initialize on load and C_Finalize on destruction
+*/
+class BOTAN_DLL Module final
+ {
+ public:
+ /**
+ * Loads the shared library and calls C_Initialize
+ * @param file_path the path to the PKCS#11 shared library
+ * @param init_args flags to use for `C_Initialize`
+ */
+ Module(const std::string& file_path, C_InitializeArgs init_args = { nullptr, nullptr, nullptr, nullptr, static_cast< CK_FLAGS >(Flag::OsLockingOk), nullptr });
+
+/* Microsoft Visual Studio <= 2013 does not support default generated move special member functions.
+ Everything else we target should support it */
+#if !defined( _MSC_VER ) || ( _MSC_VER >= 1900 )
+ Module(Module&& other) = default;
+ Module& operator=(Module&& other) = default;
+#endif
+
+ // Dtor calls C_Finalize(). A copy could be deleted while the origin still exists
+ // Furthermore std::unique_ptr member -> not copyable
+ Module(const Module& other) = delete;
+ Module& operator=(const Module& other) = delete;
+
+ /// Calls C_Finalize()
+ ~Module() BOTAN_NOEXCEPT;
+
+ /**
+ * Reloads the module and reinitializes it
+ * @param init_args flags to use for `C_Initialize`
+ */
+ void reload(C_InitializeArgs init_args = { nullptr, nullptr, nullptr, nullptr, static_cast< CK_FLAGS >(Flag::OsLockingOk), nullptr });
+
+ inline LowLevel* operator->() const
+ {
+ return m_low_level.get();
+ }
+
+ /// @return general information about Cryptoki
+ inline Info get_info() const
+ {
+ Info info;
+ m_low_level->C_GetInfo(&info);
+ return info;
+ }
+
+ private:
+ const std::string m_file_path;
+ FunctionListPtr m_func_list = nullptr;
+ std::unique_ptr<Dynamically_Loaded_Library> m_library = nullptr;
+ std::unique_ptr<LowLevel> m_low_level = nullptr;
+ };
+
+}
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_object.cpp b/src/lib/prov/pkcs11/p11_object.cpp
new file mode 100644
index 000000000..ef7477284
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_object.cpp
@@ -0,0 +1,217 @@
+/*
+* PKCS#11 Object
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_object.h>
+
+#include <map>
+
+namespace Botan {
+
+namespace PKCS11 {
+
+AttributeContainer::AttributeContainer(ObjectClass object_class)
+ {
+ add_class(object_class);
+ }
+
+void AttributeContainer::add_class(ObjectClass object_class)
+ {
+ m_numerics.push_back(static_cast< uint64_t >(object_class));
+ add_attribute(AttributeType::Class, reinterpret_cast< byte* >(&m_numerics.back()), sizeof(ObjectClass));
+ }
+
+void AttributeContainer::add_string(AttributeType attribute, const std::string& value)
+ {
+ m_strings.push_back(value);
+ add_attribute(attribute, reinterpret_cast< const byte* >(m_strings.back().data()), value.size());
+ }
+
+void AttributeContainer::add_binary(AttributeType attribute, const byte* value, size_t length)
+ {
+ m_vectors.push_back(secure_vector<byte>(value, value + length));
+ add_attribute(attribute, reinterpret_cast< const byte* >(m_vectors.back().data()), length);
+ }
+
+void AttributeContainer::add_bool(AttributeType attribute, bool value)
+ {
+ m_numerics.push_back(value ? True : False);
+ add_attribute(attribute, reinterpret_cast< byte* >(&m_numerics.back()), sizeof(Bbool));
+ }
+
+void AttributeContainer::add_attribute(AttributeType attribute, const byte* value, uint32_t size)
+ {
+ bool exists = false;
+ // check if the attribute has been added already
+ for(auto& existing_attribute : m_attributes)
+ {
+ if(existing_attribute.type == static_cast< CK_ATTRIBUTE_TYPE >(attribute))
+ {
+ // remove old entries
+ m_strings.erase(std::remove_if(m_strings.begin(), m_strings.end(), [ &existing_attribute ](const std::string& data)
+ {
+ return data.data() == existing_attribute.pValue;
+ }), m_strings.end());
+
+ m_numerics.erase(std::remove_if(m_numerics.begin(), m_numerics.end(), [ &existing_attribute ](const uint64_t& data)
+ {
+ return &data == existing_attribute.pValue;
+ }), m_numerics.end());
+
+ m_vectors.erase(std::remove_if(m_vectors.begin(),
+ m_vectors.end(), [ &existing_attribute ](const secure_vector<byte>& data)
+ {
+ return data.data() == existing_attribute.pValue;
+ }), m_vectors.end());
+
+ existing_attribute.pValue = const_cast< byte* >(value);
+ existing_attribute.ulValueLen = size;
+ exists = true;
+ break;
+ }
+ }
+
+ if(!exists)
+ {
+ m_attributes.push_back(Attribute{ static_cast< CK_ATTRIBUTE_TYPE >(attribute), const_cast< byte* >(value), size });
+ }
+ }
+
+// ====================================================================================================
+
+ObjectFinder::ObjectFinder(Session& session, const std::vector<Attribute>& search_template)
+ : m_session(session), m_search_terminated(false)
+ {
+ module()->C_FindObjectsInit(m_session.get().handle(), const_cast< Attribute* >(search_template.data()),
+ search_template.size());
+ }
+
+ObjectFinder::~ObjectFinder() BOTAN_NOEXCEPT
+ {
+ if(m_search_terminated == false)
+ {
+ module()->C_FindObjectsFinal(m_session.get().handle(), nullptr);
+ }
+ }
+
+std::vector<ObjectHandle> ObjectFinder::find(uint32_t max_count) const
+ {
+ std::vector<ObjectHandle> result(max_count);
+ Ulong objectCount = 0;
+ module()->C_FindObjects(m_session.get().handle(), result.data(), max_count, &objectCount);
+ if(objectCount < max_count)
+ {
+ result.resize(objectCount);
+ }
+ return result;
+ }
+
+void ObjectFinder::finish()
+ {
+ module()->C_FindObjectsFinal(m_session.get().handle());
+ m_search_terminated = true;
+ }
+
+// ====================================================================================================
+
+ObjectProperties::ObjectProperties(ObjectClass object_class)
+ : AttributeContainer(object_class), m_object_class(object_class)
+ {}
+
+// ====================================================================================================
+
+StorageObjectProperties::StorageObjectProperties(ObjectClass object_class)
+ : ObjectProperties(object_class)
+ {}
+
+// ====================================================================================================
+
+DataObjectProperties::DataObjectProperties()
+ : StorageObjectProperties(ObjectClass::Data)
+ {}
+
+// ====================================================================================================
+
+CertificateProperties::CertificateProperties(CertificateType cert_type)
+ : StorageObjectProperties(ObjectClass::Certificate), m_cert_type(cert_type)
+ {
+ add_numeric(AttributeType::CertificateType, static_cast< CK_CERTIFICATE_TYPE >(m_cert_type));
+ }
+
+// ====================================================================================================
+
+KeyProperties::KeyProperties(ObjectClass object_class, KeyType key_type)
+ : StorageObjectProperties(object_class), m_key_type(key_type)
+ {
+ add_numeric(AttributeType::KeyType, static_cast< CK_ULONG >(m_key_type));
+ }
+
+// ====================================================================================================
+
+PublicKeyProperties::PublicKeyProperties(KeyType key_type)
+ : KeyProperties(ObjectClass::PublicKey, key_type)
+ {}
+
+// ====================================================================================================
+
+PrivateKeyProperties::PrivateKeyProperties(KeyType key_type)
+ : KeyProperties(ObjectClass::PrivateKey, key_type)
+ {}
+
+// ====================================================================================================
+
+SecretKeyProperties::SecretKeyProperties(KeyType key_type)
+ : KeyProperties(ObjectClass::SecretKey, key_type)
+ {}
+
+// ====================================================================================================
+
+DomainParameterProperties::DomainParameterProperties(KeyType key_type)
+ : StorageObjectProperties(ObjectClass::DomainParameters), m_key_type(key_type)
+ {
+ add_numeric(AttributeType::KeyType, static_cast< CK_ULONG >(m_key_type));
+ }
+
+// ====================================================================================================
+
+Object::Object(Session& session, ObjectHandle handle)
+ : m_session(session), m_handle(handle)
+ {}
+
+Object::Object(Session& session, const ObjectProperties& obj_props)
+ : m_session(session), m_handle(0)
+ {
+ m_session.get().module()->C_CreateObject(m_session.get().handle(), obj_props.data(), obj_props.count(), &m_handle);
+ }
+
+secure_vector<byte> Object::get_attribute_value(AttributeType attribute) const
+ {
+ std::map<AttributeType, secure_vector<byte>> attribute_map = { { attribute, secure_vector<byte>() } };
+ module()->C_GetAttributeValue(m_session.get().handle(), m_handle, attribute_map);
+ return attribute_map.at(attribute);
+ }
+
+void Object::set_attribute_value(AttributeType attribute, const secure_vector<byte>& value) const
+ {
+ std::map<AttributeType, secure_vector<byte>> attribute_map = { { attribute, value } };
+ module()->C_SetAttributeValue(m_session.get().handle(), m_handle, attribute_map);
+ }
+
+void Object::destroy() const
+ {
+ module()->C_DestroyObject(m_session.get().handle(), m_handle);
+ }
+
+ObjectHandle Object::copy(const AttributeContainer& modified_attributes) const
+ {
+ ObjectHandle copied_handle;
+ module()->C_CopyObject(m_session.get().handle(), m_handle, modified_attributes.data(), modified_attributes.count(),
+ &copied_handle);
+ return copied_handle;
+ }
+}
+}
diff --git a/src/lib/prov/pkcs11/p11_object.h b/src/lib/prov/pkcs11/p11_object.h
new file mode 100644
index 000000000..4a6a54b20
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_object.h
@@ -0,0 +1,743 @@
+/*
+* PKCS#11 Object
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_OBJECT_H__
+#define BOTAN_P11_OBJECT_H__
+
+#include <botan/p11.h>
+#include <botan/p11_session.h>
+#include <botan/secmem.h>
+
+#include <vector>
+#include <string>
+#include <type_traits>
+#include <list>
+#include <functional>
+
+namespace Botan {
+namespace PKCS11 {
+
+class Module;
+
+/// Helper class to build the Attribute / CK_ATTRIBUTE structures
+class BOTAN_DLL AttributeContainer
+ {
+ public:
+ AttributeContainer() = default;
+
+ /// @param object_class the class type of this container
+ AttributeContainer(ObjectClass object_class);
+
+ virtual ~AttributeContainer() = default;
+
+/* Microsoft Visual Studio <= 2013 does not support default generated move special member functions.
+ Everything else we target should support it */
+#if !defined( _MSC_VER ) || ( _MSC_VER >= 1900 )
+ AttributeContainer(AttributeContainer&& other) = default;
+ AttributeContainer& operator=(AttributeContainer&& other) = default;
+#endif
+
+ // Warning when implementing copy/assignment: m_attributes contains pointers to the other members which must be updated after a copy
+ AttributeContainer(const AttributeContainer& other) = delete;
+ AttributeContainer& operator=(const AttributeContainer& other) = delete;
+
+ /// @return the attributes this container contains
+ inline const std::vector<Attribute>& attributes() const
+ {
+ return m_attributes;
+ }
+
+ inline Attribute* data() const
+ {
+ return const_cast< Attribute* >(m_attributes.data());
+ }
+
+ /// @return the number of attributes in this container
+ inline size_t count() const
+ {
+ return m_attributes.size();
+ }
+
+ /// Add a class attribute (CKA_CLASS / AttributeType::Class)
+ void add_class(ObjectClass object_class);
+
+ /// Add a string attribute (e.g. CKA_LABEL / AttributeType::Label)
+ void add_string(AttributeType attribute, const std::string& value);
+
+ /// Add a binary attribute (e.g. CKA_ID / AttributeType::Id)
+ void add_binary(AttributeType attribute, const byte* value, size_t length);
+
+ /// Add a binary attribute (e.g. CKA_ID / AttributeType::Id)
+ template<typename TAlloc>
+ void add_binary(AttributeType attribute, const std::vector<byte, TAlloc>& binary)
+ {
+ add_binary(attribute, binary.data(), binary.size());
+ }
+
+ /// Add a bool attribute (e.g. CKA_SENSITIVE / AttributeType::Sensitive)
+ void add_bool(AttributeType attribute, bool value);
+
+ /// Add a numeric attribute (e.g. CKA_MODULUS_BITS / AttributeType::ModulusBits)
+ template<typename T>
+ void add_numeric(AttributeType attribute, T value)
+ {
+ static_assert(std::is_integral<T>::value, "Numeric value required.");
+ m_numerics.push_back(static_cast< uint64_t >(value));
+ add_attribute(attribute, reinterpret_cast< byte* >(&m_numerics.back()), sizeof(T));
+ }
+
+ protected:
+ /// Add a attribute with the given value and size to the attribute collection `m_attributes`
+ void add_attribute(AttributeType attribute, const byte* value, uint32_t size);
+
+ private:
+ std::vector<Attribute> m_attributes;
+ std::list<uint64_t> m_numerics;
+ std::list<std::string> m_strings;
+ std::list<secure_vector<byte>> m_vectors;
+ };
+
+/// Manages calls to C_FindObjects* functions (C_FindObjectsInit -> C_FindObjects -> C_FindObjectsFinal)
+class BOTAN_DLL ObjectFinder final
+ {
+ public:
+ /**
+ * Initializes a search for token and session objects that match a template (calls C_FindObjectsInit)
+ * @param session the session to use for the search
+ * @param search_template the search_template as a vector of `Attribute`
+ */
+ ObjectFinder(Session& session, const std::vector<Attribute>& search_template);
+
+ ObjectFinder(const ObjectFinder& other) = default;
+ ObjectFinder& operator=(const ObjectFinder& other) = default;
+
+/* Microsoft Visual Studio <= 2013 does not support default generated move special member functions.
+ Everything else we target should support it */
+#if !defined( _MSC_VER ) || ( _MSC_VER >= 1900 )
+ ObjectFinder(ObjectFinder&& other) = default;
+ ObjectFinder& operator=(ObjectFinder&& other) = default;
+#endif
+
+ /// Terminates a search for token and session objects (calls C_FindObjectsFinal)
+ ~ObjectFinder() BOTAN_NOEXCEPT;
+
+ /**
+ * Starts or continues a search for token and session objects that match a template, obtaining additional object handles (calls C_FindObjects)
+ * @param max_count maximum amount of object handles to retrieve. Default = 100
+ * @return the result of the search as a vector of `ObjectHandle`
+ */
+ std::vector<ObjectHandle> find(std::uint32_t max_count = 100) const;
+
+ /// Finishes the search operation manually to allow a new ObjectFinder to exist
+ void finish();
+
+ /// @return the module this `ObjectFinder` belongs to
+ inline Module& module() const
+ {
+ return m_session.get().module();
+ }
+
+ private:
+ const std::reference_wrapper<Session> m_session;
+ bool m_search_terminated;
+ };
+
+/// Common attributes of all objects
+class BOTAN_DLL ObjectProperties : public AttributeContainer
+ {
+ public:
+ /// @param object_class the object class of the object
+ ObjectProperties(ObjectClass object_class);
+
+ /// @return the object class of this object
+ inline ObjectClass object_class() const
+ {
+ return m_object_class;
+ }
+
+ private:
+ const ObjectClass m_object_class;
+ };
+
+/// Common attributes of all storage objects
+class BOTAN_DLL StorageObjectProperties : public ObjectProperties
+ {
+ public:
+ /// @param object_class the CK_OBJECT_CLASS this storage object belongs to
+ StorageObjectProperties(ObjectClass object_class);
+
+ /// @param label description of the object (RFC2279 string)
+ inline void set_label(const std::string& label)
+ {
+ add_string(AttributeType::Label, label);
+ }
+
+ /// @param value if true the object is a token object; otherwise the object is a session object
+ inline void set_token(bool value)
+ {
+ add_bool(AttributeType::Token, value);
+ }
+
+ /**
+ * @param value if true the object is a private object; otherwise the object is a public object
+ * When private, a user may not access the object until the user has been authenticated to the token
+ */
+ inline void set_private(bool value)
+ {
+ add_bool(AttributeType::Private, value);
+ }
+
+ /// @param value if true the object can be modified, otherwise it is read-only
+ void set_modifiable(bool value)
+ {
+ add_bool(AttributeType::Modifiable, value);
+ }
+
+ /// @param value if true the object can be copied using C_CopyObject
+ void set_copyable(bool value)
+ {
+ add_bool(AttributeType::Copyable, value);
+ }
+
+ /// @param value if true the object can be destroyed using C_DestroyObject
+ void set_destroyable(bool value)
+ {
+ add_bool(AttributeType::Destroyable, value);
+ }
+ };
+
+/// Common attributes of all data objects
+class BOTAN_DLL DataObjectProperties : public StorageObjectProperties
+ {
+ public:
+ DataObjectProperties();
+
+ /// @param value description of the application that manages the object (RFC2279 string)
+ inline void set_application(const std::string& value)
+ {
+ add_string(AttributeType::Application, value);
+ }
+
+ /// @param object_id DER-encoding of the object identifier indicating the data object type
+ inline void set_object_id(const std::vector<byte>& object_id)
+ {
+ add_binary(AttributeType::ObjectId, object_id);
+ }
+
+ /// @param value value of the object
+ inline void set_value(const secure_vector<byte>& value)
+ {
+ add_binary(AttributeType::Value, value);
+ }
+ };
+
+/// Common attributes of all certificate objects
+class BOTAN_DLL CertificateProperties : public StorageObjectProperties
+ {
+ public:
+ /// @param cert_type type of certificate
+ CertificateProperties(CertificateType cert_type);
+
+ /// @param value the certificate can be trusted for the application that it was created (can only be set to true by SO user)
+ inline void set_trusted(bool value)
+ {
+ add_bool(AttributeType::Trusted, value);
+ }
+
+ /// @param category one of `CertificateCategory`
+ inline void set_category(CertificateCategory category)
+ {
+ add_numeric(AttributeType::CertificateCategory, static_cast< CK_CERTIFICATE_CATEGORY >(category));
+ }
+
+ /**
+ * @param checksum the value of this attribute is derived from the certificate by taking the
+ * first three bytes of the SHA - 1 hash of the certificate object�s `CKA_VALUE` attribute
+ */
+ inline void set_check_value(const std::vector<byte>& checksum)
+ {
+ add_binary(AttributeType::CheckValue, checksum);
+ }
+
+ /// @param date start date for the certificate
+ inline void set_start_date(Date date)
+ {
+ add_binary(AttributeType::StartDate, reinterpret_cast<byte*>(&date), sizeof(Date));
+ }
+
+ /// @param date end date for the certificate
+ inline void set_end_date(Date date)
+ {
+ add_binary(AttributeType::EndDate, reinterpret_cast<byte*>(&date), sizeof(Date));
+ }
+
+ /// @param pubkey_info DER-encoding of the SubjectPublicKeyInfo for the public key contained in this certificate
+ inline void set_public_key_info(const std::vector<byte>& pubkey_info)
+ {
+ add_binary(AttributeType::PublicKeyInfo, pubkey_info);
+ }
+
+ /// @return the certificate type of this certificate object
+ inline CertificateType cert_type() const
+ {
+ return m_cert_type;
+ }
+
+ private:
+ const CertificateType m_cert_type;
+ };
+
+/// Common attributes of all key objects
+class BOTAN_DLL KeyProperties : public StorageObjectProperties
+ {
+ public:
+ /**
+ * @param object_class the `CK_OBJECT_CLASS` this key object belongs to
+ * @param key_type type of key
+ */
+ KeyProperties(ObjectClass object_class, KeyType key_type);
+
+ /// @param id key identifier for key
+ inline void set_id(const std::vector<byte>& id)
+ {
+ add_binary(AttributeType::Id, id);
+ }
+
+ /// @param date start date for the key
+ inline void set_start_date(Date date)
+ {
+ add_binary(AttributeType::StartDate, reinterpret_cast<byte*>(&date), sizeof(Date));
+ }
+
+ /// @param date end date for the key
+ inline void set_end_date(Date date)
+ {
+ add_binary(AttributeType::EndDate, reinterpret_cast<byte*>(&date), sizeof(Date));
+ }
+
+ /// @param value true if key supports key derivation (i.e., if other keys can be derived from this one)
+ inline void set_derive(bool value)
+ {
+ add_bool(AttributeType::Derive, value);
+ }
+
+ /**
+ * Sets a list of mechanisms allowed to be used with this key
+ * Not implemented
+ */
+ inline void set_allowed_mechanisms(const std::vector<MechanismType>&)
+ {
+ throw Exception("Not implemented (KeyProperties::set_allowed_mechanisms)");
+ }
+
+ /// @return the key type of this key object
+ inline KeyType key_type() const
+ {
+ return m_key_type;
+ }
+
+ private:
+ const KeyType m_key_type;
+ };
+
+/// Common attributes of all public key objects
+class BOTAN_DLL PublicKeyProperties : public KeyProperties
+ {
+ public:
+ /// @param key_type type of key
+ PublicKeyProperties(KeyType key_type);
+
+ /// @param subject DER-encoding of the key subject name
+ inline void set_subject(const std::vector<byte>& subject)
+ {
+ add_binary(AttributeType::Subject, subject);
+ }
+
+ /// @param value true if the key supports encryption
+ inline void set_encrypt(bool value)
+ {
+ add_bool(AttributeType::Encrypt, value);
+ }
+
+ /// @param value true if the key supports verification where the signature is an appendix to the data
+ inline void set_verify(bool value)
+ {
+ add_bool(AttributeType::Verify, value);
+ }
+
+ /// @param value true if the key supports verification where the data is recovered from the signature
+ inline void set_verify_recover(bool value)
+ {
+ add_bool(AttributeType::VerifyRecover, value);
+ }
+
+ /// @param value true if the key supports wrapping (i.e., can be used to wrap other keys)
+ inline void set_wrap(bool value)
+ {
+ add_bool(AttributeType::Wrap, value);
+ }
+
+ /**
+ * @param value true if the key can be trusted for the application that it was created.
+ * The wrapping key can be used to wrap keys with `CKA_WRAP_WITH_TRUSTED` set to `CK_TRUE`
+ */
+ inline void set_trusted(bool value)
+ {
+ add_bool(AttributeType::Trusted, value);
+ }
+
+ /**
+ * For wrapping keys
+ * The attribute template to match against any keys wrapped using this wrapping key.
+ * Keys that do not match cannot be wrapped
+ * Not implemented
+ */
+ inline void set_wrap_template(const AttributeContainer&)
+ {
+ throw Exception("Not implemented (PublicKeyProperties::set_wrap_template)");
+ }
+
+ /// @param pubkey_info DER-encoding of the SubjectPublicKeyInfo for this public key
+ inline void set_public_key_info(const std::vector<byte>& pubkey_info)
+ {
+ add_binary(AttributeType::PublicKeyInfo, pubkey_info);
+ }
+ };
+
+/// Common attributes of all private keys
+class BOTAN_DLL PrivateKeyProperties : public KeyProperties
+ {
+ public:
+ /// @param key_type type of key
+ PrivateKeyProperties(KeyType key_type);
+
+ /// @param subject DER-encoding of the key subject name
+ inline void set_subject(const std::vector<byte>& subject)
+ {
+ add_binary(AttributeType::Subject, subject);
+ }
+
+ /// @param value true if the key is sensitive
+ inline void set_sensitive(bool value)
+ {
+ add_bool(AttributeType::Sensitive, value);
+ }
+
+ /// @param value true if the key supports decryption
+ inline void set_decrypt(bool value)
+ {
+ add_bool(AttributeType::Decrypt, value);
+ }
+
+ /// @param value true if the key supports signatures where the signature is an appendix to the data
+ inline void set_sign(bool value)
+ {
+ add_bool(AttributeType::Sign, value);
+ }
+
+ /// @param value true if the key supports signatures where the data can be recovered from the signature
+ inline void set_sign_recover(bool value)
+ {
+ add_bool(AttributeType::SignRecover, value);
+ }
+
+ /// @param value true if the key supports unwrapping (i.e., can be used to unwrap other keys)
+ inline void set_unwrap(bool value)
+ {
+ add_bool(AttributeType::Unwrap, value);
+ }
+
+ /// @param value true if the key is extractable and can be wrapped
+ inline void set_extractable(bool value)
+ {
+ add_bool(AttributeType::Extractable, value);
+ }
+
+ /// @param value true if the key can only be wrapped with a wrapping key that has `CKA_TRUSTED` set to `CK_TRUE`
+ inline void set_wrap_with_trusted(bool value)
+ {
+ add_bool(AttributeType::WrapWithTrusted, value);
+ }
+
+ /// @param value If true, the user has to supply the PIN for each use (sign or decrypt) with the key
+ inline void set_always_authenticate(bool value)
+ {
+ add_bool(AttributeType::AlwaysAuthenticate, value);
+ }
+
+ /**
+ * For wrapping keys
+ * The attribute template to apply to any keys unwrapped using this wrapping key.
+ * Any user supplied template is applied after this template as if the object has already been created
+ * Not implemented
+ */
+ inline void set_unwrap_template(const AttributeContainer&)
+ {
+ throw Exception("Not implemented (PrivateKeyProperties::set_unwrap_template)");
+ }
+
+ /// @param pubkey_info DER-encoding of the SubjectPublicKeyInfo for this public key
+ inline void set_public_key_info(const std::vector<byte>& pubkey_info)
+ {
+ add_binary(AttributeType::PublicKeyInfo, pubkey_info);
+ }
+ };
+
+/// Common attributes of all secret (symmetric) keys
+class BOTAN_DLL SecretKeyProperties : public KeyProperties
+ {
+ public:
+ /// @param key_type type of key
+ SecretKeyProperties(KeyType key_type);
+
+ /// @param value true if the key is sensitive
+ inline void set_sensitive(bool value)
+ {
+ add_bool(AttributeType::Sensitive, value);
+ }
+
+ /// @param value true if the key supports encryption
+ inline void set_encrypt(bool value)
+ {
+ add_bool(AttributeType::Encrypt, value);
+ }
+
+ /// @param value true if the key supports decryption
+ inline void set_decrypt(bool value)
+ {
+ add_bool(AttributeType::Decrypt, value);
+ }
+
+ /// @param value true if the key supports signatures where the signature is an appendix to the data
+ inline void set_sign(bool value)
+ {
+ add_bool(AttributeType::Sign, value);
+ }
+
+ /// @param value true if the key supports verification where the signature is an appendix to the data
+ inline void set_verify(bool value)
+ {
+ add_bool(AttributeType::Verify, value);
+ }
+
+ /// @param value true if the key supports unwrapping (i.e., can be used to unwrap other keys)
+ inline void set_unwrap(bool value)
+ {
+ add_bool(AttributeType::Unwrap, value);
+ }
+
+ /// @param value true if the key is extractable and can be wrapped
+ inline void set_extractable(bool value)
+ {
+ add_bool(AttributeType::Extractable, value);
+ }
+
+ /// @param value true if the key can only be wrapped with a wrapping key that has `CKA_TRUSTED` set to `CK_TRUE`
+ inline void set_wrap_with_trusted(bool value)
+ {
+ add_bool(AttributeType::WrapWithTrusted, value);
+ }
+
+ /// @param value if true, the user has to supply the PIN for each use (sign or decrypt) with the key
+ inline void set_always_authenticate(bool value)
+ {
+ add_bool(AttributeType::AlwaysAuthenticate, value);
+ }
+
+ /// @param value true if the key supports wrapping (i.e., can be used to wrap other keys)
+ inline void set_wrap(bool value)
+ {
+ add_bool(AttributeType::Wrap, value);
+ }
+
+ /**
+ * @param value the key can be trusted for the application that it was created.
+ * The wrapping key can be used to wrap keys with `CKA_WRAP_WITH_TRUSTED` set to `CK_TRUE`
+ */
+ inline void set_trusted(bool value)
+ {
+ add_bool(AttributeType::Trusted, value);
+ }
+
+ /// @param checksum the key check value of this key
+ inline void set_check_value(const std::vector<byte>& checksum)
+ {
+ add_binary(AttributeType::CheckValue, checksum);
+ }
+
+ /**
+ * For wrapping keys
+ * The attribute template to match against any keys wrapped using this wrapping key.
+ * Keys that do not match cannot be wrapped
+ * Not implemented
+ */
+ inline void set_wrap_template(const AttributeContainer&)
+ {
+ throw Exception("Not implemented (SecretKeyProperties::set_wrap_template)");
+ }
+
+ /**
+ * For wrapping keys
+ * The attribute template to apply to any keys unwrapped using this wrapping key
+ * Any user supplied template is applied after this template as if the object has already been created
+ * Not Implemented
+ */
+ inline void set_unwrap_template(const AttributeContainer&)
+ {
+ throw Exception("Not implemented (SecretKeyProperties::set_unwrap_template)");
+ }
+ };
+
+/// Common attributes of domain parameter
+class BOTAN_DLL DomainParameterProperties : public StorageObjectProperties
+ {
+ public:
+ /// @param key_type type of key the domain parameters can be used to generate
+ DomainParameterProperties(KeyType key_type);
+
+ /// @return the key type
+ inline KeyType key_type() const
+ {
+ return m_key_type;
+ }
+
+ private:
+ const KeyType m_key_type;
+ };
+
+class BOTAN_DLL Object
+ {
+ public:
+ /**
+ * Creates an `Object` from an existing PKCS#11 object
+ * @param session the session the object belongs to
+ * @param handle handle of the object
+ */
+
+ Object(Session& session, ObjectHandle handle);
+
+ /**
+ * Creates the object
+ * @param session the session in which the object should be created
+ * @param obj_props properties of this object
+ */
+ Object(Session& session, const ObjectProperties& obj_props);
+
+ virtual ~Object() = default;
+
+ /// Searches for all objects of the given type that match `search_template`
+ template<typename T>
+ static std::vector<T> search(Session& session, const std::vector<Attribute>& search_template);
+
+ /// Searches for all objects of the given type using the label (`CKA_LABEL`)
+ template<typename T>
+ static std::vector<T> search(Session& session, const std::string& label);
+
+ /// Searches for all objects of the given type using the id (`CKA_ID`)
+ template<typename T>
+ static std::vector<T> search(Session& session, const std::vector<byte>& id);
+
+ /// Searches for all objects of the given type using the label (`CKA_LABEL`) and id (`CKA_ID`)
+ template<typename T>
+ static std::vector<T> search(Session& session, const std::string& label, const std::vector<byte>& id);
+
+ /// Searches for all objects of the given type
+ template<typename T>
+ static std::vector<T> search(Session& session);
+
+ /// @returns the value of the given attribute (using `C_GetAttributeValue`)
+ secure_vector<byte> get_attribute_value(AttributeType attribute) const;
+
+ /// Sets the given value for the attribute (using `C_SetAttributeValue`)
+ void set_attribute_value(AttributeType attribute, const secure_vector<byte>& value) const;
+
+ /// Destroys the object
+ void destroy() const;
+
+ /**
+ * Copies the object
+ * @param modified_attributes the attributes of the copied object
+ */
+ ObjectHandle copy(const AttributeContainer& modified_attributes) const;
+
+ /// @return the handle of this object.
+ inline ObjectHandle handle() const
+ {
+ return m_handle;
+ }
+
+ /// @return the session this objects belongs to
+ inline Session& session() const
+ {
+ return m_session;
+ }
+
+ /// @return the module this object belongs to
+ inline Module& module() const
+ {
+ return m_session.get().module();
+ }
+ protected:
+ Object(Session& session)
+ : m_session(session)
+ {}
+
+ const std::reference_wrapper<Session> m_session;
+ ObjectHandle m_handle;
+ };
+
+template<typename T>
+std::vector<T> Object::search(Session& session, const std::vector<Attribute>& search_template)
+ {
+ ObjectFinder finder(session, search_template);
+ std::vector<ObjectHandle> handles = finder.find();
+ std::vector<T> result;
+ result.reserve(handles.size());
+ for(const auto& handle : handles)
+ {
+ result.emplace_back(T(session, handle));
+ }
+ return result;
+ }
+
+template<typename T>
+std::vector<T> Object::search(Session& session, const std::string& label)
+ {
+ AttributeContainer search_template(T::Class);
+ search_template.add_string(AttributeType::Label, label);
+ return search<T>(session, search_template.attributes());
+ }
+
+template<typename T>
+std::vector<T> Object::search(Session& session, const std::vector<byte>& id)
+ {
+ AttributeContainer search_template(T::Class);
+ search_template.add_binary(AttributeType::Id, id);
+ return search<T>(session, search_template.attributes());
+ }
+
+template<typename T>
+std::vector<T> Object::search(Session& session, const std::string& label, const std::vector<byte>& id)
+ {
+ AttributeContainer search_template(T::Class);
+ search_template.add_string(AttributeType::Label, label);
+ search_template.add_binary(AttributeType::Id, id);
+ return search<T>(session, search_template.attributes());
+ }
+
+template<typename T>
+std::vector<T> Object::search(Session& session)
+ {
+ return search<T>(session, AttributeContainer(T::Class).attributes());
+ }
+
+}
+
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_randomgenerator.cpp b/src/lib/prov/pkcs11/p11_randomgenerator.cpp
new file mode 100644
index 000000000..eaf9933c6
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_randomgenerator.cpp
@@ -0,0 +1,31 @@
+/*
+* PKCS#11 Random Generator
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_randomgenerator.h>
+
+namespace Botan {
+
+namespace PKCS11 {
+
+PKCS11_RNG::PKCS11_RNG(Session& session)
+ : m_session(session)
+ {}
+
+void PKCS11_RNG::randomize(Botan::byte output[], std::size_t length)
+ {
+ module()->C_GenerateRandom(m_session.get().handle(), output, length);
+ }
+
+void PKCS11_RNG::add_entropy(const Botan::byte in[], std::size_t length)
+ {
+ module()->C_SeedRandom(m_session.get().handle(), const_cast<Botan::byte*>(in), length);
+ }
+
+}
+}
+
diff --git a/src/lib/prov/pkcs11/p11_randomgenerator.h b/src/lib/prov/pkcs11/p11_randomgenerator.h
new file mode 100644
index 000000000..a291c89f3
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_randomgenerator.h
@@ -0,0 +1,70 @@
+/*
+* PKCS#11 Random Generator
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_RNG_H__
+#define BOTAN_P11_RNG_H__
+
+#include <botan/rng.h>
+#include <botan/p11_session.h>
+#include <botan/entropy_src.h>
+
+#include <string>
+#include <functional>
+
+namespace Botan {
+namespace PKCS11 {
+
+class Module;
+
+/// A random generator that only fetches random from the PKCS#11 RNG
+class BOTAN_DLL PKCS11_RNG final : public Hardware_RNG
+ {
+ public:
+ /// Initialize the RNG with the PKCS#11 session that provides access to the cryptoki functions
+ explicit PKCS11_RNG(Session& session);
+
+ void clear() override
+ {}
+
+ std::string name() const override
+ {
+ return "PKCS11_RNG";
+ }
+
+ /// Always returns true
+ bool is_seeded() const override
+ {
+ return true;
+ }
+
+ /// No operation - always returns 0
+ size_t reseed(Entropy_Sources&, size_t, std::chrono::milliseconds) override
+ {
+ return 0;
+ }
+
+ /// @return the module used by this RNG
+ inline Module& module() const
+ {
+ return m_session.get().module();
+ }
+
+ /// Calls `C_GenerateRandom` to generate random data
+ void randomize(Botan::byte output[], std::size_t length) override;
+
+ /// Calls `C_SeedRandom` to add entropy to the random generation function of the token/middleware
+ void add_entropy(const Botan::byte in[], std::size_t length) override;
+
+ private:
+ const std::reference_wrapper<Session> m_session;
+ };
+}
+
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_rsa.cpp b/src/lib/prov/pkcs11/p11_rsa.cpp
new file mode 100644
index 000000000..9e5675301
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_rsa.cpp
@@ -0,0 +1,377 @@
+/*
+* PKCS#11 RSA
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_rsa.h>
+
+#if defined(BOTAN_HAS_RSA)
+
+#include <botan/internal/p11_mechanism.h>
+#include <botan/pk_ops.h>
+#include <botan/internal/algo_registry.h>
+#include <botan/internal/pk_utils.h>
+#include <botan/rng.h>
+#include <botan/blinding.h>
+
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#else
+ #include <botan/auto_rng.h>
+#endif
+
+namespace Botan {
+
+namespace PKCS11 {
+
+RSA_PublicKeyImportProperties::RSA_PublicKeyImportProperties(const BigInt& modulus, const BigInt& pub_exponent)
+ : PublicKeyProperties(KeyType::Rsa), m_modulus(modulus), m_pub_exponent(pub_exponent)
+ {
+ add_binary(AttributeType::Modulus, BigInt::encode(m_modulus));
+ add_binary(AttributeType::PublicExponent, BigInt::encode(m_pub_exponent));
+ }
+
+RSA_PublicKeyGenerationProperties::RSA_PublicKeyGenerationProperties(Ulong bits)
+ : PublicKeyProperties(KeyType::Rsa)
+ {
+ add_numeric(AttributeType::ModulusBits, bits);
+ }
+
+PKCS11_RSA_PublicKey::PKCS11_RSA_PublicKey(Session& session, ObjectHandle handle)
+ : Object(session, handle)
+ {
+ m_n = BigInt::decode(get_attribute_value(AttributeType::Modulus));
+ m_e = BigInt::decode(get_attribute_value(AttributeType::PublicExponent));
+ }
+
+PKCS11_RSA_PublicKey::PKCS11_RSA_PublicKey(Session& session, const RSA_PublicKeyImportProperties& pubkey_props)
+ : RSA_PublicKey(pubkey_props.modulus(), pubkey_props.pub_exponent()), Object(session, pubkey_props)
+ {}
+
+
+RSA_PrivateKeyImportProperties::RSA_PrivateKeyImportProperties(const BigInt& modulus, const BigInt& priv_exponent)
+ : PrivateKeyProperties(KeyType::Rsa), m_modulus(modulus), m_priv_exponent(priv_exponent)
+ {
+ add_binary(AttributeType::Modulus, BigInt::encode(m_modulus));
+ add_binary(AttributeType::PrivateExponent, BigInt::encode(m_priv_exponent));
+ }
+
+
+PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, ObjectHandle handle)
+ : Object(session, handle)
+ {
+ m_n = BigInt::decode(get_attribute_value(AttributeType::Modulus));
+ m_e = BigInt::decode(get_attribute_value(AttributeType::PublicExponent));
+ }
+
+PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, const RSA_PrivateKeyImportProperties& priv_key_props)
+ : Object(session, priv_key_props)
+ {
+ m_n = priv_key_props.modulus();
+ m_e = BigInt::decode(get_attribute_value(AttributeType::PublicExponent));
+ }
+
+PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, uint32_t bits,
+ const RSA_PrivateKeyGenerationProperties& priv_key_props)
+ : RSA_PublicKey(), Object(session)
+ {
+ RSA_PublicKeyGenerationProperties pub_key_props(bits);
+ pub_key_props.set_encrypt(true);
+ pub_key_props.set_verify(true);
+ pub_key_props.set_token(false); // don't create a persistent public key object
+
+ ObjectHandle pub_key_handle = 0;
+ m_handle = 0;
+ Mechanism mechanism = { static_cast< CK_MECHANISM_TYPE >(MechanismType::RsaPkcsKeyPairGen), nullptr, 0 };
+ session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
+ pub_key_props.data(), pub_key_props.count(), priv_key_props.data(), priv_key_props.count(),
+ &pub_key_handle, &m_handle);
+
+ m_n = BigInt::decode(get_attribute_value(AttributeType::Modulus));
+ m_e = BigInt::decode(get_attribute_value(AttributeType::PublicExponent));
+ }
+
+RSA_PrivateKey PKCS11_RSA_PrivateKey::export_key() const
+ {
+ auto p = get_attribute_value(AttributeType::Prime1);
+ auto q = get_attribute_value(AttributeType::Prime2);
+ auto e = get_attribute_value(AttributeType::PublicExponent);
+ auto d = get_attribute_value(AttributeType::PrivateExponent);
+ auto n = get_attribute_value(AttributeType::Modulus);
+
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ System_RNG rng;
+#else
+ AutoSeeded_RNG rng;
+#endif
+
+ return RSA_PrivateKey(rng
+ , BigInt::decode(p)
+ , BigInt::decode(q)
+ , BigInt::decode(e)
+ , BigInt::decode(d)
+ , BigInt::decode(n));
+ }
+
+secure_vector<byte> PKCS11_RSA_PrivateKey::pkcs8_private_key() const
+ {
+ return export_key().pkcs8_private_key();
+ }
+
+
+namespace {
+// note: multiple-part decryption operations (with C_DecryptUpdate/C_DecryptFinal)
+// are not supported (PK_Ops::Decryption does not provide an `update` method)
+class PKCS11_RSA_Decryption_Operation : public PK_Ops::Decryption
+ {
+ public:
+ typedef PKCS11_RSA_PrivateKey Key_Type;
+
+ PKCS11_RSA_Decryption_Operation(const PKCS11_RSA_PrivateKey& key, const std::string& padding)
+ : m_key(key), m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding)),
+ m_powermod(m_key.get_e(), m_key.get_n()), m_blinder(m_key.get_n(),
+ [ this ](const BigInt& k) { return m_powermod(k); },
+ [ this ](const BigInt& k) { return inverse_mod(k, m_key.get_n()); })
+ {
+ m_bits = m_key.get_n().bits() - 1;
+ }
+
+ size_t max_input_bits() const override
+ {
+ return m_bits;
+ }
+
+ secure_vector<byte> decrypt(byte& valid_mask, const byte ciphertext[], size_t ciphertext_len) override
+ {
+ valid_mask = 0;
+ m_key.module()->C_DecryptInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
+
+ std::vector<byte> encrypted_data(ciphertext, ciphertext + ciphertext_len);
+
+ // blind for RSA/RAW decryption
+ if(! m_mechanism.padding_size())
+ {
+ encrypted_data = BigInt::encode(m_blinder.blind(BigInt::decode(encrypted_data)));
+ }
+
+ secure_vector<byte> decrypted_data;
+ m_key.module()->C_Decrypt(m_key.session().handle(), encrypted_data, decrypted_data);
+
+ // Unblind for RSA/RAW decryption
+ if(!m_mechanism.padding_size())
+ {
+ decrypted_data = BigInt::encode_1363(m_blinder.unblind(BigInt::decode(decrypted_data)), m_key.get_n().bits() / 8 );
+ }
+
+ valid_mask = 0xFF;
+ return decrypted_data;
+ }
+
+ private:
+ const PKCS11_RSA_PrivateKey& m_key;
+ MechanismWrapper m_mechanism;
+ size_t m_bits = 0;
+ Fixed_Exponent_Power_Mod m_powermod;
+ Blinder m_blinder;
+ };
+
+// note: multiple-part encryption operations (with C_EncryptUpdate/C_EncryptFinal)
+// are not supported (PK_Ops::Encryption does not provide an `update` method)
+class PKCS11_RSA_Encryption_Operation : public PK_Ops::Encryption
+ {
+ public:
+ typedef PKCS11_RSA_PublicKey Key_Type;
+
+ PKCS11_RSA_Encryption_Operation(const PKCS11_RSA_PublicKey& key, const std::string& padding)
+ : m_key(key), m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding))
+ {
+ m_bits = 8 * (key.get_n().bytes() - m_mechanism.padding_size()) - 1;
+ }
+
+ size_t max_input_bits() const override
+ {
+ return m_bits;
+ }
+
+ secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) override
+ {
+ m_key.module()->C_EncryptInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
+
+ secure_vector<byte> encrytped_data;
+ m_key.module()->C_Encrypt(m_key.session().handle(), secure_vector<byte>(msg, msg + msg_len), encrytped_data);
+ return encrytped_data;
+ }
+
+ private:
+ const PKCS11_RSA_PublicKey& m_key;
+ MechanismWrapper m_mechanism;
+ size_t m_bits = 0;
+ };
+
+
+class PKCS11_RSA_Signature_Operation : public PK_Ops::Signature
+ {
+ public:
+ typedef PKCS11_RSA_PrivateKey Key_Type;
+
+ PKCS11_RSA_Signature_Operation(const PKCS11_RSA_PrivateKey& key, const std::string& padding)
+ : m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding))
+ {}
+
+ size_t message_part_size() const override
+ {
+ return m_key.get_n().bytes();
+ }
+
+ void update(const byte msg[], size_t msg_len) override
+ {
+ if(!m_initialized)
+ {
+ // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
+ m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
+ m_initialized = true;
+ m_first_message = secure_vector<byte>(msg, msg + msg_len);
+ return;
+ }
+
+ if(!m_first_message.empty())
+ {
+ // second call to update: start multiple-part operation
+ m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
+ m_first_message.clear();
+ }
+
+ m_key.module()->C_SignUpdate(m_key.session().handle(), const_cast< Byte* >(msg), msg_len);
+ }
+
+ secure_vector<byte> sign(RandomNumberGenerator&) override
+ {
+ secure_vector<byte> signature;
+ if(!m_first_message.empty())
+ {
+ // single call to update: perform single-part operation
+ m_key.module()->C_Sign(m_key.session().handle(), m_first_message, signature);
+ m_first_message.clear();
+ }
+ else
+ {
+ // multiple calls to update (or none): finish multiple-part operation
+ m_key.module()->C_SignFinal(m_key.session().handle(), signature);
+ }
+ m_initialized = false;
+ return signature;
+ }
+
+ private:
+ const PKCS11_RSA_PrivateKey& m_key;
+ bool m_initialized = false;
+ secure_vector<byte> m_first_message;
+ MechanismWrapper m_mechanism;
+ };
+
+
+class PKCS11_RSA_Verification_Operation : public PK_Ops::Verification
+ {
+ public:
+ typedef PKCS11_RSA_PublicKey Key_Type;
+
+ PKCS11_RSA_Verification_Operation(const PKCS11_RSA_PublicKey& key, const std::string& padding)
+ : m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding))
+ {}
+
+ size_t message_part_size() const override
+ {
+ return m_key.get_n().bytes();
+ }
+
+ size_t max_input_bits() const override
+ {
+ return m_key.get_n().bits() - 1;
+ }
+
+ void update(const byte msg[], size_t msg_len) override
+ {
+ if(!m_initialized)
+ {
+ // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
+ m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
+ m_initialized = true;
+ m_first_message = secure_vector<byte>(msg, msg + msg_len);
+ return;
+ }
+
+ if(!m_first_message.empty())
+ {
+ // second call to update: start multiple-part operation
+ m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
+ m_first_message.clear();
+ }
+
+ m_key.module()->C_VerifyUpdate(m_key.session().handle(), const_cast< Byte* >(msg), msg_len);
+ }
+
+ bool is_valid_signature(const byte sig[], size_t sig_len) override
+ {
+ ReturnValue return_value = ReturnValue::SignatureInvalid;
+ if(!m_first_message.empty())
+ {
+ // single call to update: perform single-part operation
+ m_key.module()->C_Verify(m_key.session().handle(), m_first_message.data(), m_first_message.size(),
+ const_cast< Byte* >(sig), sig_len, &return_value);
+ m_first_message.clear();
+ }
+ else
+ {
+ // multiple calls to update (or none): finish multiple-part operation
+ m_key.module()->C_VerifyFinal(m_key.session().handle(), const_cast< Byte* >(sig), sig_len, &return_value);
+ }
+ m_initialized = false;
+ if(return_value != ReturnValue::OK && return_value != ReturnValue::SignatureInvalid)
+ {
+ throw PKCS11_ReturnError(return_value);
+ }
+ return return_value == ReturnValue::OK;
+ }
+
+ private:
+ const PKCS11_RSA_PublicKey& m_key;
+ bool m_initialized = false;
+ secure_vector<byte> m_first_message;
+ MechanismWrapper m_mechanism;
+ };
+
+BOTAN_REGISTER_TYPE(PK_Ops::Decryption, PKCS11_RSA_Decryption_Operation, "RSA",
+ (make_pk_op<PK_Ops::Decryption, PKCS11_RSA_Decryption_Operation>), "pkcs11", BOTAN_PKCS11_RSA_PRIO);
+
+BOTAN_REGISTER_TYPE(PK_Ops::Encryption, PKCS11_RSA_Encryption_Operation, "RSA",
+ (make_pk_op<PK_Ops::Encryption, PKCS11_RSA_Encryption_Operation>), "pkcs11", BOTAN_PKCS11_RSA_PRIO);
+
+BOTAN_REGISTER_TYPE(PK_Ops::Signature, PKCS11_RSA_Signature_Operation, "RSA",
+ (make_pk_op<PK_Ops::Signature, PKCS11_RSA_Signature_Operation>), "pkcs11", BOTAN_PKCS11_RSA_PRIO);
+
+BOTAN_REGISTER_TYPE(PK_Ops::Verification, PKCS11_RSA_Verification_Operation, "RSA",
+ (make_pk_op<PK_Ops::Verification, PKCS11_RSA_Verification_Operation>), "pkcs11", BOTAN_PKCS11_RSA_PRIO);
+
+}
+
+PKCS11_RSA_KeyPair generate_rsa_keypair(Session& session, const RSA_PublicKeyGenerationProperties& pub_props,
+ const RSA_PrivateKeyGenerationProperties& priv_props)
+ {
+ ObjectHandle pub_key_handle = 0;
+ ObjectHandle priv_key_handle = 0;
+
+ Mechanism mechanism = { static_cast< CK_MECHANISM_TYPE >(MechanismType::RsaPkcsKeyPairGen), nullptr, 0 };
+
+ session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
+ pub_props.data(), pub_props.count(), priv_props.data(), priv_props.count(),
+ &pub_key_handle, &priv_key_handle);
+
+ return std::make_pair(PKCS11_RSA_PublicKey(session, pub_key_handle), PKCS11_RSA_PrivateKey(session, priv_key_handle));
+ }
+
+}
+}
+#endif
diff --git a/src/lib/prov/pkcs11/p11_rsa.h b/src/lib/prov/pkcs11/p11_rsa.h
new file mode 100644
index 000000000..2739cf3e5
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_rsa.h
@@ -0,0 +1,212 @@
+/*
+* PKCS#11 RSA
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_RSA_H__
+#define BOTAN_P11_RSA_H__
+
+#include <botan/build.h>
+#include <botan/p11.h>
+#include <botan/p11_session.h>
+#include <botan/p11_object.h>
+
+#if defined(BOTAN_HAS_RSA)
+#include <botan/rsa.h>
+#include <utility>
+
+namespace Botan {
+namespace PKCS11 {
+
+/// Properties for generating a PKCS#11 RSA public key
+class BOTAN_DLL RSA_PublicKeyGenerationProperties final : public PublicKeyProperties
+ {
+ public:
+ /// @param bits length in bits of modulus n
+ explicit RSA_PublicKeyGenerationProperties(Ulong bits);
+
+ /// @param pub_exponent public exponent e
+ inline void set_pub_exponent(const BigInt& pub_exponent = BigInt(0x10001))
+ {
+ add_binary(AttributeType::PublicExponent, BigInt::encode(pub_exponent));
+ }
+
+ virtual ~RSA_PublicKeyGenerationProperties() = default;
+ };
+
+/// Properties for importing a PKCS#11 RSA public key
+class BOTAN_DLL RSA_PublicKeyImportProperties final : public PublicKeyProperties
+ {
+ public:
+ /// @param modulus modulus n
+ /// @param pub_exponent public exponent e
+ RSA_PublicKeyImportProperties(const BigInt& modulus, const BigInt& pub_exponent);
+
+ /// @return the modulus
+ inline const BigInt& modulus() const
+ {
+ return m_modulus;
+ }
+
+ /// @return the public exponent
+ inline const BigInt& pub_exponent() const
+ {
+ return m_pub_exponent;
+ }
+
+ virtual ~RSA_PublicKeyImportProperties() = default;
+ private:
+ const BigInt m_modulus;
+ const BigInt m_pub_exponent;
+ };
+
+/// Represents a PKCS#11 RSA public key
+class BOTAN_DLL PKCS11_RSA_PublicKey final : public RSA_PublicKey,
+ public Object
+ {
+ public:
+ static const ObjectClass Class = ObjectClass::PublicKey;
+
+ /**
+ * Creates a PKCS11_RSA_PublicKey object from an existing PKCS#11 RSA public key
+ * @param session the session to use
+ * @param handle the handle of the RSA public key
+ */
+ PKCS11_RSA_PublicKey(Session& session, ObjectHandle handle);
+
+ /**
+ * Imports a RSA public key
+ * @param session the session to use
+ * @param pubkey_props the attributes of the public key
+ */
+ PKCS11_RSA_PublicKey(Session& session, const RSA_PublicKeyImportProperties& pubkey_props);
+ };
+
+/// Properties for importing a PKCS#11 RSA private key
+class BOTAN_DLL RSA_PrivateKeyImportProperties final : public PrivateKeyProperties
+ {
+ public:
+ /**
+ * @param modulus modulus n
+ * @param priv_exponent private exponent d
+ */
+ RSA_PrivateKeyImportProperties(const BigInt& modulus, const BigInt& priv_exponent);
+
+ /// @param pub_exponent public exponent e
+ inline void set_pub_exponent(const BigInt& pub_exponent)
+ {
+ add_binary(AttributeType::PublicExponent, BigInt::encode(pub_exponent));
+ }
+
+ /// @param prime1 prime p
+ inline void set_prime_1(const BigInt& prime1)
+ {
+ add_binary(AttributeType::Prime1, BigInt::encode(prime1));
+ }
+
+ /// @param prime2 prime q
+ inline void set_prime_2(const BigInt& prime2)
+ {
+ add_binary(AttributeType::Prime2, BigInt::encode(prime2));
+ }
+
+ /// @param exp1 private exponent d modulo p-1
+ inline void set_exponent_1(const BigInt& exp1)
+ {
+ add_binary(AttributeType::Exponent1, BigInt::encode(exp1));
+ }
+
+ /// @param exp2 private exponent d modulo q-1
+ inline void set_exponent_2(const BigInt& exp2)
+ {
+ add_binary(AttributeType::Exponent2, BigInt::encode(exp2));
+ }
+
+ /// @param coeff CRT coefficient q^-1 mod p
+ inline void set_coefficient(const BigInt& coeff)
+ {
+ add_binary(AttributeType::Coefficient, BigInt::encode(coeff));
+ }
+
+ /// @return the modulus
+ inline const BigInt& modulus() const
+ {
+ return m_modulus;
+ }
+
+ /// @return the private exponent
+ inline const BigInt& priv_exponent() const
+ {
+ return m_priv_exponent;
+ }
+
+ virtual ~RSA_PrivateKeyImportProperties() = default;
+
+ private:
+ const BigInt m_modulus;
+ const BigInt m_priv_exponent;
+ };
+
+/// Properties for generating a PKCS#11 RSA private key
+class BOTAN_DLL RSA_PrivateKeyGenerationProperties final : public PrivateKeyProperties
+ {
+ public:
+ RSA_PrivateKeyGenerationProperties()
+ : PrivateKeyProperties(KeyType::Rsa)
+ {}
+
+ virtual ~RSA_PrivateKeyGenerationProperties() = default;
+ };
+
+/// Represents a PKCS#11 RSA private key
+class BOTAN_DLL PKCS11_RSA_PrivateKey final : public Private_Key,
+ public RSA_PublicKey,
+ public Object
+ {
+ public:
+ static const ObjectClass Class = ObjectClass::PrivateKey;
+
+ /// Creates a PKCS11_RSA_PrivateKey object from an existing PKCS#11 RSA private key
+ PKCS11_RSA_PrivateKey(Session& session, ObjectHandle handle);
+
+ /**
+ * Imports a RSA private key
+ * @param session the session to use
+ * @param priv_key_props the properties of the RSA private key
+ */
+ PKCS11_RSA_PrivateKey(Session& session, const RSA_PrivateKeyImportProperties& priv_key_props);
+
+ /**
+ * Generates a PKCS#11 RSA private key
+ * @param session
+ * @param bits length in bits of modulus n
+ * @param priv_key_props the properties of the RSA private key
+ * @note no persistent public key object will be created
+ */
+ PKCS11_RSA_PrivateKey(Session& session, uint32_t bits, const RSA_PrivateKeyGenerationProperties& priv_key_props);
+
+ /// @return the exported RSA private key
+ RSA_PrivateKey export_key() const;
+
+ secure_vector<byte> pkcs8_private_key() const override;
+ };
+
+using PKCS11_RSA_KeyPair = std::pair<PKCS11_RSA_PublicKey, PKCS11_RSA_PrivateKey>;
+
+/**
+* RSA key pair generation
+* @param session the session that should be used for the key generation
+* @param pub_props properties of the public key
+* @param priv_props properties of the private key
+*/
+BOTAN_DLL PKCS11_RSA_KeyPair generate_rsa_keypair(Session& session, const RSA_PublicKeyGenerationProperties& pub_props,
+ const RSA_PrivateKeyGenerationProperties& priv_props);
+}
+
+}
+#endif
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_session.cpp b/src/lib/prov/pkcs11/p11_session.cpp
new file mode 100644
index 000000000..ceb316169
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_session.cpp
@@ -0,0 +1,89 @@
+/*
+* PKCS#11 Session
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_session.h>
+
+namespace Botan {
+namespace PKCS11 {
+
+Session::Session(Slot& slot, bool read_only)
+ : Session(slot, PKCS11::flags(Flag::SerialSession | (read_only ? Flag::None : Flag::RwSession)), nullptr, nullptr)
+ {}
+
+Session::Session(Slot& slot, Flags flags, VoidPtr callback_data, Notify notify_callback)
+ : m_slot(slot), m_handle(0), m_logged_in(false)
+ {
+ module()->C_OpenSession(m_slot.slot_id(), flags, callback_data, notify_callback, &m_handle);
+ }
+
+Session::Session(Slot& slot, SessionHandle handle)
+ : m_slot(slot), m_handle(handle)
+ {
+ SessionInfo info = get_info();
+ if(info.state == static_cast<CK_STATE>(SessionState::RoPublicSession)
+ || info.state == static_cast<CK_STATE>(SessionState::RwPublicSession))
+ {
+ m_logged_in = false;
+ }
+ else
+ {
+ m_logged_in = true;
+ }
+ }
+
+Session::~Session() BOTAN_NOEXCEPT
+ {
+ if(m_handle)
+ {
+ if(m_logged_in)
+ {
+ module()->C_Logout(m_handle, nullptr);
+ }
+ module()->C_CloseSession(m_handle, nullptr);
+ m_handle = 0;
+ }
+ }
+
+SessionHandle Session::release()
+ {
+ SessionHandle handle = 0;
+ std::swap(handle, m_handle);
+ return handle;
+ }
+
+void Session::login(UserType user_type, const secure_string& pin)
+ {
+ module()->C_Login(m_handle, user_type, pin);
+ m_logged_in = true;
+ }
+
+void Session::logoff()
+ {
+ module()->C_Logout(m_handle);
+ m_logged_in = false;
+ }
+
+SessionInfo Session::get_info() const
+ {
+ SessionInfo info;
+ module()->C_GetSessionInfo(m_handle, &info);
+ return info;
+ }
+
+void Session::set_pin(const secure_string& old_pin, const secure_string& new_pin) const
+ {
+ module()->C_SetPIN(m_handle, old_pin, new_pin);
+ }
+
+void Session::init_pin(const secure_string& new_pin)
+ {
+ module()->C_InitPIN(m_handle, new_pin);
+ }
+
+}
+}
diff --git a/src/lib/prov/pkcs11/p11_session.h b/src/lib/prov/pkcs11/p11_session.h
new file mode 100644
index 000000000..49f223a90
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_session.h
@@ -0,0 +1,105 @@
+/*
+* PKCS#11 Session
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_SESSION_H__
+#define BOTAN_P11_SESSION_H__
+
+#include <botan/p11.h>
+#include <botan/p11_slot.h>
+
+#include <utility>
+
+namespace Botan {
+namespace PKCS11 {
+class Module;
+
+/// Represents a PKCS#11 session
+class BOTAN_DLL Session final
+ {
+ public:
+ /**
+ * @param slot the slot to use
+ * @param read_only true if the session should be read only, false to create a read-write session
+ */
+ Session(Slot& slot, bool read_only);
+
+ /**
+ * @param slot the slot to use
+ * @param flags the flags to use for the session. Remark: Flag::SerialSession is mandatory
+ * @param callback_data application-defined pointer to be passed to the notification callback
+ * @param notify_callback address of the notification callback function
+ */
+ Session(Slot& slot, Flags flags, VoidPtr callback_data, Notify notify_callback);
+
+ /// Takes ownership of a session
+ Session(Slot& slot, SessionHandle handle);
+
+/* Microsoft Visual Studio <= 2013 does not support default generated move special member functions.
+ Everything else we target should support it */
+#if !defined( _MSC_VER ) || ( _MSC_VER >= 1900 )
+ Session(Session&& other) = default;
+ Session& operator=(Session&& other) = default;
+#endif
+
+ // Dtor calls C_CloseSession() and eventually C_Logout. A copy could close the session while the origin still exists
+ Session(const Session& other) = delete;
+ Session& operator=(const Session& other) = delete;
+
+ /// Logout user and close the session on destruction
+ ~Session() BOTAN_NOEXCEPT;
+
+ /// @return a reference to the slot
+ inline const Slot& slot() const
+ {
+ return m_slot;
+ }
+
+ /// @return the session handle of this session
+ inline SessionHandle handle() const
+ {
+ return m_handle;
+ }
+
+ /// @return a reference to the used module
+ inline Module& module() const
+ {
+ return m_slot.module();
+ }
+
+ /// @return the released session handle
+ SessionHandle release();
+
+ /**
+ * Login to this session
+ * @param userType the user type to use for the login
+ * @param pin the PIN of the user
+ */
+ void login(UserType userType, const secure_string& pin);
+
+ /// Logout from this session
+ void logoff();
+
+ /// @return information about this session
+ SessionInfo get_info() const;
+
+ /// Calls `C_SetPIN` to change the PIN using the old PIN (requires a logged in session)
+ void set_pin(const secure_string& old_pin, const secure_string& new_pin) const;
+
+ /// Calls `C_InitPIN` to change or initialize the PIN using the SO_PIN (requires a logged in session)
+ void init_pin(const secure_string& new_pin);
+
+ private:
+ const Slot& m_slot;
+ SessionHandle m_handle;
+ bool m_logged_in;
+ };
+
+}
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_slot.cpp b/src/lib/prov/pkcs11/p11_slot.cpp
new file mode 100644
index 000000000..95a0fad50
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_slot.cpp
@@ -0,0 +1,60 @@
+/*
+* PKCS#11 Slot
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_slot.h>
+
+namespace Botan {
+
+namespace PKCS11 {
+
+Slot::Slot(Module& module, SlotId slot_id)
+ : m_module(module), m_slot_id(slot_id)
+ {}
+
+SlotInfo Slot::get_slot_info() const
+ {
+ SlotInfo slot_info = {};
+ m_module.get()->C_GetSlotInfo(m_slot_id, &slot_info);
+ return slot_info;
+ }
+
+std::vector<MechanismType> Slot::get_mechanism_list() const
+ {
+ std::vector<MechanismType> mechanism_list;
+ m_module.get()->C_GetMechanismList(m_slot_id, mechanism_list);
+ return mechanism_list;
+ }
+
+MechanismInfo Slot::get_mechanism_info(MechanismType mechanism_type) const
+ {
+ MechanismInfo mechanism_info = {};
+ m_module.get()->C_GetMechanismInfo(m_slot_id, mechanism_type, &mechanism_info);
+ return mechanism_info;
+ }
+
+std::vector<SlotId> Slot::get_available_slots(Module& module, bool token_present)
+ {
+ std::vector<SlotId> slot_vec;
+ module->C_GetSlotList(token_present, slot_vec);
+ return slot_vec;
+ }
+
+TokenInfo Slot::get_token_info() const
+ {
+ TokenInfo token_info;
+ m_module.get()->C_GetTokenInfo(m_slot_id, &token_info);
+ return token_info;
+ }
+
+void Slot::initialize(const std::string& label, const secure_string& so_pin) const
+ {
+ m_module.get()->C_InitToken(m_slot_id, so_pin, label);
+ }
+}
+
+}
diff --git a/src/lib/prov/pkcs11/p11_slot.h b/src/lib/prov/pkcs11/p11_slot.h
new file mode 100644
index 000000000..92e585ba1
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_slot.h
@@ -0,0 +1,79 @@
+/*
+* PKCS#11 Slot
+* (C) 2016 Daniel Neus
+* (C) 2016 Philipp Weber
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_SLOT_H__
+#define BOTAN_P11_SLOT_H__
+
+#include <string>
+#include <vector>
+#include <functional>
+
+#include <botan/p11.h>
+#include <botan/p11_module.h>
+
+namespace Botan {
+namespace PKCS11 {
+
+/// Represents a PKCS#11 Slot, i.e., a card reader
+class BOTAN_DLL Slot final
+ {
+ public:
+ /**
+ * @param module the PKCS#11 module to use
+ * @param slot_id the slot id to use
+ */
+ Slot(Module& module, SlotId slot_id);
+
+ /// @return a reference to the module that is used
+ inline Module& module() const
+ {
+ return m_module;
+ }
+
+ /// @return the slot id
+ inline SlotId slot_id() const
+ {
+ return m_slot_id;
+ }
+
+ /**
+ * Get available slots
+ * @param module the module to use
+ * @param token_present true if only slots with attached tokens should be returned, false for all slots
+ * @return a list of available slots (calls C_GetSlotList)
+ */
+ static std::vector<SlotId> get_available_slots(Module& module, bool token_present);
+
+ /// @return information about the slot (`C_GetSlotInfo`)
+ SlotInfo get_slot_info() const;
+
+ /// Obtains a list of mechanism types supported by the slot (`C_GetMechanismList`)
+ std::vector<MechanismType> get_mechanism_list() const;
+
+ /// Obtains information about a particular mechanism possibly supported by a slot (`C_GetMechanismInfo`)
+ MechanismInfo get_mechanism_info(MechanismType mechanism_type) const;
+
+ /// Obtains information about a particular token in the system (`C_GetTokenInfo`)
+ TokenInfo get_token_info() const;
+
+ /**
+ * Calls `C_InitToken` to initialize the token
+ * @param label the label for the token (must not exceed 32 bytes according to PKCS#11)
+ * @param so_pin the PIN of the security officer
+ */
+ void initialize(const std::string& label, const secure_string& so_pin) const;
+
+ private:
+ const std::reference_wrapper<Module> m_module;
+ const SlotId m_slot_id;
+ };
+
+}
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_x509.cpp b/src/lib/prov/pkcs11/p11_x509.cpp
new file mode 100644
index 000000000..76b120368
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_x509.cpp
@@ -0,0 +1,37 @@
+/*
+* PKCS#11 X.509
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_x509.h>
+
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+
+namespace Botan {
+namespace PKCS11 {
+
+X509_CertificateProperties::X509_CertificateProperties(const std::vector<byte>& subject, const std::vector<byte>& value)
+ : CertificateProperties(CertificateType::X509), m_subject(subject), m_value(value)
+ {
+ add_binary(AttributeType::Subject, m_subject);
+ add_binary(AttributeType::Value, m_value);
+ }
+
+PKCS11_X509_Certificate::PKCS11_X509_Certificate(Session& session, ObjectHandle handle)
+ : Object(session, handle), X509_Certificate(unlock(get_attribute_value(AttributeType::Value)))
+ {
+ }
+
+PKCS11_X509_Certificate::PKCS11_X509_Certificate(Session& session, const X509_CertificateProperties& props)
+ : Object(session, props), X509_Certificate(props.value())
+ {
+ }
+
+}
+
+}
+
+#endif
diff --git a/src/lib/prov/pkcs11/p11_x509.h b/src/lib/prov/pkcs11/p11_x509.h
new file mode 100644
index 000000000..f0e025ff4
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_x509.h
@@ -0,0 +1,115 @@
+/*
+* PKCS#11 X.509
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_P11_X509_H__
+#define BOTAN_P11_X509_H__
+
+#include <botan/build.h>
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+
+#include <botan/p11_object.h>
+
+#include <botan/x509cert.h>
+
+#include <vector>
+
+namespace Botan {
+namespace PKCS11 {
+
+class Session;
+
+/// Common attributes of all PKCS#11 X509 certificates
+class BOTAN_DLL X509_CertificateProperties final : public CertificateProperties
+ {
+ public:
+ /**
+ * @param subject DER-encoding of the certificate subject name
+ * @param value BER-encoding of the certificate
+ */
+ X509_CertificateProperties(const std::vector<byte>& subject, const std::vector<byte>& value);
+
+ /// @param id key identifier for public/private key pair
+ inline void set_id(const std::vector<byte>& id)
+ {
+ add_binary(AttributeType::Id, id);
+ }
+
+ /// @param issuer DER-encoding of the certificate issuer name
+ inline void set_issuer(const std::vector<byte>& issuer)
+ {
+ add_binary(AttributeType::Issuer, issuer);
+ }
+
+ /// @param serial DER-encoding of the certificate serial number
+ inline void set_serial(const std::vector<byte>& serial)
+ {
+ add_binary(AttributeType::SerialNumber, serial);
+ }
+
+ /// @param hash hash value of the subject public key
+ inline void set_subject_pubkey_hash(const std::vector<byte>& hash)
+ {
+ add_binary(AttributeType::HashOfSubjectPublicKey, hash);
+ }
+
+ /// @param hash hash value of the issuer public key
+ inline void set_issuer_pubkey_hash(const std::vector<byte>& hash)
+ {
+ add_binary(AttributeType::HashOfIssuerPublicKey, hash);
+ }
+
+ /// @param alg defines the mechanism used to calculate `CKA_HASH_OF_SUBJECT_PUBLIC_KEY` and `CKA_HASH_OF_ISSUER_PUBLIC_KEY`
+ inline void set_hash_alg(MechanismType alg)
+ {
+ add_numeric(AttributeType::NameHashAlgorithm, static_cast<Ulong>(alg));
+ }
+
+ /// @return the subject
+ inline const std::vector<byte>& subject() const
+ {
+ return m_subject;
+ }
+
+ /// @return the BER-encoding of the certificate
+ inline const std::vector<byte>& value() const
+ {
+ return m_value;
+ }
+
+ private:
+ const std::vector<byte> m_subject;
+ const std::vector<byte> m_value;
+ };
+
+/// Represents a PKCS#11 X509 certificate
+class BOTAN_DLL PKCS11_X509_Certificate final : public Object, public X509_Certificate
+ {
+ public:
+ static const ObjectClass Class = ObjectClass::Certificate;
+
+ /**
+ * Create a PKCS11_X509_Certificate object from an existing PKCS#11 X509 cert
+ * @param session the session to use
+ * @param handle the handle of the X.509 certificate
+ */
+ PKCS11_X509_Certificate(Session& session, ObjectHandle handle);
+
+ /**
+ * Imports a X.509 certificate
+ * @param session the session to use
+ * @param props the attributes of the X.509 certificate
+ */
+ PKCS11_X509_Certificate(Session& session, const X509_CertificateProperties& props);
+ };
+
+}
+}
+
+#endif
+
+#endif
diff --git a/src/lib/prov/pkcs11/pkcs11.h b/src/lib/prov/pkcs11/pkcs11.h
new file mode 100644
index 000000000..c66b0bca9
--- /dev/null
+++ b/src/lib/prov/pkcs11/pkcs11.h
@@ -0,0 +1,264 @@
+/*
+ * PKCS #11 Cryptographic Token Interface Base Specification Version 2.40 Errata 01
+ * Committee Specification Draft 01 / Public Review Draft 01
+ * 09 December 2015
+ * Copyright (c) OASIS Open 2015. All Rights Reserved.
+ * Source: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/csprd01/include/pkcs11-v2.40/
+ * Latest version of the specification: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
+ * https://www.oasis-open.org/policies-guidelines/ipr
+ */
+
+#ifndef _PKCS11_H_
+#define _PKCS11_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Before including this file (pkcs11.h) (or pkcs11t.h by
+ * itself), 5 platform-specific macros must be defined. These
+ * macros are described below, and typical definitions for them
+ * are also given. Be advised that these definitions can depend
+ * on both the platform and the compiler used (and possibly also
+ * on whether a Cryptoki library is linked statically or
+ * dynamically).
+ *
+ * In addition to defining these 5 macros, the packing convention
+ * for Cryptoki structures should be set. The Cryptoki
+ * convention on packing is that structures should be 1-byte
+ * aligned.
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, this might be done by using the following
+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(push, cryptoki, 1)
+ *
+ * and using the following preprocessor directive after including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(pop, cryptoki)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, this might be done by using
+ * the following preprocessor directive before including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(1)
+ *
+ * In a UNIX environment, you're on your own for this. You might
+ * not need to do (or be able to do!) anything.
+ *
+ *
+ * Now for the macros:
+ *
+ *
+ * 1. CK_PTR: The indirection string for making a pointer to an
+ * object. It can be used like this:
+ *
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, it might be defined by:
+ *
+ * #define CK_PTR far *
+ *
+ * In a typical UNIX environment, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ *
+ * 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
+ * an importable Cryptoki library function declaration out of a
+ * return type and a function name. It should be used in the
+ * following fashion:
+ *
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
+ * CK_VOID_PTR pReserved
+ * );
+ *
+ * If you're using Microsoft Developer Studio 5.0 to declare a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __declspec(dllimport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to declare a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType name
+ *
+ *
+ * 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
+ * which makes a Cryptoki API function pointer declaration or
+ * function pointer type declaration out of a return type and a
+ * function name. It should be used in the following fashion:
+ *
+ * // Define funcPtr to be a pointer to a Cryptoki API function
+ * // taking arguments args and returning CK_RV.
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
+ *
+ * or
+ *
+ * // Define funcPtrType to be the type of a pointer to a
+ * // Cryptoki API function taking arguments args and returning
+ * // CK_RV, and then define funcPtr to be a variable of type
+ * // funcPtrType.
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
+ * funcPtrType funcPtr;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to access
+ * functions in a Win32 Cryptoki .dll, in might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __declspec(dllimport) (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to access functions in a Win16 Cryptoki .dll, it might
+ * be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __export _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
+ * a function pointer type for an application callback out of
+ * a return type for the callback and a name for the callback.
+ * It should be used in the following fashion:
+ *
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
+ *
+ * to declare a function pointer, myCallback, to a callback
+ * which takes arguments args and returns a CK_RV. It can also
+ * be used like this:
+ *
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
+ * myCallbackType myCallback;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to do Win32
+ * Cryptoki development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to do Win16 development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 5. NULL_PTR: This macro is the value of a NULL pointer.
+ *
+ * In any ANSI/ISO C environment (and in many others as well),
+ * this should best be defined by
+ *
+ * #ifndef NULL_PTR
+ * #define NULL_PTR 0
+ * #endif
+ */
+
+
+/* All the various Cryptoki types and #define'd values are in the
+ * file pkcs11t.h.
+ */
+#include "pkcs11t.h"
+
+#define __PASTE(x,y) x##y
+
+
+/* ==============================================================
+ * Define the "extern" form of all the entry points.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ extern CK_DECLARE_FUNCTION(CK_RV, name)
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes.
+ */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define the typedef form of all the entry points. That is, for
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
+ * a pointer to that kind of function.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes.
+ */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define structed vector of entry points. A CK_FUNCTION_LIST
+ * contains a CK_VERSION indicating a library's Cryptoki version
+ * and then a whole slew of function pointers to the routines in
+ * the library. This type was declared, but not defined, in
+ * pkcs11t.h.
+ * ==============================================================
+ */
+
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ __PASTE(CK_,name) name;
+
+struct CK_FUNCTION_LIST {
+
+ CK_VERSION version; /* Cryptoki version */
+
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes.
+ */
+#include "pkcs11f.h"
+
+};
+
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+#undef __PASTE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PKCS11_H_ */
+
diff --git a/src/lib/prov/pkcs11/pkcs11f.h b/src/lib/prov/pkcs11/pkcs11f.h
new file mode 100644
index 000000000..48ba5726f
--- /dev/null
+++ b/src/lib/prov/pkcs11/pkcs11f.h
@@ -0,0 +1,938 @@
+/*
+ * PKCS #11 Cryptographic Token Interface Base Specification Version 2.40 Errata 01
+ * Committee Specification Draft 01 / Public Review Draft 01
+ * 09 December 2015
+ * Copyright (c) OASIS Open 2015. All Rights Reserved.
+ * Source: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/csprd01/include/pkcs11-v2.40/
+ * Latest version of the specification: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
+ * https://www.oasis-open.org/policies-guidelines/ipr
+ */
+
+/* This header file contains pretty much everything about all the
+ * Cryptoki function prototypes. Because this information is
+ * used for more than just declaring function prototypes, the
+ * order of the functions appearing herein is important, and
+ * should not be altered.
+ */
+
+/* General-purpose */
+
+/* C_Initialize initializes the Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Initialize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
+ * cast to CK_C_INITIALIZE_ARGS_PTR
+ * and dereferenced
+ */
+);
+#endif
+
+
+/* C_Finalize indicates that an application is done with the
+ * Cryptoki library.
+ */
+CK_PKCS11_FUNCTION_INFO(C_Finalize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_INFO_PTR pInfo /* location that receives information */
+);
+#endif
+
+
+/* C_GetFunctionList returns the function list. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
+ * function list
+ */
+);
+#endif
+
+
+
+/* Slot and token management */
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_BBOOL tokenPresent, /* only slots with tokens */
+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
+ CK_ULONG_PTR pulCount /* receives number of slots */
+);
+#endif
+
+
+/* C_GetSlotInfo obtains information about a particular slot in
+ * the system.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the ID of the slot */
+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
+);
+#endif
+
+
+/* C_GetTokenInfo obtains information about a particular token
+ * in the system.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
+);
+#endif
+
+
+/* C_GetMechanismList obtains a list of mechanism types
+ * supported by a token.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of token's slot */
+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
+ CK_ULONG_PTR pulCount /* gets # of mechs. */
+);
+#endif
+
+
+/* C_GetMechanismInfo obtains information about a particular
+ * mechanism possibly supported by a token.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_MECHANISM_TYPE type, /* type of mechanism */
+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
+);
+#endif
+
+
+/* C_InitToken initializes a token. */
+CK_PKCS11_FUNCTION_INFO(C_InitToken)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+);
+#endif
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
+ CK_ULONG ulPinLen /* length in bytes of the PIN */
+);
+#endif
+
+
+/* C_SetPIN modifies the PIN of the user who is logged in. */
+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
+ CK_ULONG ulOldLen, /* length of the old PIN */
+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
+ CK_ULONG ulNewLen /* length of the new PIN */
+);
+#endif
+
+
+
+/* Session management */
+
+/* C_OpenSession opens a session between an application and a
+ * token.
+ */
+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the slot's ID */
+ CK_FLAGS flags, /* from CK_SESSION_INFO */
+ CK_VOID_PTR pApplication, /* passed to callback */
+ CK_NOTIFY Notify, /* callback function */
+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
+);
+#endif
+
+
+/* C_CloseSession closes a session between an application and a
+ * token.
+ */
+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID /* the token's slot */
+);
+#endif
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_SESSION_INFO_PTR pInfo /* receives session info */
+);
+#endif
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* gets state */
+ CK_ULONG_PTR pulOperationStateLen /* gets state length */
+);
+#endif
+
+
+/* C_SetOperationState restores the state of the cryptographic
+ * operation in a session.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* holds state */
+ CK_ULONG ulOperationStateLen, /* holds state length */
+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
+);
+#endif
+
+
+/* C_Login logs a user into a token. */
+CK_PKCS11_FUNCTION_INFO(C_Login)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_USER_TYPE userType, /* the user type */
+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
+ CK_ULONG ulPinLen /* the length of the PIN */
+);
+#endif
+
+
+/* C_Logout logs a user out from a token. */
+CK_PKCS11_FUNCTION_INFO(C_Logout)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Object management */
+
+/* C_CreateObject creates a new object. */
+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
+);
+#endif
+
+
+/* C_CopyObject copies an object, creating a new object for the
+ * copy.
+ */
+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
+);
+#endif
+
+
+/* C_DestroyObject destroys an object. */
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject /* the object's handle */
+);
+#endif
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ULONG_PTR pulSize /* receives size of object */
+);
+#endif
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+ * attributes.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+ * attributes.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_FindObjectsInit initializes a search for token and session
+ * objects that match a template.
+ */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
+ CK_ULONG ulCount /* attrs in search template */
+);
+#endif
+
+
+/* C_FindObjects continues a search for token and session
+ * objects that match a template, obtaining additional object
+ * handles.
+ */
+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
+ CK_ULONG ulMaxObjectCount, /* max handles to get */
+ CK_ULONG_PTR pulObjectCount /* actual # returned */
+);
+#endif
+
+
+/* C_FindObjectsFinal finishes a search for token and session
+ * objects.
+ */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Encryption and decryption */
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
+);
+#endif
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pData, /* the plaintext data */
+ CK_ULONG ulDataLen, /* bytes of plaintext */
+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptUpdate continues a multiple-part encryption
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext data len */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptFinal finishes a multiple-part encryption
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session handle */
+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
+);
+#endif
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of decryption key */
+);
+#endif
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedData, /* ciphertext */
+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
+ CK_BYTE_PTR pData, /* gets plaintext */
+ CK_ULONG_PTR pulDataLen /* gets p-text size */
+);
+#endif
+
+
+/* C_DecryptUpdate continues a multiple-part decryption
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* input length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* p-text size */
+);
+#endif
+
+
+/* C_DecryptFinal finishes a multiple-part decryption
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pLastPart, /* gets plaintext */
+ CK_ULONG_PTR pulLastPartLen /* p-text size */
+);
+#endif
+
+
+
+/* Message digesting */
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
+);
+#endif
+
+
+/* C_Digest digests data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Digest)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* data to be digested */
+ CK_ULONG ulDataLen, /* bytes of data to digest */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets digest length */
+);
+#endif
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* data to be digested */
+ CK_ULONG ulPartLen /* bytes of data to be digested */
+);
+#endif
+
+
+/* C_DigestKey continues a multi-part message-digesting
+ * operation, by digesting the value of a secret key as part of
+ * the data already digested.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hKey /* secret key to digest */
+);
+#endif
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
+);
+#endif
+
+
+
+/* Signing and MACing */
+
+/* C_SignInit initializes a signature (private key encryption)
+ * operation, where the signature is (will be) an appendix to
+ * the data, and plaintext cannot be recovered from the
+ * signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of signature key */
+);
+#endif
+
+
+/* C_Sign signs (encrypts with private key) data in a single
+ * part, where the signature is (will be) an appendix to the
+ * data, and plaintext cannot be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_Sign)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the data to sign */
+ CK_ULONG ulPartLen /* count of bytes to sign */
+);
+#endif
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * returning the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignRecoverInit initializes a signature operation, where
+ * the data can be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
+);
+#endif
+
+
+/* C_SignRecover signs data in a single operation, where the
+ * data can be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+
+/* Verifying signatures and MACs */
+
+/* C_VerifyInit initializes a verification operation, where the
+ * signature is an appendix to the data, and plaintext cannot
+ * cannot be recovered from the signature (e.g. DSA).
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data, and plaintext
+ * cannot be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_Verify)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* signed data */
+ CK_ULONG ulDataLen, /* length of signed data */
+ CK_BYTE_PTR pSignature, /* signature */
+ CK_ULONG ulSignatureLen /* signature length*/
+);
+#endif
+
+
+/* C_VerifyUpdate continues a multiple-part verification
+ * operation, where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* signed data */
+ CK_ULONG ulPartLen /* length of signed data */
+);
+#endif
+
+
+/* C_VerifyFinal finishes a multiple-part verification
+ * operation, checking the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen /* signature length */
+);
+#endif
+
+
+/* C_VerifyRecoverInit initializes a signature verification
+ * operation, where the data is recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_VerifyRecover verifies a signature in a single-part
+ * operation, where the data is recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen, /* signature length */
+ CK_BYTE_PTR pData, /* gets signed data */
+ CK_ULONG_PTR pulDataLen /* gets signed data len */
+);
+#endif
+
+
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting
+ * and encryption operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets plaintext len */
+);
+#endif
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets p-text length */
+);
+#endif
+
+
+
+/* Key management */
+
+/* C_GenerateKey generates a secret key, creating a new key
+ * object.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
+ CK_ULONG ulCount, /* # of attrs in template */
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
+);
+#endif
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session handle */
+ CK_MECHANISM_PTR pMechanism, /* key-gen mech. */
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */
+ CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */
+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */
+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */
+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */
+);
+#endif
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
+);
+#endif
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+ * key object.
+ */
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key
+ * object.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
+ CK_OBJECT_HANDLE hBaseKey, /* base key */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+
+/* Random number generation */
+
+/* C_SeedRandom mixes additional seed material into the token's
+ * random number generator.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSeed, /* the seed material */
+ CK_ULONG ulSeedLen /* length of seed material */
+);
+#endif
+
+
+/* C_GenerateRandom generates random data. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR RandomData, /* receives the random data */
+ CK_ULONG ulRandomLen /* # of bytes to generate */
+);
+#endif
+
+
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus is a legacy function; it obtains an
+ * updated status of a function running in parallel with an
+ * application.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CancelFunction is a legacy function; it cancels a function
+ * running in parallel.
+ */
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur.
+ */
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FLAGS flags, /* blocking/nonblocking flag */
+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
diff --git a/src/lib/prov/pkcs11/pkcs11t.h b/src/lib/prov/pkcs11/pkcs11t.h
new file mode 100644
index 000000000..c183ea974
--- /dev/null
+++ b/src/lib/prov/pkcs11/pkcs11t.h
@@ -0,0 +1,2002 @@
+/*
+ * PKCS #11 Cryptographic Token Interface Base Specification Version 2.40 Errata 01
+ * Committee Specification Draft 01 / Public Review Draft 01
+ * 09 December 2015
+ * Copyright (c) OASIS Open 2015. All Rights Reserved.
+ * Source: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/csprd01/include/pkcs11-v2.40/
+ * Latest version of the specification: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
+ * https://www.oasis-open.org/policies-guidelines/ipr
+ */
+
+/* See top of pkcs11.h for information about the macros that
+ * must be defined and the structure-packing conventions that
+ * must be set before including this file.
+ */
+
+#ifndef _PKCS11T_H_
+#define _PKCS11T_H_ 1
+
+#define CRYPTOKI_VERSION_MAJOR 2
+#define CRYPTOKI_VERSION_MINOR 40
+#define CRYPTOKI_VERSION_AMENDMENT 0
+
+#define CK_TRUE 1
+#define CK_FALSE 0
+
+#ifndef CK_DISABLE_TRUE_FALSE
+#ifndef FALSE
+#define FALSE CK_FALSE
+#endif
+#ifndef TRUE
+#define TRUE CK_TRUE
+#endif
+#endif
+
+/* an unsigned 8-bit value */
+typedef unsigned char CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_CHAR;
+
+/* an 8-bit UTF-8 character */
+typedef CK_BYTE CK_UTF8CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+typedef long int CK_LONG;
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef CK_ULONG CK_FLAGS;
+
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE 0UL
+
+
+typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+typedef CK_CHAR CK_PTR CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
+typedef CK_ULONG CK_PTR CK_ULONG_PTR;
+typedef void CK_PTR CK_VOID_PTR;
+
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
+
+
+/* The following value is always invalid if used as a session
+ * handle or object handle
+ */
+#define CK_INVALID_HANDLE 0UL
+
+
+typedef struct CK_VERSION {
+ CK_BYTE major; /* integer portion of version number */
+ CK_BYTE minor; /* 1/100ths portion of version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
+
+
+typedef struct CK_INFO {
+ 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;
+
+typedef CK_INFO CK_PTR CK_INFO_PTR;
+
+
+/* CK_NOTIFICATION enumerates the types of notifications that
+ * Cryptoki provides to an application
+ */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER 0UL
+#define CKN_OTP_CHANGED 1UL
+
+typedef CK_ULONG CK_SLOT_ID;
+
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot */
+typedef struct CK_SLOT_INFO {
+ 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;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_TOKEN_PRESENT 0x00000001UL /* a token is there */
+#define CKF_REMOVABLE_DEVICE 0x00000002UL /* removable devices*/
+#define CKF_HW_SLOT 0x00000004UL /* hardware slot */
+
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token */
+typedef struct CK_TOKEN_INFO {
+ 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;
+
+/* The flags parameter is defined as follows:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RNG 0x00000001UL /* has random # generator */
+#define CKF_WRITE_PROTECTED 0x00000002UL /* token is write-protected */
+#define CKF_LOGIN_REQUIRED 0x00000004UL /* user must login */
+#define CKF_USER_PIN_INITIALIZED 0x00000008UL /* normal user's PIN is set */
+
+/* CKF_RESTORE_KEY_NOT_NEEDED. If it is set,
+ * that means that *every* time the state of cryptographic
+ * operations of a session is successfully saved, all keys
+ * needed to continue those operations are stored in the state
+ */
+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL
+
+/* CKF_CLOCK_ON_TOKEN. If it is set, that means
+ * that the token has some sort of clock. The time on that
+ * clock is returned in the token info structure
+ */
+#define CKF_CLOCK_ON_TOKEN 0x00000040UL
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH. If it is
+ * set, that means that there is some way for the user to login
+ * without sending a PIN through the Cryptoki library itself
+ */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL
+
+/* CKF_DUAL_CRYPTO_OPERATIONS. If it is true,
+ * that means that a single session with the token can perform
+ * dual simultaneous cryptographic operations (digest and
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
+ * and sign)
+ */
+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL
+
+/* CKF_TOKEN_INITIALIZED. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized.
+ */
+#define CKF_TOKEN_INITIALIZED 0x00000400UL
+
+/* CKF_SECONDARY_AUTHENTICATION. If it is
+ * true, the token supports secondary authentication for
+ * private key objects.
+ */
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL
+
+/* CKF_USER_PIN_COUNT_LOW. If it is true, an
+ * incorrect user login PIN has been entered at least once
+ * since the last successful authentication.
+ */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000UL
+
+/* CKF_USER_PIN_FINAL_TRY. If it is true,
+ * supplying an incorrect user PIN will it to become locked.
+ */
+#define CKF_USER_PIN_FINAL_TRY 0x00020000UL
+
+/* CKF_USER_PIN_LOCKED. If it is true, the
+ * user PIN has been locked. User login to the token is not
+ * possible.
+ */
+#define CKF_USER_PIN_LOCKED 0x00040000UL
+
+/* CKF_USER_PIN_TO_BE_CHANGED. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card.
+ */
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL
+
+/* CKF_SO_PIN_COUNT_LOW. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
+ * the last successful authentication.
+ */
+#define CKF_SO_PIN_COUNT_LOW 0x00100000UL
+
+/* CKF_SO_PIN_FINAL_TRY. If it is true,
+ * supplying an incorrect SO PIN will it to become locked.
+ */
+#define CKF_SO_PIN_FINAL_TRY 0x00200000UL
+
+/* CKF_SO_PIN_LOCKED. If it is true, the SO
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED 0x00400000UL
+
+/* CKF_SO_PIN_TO_BE_CHANGED. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card.
+ */
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL
+
+#define CKF_ERROR_STATE 0x01000000UL
+
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
+ * identifies a session
+ */
+typedef CK_ULONG CK_SESSION_HANDLE;
+
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+
+
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
+typedef CK_ULONG CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO 0UL
+/* Normal user */
+#define CKU_USER 1UL
+/* Context specific */
+#define CKU_CONTEXT_SPECIFIC 2UL
+
+/* CK_STATE enumerates the session states */
+typedef CK_ULONG CK_STATE;
+#define CKS_RO_PUBLIC_SESSION 0UL
+#define CKS_RO_USER_FUNCTIONS 1UL
+#define CKS_RW_PUBLIC_SESSION 2UL
+#define CKS_RW_USER_FUNCTIONS 3UL
+#define CKS_RW_SO_FUNCTIONS 4UL
+
+/* CK_SESSION_INFO provides information about a session */
+typedef struct CK_SESSION_INFO {
+ CK_SLOT_ID slotID;
+ CK_STATE state;
+ CK_FLAGS flags; /* see below */
+ CK_ULONG ulDeviceError; /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RW_SESSION 0x00000002UL /* session is r/w */
+#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */
+
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
+ * object
+ */
+typedef CK_ULONG CK_OBJECT_HANDLE;
+
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
+ * types) of objects that Cryptoki recognizes. It is defined
+ * as follows:
+ */
+typedef CK_ULONG CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+#define CKO_DATA 0x00000000UL
+#define CKO_CERTIFICATE 0x00000001UL
+#define CKO_PUBLIC_KEY 0x00000002UL
+#define CKO_PRIVATE_KEY 0x00000003UL
+#define CKO_SECRET_KEY 0x00000004UL
+#define CKO_HW_FEATURE 0x00000005UL
+#define CKO_DOMAIN_PARAMETERS 0x00000006UL
+#define CKO_MECHANISM 0x00000007UL
+#define CKO_OTP_KEY 0x00000008UL
+
+#define CKO_VENDOR_DEFINED 0x80000000UL
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+/* CK_HW_FEATURE_TYPE is a value that identifies the hardware feature type
+ * of an object with CK_OBJECT_CLASS equal to CKO_HW_FEATURE.
+ */
+typedef CK_ULONG CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined */
+#define CKH_MONOTONIC_COUNTER 0x00000001UL
+#define CKH_CLOCK 0x00000002UL
+#define CKH_USER_INTERFACE 0x00000003UL
+#define CKH_VENDOR_DEFINED 0x80000000UL
+
+/* CK_KEY_TYPE is a value that identifies a key type */
+typedef CK_ULONG CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA 0x00000000UL
+#define CKK_DSA 0x00000001UL
+#define CKK_DH 0x00000002UL
+#define CKK_ECDSA 0x00000003UL /* Deprecated */
+#define CKK_EC 0x00000003UL
+#define CKK_X9_42_DH 0x00000004UL
+#define CKK_KEA 0x00000005UL
+#define CKK_GENERIC_SECRET 0x00000010UL
+#define CKK_RC2 0x00000011UL
+#define CKK_RC4 0x00000012UL
+#define CKK_DES 0x00000013UL
+#define CKK_DES2 0x00000014UL
+#define CKK_DES3 0x00000015UL
+#define CKK_CAST 0x00000016UL
+#define CKK_CAST3 0x00000017UL
+#define CKK_CAST5 0x00000018UL /* Deprecated */
+#define CKK_CAST128 0x00000018UL
+#define CKK_RC5 0x00000019UL
+#define CKK_IDEA 0x0000001AUL
+#define CKK_SKIPJACK 0x0000001BUL
+#define CKK_BATON 0x0000001CUL
+#define CKK_JUNIPER 0x0000001DUL
+#define CKK_CDMF 0x0000001EUL
+#define CKK_AES 0x0000001FUL
+#define CKK_BLOWFISH 0x00000020UL
+#define CKK_TWOFISH 0x00000021UL
+#define CKK_SECURID 0x00000022UL
+#define CKK_HOTP 0x00000023UL
+#define CKK_ACTI 0x00000024UL
+#define CKK_CAMELLIA 0x00000025UL
+#define CKK_ARIA 0x00000026UL
+
+#define CKK_MD5_HMAC 0x00000027UL
+#define CKK_SHA_1_HMAC 0x00000028UL
+#define CKK_RIPEMD128_HMAC 0x00000029UL
+#define CKK_RIPEMD160_HMAC 0x0000002AUL
+#define CKK_SHA256_HMAC 0x0000002BUL
+#define CKK_SHA384_HMAC 0x0000002CUL
+#define CKK_SHA512_HMAC 0x0000002DUL
+#define CKK_SHA224_HMAC 0x0000002EUL
+
+#define CKK_SEED 0x0000002FUL
+#define CKK_GOSTR3410 0x00000030UL
+#define CKK_GOSTR3411 0x00000031UL
+#define CKK_GOST28147 0x00000032UL
+
+
+
+#define CKK_VENDOR_DEFINED 0x80000000UL
+
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
+ * type
+ */
+typedef CK_ULONG CK_CERTIFICATE_TYPE;
+
+#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL
+#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL
+#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL
+#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL
+
+#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL
+#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL
+#define CK_SECURITY_DOMAIN_OPERATOR 2UL
+#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL
+
+
+/* The following certificate types are defined: */
+#define CKC_X_509 0x00000000UL
+#define CKC_X_509_ATTR_CERT 0x00000001UL
+#define CKC_WTLS 0x00000002UL
+#define CKC_VENDOR_DEFINED 0x80000000UL
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+ * type
+ */
+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+
+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
+ * consists of an array of values.
+ */
+#define CKF_ARRAY_ATTRIBUTE 0x40000000UL
+
+/* The following OTP-related defines relate to the CKA_OTP_FORMAT attribute */
+#define CK_OTP_FORMAT_DECIMAL 0UL
+#define CK_OTP_FORMAT_HEXADECIMAL 1UL
+#define CK_OTP_FORMAT_ALPHANUMERIC 2UL
+#define CK_OTP_FORMAT_BINARY 3UL
+
+/* The following OTP-related defines relate to the CKA_OTP_..._REQUIREMENT
+ * attributes
+ */
+#define CK_OTP_PARAM_IGNORED 0UL
+#define CK_OTP_PARAM_OPTIONAL 1UL
+#define CK_OTP_PARAM_MANDATORY 2UL
+
+/* The following attribute types are defined: */
+#define CKA_CLASS 0x00000000UL
+#define CKA_TOKEN 0x00000001UL
+#define CKA_PRIVATE 0x00000002UL
+#define CKA_LABEL 0x00000003UL
+#define CKA_APPLICATION 0x00000010UL
+#define CKA_VALUE 0x00000011UL
+#define CKA_OBJECT_ID 0x00000012UL
+#define CKA_CERTIFICATE_TYPE 0x00000080UL
+#define CKA_ISSUER 0x00000081UL
+#define CKA_SERIAL_NUMBER 0x00000082UL
+#define CKA_AC_ISSUER 0x00000083UL
+#define CKA_OWNER 0x00000084UL
+#define CKA_ATTR_TYPES 0x00000085UL
+#define CKA_TRUSTED 0x00000086UL
+#define CKA_CERTIFICATE_CATEGORY 0x00000087UL
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL
+#define CKA_URL 0x00000089UL
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL
+#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL
+#define CKA_CHECK_VALUE 0x00000090UL
+
+#define CKA_KEY_TYPE 0x00000100UL
+#define CKA_SUBJECT 0x00000101UL
+#define CKA_ID 0x00000102UL
+#define CKA_SENSITIVE 0x00000103UL
+#define CKA_ENCRYPT 0x00000104UL
+#define CKA_DECRYPT 0x00000105UL
+#define CKA_WRAP 0x00000106UL
+#define CKA_UNWRAP 0x00000107UL
+#define CKA_SIGN 0x00000108UL
+#define CKA_SIGN_RECOVER 0x00000109UL
+#define CKA_VERIFY 0x0000010AUL
+#define CKA_VERIFY_RECOVER 0x0000010BUL
+#define CKA_DERIVE 0x0000010CUL
+#define CKA_START_DATE 0x00000110UL
+#define CKA_END_DATE 0x00000111UL
+#define CKA_MODULUS 0x00000120UL
+#define CKA_MODULUS_BITS 0x00000121UL
+#define CKA_PUBLIC_EXPONENT 0x00000122UL
+#define CKA_PRIVATE_EXPONENT 0x00000123UL
+#define CKA_PRIME_1 0x00000124UL
+#define CKA_PRIME_2 0x00000125UL
+#define CKA_EXPONENT_1 0x00000126UL
+#define CKA_EXPONENT_2 0x00000127UL
+#define CKA_COEFFICIENT 0x00000128UL
+#define CKA_PUBLIC_KEY_INFO 0x00000129UL
+#define CKA_PRIME 0x00000130UL
+#define CKA_SUBPRIME 0x00000131UL
+#define CKA_BASE 0x00000132UL
+
+#define CKA_PRIME_BITS 0x00000133UL
+#define CKA_SUBPRIME_BITS 0x00000134UL
+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
+
+#define CKA_VALUE_BITS 0x00000160UL
+#define CKA_VALUE_LEN 0x00000161UL
+#define CKA_EXTRACTABLE 0x00000162UL
+#define CKA_LOCAL 0x00000163UL
+#define CKA_NEVER_EXTRACTABLE 0x00000164UL
+#define CKA_ALWAYS_SENSITIVE 0x00000165UL
+#define CKA_KEY_GEN_MECHANISM 0x00000166UL
+
+#define CKA_MODIFIABLE 0x00000170UL
+#define CKA_COPYABLE 0x00000171UL
+
+#define CKA_DESTROYABLE 0x00000172UL
+
+#define CKA_ECDSA_PARAMS 0x00000180UL /* Deprecated */
+#define CKA_EC_PARAMS 0x00000180UL
+
+#define CKA_EC_POINT 0x00000181UL
+
+#define CKA_SECONDARY_AUTH 0x00000200UL /* Deprecated */
+#define CKA_AUTH_PIN_FLAGS 0x00000201UL /* Deprecated */
+
+#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL
+
+#define CKA_WRAP_WITH_TRUSTED 0x00000210UL
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211UL)
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212UL)
+#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000213UL)
+
+#define CKA_OTP_FORMAT 0x00000220UL
+#define CKA_OTP_LENGTH 0x00000221UL
+#define CKA_OTP_TIME_INTERVAL 0x00000222UL
+#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL
+#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL
+#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL
+#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL
+#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL
+#define CKA_OTP_COUNTER 0x0000022EUL
+#define CKA_OTP_TIME 0x0000022FUL
+#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL
+#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL
+#define CKA_OTP_SERVICE_LOGO 0x0000022CUL
+#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL
+
+#define CKA_GOSTR3410_PARAMS 0x00000250UL
+#define CKA_GOSTR3411_PARAMS 0x00000251UL
+#define CKA_GOST28147_PARAMS 0x00000252UL
+
+#define CKA_HW_FEATURE_TYPE 0x00000300UL
+#define CKA_RESET_ON_INIT 0x00000301UL
+#define CKA_HAS_RESET 0x00000302UL
+
+#define CKA_PIXEL_X 0x00000400UL
+#define CKA_PIXEL_Y 0x00000401UL
+#define CKA_RESOLUTION 0x00000402UL
+#define CKA_CHAR_ROWS 0x00000403UL
+#define CKA_CHAR_COLUMNS 0x00000404UL
+#define CKA_COLOR 0x00000405UL
+#define CKA_BITS_PER_PIXEL 0x00000406UL
+#define CKA_CHAR_SETS 0x00000480UL
+#define CKA_ENCODING_METHODS 0x00000481UL
+#define CKA_MIME_TYPES 0x00000482UL
+#define CKA_MECHANISM_TYPE 0x00000500UL
+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL
+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL
+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL
+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600UL)
+
+#define CKA_VENDOR_DEFINED 0x80000000UL
+
+/* CK_ATTRIBUTE is a structure that includes the type, length
+ * and value of an attribute
+ */
+typedef struct CK_ATTRIBUTE {
+ CK_ATTRIBUTE_TYPE type;
+ CK_VOID_PTR pValue;
+ CK_ULONG ulValueLen; /* in bytes */
+} CK_ATTRIBUTE;
+
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+/* CK_DATE is a structure that defines a date */
+typedef struct CK_DATE{
+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
+ CK_CHAR month[2]; /* the month ("01" - "12") */
+ CK_CHAR day[2]; /* the day ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
+ * type
+ */
+typedef CK_ULONG CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL
+#define CKM_RSA_PKCS 0x00000001UL
+#define CKM_RSA_9796 0x00000002UL
+#define CKM_RSA_X_509 0x00000003UL
+
+#define CKM_MD2_RSA_PKCS 0x00000004UL
+#define CKM_MD5_RSA_PKCS 0x00000005UL
+#define CKM_SHA1_RSA_PKCS 0x00000006UL
+
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL
+#define CKM_RSA_PKCS_OAEP 0x00000009UL
+
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL
+#define CKM_RSA_X9_31 0x0000000BUL
+#define CKM_SHA1_RSA_X9_31 0x0000000CUL
+#define CKM_RSA_PKCS_PSS 0x0000000DUL
+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL
+
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL
+#define CKM_DSA 0x00000011UL
+#define CKM_DSA_SHA1 0x00000012UL
+#define CKM_DSA_SHA224 0x00000013UL
+#define CKM_DSA_SHA256 0x00000014UL
+#define CKM_DSA_SHA384 0x00000015UL
+#define CKM_DSA_SHA512 0x00000016UL
+
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL
+#define CKM_DH_PKCS_DERIVE 0x00000021UL
+
+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL
+#define CKM_X9_42_DH_DERIVE 0x00000031UL
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL
+#define CKM_X9_42_MQV_DERIVE 0x00000033UL
+
+#define CKM_SHA256_RSA_PKCS 0x00000040UL
+#define CKM_SHA384_RSA_PKCS 0x00000041UL
+#define CKM_SHA512_RSA_PKCS 0x00000042UL
+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL
+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL
+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL
+
+#define CKM_SHA224_RSA_PKCS 0x00000046UL
+#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL
+
+#define CKM_SHA512_224 0x00000048UL
+#define CKM_SHA512_224_HMAC 0x00000049UL
+#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL
+#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL
+#define CKM_SHA512_256 0x0000004CUL
+#define CKM_SHA512_256_HMAC 0x0000004DUL
+#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL
+#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL
+
+#define CKM_SHA512_T 0x00000050UL
+#define CKM_SHA512_T_HMAC 0x00000051UL
+#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL
+#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL
+
+#define CKM_RC2_KEY_GEN 0x00000100UL
+#define CKM_RC2_ECB 0x00000101UL
+#define CKM_RC2_CBC 0x00000102UL
+#define CKM_RC2_MAC 0x00000103UL
+
+#define CKM_RC2_MAC_GENERAL 0x00000104UL
+#define CKM_RC2_CBC_PAD 0x00000105UL
+
+#define CKM_RC4_KEY_GEN 0x00000110UL
+#define CKM_RC4 0x00000111UL
+#define CKM_DES_KEY_GEN 0x00000120UL
+#define CKM_DES_ECB 0x00000121UL
+#define CKM_DES_CBC 0x00000122UL
+#define CKM_DES_MAC 0x00000123UL
+
+#define CKM_DES_MAC_GENERAL 0x00000124UL
+#define CKM_DES_CBC_PAD 0x00000125UL
+
+#define CKM_DES2_KEY_GEN 0x00000130UL
+#define CKM_DES3_KEY_GEN 0x00000131UL
+#define CKM_DES3_ECB 0x00000132UL
+#define CKM_DES3_CBC 0x00000133UL
+#define CKM_DES3_MAC 0x00000134UL
+
+#define CKM_DES3_MAC_GENERAL 0x00000135UL
+#define CKM_DES3_CBC_PAD 0x00000136UL
+#define CKM_DES3_CMAC_GENERAL 0x00000137UL
+#define CKM_DES3_CMAC 0x00000138UL
+#define CKM_CDMF_KEY_GEN 0x00000140UL
+#define CKM_CDMF_ECB 0x00000141UL
+#define CKM_CDMF_CBC 0x00000142UL
+#define CKM_CDMF_MAC 0x00000143UL
+#define CKM_CDMF_MAC_GENERAL 0x00000144UL
+#define CKM_CDMF_CBC_PAD 0x00000145UL
+
+#define CKM_DES_OFB64 0x00000150UL
+#define CKM_DES_OFB8 0x00000151UL
+#define CKM_DES_CFB64 0x00000152UL
+#define CKM_DES_CFB8 0x00000153UL
+
+#define CKM_MD2 0x00000200UL
+
+#define CKM_MD2_HMAC 0x00000201UL
+#define CKM_MD2_HMAC_GENERAL 0x00000202UL
+
+#define CKM_MD5 0x00000210UL
+
+#define CKM_MD5_HMAC 0x00000211UL
+#define CKM_MD5_HMAC_GENERAL 0x00000212UL
+
+#define CKM_SHA_1 0x00000220UL
+
+#define CKM_SHA_1_HMAC 0x00000221UL
+#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL
+
+#define CKM_RIPEMD128 0x00000230UL
+#define CKM_RIPEMD128_HMAC 0x00000231UL
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL
+#define CKM_RIPEMD160 0x00000240UL
+#define CKM_RIPEMD160_HMAC 0x00000241UL
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL
+
+#define CKM_SHA256 0x00000250UL
+#define CKM_SHA256_HMAC 0x00000251UL
+#define CKM_SHA256_HMAC_GENERAL 0x00000252UL
+#define CKM_SHA224 0x00000255UL
+#define CKM_SHA224_HMAC 0x00000256UL
+#define CKM_SHA224_HMAC_GENERAL 0x00000257UL
+#define CKM_SHA384 0x00000260UL
+#define CKM_SHA384_HMAC 0x00000261UL
+#define CKM_SHA384_HMAC_GENERAL 0x00000262UL
+#define CKM_SHA512 0x00000270UL
+#define CKM_SHA512_HMAC 0x00000271UL
+#define CKM_SHA512_HMAC_GENERAL 0x00000272UL
+#define CKM_SECURID_KEY_GEN 0x00000280UL
+#define CKM_SECURID 0x00000282UL
+#define CKM_HOTP_KEY_GEN 0x00000290UL
+#define CKM_HOTP 0x00000291UL
+#define CKM_ACTI 0x000002A0UL
+#define CKM_ACTI_KEY_GEN 0x000002A1UL
+
+#define CKM_CAST_KEY_GEN 0x00000300UL
+#define CKM_CAST_ECB 0x00000301UL
+#define CKM_CAST_CBC 0x00000302UL
+#define CKM_CAST_MAC 0x00000303UL
+#define CKM_CAST_MAC_GENERAL 0x00000304UL
+#define CKM_CAST_CBC_PAD 0x00000305UL
+#define CKM_CAST3_KEY_GEN 0x00000310UL
+#define CKM_CAST3_ECB 0x00000311UL
+#define CKM_CAST3_CBC 0x00000312UL
+#define CKM_CAST3_MAC 0x00000313UL
+#define CKM_CAST3_MAC_GENERAL 0x00000314UL
+#define CKM_CAST3_CBC_PAD 0x00000315UL
+/* Note that CAST128 and CAST5 are the same algorithm */
+#define CKM_CAST5_KEY_GEN 0x00000320UL
+#define CKM_CAST128_KEY_GEN 0x00000320UL
+#define CKM_CAST5_ECB 0x00000321UL
+#define CKM_CAST128_ECB 0x00000321UL
+#define CKM_CAST5_CBC 0x00000322UL /* Deprecated */
+#define CKM_CAST128_CBC 0x00000322UL
+#define CKM_CAST5_MAC 0x00000323UL /* Deprecated */
+#define CKM_CAST128_MAC 0x00000323UL
+#define CKM_CAST5_MAC_GENERAL 0x00000324UL /* Deprecated */
+#define CKM_CAST128_MAC_GENERAL 0x00000324UL
+#define CKM_CAST5_CBC_PAD 0x00000325UL /* Deprecated */
+#define CKM_CAST128_CBC_PAD 0x00000325UL
+#define CKM_RC5_KEY_GEN 0x00000330UL
+#define CKM_RC5_ECB 0x00000331UL
+#define CKM_RC5_CBC 0x00000332UL
+#define CKM_RC5_MAC 0x00000333UL
+#define CKM_RC5_MAC_GENERAL 0x00000334UL
+#define CKM_RC5_CBC_PAD 0x00000335UL
+#define CKM_IDEA_KEY_GEN 0x00000340UL
+#define CKM_IDEA_ECB 0x00000341UL
+#define CKM_IDEA_CBC 0x00000342UL
+#define CKM_IDEA_MAC 0x00000343UL
+#define CKM_IDEA_MAC_GENERAL 0x00000344UL
+#define CKM_IDEA_CBC_PAD 0x00000345UL
+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL
+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL
+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL
+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL
+#define CKM_XOR_BASE_AND_DATA 0x00000364UL
+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL
+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL
+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL
+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL
+
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL
+
+#define CKM_TLS_PRF 0x00000378UL
+
+#define CKM_SSL3_MD5_MAC 0x00000380UL
+#define CKM_SSL3_SHA1_MAC 0x00000381UL
+#define CKM_MD5_KEY_DERIVATION 0x00000390UL
+#define CKM_MD2_KEY_DERIVATION 0x00000391UL
+#define CKM_SHA1_KEY_DERIVATION 0x00000392UL
+
+#define CKM_SHA256_KEY_DERIVATION 0x00000393UL
+#define CKM_SHA384_KEY_DERIVATION 0x00000394UL
+#define CKM_SHA512_KEY_DERIVATION 0x00000395UL
+#define CKM_SHA224_KEY_DERIVATION 0x00000396UL
+
+#define CKM_PBE_MD2_DES_CBC 0x000003A0UL
+#define CKM_PBE_MD5_DES_CBC 0x000003A1UL
+#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL
+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL
+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL /* Deprecated */
+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL
+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL /* Deprecated */
+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL
+#define CKM_PBE_SHA1_RC4_128 0x000003A6UL
+#define CKM_PBE_SHA1_RC4_40 0x000003A7UL
+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL
+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL
+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL
+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL
+
+#define CKM_PKCS5_PBKD2 0x000003B0UL
+
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL
+
+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL
+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL
+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL
+#define CKM_WTLS_PRF 0x000003D3UL
+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL
+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL
+
+#define CKM_TLS10_MAC_SERVER 0x000003D6UL
+#define CKM_TLS10_MAC_CLIENT 0x000003D7UL
+#define CKM_TLS12_MAC 0x000003D8UL
+#define CKM_TLS12_KDF 0x000003D9UL
+#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL
+#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL
+#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL
+#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL
+#define CKM_TLS_MAC 0x000003E4UL
+#define CKM_TLS_KDF 0x000003E5UL
+
+#define CKM_KEY_WRAP_LYNKS 0x00000400UL
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL
+
+#define CKM_CMS_SIG 0x00000500UL
+#define CKM_KIP_DERIVE 0x00000510UL
+#define CKM_KIP_WRAP 0x00000511UL
+#define CKM_KIP_MAC 0x00000512UL
+
+#define CKM_CAMELLIA_KEY_GEN 0x00000550UL
+#define CKM_CAMELLIA_ECB 0x00000551UL
+#define CKM_CAMELLIA_CBC 0x00000552UL
+#define CKM_CAMELLIA_MAC 0x00000553UL
+#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL
+#define CKM_CAMELLIA_CBC_PAD 0x00000555UL
+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL
+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL
+#define CKM_CAMELLIA_CTR 0x00000558UL
+
+#define CKM_ARIA_KEY_GEN 0x00000560UL
+#define CKM_ARIA_ECB 0x00000561UL
+#define CKM_ARIA_CBC 0x00000562UL
+#define CKM_ARIA_MAC 0x00000563UL
+#define CKM_ARIA_MAC_GENERAL 0x00000564UL
+#define CKM_ARIA_CBC_PAD 0x00000565UL
+#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL
+#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL
+
+#define CKM_SEED_KEY_GEN 0x00000650UL
+#define CKM_SEED_ECB 0x00000651UL
+#define CKM_SEED_CBC 0x00000652UL
+#define CKM_SEED_MAC 0x00000653UL
+#define CKM_SEED_MAC_GENERAL 0x00000654UL
+#define CKM_SEED_CBC_PAD 0x00000655UL
+#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL
+#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL
+
+#define CKM_SKIPJACK_KEY_GEN 0x00001000UL
+#define CKM_SKIPJACK_ECB64 0x00001001UL
+#define CKM_SKIPJACK_CBC64 0x00001002UL
+#define CKM_SKIPJACK_OFB64 0x00001003UL
+#define CKM_SKIPJACK_CFB64 0x00001004UL
+#define CKM_SKIPJACK_CFB32 0x00001005UL
+#define CKM_SKIPJACK_CFB16 0x00001006UL
+#define CKM_SKIPJACK_CFB8 0x00001007UL
+#define CKM_SKIPJACK_WRAP 0x00001008UL
+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL
+#define CKM_SKIPJACK_RELAYX 0x0000100aUL
+#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL
+#define CKM_KEA_KEY_DERIVE 0x00001011UL
+#define CKM_KEA_DERIVE 0x00001012UL
+#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL
+#define CKM_BATON_KEY_GEN 0x00001030UL
+#define CKM_BATON_ECB128 0x00001031UL
+#define CKM_BATON_ECB96 0x00001032UL
+#define CKM_BATON_CBC128 0x00001033UL
+#define CKM_BATON_COUNTER 0x00001034UL
+#define CKM_BATON_SHUFFLE 0x00001035UL
+#define CKM_BATON_WRAP 0x00001036UL
+
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL /* Deprecated */
+#define CKM_EC_KEY_PAIR_GEN 0x00001040UL
+
+#define CKM_ECDSA 0x00001041UL
+#define CKM_ECDSA_SHA1 0x00001042UL
+#define CKM_ECDSA_SHA224 0x00001043UL
+#define CKM_ECDSA_SHA256 0x00001044UL
+#define CKM_ECDSA_SHA384 0x00001045UL
+#define CKM_ECDSA_SHA512 0x00001046UL
+
+#define CKM_ECDH1_DERIVE 0x00001050UL
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL
+#define CKM_ECMQV_DERIVE 0x00001052UL
+
+#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL
+#define CKM_RSA_AES_KEY_WRAP 0x00001054UL
+
+#define CKM_JUNIPER_KEY_GEN 0x00001060UL
+#define CKM_JUNIPER_ECB128 0x00001061UL
+#define CKM_JUNIPER_CBC128 0x00001062UL
+#define CKM_JUNIPER_COUNTER 0x00001063UL
+#define CKM_JUNIPER_SHUFFLE 0x00001064UL
+#define CKM_JUNIPER_WRAP 0x00001065UL
+#define CKM_FASTHASH 0x00001070UL
+
+#define CKM_AES_KEY_GEN 0x00001080UL
+#define CKM_AES_ECB 0x00001081UL
+#define CKM_AES_CBC 0x00001082UL
+#define CKM_AES_MAC 0x00001083UL
+#define CKM_AES_MAC_GENERAL 0x00001084UL
+#define CKM_AES_CBC_PAD 0x00001085UL
+#define CKM_AES_CTR 0x00001086UL
+#define CKM_AES_GCM 0x00001087UL
+#define CKM_AES_CCM 0x00001088UL
+#define CKM_AES_CTS 0x00001089UL
+#define CKM_AES_CMAC 0x0000108AUL
+#define CKM_AES_CMAC_GENERAL 0x0000108BUL
+
+#define CKM_AES_XCBC_MAC 0x0000108CUL
+#define CKM_AES_XCBC_MAC_96 0x0000108DUL
+#define CKM_AES_GMAC 0x0000108EUL
+
+#define CKM_BLOWFISH_KEY_GEN 0x00001090UL
+#define CKM_BLOWFISH_CBC 0x00001091UL
+#define CKM_TWOFISH_KEY_GEN 0x00001092UL
+#define CKM_TWOFISH_CBC 0x00001093UL
+#define CKM_BLOWFISH_CBC_PAD 0x00001094UL
+#define CKM_TWOFISH_CBC_PAD 0x00001095UL
+
+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL
+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL
+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL
+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL
+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL
+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL
+
+#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL
+#define CKM_GOSTR3410 0x00001201UL
+#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL
+#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL
+#define CKM_GOSTR3410_DERIVE 0x00001204UL
+#define CKM_GOSTR3411 0x00001210UL
+#define CKM_GOSTR3411_HMAC 0x00001211UL
+#define CKM_GOST28147_KEY_GEN 0x00001220UL
+#define CKM_GOST28147_ECB 0x00001221UL
+#define CKM_GOST28147 0x00001222UL
+#define CKM_GOST28147_MAC 0x00001223UL
+#define CKM_GOST28147_KEY_WRAP 0x00001224UL
+
+#define CKM_DSA_PARAMETER_GEN 0x00002000UL
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL
+#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL
+#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL
+
+#define CKM_AES_OFB 0x00002104UL
+#define CKM_AES_CFB64 0x00002105UL
+#define CKM_AES_CFB8 0x00002106UL
+#define CKM_AES_CFB128 0x00002107UL
+
+#define CKM_AES_CFB1 0x00002108UL
+#define CKM_AES_KEY_WRAP 0x00002109UL /* WAS: 0x00001090 */
+#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL /* WAS: 0x00001091 */
+
+#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL
+#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL
+
+#define CKM_VENDOR_DEFINED 0x80000000UL
+
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular
+ * mechanism
+ */
+typedef struct CK_MECHANISM {
+ CK_MECHANISM_TYPE mechanism;
+ CK_VOID_PTR pParameter;
+ CK_ULONG ulParameterLen; /* in bytes */
+} CK_MECHANISM;
+
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* 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
+
+/* Describe a token's EC capabilities not available in mechanism
+ * information.
+ */
+#define CKF_EC_F_P 0x00100000UL
+#define CKF_EC_F_2M 0x00200000UL
+#define CKF_EC_ECPARAMETERS 0x00400000UL
+#define CKF_EC_NAMEDCURVE 0x00800000UL
+#define CKF_EC_UNCOMPRESS 0x01000000UL
+#define CKF_EC_COMPRESS 0x02000000UL
+
+#define CKF_EXTENSION 0x80000000UL
+
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+/* CK_RV is a value that identifies the return value of a
+ * Cryptoki function
+ */
+typedef CK_ULONG CK_RV;
+
+#define CKR_OK 0x00000000UL
+#define CKR_CANCEL 0x00000001UL
+#define CKR_HOST_MEMORY 0x00000002UL
+#define CKR_SLOT_ID_INVALID 0x00000003UL
+
+#define CKR_GENERAL_ERROR 0x00000005UL
+#define CKR_FUNCTION_FAILED 0x00000006UL
+
+#define CKR_ARGUMENTS_BAD 0x00000007UL
+#define CKR_NO_EVENT 0x00000008UL
+#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL
+#define CKR_CANT_LOCK 0x0000000AUL
+
+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL
+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL
+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL
+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL
+
+#define CKR_ACTION_PROHIBITED 0x0000001BUL
+
+#define CKR_DATA_INVALID 0x00000020UL
+#define CKR_DATA_LEN_RANGE 0x00000021UL
+#define CKR_DEVICE_ERROR 0x00000030UL
+#define CKR_DEVICE_MEMORY 0x00000031UL
+#define CKR_DEVICE_REMOVED 0x00000032UL
+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL
+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL
+#define CKR_FUNCTION_CANCELED 0x00000050UL
+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL
+
+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL
+
+#define CKR_KEY_HANDLE_INVALID 0x00000060UL
+
+#define CKR_KEY_SIZE_RANGE 0x00000062UL
+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL
+
+#define CKR_KEY_NOT_NEEDED 0x00000064UL
+#define CKR_KEY_CHANGED 0x00000065UL
+#define CKR_KEY_NEEDED 0x00000066UL
+#define CKR_KEY_INDIGESTIBLE 0x00000067UL
+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL
+#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL
+#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL
+
+#define CKR_MECHANISM_INVALID 0x00000070UL
+#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL
+
+#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL
+#define CKR_OPERATION_ACTIVE 0x00000090UL
+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL
+#define CKR_PIN_INCORRECT 0x000000A0UL
+#define CKR_PIN_INVALID 0x000000A1UL
+#define CKR_PIN_LEN_RANGE 0x000000A2UL
+
+#define CKR_PIN_EXPIRED 0x000000A3UL
+#define CKR_PIN_LOCKED 0x000000A4UL
+
+#define CKR_SESSION_CLOSED 0x000000B0UL
+#define CKR_SESSION_COUNT 0x000000B1UL
+#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL
+#define CKR_SESSION_READ_ONLY 0x000000B5UL
+#define CKR_SESSION_EXISTS 0x000000B6UL
+
+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL
+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL
+
+#define CKR_SIGNATURE_INVALID 0x000000C0UL
+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL
+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL
+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL
+#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL
+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL
+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL
+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL
+#define CKR_USER_NOT_LOGGED_IN 0x00000101UL
+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL
+#define CKR_USER_TYPE_INVALID 0x00000103UL
+
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL
+#define CKR_USER_TOO_MANY_TYPES 0x00000105UL
+
+#define CKR_WRAPPED_KEY_INVALID 0x00000110UL
+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL
+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL
+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL
+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL
+
+#define CKR_RANDOM_NO_RNG 0x00000121UL
+
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL
+
+#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL
+
+#define CKR_BUFFER_TOO_SMALL 0x00000150UL
+#define CKR_SAVED_STATE_INVALID 0x00000160UL
+#define CKR_INFORMATION_SENSITIVE 0x00000170UL
+#define CKR_STATE_UNSAVEABLE 0x00000180UL
+
+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL
+#define CKR_MUTEX_BAD 0x000001A0UL
+#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL
+
+#define CKR_NEW_PIN_MODE 0x000001B0UL
+#define CKR_NEXT_OTP 0x000001B1UL
+
+#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL
+#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL
+#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL
+#define CKR_PIN_TOO_WEAK 0x000001B8UL
+#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL
+
+#define CKR_FUNCTION_REJECTED 0x00000200UL
+
+#define CKR_VENDOR_DEFINED 0x80000000UL
+
+
+/* CK_NOTIFY is an application callback that processes events */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_NOTIFICATION event,
+ CK_VOID_PTR pApplication /* passed to C_OpenSession */
+);
+
+
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+ * version and pointers of appropriate types to all the
+ * Cryptoki functions
+ */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+
+/* CK_CREATEMUTEX is an application callback for creating a
+ * mutex object
+ */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a
+ * mutex object
+ */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
+ * mutex
+ */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
+ * C_Initialize
+ */
+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;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL
+#define CKF_OS_LOCKING_OK 0x00000002UL
+
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK 1
+
+/* CK_RSA_PKCS_MGF_TYPE is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
+ * scheme.
+ */
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
+
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+#define CKG_MGF1_SHA1 0x00000001UL
+#define CKG_MGF1_SHA256 0x00000002UL
+#define CKG_MGF1_SHA384 0x00000003UL
+#define CKG_MGF1_SHA512 0x00000004UL
+#define CKG_MGF1_SHA224 0x00000005UL
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
+ * of the encoding parameter when formatting a message block
+ * for the PKCS #1 OAEP encryption scheme.
+ */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED 0x00000001UL
+
+/* CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism.
+ */
+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;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
+
+/* CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_PSS mechanism(s).
+ */
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_ULONG sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
+
+typedef CK_ULONG CK_EC_KDF_TYPE;
+
+/* The following EC Key Derivation Functions are defined */
+#define CKD_NULL 0x00000001UL
+#define CKD_SHA1_KDF 0x00000002UL
+
+/* The following X9.42 DH key derivation functions are defined */
+#define CKD_SHA1_KDF_ASN1 0x00000003UL
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL
+#define CKD_SHA224_KDF 0x00000005UL
+#define CKD_SHA256_KDF 0x00000006UL
+#define CKD_SHA384_KDF 0x00000007UL
+#define CKD_SHA512_KDF 0x00000008UL
+#define CKD_CPDIVERSIFY_KDF 0x00000009UL
+
+
+/* CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
+ * where each party contributes one key pair.
+ */
+typedef struct CK_ECDH1_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_ECDH1_DERIVE_PARAMS;
+
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
+
+/*
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs.
+ */
+typedef struct CK_ECDH2_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_ECDH2_DERIVE_PARAMS;
+
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_ECMQV_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_ECMQV_DERIVE_PARAMS;
+
+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
+
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms
+ */
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
+
+/* CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
+ * contributes one key pair
+ */
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_X9_42_DH1_DERIVE_PARAMS;
+
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
+
+/* CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
+ * mechanisms, where each party contributes two key pairs
+ */
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_X9_42_DH2_DERIVE_PARAMS;
+
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_X9_42_MQV_DERIVE_PARAMS;
+
+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
+ * CKM_KEA_DERIVE mechanism
+ */
+typedef struct CK_KEA_DERIVE_PARAMS {
+ CK_BBOOL isSender;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pRandomB;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
+ * holds the effective keysize
+ */
+typedef CK_ULONG CK_RC2_PARAMS;
+
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+ * mechanism
+ */
+typedef struct CK_RC2_CBC_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_BYTE iv[8]; /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC2_MAC_GENERAL mechanism
+ */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+ * CKM_RC5_MAC mechanisms
+ */
+typedef struct CK_RC5_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+} CK_RC5_PARAMS;
+
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+ * mechanism
+ */
+typedef struct CK_RC5_CBC_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_BYTE_PTR pIv; /* pointer to IV */
+ CK_ULONG ulIvLen; /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC5_MAC_GENERAL mechanism
+ */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
+ * the MAC
+ */
+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[8];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism
+ */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pPassword;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPAndGLen;
+ CK_ULONG ulQLen;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pPrimeP;
+ CK_BYTE_PTR pBaseG;
+ CK_BYTE_PTR pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+ CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism
+ */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+ CK_ULONG ulOldWrappedXLen;
+ CK_BYTE_PTR pOldWrappedX;
+ CK_ULONG ulOldPasswordLen;
+ CK_BYTE_PTR pOldPassword;
+ CK_ULONG ulOldPublicDataLen;
+ CK_BYTE_PTR pOldPublicData;
+ CK_ULONG ulOldRandomLen;
+ CK_BYTE_PTR pOldRandomA;
+ CK_ULONG ulNewPasswordLen;
+ CK_BYTE_PTR pNewPassword;
+ CK_ULONG ulNewPublicDataLen;
+ CK_BYTE_PTR pNewPublicData;
+ CK_ULONG ulNewRandomLen;
+ CK_BYTE_PTR pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+
+typedef struct CK_PBE_PARAMS {
+ CK_BYTE_PTR pInitVector;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_ULONG ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+ * CKM_KEY_WRAP_SET_OAEP mechanism
+ */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+ CK_BYTE bBC; /* block contents byte */
+ CK_BYTE_PTR pX; /* extra data */
+ CK_ULONG ulXLen; /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+typedef struct CK_SSL3_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hClientMacSecret;
+ CK_OBJECT_HANDLE hServerMacSecret;
+ CK_OBJECT_HANDLE hClientKey;
+ CK_OBJECT_HANDLE hServerKey;
+ CK_BYTE_PTR pIVClient;
+ CK_BYTE_PTR pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+typedef struct CK_TLS_PRF_PARAMS {
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_TLS_PRF_PARAMS;
+
+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
+
+typedef struct CK_WTLS_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_WTLS_RANDOM_DATA;
+
+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
+
+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_BYTE_PTR pVersion;
+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
+
+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_WTLS_PRF_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_WTLS_PRF_PARAMS;
+
+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hMacSecret;
+ CK_OBJECT_HANDLE hKey;
+ CK_BYTE_PTR pIV;
+} CK_WTLS_KEY_MAT_OUT;
+
+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_ULONG ulSequenceNumber;
+ CK_BBOOL bIsExport;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_WTLS_KEY_MAT_PARAMS;
+
+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
+
+typedef struct CK_CMS_SIG_PARAMS {
+ CK_OBJECT_HANDLE certificateHandle;
+ CK_MECHANISM_PTR pSigningMechanism;
+ CK_MECHANISM_PTR pDigestMechanism;
+ CK_UTF8CHAR_PTR pContentType;
+ CK_BYTE_PTR pRequestedAttributes;
+ CK_ULONG ulRequestedAttributesLen;
+ CK_BYTE_PTR pRequiredAttributes;
+ CK_ULONG ulRequiredAttributesLen;
+} CK_CMS_SIG_PARAMS;
+
+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
+
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+ CK_BYTE_PTR pData;
+ CK_ULONG ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
+ CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
+/* The CK_EXTRACT_PARAMS is used for the
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
+ * of the base key should be used as the first bit of the
+ * derived key
+ */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
+ * key bits using PKCS #5 PBKDF2.
+ */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR \
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL
+#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL
+
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
+ * PBKDF2.
+ */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR \
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED 0x00000001UL
+
+/* CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * parameters to the CKM_PKCS5_PBKD2 mechanism.
+ */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG_PTR ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PARAMS2 is a corrected version of the CK_PKCS5_PBKD2_PARAMS
+ * structure that provides the parameters to the CKM_PKCS5_PBKD2 mechanism
+ * noting that the ulPasswordLen field is a CK_ULONG and not a CK_ULONG_PTR.
+ */
+typedef struct CK_PKCS5_PBKD2_PARAMS2 {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS2;
+
+typedef CK_PKCS5_PBKD2_PARAMS2 CK_PTR CK_PKCS5_PBKD2_PARAMS2_PTR;
+
+typedef CK_ULONG CK_OTP_PARAM_TYPE;
+typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */
+
+typedef struct CK_OTP_PARAM {
+ CK_OTP_PARAM_TYPE type;
+ CK_VOID_PTR pValue;
+ CK_ULONG ulValueLen;
+} CK_OTP_PARAM;
+
+typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
+
+typedef struct CK_OTP_PARAMS {
+ CK_OTP_PARAM_PTR pParams;
+ CK_ULONG ulCount;
+} CK_OTP_PARAMS;
+
+typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
+
+typedef struct CK_OTP_SIGNATURE_INFO {
+ CK_OTP_PARAM_PTR pParams;
+ CK_ULONG ulCount;
+} CK_OTP_SIGNATURE_INFO;
+
+typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
+
+#define CK_OTP_VALUE 0UL
+#define CK_OTP_PIN 1UL
+#define CK_OTP_CHALLENGE 2UL
+#define CK_OTP_TIME 3UL
+#define CK_OTP_COUNTER 4UL
+#define CK_OTP_FLAGS 5UL
+#define CK_OTP_OUTPUT_LENGTH 6UL
+#define CK_OTP_OUTPUT_FORMAT 7UL
+
+#define CKF_NEXT_OTP 0x00000001UL
+#define CKF_EXCLUDE_TIME 0x00000002UL
+#define CKF_EXCLUDE_COUNTER 0x00000004UL
+#define CKF_EXCLUDE_CHALLENGE 0x00000008UL
+#define CKF_EXCLUDE_PIN 0x00000010UL
+#define CKF_USER_FRIENDLY_OTP 0x00000020UL
+
+typedef struct CK_KIP_PARAMS {
+ CK_MECHANISM_PTR pMechanism;
+ CK_OBJECT_HANDLE hKey;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+} CK_KIP_PARAMS;
+
+typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
+
+typedef struct CK_AES_CTR_PARAMS {
+ CK_ULONG ulCounterBits;
+ CK_BYTE cb[16];
+} CK_AES_CTR_PARAMS;
+
+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
+
+typedef struct CK_GCM_PARAMS {
+ CK_BYTE_PTR pIv;
+ CK_ULONG ulIvLen;
+ CK_ULONG ulIvBits;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulTagBits;
+} CK_GCM_PARAMS;
+
+typedef CK_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR;
+
+typedef struct CK_CCM_PARAMS {
+ CK_ULONG ulDataLen;
+ CK_BYTE_PTR pNonce;
+ CK_ULONG ulNonceLen;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulMACLen;
+} CK_CCM_PARAMS;
+
+typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR;
+
+/* Deprecated. Use CK_GCM_PARAMS */
+typedef struct CK_AES_GCM_PARAMS {
+ CK_BYTE_PTR pIv;
+ CK_ULONG ulIvLen;
+ CK_ULONG ulIvBits;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulTagBits;
+} CK_AES_GCM_PARAMS;
+
+typedef CK_AES_GCM_PARAMS CK_PTR CK_AES_GCM_PARAMS_PTR;
+
+/* Deprecated. Use CK_CCM_PARAMS */
+typedef struct CK_AES_CCM_PARAMS {
+ CK_ULONG ulDataLen;
+ CK_BYTE_PTR pNonce;
+ CK_ULONG ulNonceLen;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulMACLen;
+} CK_AES_CCM_PARAMS;
+
+typedef CK_AES_CCM_PARAMS CK_PTR CK_AES_CCM_PARAMS_PTR;
+
+typedef struct CK_CAMELLIA_CTR_PARAMS {
+ CK_ULONG ulCounterBits;
+ CK_BYTE cb[16];
+} CK_CAMELLIA_CTR_PARAMS;
+
+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
+
+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \
+ CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \
+ CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_DSA_PARAMETER_GEN_PARAM {
+ CK_MECHANISM_TYPE hash;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_ULONG ulIndex;
+} CK_DSA_PARAMETER_GEN_PARAM;
+
+typedef CK_DSA_PARAMETER_GEN_PARAM CK_PTR CK_DSA_PARAMETER_GEN_PARAM_PTR;
+
+typedef struct CK_ECDH_AES_KEY_WRAP_PARAMS {
+ CK_ULONG ulAESKeyBits;
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+} CK_ECDH_AES_KEY_WRAP_PARAMS;
+
+typedef CK_ECDH_AES_KEY_WRAP_PARAMS CK_PTR CK_ECDH_AES_KEY_WRAP_PARAMS_PTR;
+
+typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN;
+
+typedef CK_ULONG CK_CERTIFICATE_CATEGORY;
+
+typedef struct CK_RSA_AES_KEY_WRAP_PARAMS {
+ CK_ULONG ulAESKeyBits;
+ CK_RSA_PKCS_OAEP_PARAMS_PTR pOAEPParams;
+} CK_RSA_AES_KEY_WRAP_PARAMS;
+
+typedef CK_RSA_AES_KEY_WRAP_PARAMS CK_PTR CK_RSA_AES_KEY_WRAP_PARAMS_PTR;
+
+typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+ CK_MECHANISM_TYPE prfHashMechanism;
+} CK_TLS12_MASTER_KEY_DERIVE_PARAMS;
+
+typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_TLS12_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+ CK_MECHANISM_TYPE prfHashMechanism;
+} CK_TLS12_KEY_MAT_PARAMS;
+
+typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR;
+
+typedef struct CK_TLS_KDF_PARAMS {
+ CK_MECHANISM_TYPE prfMechanism;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLength;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_BYTE_PTR pContextData;
+ CK_ULONG ulContextDataLength;
+} CK_TLS_KDF_PARAMS;
+
+typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR;
+
+typedef struct CK_TLS_MAC_PARAMS {
+ CK_MECHANISM_TYPE prfHashMechanism;
+ CK_ULONG ulMacLength;
+ CK_ULONG ulServerOrClient;
+} CK_TLS_MAC_PARAMS;
+
+typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR;
+
+typedef struct CK_GOSTR3410_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pUKM;
+ CK_ULONG ulUKMLen;
+} CK_GOSTR3410_DERIVE_PARAMS;
+
+typedef CK_GOSTR3410_DERIVE_PARAMS CK_PTR CK_GOSTR3410_DERIVE_PARAMS_PTR;
+
+typedef struct CK_GOSTR3410_KEY_WRAP_PARAMS {
+ CK_BYTE_PTR pWrapOID;
+ CK_ULONG ulWrapOIDLen;
+ CK_BYTE_PTR pUKM;
+ CK_ULONG ulUKMLen;
+ CK_OBJECT_HANDLE hKey;
+} CK_GOSTR3410_KEY_WRAP_PARAMS;
+
+typedef CK_GOSTR3410_KEY_WRAP_PARAMS CK_PTR CK_GOSTR3410_KEY_WRAP_PARAMS_PTR;
+
+typedef struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_SEED_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \
+ CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+#endif /* _PKCS11T_H_ */
+
diff --git a/src/lib/prov/tpm/tpm.h b/src/lib/prov/tpm/tpm.h
index 4a9dcd3c6..b8093518c 100644
--- a/src/lib/prov/tpm/tpm.h
+++ b/src/lib/prov/tpm/tpm.h
@@ -1,3 +1,4 @@
+
/*
* TPM 1.2 interface
* (C) 2015 Jack Lloyd
@@ -71,34 +72,27 @@ class BOTAN_DLL TPM_Context
TSS_HTPM m_tpm;
};
-class BOTAN_DLL TPM_RNG : public RandomNumberGenerator
+class BOTAN_DLL TPM_RNG : public Hardware_RNG
{
public:
TPM_RNG(TPM_Context& ctx) : m_ctx(ctx) {}
+ void add_entropy(const byte in[], size_t in_len) override
+ {
+ m_ctx.stir_random(in, in_len);
+ }
+
void randomize(byte out[], size_t out_len) override
{
m_ctx.gen_random(out, out_len);
}
- void clear() override {}
-
std::string name() const override { return "TPM_RNG"; }
- size_t reseed_with_sources(Entropy_Sources&,
- size_t,
- std::chrono::milliseconds) override
- {
- // TODO: poll and stir
- return 0;
- }
+ bool is_seeded() const override { return true; }
- void add_entropy(const byte in[], size_t in_len) override
- {
- m_ctx.stir_random(in, in_len);
- }
+ void clear() override {}
- bool is_seeded() const override { return true; }
private:
TPM_Context& m_ctx;
};