Closed mouse07410 closed 1 year ago
The crash seem to happen deep into libyubihsm ... which seem to link in openssl once again ... depending on the version of openssl linked in and how that is doen it may be due to symbol clashing or some other reason.
Can you ldd libyubihsm.2.4.0.dylib to see which openssl it links against? Also, if you have valgrind installed it would be nice to run the command through valgrind as it often gives a pretty good hint of what causes the carsh in the first place.
However note that this is happening during openssl deinit, so I think this is a similar problem to #187, where the yubikey library is liberally using the common openssl libctx, and it is invoking it after openssl already started deiniting it. May have no solution except for yuico fixing their library to use a non-default libctx.
As for the issue with reading the key, a pkcs11-spy trace would be nice.
Ah the reason we are not asking for a PIN anymore is: #190 I guess the only way to solve this for something like yubiHSM, is to add a configuration option that always forces a login regardless of the kind of key being read. Either that or find out if a specific error is returned and retry to read the store after login. A SPY log would be helpful to see if we have such a clear error to look at during key search. Potentially we could always retry with login if no key is found at all ... but it would be annoying for tokens that do allow reading keys without PIN, and the only problem is the key search parameters simply match nothing ...
The crash seem to happen deep into libyubihsm ... which seem to link in openssl once again ... depending on the version of openssl linked in and how that is doen it may be due to symbol clashing or some other reason.
Probably unlikely - everything built "normally" gets linked to OpenSSL-3.0.8.
Can you ldd libyubihsm.2.4.0.dylib to see which openssl it links against?
$ ll /usr/local/lib/yubihsm_pkcs11.dylib
lrwxr-xr-x 1 root wheel 42 Nov 20 2021 /usr/local/lib/yubihsm_pkcs11.dylib@ -> /usr/local/lib/pkcs11/yubihsm_pkcs11.dylib
$ otool -L /usr/local/lib/yubihsm_pkcs11.dylib
/usr/local/lib/yubihsm_pkcs11.dylib:
@rpath/yubihsm_pkcs11.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/libiconv.2.dylib (compatibility version 9.0.0, current version 9.1.0)
@rpath/libyubihsm.2.dylib (compatibility version 2.0.0, current version 2.4.0)
/opt/local/libexec/openssl3/lib/libcrypto.3.dylib (compatibility version 3.0.0, current version 3.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0)
$
Also, if you have valgrind installed it would be nice to run the command through valgrind as it often gives a pretty good hint of what causes the carsh in the first place.
Sorry, cannot. :-(
However note that this is happening during openssl deinit, so I think this is a similar problem to https://github.com/latchset/pkcs11-provider/issues/187, where the yubikey library is liberally using the common openssl libctx, and it is invoking it after openssl already started deiniting it. May have no solution except for yuico fixing their library to use a non-default libctx.
If we know for sure that this is the cause, perhaps you can help me crafting an issue - and I'll post it to Yubico. More often than not, they'd listen.
As for the issue with reading the key, a pkcs11-spy trace would be nice.
Ah the reason we are not asking for a PIN anymore is: https://github.com/latchset/pkcs11-provider/pull/190 I guess the only way to solve this for something like yubiHSM, is to add a configuration option that always forces a login regardless of the kind of key being read.
Yeah, here's the problem:
I think it applies to any HSM, though YubiHSM is the only one I can fool around at will.
Potentially we could always retry with login if no key is found at all ...
I very much support this approach.
but it would be annoying for tokens that do allow reading keys without PIN, and the only problem is the key search parameters simply match nothing ...
You're certainly right - but, given the likelihood of such occurrences should be quite rare, I'd say let's bite the bullet and implement it this way. Make 85% of users/use-cases happy, and 15% unfortunately suffer - unpleasant but better than the reverse.
Please check if #197 resolves your issue, I will pile a little bit more documentation i that PR, but the first patch is what you need
Please check if #197 resolves your issue, I will pile a little bit more documentation i that PR, but the first patch is what you need
Alas, no:
$ openssl pkeyutl -encrypt -pubin -inkey "pkcs11:model=YubiHSM;token=YubiHSM;id=%04%02;object=RSA-OAEP;type=public" -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha384 -pkeyopt rsa_mgf1_md:sha384 -in /tmp/key.bin -out /tmp/key.enc1
Enter pass phrase for PKCS#11 Token (Slot 0 - YubiHSM Connector 0.0.0.0):
Public Key operation error
8096FA56F87F0000:error:42000063:pkcs11:p11prov_EncryptInit:The specified key is not the correct type of key to use with the specified mechanism:./interface.gen.c:413:Error returned by C_EncryptInit
Segmentation fault: 11
Well it does solve the prompting problem and the spy file shows the key is found and available. So at least it solves that part.
However C_EncryptInit does not like that this key is used with CKM_RSA_PKCS_OAEP and the parameters we select, and returns CKR_KEY_TYPE_INCONSISTENT
There are three cases in which this is returned in opensc, so it is not clear to me why it does this.
If you can perform this exact operation but using the engine I would love to see a spy trace of that too. It is quite possible we are doing something wrong setting up OAEP paramters, as most of the tests use just regular PKCS1.5 padding for encryption.
Well it does solve the prompting problem and the spy file shows the key is found and available. So at least it solves that part.
Yes.
However
C_EncryptInit
does not like that this key is used withCKM_RSA_PKCS_OAEP
and the parameters we select, and returnsCKR_KEY_TYPE_INCONSISTENT
Which confuses me too. @dengert, it became customary to ask you whenever we're stymied. ;-) The key is obviously RSA-OAEP:
Object 21:
URL: pkcs11:model=YubiHSM;manufacturer=Yubico%20%28www.yubico.com%29;token=YubiHSM;id=%04%02;object=RSA-OAEP;type=private
Type: Private key (RSA-3072)
Label: RSA-OAEP
Flags: CKA_PRIVATE; CKA_EXTRACTABLE; CKA_SENSITIVE;
ID: 04:02
Object 22:
URL: pkcs11:model=YubiHSM;manufacturer=Yubico%20%28www.yubico.com%29;token=YubiHSM;id=%04%02;object=RSA-OAEP;type=public
Type: Public key (RSA-3072)
Label: RSA-OAEP
Flags: CKA_EXTRACTABLE;
ID: 04:02
And the mechanisms HSM supports are
$ yhsm2-tool -M
Using slot 0 with a present token (0x0)
Supported mechanisms:
RSA-PKCS, keySize={2048,4096}, hw, encrypt, decrypt, sign, verify
SHA1-RSA-PKCS, keySize={2048,4096}, hw, sign, verify
SHA256-RSA-PKCS, keySize={2048,4096}, hw, sign, verify
SHA384-RSA-PKCS, keySize={2048,4096}, hw, sign, verify
SHA512-RSA-PKCS, keySize={2048,4096}, hw, sign, verify
RSA-PKCS-PSS, keySize={2048,4096}, hw, sign, verify
SHA1-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign, verify
SHA256-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign, verify
SHA384-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign, verify
SHA512-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign, verify
RSA-PKCS-KEY-PAIR-GEN, keySize={2048,4096}, hw, generate_key_pair
ECDSA-KEY-PAIR-GEN, keySize={224,521}, hw, generate_key_pair, EC F_P, EC OID, EC uncompressed
SHA-1-HMAC, keySize={1,512}, hw, sign, verify
GENERIC-SECRET-KEY-GEN, keySize={1,1024}, hw, generate
SHA256-HMAC, keySize={1,512}, hw, sign, verify
SHA384-HMAC, keySize={1,1024}, hw, sign, verify
SHA512-HMAC, keySize={1,1024}, hw, sign, verify
ECDSA, keySize={224,521}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
ECDSA-SHA1, keySize={224,521}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
ECDH1-DERIVE, keySize={224,521}, hw, derive, EC F_P, EC OID, EC uncompressed
RSA-PKCS-OAEP, keySize={2048,4096}, hw, encrypt, decrypt
mechtype-0xD9554204, keySize={128,256}, hw, encrypt, decrypt, wrap, unwrap
ECDSA-SHA256, keySize={224,521}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
ECDSA-SHA384, keySize={224,521}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
ECDSA-SHA512, keySize={224,521}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
SHA-1, digest
SHA256, digest
SHA384, digest
SHA512, digest
(Note hw
at all of them except simple digests, and absence of "raw" RSA operations.)
If you can perform this exact operation but using the engine I would love to see a spy trace of that too. It is quite possible we are doing something wrong setting up OAEP paramters, as most of the tests use just regular PKCS1.5 padding for encryption
Unfortunately, again, there's no PKCS#11 traffic capture after authentication. I've no idea why. yhsm2-rsa-encr-engine-spy2.txt
Also, if you cloned that engine code - you can see how they set the OAEP (and PSS) parameters...
Once again the pkcs11-spy traces with engine lacks all the actual cryptographic operations ... I wonder if it is because with public keys OpenSSL tends to export/import them and do the operation in software instead of deferring to the card ...
Would you mind running the decrypt operation through the spy, that one must be done on the card ...
Spy says pkcs11-module used by libp11 and engine /usr/local/lib/yubihsm_pkcs11.dylib
May need to ask Yubico.
the C_FindObjects did not find any objects. but was looking for a profile so cold be OK.
4 unknown Mechanisms Unknown Mechanism (d9554204) CK_VENDOR_SPECIFIC |"Y" "U" "B" 04 Unknown Mechanism (00001044) CKM_ECDSA_SHA256 Unknown Mechanism (00001045) CKM_ECDSA_SHA384 Unknown Mechanism (00001046) CKM_ECDSA_SHA512 (the spy should have mapped the 3 above.)
But trace says Enter PKCS#11 token PIN for YubiHSM:
And next is C_Finalize Something is missing.
libl11 and engine do support OAEP: https://github.com/OpenSC/libp11/blob/master/src/p11_pkey.c#L301-L311
But note not the "Label".
OpenSSL tends to export/import them and do the operation in software instead
Agree.
I wonder if it is because with public keys OpenSSL tends to export/import them and do the operation in software instead of deferring to the card
I don't know, but @dengert concurs with you. And re-checking the traces, I did see retrieval of the pubkey. So it's possible.
Would you mind running the decrypt operation through the spy, that one must be done on the card ...
May need to ask Yubico.
Possible. But since the libp11
engine seems to weather these operations fine - would it be possible to make the provider do exactly the same thing?
Possible. But since the
libp11
engine seems to weather these operations fine - would it be possible to make the provider do exactly the same thing?
That's mostly up to OpenSSL I would say, not clear to me why it is behaving differently in this case. But then I also do not see why the operation should fail.
I checked your log and the DecryptInit operation is initialized just the same way the EncryptInit one is ... so I do not know why the opensc-pkcs11 driver is complaining. Possibly a bug masqueraded by the fact that usually with the engine this function is never exercised ...
The spy you sent was taken using pkcs11-provider, did the decryption work correctly in this case (aside for the segmentation fault which is a separate issue)
The spy you sent was taken using pkcs11-provider, did the decryption work correctly in this case (aside for the segmentation fault which is a separate issue)
Yes, it looks like the decrypted 32-byte value matched the original plaintext.
Current master with current #197 merged still fail encryption:
echo 7ac26e8e9960218e013d0931aca959588135e466dedf09a9ff8cd87eb214b1ec | xxd -r -p -c 200 | openssl pkeyutl -encrypt -pubin -inkey "pkcs11:model=YubiHSM;token=YubiHSM;id=%04%02;object=RSA-OAEP;type=public" -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha384 -pkeyopt rsa_mgf1_md:sha384 -out /tmp/derive.65014.key.enc
Enter pass phrase for PKCS#11 Token (Slot 0 - YubiHSM Connector 0.0.0.0):
Public Key operation error
8096FA56F87F0000:error:42000063:pkcs11:p11prov_EncryptInit:The specified key is not the correct type of key to use with the specified mechanism:./interface.gen.c:413:Error returned by C_EncryptInit
Maybe the key (no pun intended) to dealing with all operations on public objects (certs, pubkeys, and such) is to extract them and let the software (OpenSSL) perform the computations? Perhaps, that's what libp11
does?
From https://developers.yubico.com/YubiHSM2/Component_Reference/PKCS_11/
C_Encrypt
andC_Verify
for Asymmetric Keys are performed in software, as well as all of the C_Digest operations.
@mouse07410 ykcs11 just uses openssl to do those operations, it does not expect the calling application to do them.
And I can't force this, as I may have mentioned earlier this is a generic pkcs11 provider, not tailored to only specific low spec modules. The idea is to allow any operation to be offloaded. For example you may have a HW accelerator for signature verification or asym encryption that you definitely may want to use (which is why there is a parameter to deny exporting even public keys to openssl).
If a pkcs11 driver is buggy we either get it fixed, or we'll try to do a custom quirk for that one.
@simo5 I understand your reasoning. So, how do we deal with this problem? It looks like we got it solved for smartcards (sign/verify and encrypt/decrypt), and only HSM encrypt remains problematic? Plus, crash at the end of HSM decrypt?
Would you like me to open two new issues - for HSM encrypt, and for crash after HSM decrypt (which could impact user-written apps that use OpenSSL libraries to access HSM)?
I think this bug is ok for the encryption issue, we need to find out what is causing it. For the crash, that's a separate issue, and I am convinced it is a problem in yubico's drivers. Nothing I can really do there, it is a crash in openssl destructor phase because yubico is using the default openssl context ...
For the crash, that's a separate issue, and I am convinced it is a problem in yubico's drivers.
Reported in https://github.com/Yubico/yubihsm-shell/issues/319
Describe the bug
Fails to either encrypt or decrypt.
To Reproduce
Encryption (with provider):
Encryption failed - needed to prompt for the PIN, but it didn't.
For decryption (with provider):
Appears to have decrypted correctly before crashing OpenSSL. Observed crash:
Expected behavior
For encryption (showing with the engine):
For decryption (showing with the engine):
Operating environment (please complete the following information):
Token and application used (please complete the following information):
Additional context
Works with engine, partially works for decryption with HSM when invoked manually. Adding or removing
object=RSA_OAEP;
to the key URI seems to have no effect, probably better to remove it.