Open onavratil-monetplus opened 4 years ago
Unfortunately the output from OpenSSL isn't very helpful. Can you provide a minimum working example in C to reproduce this issue? That would allow us to investigate this further.
Hope you are okay with Botan (else the PKCS is gory).
I get log:
Aug 20 10:03:22 localhost MWE[11996]: OSSLEVPSymmetricAlgorithm.cpp(512): EVP_DecryptFinal failed (0x00000000): error:00000000:lib(0):func(0):reason(0)
MWE output:
No problem up to here...
Got excption PKCS11 error 5 code 5
the MWE:
#include <botan/p11_module.h>
#include <iostream>
#include <iomanip>
#include <optional>
#include <botan/p11_slot.h>
#include <botan/p11_object.h>
#include <botan/p11_session.h>
#include <botan/p11_rsa.h>
namespace P11 = Botan::PKCS11;
int main(int argc, char ** argv){
P11::Module module("/usr/local/lib/softhsm/libsofthsm2.so");
std::vector<P11::SlotId> slots = P11::Slot::get_available_slots(module, true);
std::optional<P11::Slot> targetSlot;
/* Initialize temp token */
for(auto const &slotId : slots){
P11::Slot slot(module, slotId);
auto tokenInfo = slot.get_token_info();
if(tokenInfo.flags & static_cast<CK_FLAGS>(P11::Flag::TokenInitialized)){
//skip initialized
continue;
}
slot.initialize("Temp token", {'1','2','3','4'});
P11::set_pin(slot, {'1','2','3','4'}, {'1','1','1','1'});
targetSlot.emplace(slot);
break;
}
if(!targetSlot)
return -1;
/* Log in session */
P11::Session session(*targetSlot, false);
session.login(P11::UserType::User, {'1','1','1','1'});
/* Generate aes key */
P11::SecretKeyProperties propsEncryptor(P11::KeyType::Aes);
propsEncryptor.set_label("Temp AES Key");
propsEncryptor.set_encrypt(true);
propsEncryptor.set_decrypt(true);
propsEncryptor.set_token(false);
propsEncryptor.add_numeric(P11::AttributeType::ValueLen, 32UL);
P11::Mechanism mechaEncryption = {static_cast<CK_MECHANISM_TYPE >(P11::MechanismType::AesKeyGen), NULL_PTR, 0};
P11::ObjectHandle keyHandle;
const std::vector<P11::Attribute> vec = propsEncryptor.attributes();
module->C_GenerateKey(session.handle(), &mechaEncryption, const_cast<CK_ATTRIBUTE*>(&vec[0]), vec.size(), &keyHandle);
/* Prepare for GCM encryption with 0 tag */
std::vector<uint8_t> iv(12,0);
CK_GCM_PARAMS params;
params.pIv = iv.data();
params.ulIvLen = iv.size();
params.pAAD = NULL_PTR;
params.ulAADLen = 0;
params.ulTagBits = 0;
P11::Mechanism mecha = {static_cast<CK_MECHANISM_TYPE>(P11::MechanismType::AesGcm), ¶ms, sizeof(params)};
std::vector<uint8_t> sampleData{1,2,3,4,5,6,7,8,9,10};
std::vector<uint8_t> encryptedData;
/* GCM encryption with 0 tag */
module->C_EncryptInit(session.handle(), &mecha, keyHandle);
module->C_Encrypt(session.handle(), sampleData, encryptedData);
/* GCM Decryption of the same data */
std::vector<uint8_t> decryptedData;
module->C_DecryptInit(session.handle(), &mecha, keyHandle);
std::cout << "No problem up to here..." << std::endl;
try{
module->C_Decrypt(session.handle(), encryptedData, decryptedData);
}
catch(const P11::PKCS11_Error &e){
std::cout << "Got excption " << e.what() << " code " << e.error_code() << std::endl;
}
return 0;
}
Interesting that you used Botan; this leads me to a follow-up question: if you build SoftHSM against Botan, does it work then? (just so we know)
I have another environment with botan-compiled SoftHSM. The MWE throws
terminate called after throwing an instance of 'Botan::PKCS11::PKCS11_ReturnError'
what(): PKCS11 error 112
Aborted
from pkcs docs CKR_MECHANISM_INVALID 0x00000070UL
I get this one already thrown at EncryptInit. Not sure if GCM is supported there at all. But at least, I get a error message on a reasonable place (not in the last step)
One more interesting thing. I tried the same MWE with extending ulTagBits to 128. Then it passes Botan-compiled softhsm2 too....
I think it is related to
https://github.com/randombit/botan/issues/1207
Moreover....I believe that in this case, it would be better to return CKR_MECHANISM_PARAM_INVALID
rather than CKR_MECHANISM_INVALID
Could you open a separate issue for that, I think you're right (it should return CKR_MECHANISM_PARAM_INVALID
)
I can succesfully encrypt with:
But an attempt to decrypt with an IDENTICAL mechanism fails in
C_Decrypt
(notC_DecryptInit
) with aCKR_GENERAL_ERROR 0x00000005UL
Syslog tells meOSSLEVPSymmetricAlgorithm.cpp(512): EVP_DecryptFinal failed (0x00000000): error:00000000:lib(0):func(0):reason(0)
Identical approach WORKS if I increase tagBits to 16 - thus I assume there is some exception if the tag is empty, yet I was not able to trace it properly.
In order to justify my approach: Using GCM with omitted tag (0-size) is allowed by-the-standard:
ulTagBits length of authentication tag (output following cipher text) in bits. Can be any value between 0 and 128.
and may be useful if integrity is assured on a higher level (another wrapper). GCM thus works as an equivalent for CTR, which would make more sense to use in this case, but is often not supported.