Closed mouse07410 closed 5 years ago
Correct. There is no way to implement OAEP on the low-level RSA engine interface of OpenSSL, as the OAEP parameters required to fill the CK_RSA_PKCS_OAEP_PARAMS structure are no longer available at this point.
These OAEP parameters are available in the EVP_PKEY_CTX structure of the PKEY interface. The pkcs11_params_oaep()
function may give you some clues if you are interested in the internals of our implementation.
@mtrojnar and @dengert I'm trying to understand why some things work, and some don't.
For example, here's a Yubikey NEO token with two applets (that matter in this context): PIV and OpenPGP. I'm trying to use both with OpenSSL via libp11
and OpenSC opensc-pkcs11.dylib
.
With PIV applet, everything works as expected, and OpenSSL "translates" RSA-PSS and RSA-OAEP operations into what the token understands, applying the padding in software:
openssl rand -hex -out /tmp/derive.57559.text 5120
Signing file /tmp/derive.57559.text...
openssl dgst -engine pkcs11 -keyform engine -sign "pkcs11:manufacturer=piv_II;object=SIGN%20key;type=private" -sha384 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out /tmp/derive.57559.text.sig /tmp/derive.57559.text
engine "pkcs11" set.
Enter PKCS#11 token PIN for Uri the Great:
Signature is stored in /tmp/derive.57559.text.sig
Verifying signature:
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify "pkcs11:manufacturer=piv_II;object=SIGN%20pubkey;type=public" -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature /tmp/derive.57559.text.sig /tmp/derive.57559.text
engine "pkcs11" set.
Verified OK
With OpenPGP applet though, it does fine RSA-PKCS1 signature, but fails with RSA-PSS:
OPENSC_DRIVER=openpgp ~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -sign "pkcs11:model=PKCS%2315%20emulated;manufacturer=Yubico;serial=0006038xxxxx;token=User%20PIN%20%28sig%29%20%28OpenPGP%29;id=%01;object=Signature%20key;type=private" -sha384 -sigopt rsa_padding_mode:pss -out t6400.dat.sighsmpss t6400.dat
engine "pkcs11" set.
Enter PKCS#11 token PIN for User PIN (sig) (OpenPGP):
Error Signing Data
4571960768:error:8207A070:PKCS#11 module:pkcs11_private_encrypt:Mechanism invalid:p11_rsa.c:116:
Why is it that in one case the software translation works fine, and in the other one it doesn't happen? And is there a way in libp11
to somehow signal OpenSSL that for the given token it should apply padding in software rather than expect the token to do it?
A PKCS11_SPY trace and an opensc-debug.log would be helpful.
pkcs11_private_encrypt
has:
/ Try signing first, as applications are more likely to use it /
/ OpenSSL may use it for encryption rather than signing /
PIV only does RAW, so the C_Sign should work.
OpenPGP may place more restrictions on the key, so id C_Sign fails pkcs11_private_encrypt
may try C_Encrypt
that may fail.
A PKCS11_SPY trace and an opensc-debug.log would be helpful.
@dengert you're certainly right. Here they are:
$ PKCS11SPY_OUTPUT=openpgp-spy.txt OPENSC_DEBUG=9 OPENSC_DRIVER=openpgp openssl dgst -engine pkcs11 -keyform engine -sign "pkcs11:model=PKCS%2315%20emulated;token=User%20PIN%20%28sig%29%20%28OpenPGP%29;id=%01;object=Signature%20key;type=private" -sha384 -sigopt rsa_padding_mode:pss -out t6400.dat.sighsmpkcs t6400.dat
P:83671; T:0x4572628416 08:36:24.882 [opensc-pkcs11] ctx.c:737:process_config_file: Used configuration file '/Library/OpenSC/etc/opensc.conf'
engine "pkcs11" set.
Enter PKCS#11 token PIN for User PIN (sig) (OpenPGP):
Error Signing Data
4572628588:error:8207A070:PKCS#11 module:pkcs11_private_encrypt:Mechanism invalid:p11_rsa.c:116:
$
opensc-debug.log
:
opensc-log.txt - shows successful signature using PKCS1 padding, and a failed one using PSS. Strange to me that OpenSSL did not apply the padding in software.
PKCS11_SPY
log:
openpgp-spy.txt - shows that RSA-PSS was requested directly.
So, how does OpenSSL decide whether to apply the padding by itself, or "outsource" it to the engine+token (such as YubiHSM2 that applies PSS by itself)?
So, how does OpenSSL decide whether to apply the padding by itself, or "outsource" it to the engine+token (such as YubiHSM2 that applies PSS by itself)?
OpenSSL doesn't decide what to do. We decide it in libp11. We first try CKM_RSA_PKCS_PSS, and if it fails we let OpenSSL apply the padding and use CKM_RSA_X_509 (raw RSA): https://github.com/OpenSC/libp11/blob/0ac6d4d856885656505b42498f6e72711d2c7810/src/p11_pkey.c#L383-L385
It is obviously possible that the module only supports CKM_RSA_PKCS, so neither CKM_RSA_PKCS_PSS nor CKM_RSA_X_509 can be used.
But I've seen no traces in the SPY log that suggested that anything but PSS was tried. And I'm pretty sure the token does support RSA_X_509.
What's your opinion regarding what's happening with the RSA keys from the OpenPGP applet?
I agree.
framework-pkcs11.c
has:
5485 /* Check if we support raw RSA */
5486 if (rsa_flags & SC_ALGORITHM_RSA_RAW) {
5487 mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, &mech_info, CKK_RSA, NULL, NULL);
5488 rc = sc_pkcs11_register_mechanism(p11card, mt);
5489 if (rc != CKR_OK)
5490 return rc;
5491
5492 /* We support PKCS1 padding in software */
5493 /* either the card supports it or OpenSC does */
5494 rsa_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
5495 #ifdef ENABLE_OPENSSL
5496 rsa_flags |= SC_ALGORITHM_RSA_PAD_PSS;
5497 #endif
5498 }
... then later ...
5576 if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) {
5577 mech_info.flags &= ~(CKF_DECRYPT|CKF_ENCRYPT);
5578 mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL);
5579 rc = sc_pkcs11_register_mechanism(p11card, mt);
Only one card card-sc-hsm.c
says it can support both SC_ALGORITHM_RSA_RAW
and SC_ALGORITHM_RSA_PAD_PSS
on the card:
611 flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN;
card-sc-hsm.c
executes both parts of framework-pkcs11.c
above and registers CKM_RSA_PKCS_PSS
and the PSS should be done on the card. (A pkcs11-spy and opensc-debug.log) would show which one is actually used.)
card-openpgp.c
does not support SC_ALGORITHM_RSA_RAW
or SC_ALGORITHM_RSA_PAD_PSS
so does not register any PSS mechanisms.
PIV supports SC_ALGORITHM_RSA_RAW
so CKA_RSA_X_509
and CKM_RSA_PKCS_PSS
get registered. and if CKM_RSA_PKCS_PSS
is used, the OpenSC padding will do the padding. (A pkcs11-spy and opensc-debug.log) would show which one is actually used.)
I agree.
@dengert Could you please make it clearer what/who you agree with?
Only one card
card-sc-hsm.c
says it can support bothSC_ALGORITHM_RSA_RAW
andSC_ALGORITHM_RSA_PAD_PSS
on the card
At least one other card - YubiHSM2 - does support SC_ALGORITHM_RSA_PAD_PSS
on the card. At the same time (for security reasons) it does not support SC_ALGORITHM_RSA_RAW
. This card does not have a special driver, and works fine with the PIV driver.
Also, this support we're talking about - it's not what the actual card reports, but what the driver thinks the card he's controlling should support, right?
A pkcs11-spy and opensc-debug.log) would show which one is actually used.
Both were attached here. And they seem to indicate that only RSA-PSS was tried (feel free to correct me if I'm wrong here).
Also:
For Yubikey NEO PIV applet (though I'm very sure the token itself does not do RSA-PSS, so it must be the software assist that's handling the PSS padding)
$ pkcs11-tool -M
Using slot 0 with a present token (0x0)
Supported mechanisms:
SHA-1, digest
SHA224, digest
SHA256, digest
SHA384, digest
SHA512, digest
MD5, digest
RIPEMD160, digest
GOSTR3411, digest
ECDSA, keySize={256,256}, hw, sign, other flags=0x1800000
ECDH1-COFACTOR-DERIVE, keySize={256,256}, hw, derive, other flags=0x1800000
ECDH1-DERIVE, keySize={256,256}, hw, derive, other flags=0x1800000
RSA-X-509, keySize={1024,3072}, hw, decrypt, sign, verify
RSA-PKCS, keySize={1024,3072}, hw, decrypt, sign, verify
SHA1-RSA-PKCS, keySize={1024,3072}, sign, verify
SHA224-RSA-PKCS, keySize={1024,3072}, sign, verify
SHA256-RSA-PKCS, keySize={1024,3072}, sign, verify
SHA384-RSA-PKCS, keySize={1024,3072}, sign, verify
SHA512-RSA-PKCS, keySize={1024,3072}, sign, verify
MD5-RSA-PKCS, keySize={1024,3072}, sign, verify
RIPEMD160-RSA-PKCS, keySize={1024,3072}, sign, verify
RSA-PKCS-PSS, keySize={1024,3072}, hw, sign, verify
SHA1-RSA-PKCS-PSS, keySize={1024,3072}, sign, verify
SHA224-RSA-PKCS-PSS, keySize={1024,3072}, sign, verify
SHA256-RSA-PKCS-PSS, keySize={1024,3072}, sign, verify
SHA384-RSA-PKCS-PSS, keySize={1024,3072}, sign, verify
SHA512-RSA-PKCS-PSS, keySize={1024,3072}, sign, verify
$
For Yubikey NEO OpenPGP applet
$ OPENSC_DRIVER=openpgp pkcs11-tool -L
Available slots:
Slot 0 (0x0): Yubico Yubikey NEO OTP+U2F+CCID
token label : User PIN (OpenPGP)
token manufacturer : Yubico
token model : PKCS#15 emulated
token flags : login required, rng, token initialized, PIN initialized
hardware version : 2.0
firmware version : 2.0
serial num : 0006038xxxxx
pin min/max : 6/127
Slot 1 (0x1): Yubico Yubikey NEO OTP+U2F+CCID
token label : User PIN (sig) (OpenPGP)
token manufacturer : Yubico
token model : PKCS#15 emulated
token flags : login required, rng, token initialized, PIN initialized
hardware version : 2.0
firmware version : 2.0
serial num : 0006038xxx
pin min/max : 6/127
$ OPENSC_DRIVER=openpgp pkcs11-tool -M
Using slot 0 with a present token (0x0)
Supported mechanisms:
SHA-1, digest
SHA224, digest
SHA256, digest
SHA384, digest
SHA512, digest
MD5, digest
RIPEMD160, digest
GOSTR3411, digest
RSA-PKCS, keySize={2048,2048}, hw, decrypt, sign, verify
SHA1-RSA-PKCS, keySize={2048,2048}, sign, verify
SHA224-RSA-PKCS, keySize={2048,2048}, sign, verify
SHA256-RSA-PKCS, keySize={2048,2048}, sign, verify
SHA384-RSA-PKCS, keySize={2048,2048}, sign, verify
SHA512-RSA-PKCS, keySize={2048,2048}, sign, verify
MD5-RSA-PKCS, keySize={2048,2048}, sign, verify
RIPEMD160-RSA-PKCS, keySize={2048,2048}, sign, verify
RSA-PKCS-KEY-PAIR-GEN, keySize={2048,2048}, generate_key_pair
$ OPENSC_DRIVER=openpgp pkcs11-tool --slot 0x1 -M
Supported mechanisms:
SHA-1, digest
SHA224, digest
SHA256, digest
SHA384, digest
SHA512, digest
MD5, digest
RIPEMD160, digest
GOSTR3411, digest
RSA-PKCS, keySize={2048,2048}, hw, decrypt, sign, verify
SHA1-RSA-PKCS, keySize={2048,2048}, sign, verify
SHA224-RSA-PKCS, keySize={2048,2048}, sign, verify
SHA256-RSA-PKCS, keySize={2048,2048}, sign, verify
SHA384-RSA-PKCS, keySize={2048,2048}, sign, verify
SHA512-RSA-PKCS, keySize={2048,2048}, sign, verify
MD5-RSA-PKCS, keySize={2048,2048}, sign, verify
RIPEMD160-RSA-PKCS, keySize={2048,2048}, sign, verify
RSA-PKCS-KEY-PAIR-GEN, keySize={2048,2048}, generate_key_pair
$
It is obviously possible that the module only supports
CKM_RSA_PKCS
, so neitherCKM_RSA_PKCS_PSS
norCKM_RSA_X_509
can be used
@mtrojnar but CKM_RSA_X_509
was not tried, as you can see in the log.
I agreed with @mtrojnar And just to show the sc-hsm mechanisms supported via hardware or software:
./pkcs11-tool -M
Using slot 0 with a present token (0x0)
Supported mechanisms:
SHA-1, digest
SHA224, digest
SHA256, digest
SHA384, digest
SHA512, digest
MD5, digest
RIPEMD160, digest
GOSTR3411, digest
ECDSA, keySize={192,521}, hw, sign, other flags=0x1d00000
ECDSA-SHA1, keySize={192,521}, hw, sign, other flags=0x1d00000
ECDH1-COFACTOR-DERIVE, keySize={192,521}, hw, derive, other flags=0x1d00000
ECDH1-DERIVE, keySize={192,521}, hw, derive, other flags=0x1d00000
ECDSA-KEY-PAIR-GEN, keySize={192,521}, hw, generate_key_pair, other flags=0x1d00000
RSA-X-509, keySize={1024,4096}, hw, decrypt, sign, verify
RSA-PKCS, keySize={1024,4096}, hw, decrypt, sign, verify
SHA1-RSA-PKCS, keySize={1024,4096}, sign, verify
SHA224-RSA-PKCS, keySize={1024,4096}, sign, verify
SHA256-RSA-PKCS, keySize={1024,4096}, sign, verify
SHA384-RSA-PKCS, keySize={1024,4096}, sign, verify
SHA512-RSA-PKCS, keySize={1024,4096}, sign, verify
MD5-RSA-PKCS, keySize={1024,4096}, sign, verify
RIPEMD160-RSA-PKCS, keySize={1024,4096}, sign, verify
RSA-PKCS-PSS, keySize={1024,4096}, hw, sign, verify
SHA1-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
SHA224-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
SHA256-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
SHA384-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
SHA512-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
RSA-PKCS-KEY-PAIR-GEN, keySize={1024,4096}, generate_key_pair
And it looks like OpenSC is setting the "hw" flag correctly on mechanisms that are supported on the card correctly in all 3 cases.
@mouse07410 The limitation of the NEO with OpenPGP is not due to the token, but dueto the OpenPGP applet and the OpenPGP standards.
The limitation of the NEO with OpenPGP is not due to the token, but due to the OpenPGP applet and the OpenPGP standards
So, you think there's nothing reasonable that libp11
(or OpenSSL) could do to make RSA-PSS working with RSA keys from OpenPGP applet... OK. I may not like it, but I'll have to live with it.
Correct. There is no way to implement PSS padding with only PKCS1 padding provided by the module.
There is no way to implement PSS padding with only PKCS1 padding provided by the module.
I guess my confusion stems from the fact that somehow something between OpenSSL and libp11 figures out that Yubikey NEO PIV applet cannot do PSS on the token, and applies PSS padding in software. But it (whatever "it" may be) cannot do the same with the OpenPGP applet on the same token, and requests only straight PSS from the token, which the token is incapable of.
I hoped I explained it quite clearly in https://github.com/OpenSC/libp11/issues/266#issuecomment-449659569...
Well, I must be dense, but I'm afraid I still don't get it. According to your explanation
We decide it in libp11. We first try CKM_RSA_PKCS_PSS, and if it fails we let OpenSSL apply the padding and use CKM_RSA_X_509 (raw RSA)
In case of OpenPGP applet I see the code tried PKCS_PSS, it failed - but the log did not show the subsequent attempt to try X_509. (I guess I will do the SPY over the PIV trial to see how the exchange differs.)
The fact is, both PKCS1 and PSS paddings seem to work ok for PIV keys on both "dumb" tokens (like Yubikey NEO) that only do RSA raw (and maybe PKCS1 but I doubt that), and YubiHSM2 that only does PSS and PKCS1 on the token but no RSA raw.
Somehow, RSA keys in the PIV applet are treated different from those in the OpenPGP applet - and I don't understand why. (Not that I desperately need that capability with OpenPGP keys, but I dislike feeling dumb and puzzled ;)
This is the failed PSS request:
29: C_SignInit 2018-12-23 08:36:28.533
[in] hsession = 0x7fb932512630
pMechanism->type=CKM_RSA_PKCS_PSS
pMechanism->pParameter->hashAlg=CKM_SHA384
pMechanism->pParameter->mgf=CKG_MGF1_SHA384
pMechanism->pParameter->sLen=206
[in] hKey = 0x7fb932431b80
Returned: 112 CKR_MECHANISM_INVALID
This is the failed raw RSA request:
30: C_SignInit 2018-12-23 08:36:28.533
[in] hSession = 0x7fb932512630
pMechanism->type=CKM_RSA_X_509
[in] hKey = 0x7fb932431b80
Returned: 112 CKR_MECHANISM_INVALID
If your question is "Why my module does not support raw RSA?" then I really don't know, and I don't think this is the right forum to ask this questions. The libp11 project doesn't develop PKCS#11 modules.
This is the failed raw RSA request...
Ah, I missed that. Silly me! (And I thought I examined the SPY output carefully... Oh well...)
If your question is "Why my module does not support raw RSA?" then I really don't know...
Oh no, that I didn't want to ask. If the token doesn't support raw RSA (e.g., because OpenPGP applet doesn't), that's a totally different story.
I got my answer - libp11
did try RSA_X_509
after PSS
failed, and the token refused. Now it is indeed crystal clear.
Thank you for bearing with me. Happy Holidays!
I upgraded the YubiHSM2 SDK, and was running an old(er) test-script. To my surprise, it failed on OAEP decryption:
Puzzled, I changed
openssl rsautl
toopenssl pkeyutl
, and it worked:But looking at the code in
p11_rsa.c
, I noticed that it doesn't seem to accept OAEP paddings (all the support for it is inp11_pkey.c
):Should anything be done about it? I know that
rsautl
used to work a few months ago... Since then bothlibp11
andOpenSC
evolved somewhat, and there were some additions for PSS and OAEP support in OpenSC...