-
Notifications
You must be signed in to change notification settings - Fork 803
Description
Problem Description
These are comments while experimenting with OpenPGP on a Nitro Start (GUNK) and a Yubikey 5 NFC and OpenSSL 3.1.2 generated MONTGOMERY keys and OpenSC 0.24.0-rc2. The Nitro and Yubikey initialized using GnuPG 2.2.7 gpg-card command.
Running derive commands between any two of the above produce the same generic secret key as expected.
Example using Yubikey token and the Nitro public key with output to YK10-Nitro.der:
/opt/ossl-3.1.2/bin/pkcs11-tool --slot 0 --module /opt/ossl-3.1.2/lib/opensc-pkcs11.so \
-l --slot 0 --derive -m ECDH1-DERIVE -O -d 2 -i /tmp/derive.509765.other.pubkey.der -o YK10-Nitro.der
Example of OpenSSL private key and the Nitro public key:
openssl pkeyutl -derive -keyform der -inkey openssl.pkey.der -peerform der \
-peerkey NitroStart.pubkey.02.der > openssl-Nitro.der
The problem stems from curve "friendly" names and OIDs used by different programs, RFCs and other documents.
OpenSSL is following RFC 8410 using "OBJECT IDENTIFIER ::= { 1 3 101 110 }" I
gpg-card uses "cv25519" as algorithm and does not list the OID.
OpenPGP Card Specification 3.4.1 appears to be the latest, but it does says anything about Edwards or Montgomery curves.
Internally the Yubikey and Nitro store on card C2 0B 12 2B 06 01 04 01 97 55 01 05 01 in the DO 6E. Labeled "Algorithm attributes decryption" which is: Blob 'C2', length '0B', algorithm '12' and OID (minus the tag and length) '2B 06 01 04 01 97 55 01 05 01'
This problem of inconsistent names and OIDs is known. and pkcs11-curr-v3.0-os) says:
"Montgomery EC public keys only support the use of the curveName selection to specify a curve name as defined in [RFC7748] and the use of the oID selection to specify a curve through an ECDH algorithm as defined in [RFC 8410]. Note that keys defined by RFC 7748 and RFC 8410 are incompatible."
Proposed Resolution
Since OpenSSL uses RFC 8410 and the OID 1.3.101.110 OpenSC should go with this OID. The OID 1.3.6.1.4.1.3029.1.5.1 appears to be a vendor's invented OID which is really used within the Yubikey and GNUK applets. OpenSC could continue to support the vendor's OID, but should favor the use of OID 1.3.101.110 and map this internally as needed.
Edwards curves have similar issues. RFC 8410 defines "id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }"
where as OpenSC is using the vendor's OID of 1.3.6.1.4.1.11591.15.1
(But OpenSSH is following RFC 8731 which is referring to RFC 7748.)
OpenSC 0.24.0-rc2 has some changes in pkcs11-tool .c to allow passing in a "printable string" or an OID as defined in PKCS11 3.0 but it is not complete.
Comments
I have also been working on code changes to OpenSC PKCS11 to support C_GenerateKeyPair for CKK_EC_MONTGOMERY and CKK_EC_EDWARDS in the openpgp code. So far I have been able to generate a CKK_EC_MONTGOMERY on the card
but the card-openpgp.c does not handle the public key correctly as EC keys have a leading 04 where as these key do not.
Also have some changes to pkcs11-tool.c