Nitrokey / nitrokey-start-firmware

A mirror of Gnuk's 1.0.x and 1.2.x branches.
56 stars 15 forks source link

PKCS #11 ECDSA mechanism / Bitcoin transaction signing #19

Closed roshii closed 5 years ago

roshii commented 5 years ago

Considering Nitrokey Start does support ECC (with scep256k1 curve specifically), I assume ECDSA could be added to the list of supported PKCS # 11 mechanism, isn't it?

Only RSA signature are available at the moment:

$ pkcs11-tool --slot 1 -M
Supported mechanisms:
  SHA-1, 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
  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
roshii commented 5 years ago

I am just reading that the above is most likely due to OpenSC not supporting EC operations (version 0.19). Nevertheless, I'd be happy to know if Nitrokey Start / Gnuk would allow for ECDSA over scep256k1, without salting or hashing input data.

szszszsz commented 5 years ago

Hi! If you have any command, I would be happy to provide the listing. Will output of pkcs11-tool --slot 1 -M help you?

roshii commented 5 years ago

Hi, Thanks for the feedback but I am not sure to fully understand, I will therefore explain my goals in more details. I do have a Nitrokey Start with latest firmware and loaded with an EC key on scep256k1 for signing. I want to use it to sign raw bitcoin transaction, that is raw binary data that should remain untouched before signing (no salt, no hash). As far as I understand, that would require both OpenSC and Nitrokey Start (Gnuk) to support ECDSA mechanism in the broader PKCS11 scheme.

Will output of pkcs11-tool --slot 1 -M help you?

That is indeed the very first command I ran, but I see no mention of ECDSA in its output as you can see in my first post. Note that I am running OpenSC 0.19

Considering the above, I guess either Gnuk or OpenSC doesn't handle ECDSA at the moment. Am I having a correct analyses or am I missing something?

szszszsz commented 5 years ago

I am sorry - I have somehow misread you do not have Nitrokey Start device, but asking for the output for it on supplied command.

I remember the Gnuk's creator, on which Nitrokey Start is based, has worked on signing the Bitcoin transactions by himself. Let me quote mailing list:

In 2014, I extended the routines to support the curve of secp256k1. The intention was that Gnuk Token could be used for Bitcoin transactions (by developing a tool for that). And I proposed a way to publish a public key in OpenPGP format, so that people can make sure a Bitcoin address belongs to a person.

I do not know though have results been published (I expect they have). I would check his test suite, and the older one for this feature. As for OpenSC - it has Bitcoin support merged based on the Nitrokey HSM - OpenSC#319. Perhaps you could try to ask on OpenSC ticket page regarding this.

You would need to use the provided Python library to use it then (as done in tests), if OpenSC is not supporting it directly.

szszszsz commented 5 years ago

According to NEWS page, secp256k1 is supported since 2016-05. It should be supported in the GnuPG as well. I do not know, how it looks like from the OpenSC side.

Edit: Support for this curve is also mentioned in the README, which I have missed initially.

roshii commented 5 years ago

This is very interesting, thank you.

It should be supported in the GnuPG as well.

It is indeed supported by GnuPG but after experimentation, I can confirm that it isn't suitable to sign Bitcoin transaction. As a matter of facts, GPG is salting and hashing input data before handing it over to the token for signature, breaking de facto Bitcoin signature protocol.

Anyhow, it seems clear that Gnuk does handle secp256k1 signature, thanks for pointing at the correct resources. I will therefore dig further to get to know what can be done with OpenSC and/or the Python library.

szszszsz commented 5 years ago

I see. Please let us know, if you would solve this. Leaving ticket open. @alex-nitrokey Any ideas?

alex-nitrokey commented 5 years ago

OpenSC will have rudimentary support for ECC by 0.20 which is not released yet, of course.

I did implement all I could think of needed for OpenPGP Card compatible devices, I could not fully test ECC though, as OpenSC does not have every ECC functionality implemented in the main part of the software.

In terms of secp256k1 I propbably need to disappoint you. The current implementation only includes the curves supported officially by the OpenPGP Card standard. The Nitrokey Start is far more flexible in terms of curves than the hardware implemented smart cards used in the other Nitrokeys. It is difficult to reflect that in OpenSC that expects standard conform devices.

alex-nitrokey commented 5 years ago

Thinking about it... It might be not that difficult to add support of curve25519 and secp256k1 for Nitrokey Start in OpenSC, but I guess the missing general support for handling ECC properly in OpenSC mean that this won't be included in 0.20 yet and will need some time.

alex-nitrokey commented 5 years ago

I opened an issue https://github.com/OpenSC/OpenSC/issues/1715

roshii commented 5 years ago

The current implementation only includes the curves supported officially by the OpenPGP Card standard.

Right. OpenPGP Card standard is indeed vague when it comes to ECC curve support. From the optional ECDSA support, curves from SEC 2 (incl. secp256k1) and Brainpool working group are recommended. But only a few curves from these recommendation shall be supported by an OpenPGP smart card...

The Nitrokey Start is far more flexible in terms of curves than the hardware implemented smart cards used in the other Nitrokeys.

While playing around with the Python test library I understand that support for RSA is not depending on any external library. It also allows to extract secp256k1 pubkey straight forward from the Nitrokey Start. I was therefore wondering it this Python library could be extended to handle ECC directly (without pkcs11-tool)? Is there anything I can do to help implementing this? I have no experience with hardware programming but I do know cryptography

One last note for the record, Bitcoin transaction signing should work with a Nitrokey HSM since it is based on SmartCard-HSM and has been tested back in 2016. I unfortunately do not have such a Nitrokey to try that out, but it that happens to be confirmed Nitrokey-HSM could be easely added to the list of supported device for Bitcoin HWI

jans23 commented 5 years ago

I unfortunately do not have such a Nitrokey to try that out, but it that happens to be confirmed Nitrokey-HSM could be easely added to the list of supported device for Bitcoin HWI

If you could provide a patch to Bitcoin HWI, we are glad to provide you a Nitrokey HSM for free.

roshii commented 5 years ago

If you could provide a patch to Bitcoin HWI, we are glad to provide you a Nitrokey HSM for free.

I will dive into Bitcoin HWI to see how I can patch this correctly. I'll keep you up to date