Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ed25519 Support #123

Open
Rtlagot opened this issue Jan 29, 2020 · 11 comments
Open

Ed25519 Support #123

Rtlagot opened this issue Jan 29, 2020 · 11 comments

Comments

@Rtlagot
Copy link

Rtlagot commented Jan 29, 2020

Hello,
I'd like to use this lib to first generate a Ed25519 keypair on HSM. I know that OpenSSL currently supports Ed25519, but i can't find it in the list of curve names here. Is there any way to create a keypair with Ed25519 ?

@rmhrisk
Copy link
Contributor

rmhrisk commented Jan 29, 2020

There is not a standard ed25519 way to do ed25519 via PKCS11 yet. Are you sure your smartcard or HSM supports it?

What is your devices make and model?

Does their documentation say they support it?

Do they provide a sample? If so can you share it?

With more info we may be able to help.

@Rtlagot
Copy link
Author

Rtlagot commented Jan 29, 2020

It is the Thales Luna 7 Network HSM, and it's clearly specified in the product presentation that it supports the PKCS11 API and the Ed25519 cryptography.

Unfortunately they don't provide a sample to start with.

@rmhrisk
Copy link
Contributor

rmhrisk commented Jan 29, 2020

@Fizbanoide both of these statements can be true:

  1. It supports the PKCS11 API, and
  2. It supports Ed25519.

But the union of those does not mean that PKCS#11 defines how to do ed25519 via PKCS#11 which the current version of the specification does not.

This means that each vendor, should it wish to support ed25519 via PKCS#11 will do so via proprietary extensions to PKCS#11.

As a result, no common code that works cross-vendor can be made that works with this capability, it also means that we can not look at the PKCS#11 public specification to see how to implement the logic.

It is possible in most cases to use propietary mechanisms such as the ones we are discussing via graphene, however without:

  • documentation (for constant values, etc),
  • sample (for how to produce the appropriate sequence of calls in a way the device will accept).

There is not much we can do; I personally would love to see ed25519 in P11, and, see it work in graphene; but without the above assets there is not much we can do.

If you have a support contract with the vendor I would ask for a sample, they will provide it.

Ryan

@Rtlagot
Copy link
Author

Rtlagot commented Jan 30, 2020

Alright, thanks for the answer, I'll check with Thales first to see if I can get any sample.

@Rtlagot Rtlagot closed this as completed Jan 30, 2020
@Rtlagot
Copy link
Author

Rtlagot commented Mar 3, 2020

I found a way to generate keypairs using the curve25519 with the Thales Luna 7 Network HSM and sign some data with it. Here is the code :

var keys = session.generateKeyPair(0x80000c01, { 
    token: true,
    private: false,
    encrypt: false,
    verify: true,
    derive: false,
    paramsECDSA: graphene.NamedCurve.getByName("curve25519").value,
    modifiable: false,
    label: "Generated EC Edwards pubK"
    }, { 
    token: true, 
    private: false,
    sensitive: true,
    decrypt: false,
    sign: true,
    derive: false,
    modifiable: false, 
    extractable: false,
    label: "Generated EC Edwards privK" 
});
var sign = session.createSign(0x80000c03, keys.privateKey);
sign.update("simple text 1");
sign.update("simple text 2");
var signature = sign.final();
console.log("Signature :", signature.toString("hex")); 

// verify content
var verify = session.createVerify(0x80000c03, keys.publicKey);
verify.update("simple text 1");
verify.update("simple text 2");
var verify_result = verify.final(signature);

I had to use the hexadecimal code for the mechanisms because they are not implemented so far on the 2.4 version of PKCS11.

@zosocanuck
Copy link

I found a way to generate keypairs using the curve25519 with the Thales Luna 7 Network HSM and sign some data with it. Here is the code :

var keys = session.generateKeyPair(0x80000c01, { 
    token: true,
    private: false,
    encrypt: false,
    verify: true,
    derive: false,
    paramsECDSA: graphene.NamedCurve.getByName("curve25519").value,
    modifiable: false,
    label: "Generated EC Edwards pubK"
    }, { 
    token: true, 
    private: false,
    sensitive: true,
    decrypt: false,
    sign: true,
    derive: false,
    modifiable: false, 
    extractable: false,
    label: "Generated EC Edwards privK" 
});
var sign = session.createSign(0x80000c03, keys.privateKey);
sign.update("simple text 1");
sign.update("simple text 2");
var signature = sign.final();
console.log("Signature :", signature.toString("hex")); 

// verify content
var verify = session.createVerify(0x80000c03, keys.publicKey);
verify.update("simple text 1");
verify.update("simple text 2");
var verify_result = verify.final(signature);

I had to use the hexadecimal code for the mechanisms because they are not implemented so far on the 2.4 version of PKCS11.

I attempted this code today with a Luna 7 and got the following error:

`workspaces/micronaut-devcontainer/graphene/node_modules/graphene-pk11/build/cjs/session.js:193
throw e;
^

TypeError: Cannot read property 'toUpperCase' of undefined
at Function.create (/workspaces/micronaut-devcontainer/graphene/node_modules/graphene-pk11/build/cjs/mech.js:48:57)
at Session.generateKeyPair (/workspaces/micronaut-devcontainer/graphene/node_modules/graphene-pk11/build/cjs/session.js:155:44)
at Object. (/workspaces/micronaut-devcontainer/graphene/test.js:10:20)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at internal/main/run_main_module.js:17:47`

I assume it doesn't like the hex mechanism with out some additional code changes.

@rmhrisk rmhrisk reopened this May 1, 2021
@microshine
Copy link
Contributor

0x80000c01 is a vendor mechanism. You need to register that mechanism in graphene first.

Mechanism.vendor("CustomName", 0x80000c01);

But I think it's an issue. graphene must work with a direct mechanism value

@microshine
Copy link
Contributor

I opened issue #144 to solve the mechanism problem

@microshine
Copy link
Contributor

@zosocanuck I published the new version. Please try [email protected]

@sonkkeli
Copy link

sonkkeli commented Dec 2, 2022

For the ones running into this same issue, one can use raw values like this to support ed25519 signing using graphene:

Also note that update() is not supported for ed25519 keys and signing has to be done once only.

And SoftHSM2 needs to be configured and compiled locally with the following flags:
./configure --with-openssl=/usr/lib/ssl --enable-eddsa=yes

// https://github.com/opendnssec/SoftHSMv2/blob/35938595f83923504751b40535570342f706a634/src/lib/pkcs11/pkcs11.h#L405
const CKK_EC_EDWARDS = 0x40;
 
// https://github.com/opendnssec/SoftHSMv2/blob/35938595f83923504751b40535570342f706a634/src/lib/pkcs11/pkcs11.h#L888
const CKM_EC_EDWARDS_KEY_PAIR_GEN = 0x1055;
 
// https://github.com/opendnssec/SoftHSMv2/blob/35938595f83923504751b40535570342f706a634/src/lib/pkcs11/pkcs11.h#L809
const CKM_EDDSA = 0x1057;
 
// https://github.com/opendnssec/SoftHSMv2/blob/35938595f83923504751b40535570342f706a634/src/lib/crypto/OSSLUtil.cpp#L190
const NAMED_CURVE_FOR_EDWARDS_25519 = Buffer.from("130C656477617264733235353139", "hex"); 

var keys = session.generateKeyPair(
    CKM_EC_EDWARDS_KEY_PAIR_GEN,
    {
      keyType: CKK_EC_EDWARDS,
      token: true,
      private: false,
      encrypt: false,
      verify: true,
      derive: false,
      paramsEC: NAMED_CURVE_FOR_EDWARDS_25519,
      modifiable: false,
      label: "Generated EC Edwards pubK",
    },
    {
      keyType: CKK_EC_EDWARDS,
      token: true,
      private: false,
      sensitive: true,
      decrypt: false,
      sign: true,
      derive: false,
      modifiable: false,
      extractable: false,
      label: "Generated EC Edwards privK",
    }
  );
 
  // sign content
  const dataToSign = "helloworld";
  var sign = session.createSign(CKM_EDDSA, keys.privateKey);
  var signature = sign.once(dataToSign);
 
  // verify content
  var verify = session.createVerify(CKM_EDDSA, keys.publicKey);
  var verify_result = verify.once(dataToSign, signature);
  console.log("Signature:", signature.toString("hex"), " isVerified= ", verify_result);
 
  session.logout();
  session.close();
  

@PadaliaIsha
Copy link

@sonkkeli, your code is working and I get keypair using the ed25519 algo. But can I get this key in Solana blockchain keypair format? Below is the code.

            const pkcs11PublicKey = keys.publicKey.toString('hex'); // Convert to string
            const publicKeyBytes = Buffer.from(pkcs11PublicKey, 'hex');
            console.log(publicKeyBytes.toString('utf8'));
            const publicKey = publicKeyBytes.slice(1); // Remove the first byte (0x40)
            // console.log(publicKeyBytes.toString('utf8'));

            // Convert PKCS11 private key to Solana readable form
            const pkcs11PrivateKey = keys.privateKey.toString('hex'); // Convert to string
            const privateKeyBytes = Buffer.from(pkcs11PrivateKey, 'hex');
            const privateKey = privateKeyBytes.slice(1); // Remove the first byte (0x40)

            console.log(privateKeyBytes.toString('utf8'));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants