diff options
Diffstat (limited to 'src/lib/prov')
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; }; |