Using Nitrokey Pro with OpenSC for EC keys operation

Hello,

I’m a developer working on an embedded Linux environment to implement a solution to use ECC with the Nitrokey Pro token.

Currently we’re using the following libraries to work with the token:

  • opensc 0.20
  • pcsc-lite 1.8.25
  • ccid 1.4.31

When trying to generate a new EC keypair with pkcs11-tool I get the following error:

$ pkcs11-tool --keypairgen --key-type EC:prime256v1
Using slot 0 with a present token (0x0)
error: Generate EC key mechanism not supported

Aborting.

Here is the token information reported by the pkcs11-tool

$ pkcs11-tool -T
Available slots:
Slot 0 (0x0): Nitrokey Nitrokey Pro (000000000000000000007EEB) 00 00
  token label        : OpenPGP card (User PIN)
  token manufacturer : ZeitControl
  token model        : PKCS#15 emulated
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 3.3
  firmware version   : 3.3
  serial num         : 000500007eeb
  pin min/max        : 6/64
Slot 1 (0x1): Nitrokey Nitrokey Pro (000000000000000000007EEB) 00 00
  token label        : OpenPGP card (User PIN (sig))
  token manufacturer : ZeitControl
  token model        : PKCS#15 emulated
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 3.3
  firmware version   : 3.3
  serial num         : 000500007eeb
  pin min/max        : 6/64

From the list of mechanisms it seems that EC is not supported at all. But I’m not sure if this is a HW or library/driver limitation.

$ 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

Have anyone tried to use Nitrokey Pro with OpenSC to confirm that everything I see is correct or not?
What is the actual issue with missing ECC functionality: software (library version or whatever) or hardware (wrong token version)?

We need to support EC keypair generation inside the token and deriving shared secret from the EC private key.

I appreciate any help.

Thanks

Hi @avr1985!

Take a look at OpenSC#2020. Potentially it is already supported, but commented out to avoid backward compatibility issues. We plan to test it in the coming days, but in case you would do so earlier please let me know.

Edit: H/W definitely supports ECC (e.g. with GnuPG or pkcs15-tool)

Thanks for the quick response!
I have tried using the pkcs15-init as you’ve suggested and it worked for me.
I have also tried modification for the pkcs11-tool (removed the condition inside card-openpgp.c) but it still does not work.

$ pkcs11-tool -l --login-type so --so-pin 12345678 --keypairgen --key-type EC:secp384r1 --id 03
Using slot 0 with a present token (0x0)
error: PKCS11 function C_GenerateKeyPair failed: rv = CKR_GENERAL_ERROR (0x5)
Aborting.

BTW I also tried generating RSA keypair, which also does not seem to be functional. I have found the following note in the guide from here (https://github.com/OpenSC/OpenSC/wiki/OpenPGP-card):
Note : Generating key via PKCS#11 is not supported yet. Technical reason: The operation needs Admin PIN, but we find no way in OpenSC to popup a prompt dialog for PIN entry.
Not sure if this is true at the moment (maybe the article is too old?)

Thanks again!

Thank you for testing! Will confirm and update the ticket with new logs.
About the cited fragment - nice catch. I will ask maintainers about this.

In case you have not seen it: I found a post, which suggest changing the slot attributes with GnuPG first as a workaround: