Open Rtlagot opened 4 years ago
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.
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.
@Fizbanoide both of these statements can be true:
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:
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
Alright, thanks for the answer, I'll check with Thales first to see if I can get any sample.
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 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.
I assume it doesn't like the hex mechanism with out some additional code changes.
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
I opened issue #144 to solve the mechanism problem
@zosocanuck I published the new version. Please try graphene-pk11@2.2.2
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();
@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'));
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 ?