From 53a0bdff47699382e098ff99f656da5d85eb05dd Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sun, 10 Jan 2021 07:53:01 -0800 Subject: crypto: experimental (Ed/X)25519/(Ed/X)448 support Implements initial experimental support for Curve25519 and Curve448 support for both ECDH and sign/verify in Web Crypto. Introduced as a Node.js-specific extension to Web Crypto. Signed-off-by: James M Snell Fixes: https://github.com/nodejs/node/issues/36076 PR-URL: https://github.com/nodejs/node/pull/36879 Reviewed-By: Filip Skokan --- doc/api/webcrypto.md | 101 ++++++- lib/internal/crypto/diffiehellman.js | 3 +- lib/internal/crypto/ec.js | 233 ++++++++++++---- lib/internal/crypto/util.js | 8 +- lib/internal/crypto/webcrypto.js | 31 ++- src/crypto/crypto_ecdh.cc | 308 ++++++++++++++++----- src/crypto/crypto_ecdh.h | 15 +- src/crypto/crypto_keygen.h | 3 +- src/crypto/crypto_keys.cc | 50 ++++ src/crypto/crypto_keys.h | 1 + src/crypto/crypto_sig.cc | 82 ++++-- src/env.h | 2 + test/parallel/test-webcrypto-ed25519-ed448.js | 367 ++++++++++++++++++++++++++ test/parallel/test-webcrypto-x25519-x448.js | 246 +++++++++++++++++ tools/doc/type-parser.js | 4 + 15 files changed, 1287 insertions(+), 167 deletions(-) create mode 100644 test/parallel/test-webcrypto-ed25519-ed448.js create mode 100644 test/parallel/test-webcrypto-x25519-x448.js diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index ce9999a744f..c238d32fd71 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -65,6 +65,26 @@ async function generateEcKey(namedCurve = 'P-521') { } ``` +#### ED25519/ED448/X25519/X448 Elliptic curve key pairs + +```js +const { subtle } = require('crypto').webcrypto; + +async function generateEd25519Key() { + return subtle.generateKey({ + name: 'NODE-ED25519', + namedCurve: 'NODE-ED25519', + }, true, ['sign', 'verify']); +} + +async function generateX25519Key() { + return subtle.generateKey({ + name: 'ECDH', + namedCurve: 'NODE-X25519', + }, true, ['deriveKey']); +} +``` + #### HMAC keys ```js @@ -305,6 +325,8 @@ implementation and the APIs supported for each: | `'SHA-512'` | | | | | | | | | | | | ✔ | | `'NODE-DSA'`1 | ✔ | ✔ | ✔ | | | | | | | ✔ | ✔ | | | `'NODE-DH'`1 | ✔ | ✔ | ✔ | | | | | ✔ | ✔ | | | | +| `'NODE-ED25519'`1 | ✔ | ✔ | ✔ | | | | | | | ✔ | ✔ | | +| `'NODE-ED448'`1 | ✔ | ✔ | ✔ | | | | | | | ✔ | ✔ | | 1 Node.js-specific extension @@ -420,6 +442,8 @@ Valid key usages depend on the key algorithm (identified by | `'NODE-DSA'` 1 | | | ✔ | ✔ | | | | | | `'NODE-DH'` 1 | | | | | ✔ | ✔ | | | | `'NODE-SCRYPT'` 1 | | | | | ✔ | ✔ | | | +| `'NODE-ED25519'` 1 | | | ✔ | ✔ | | | | | +| `'NODE-ED448'` 1 | | | ✔ | ✔ | | | | | 1 Node.js-specific extension. @@ -620,6 +644,8 @@ extension that allows converting a {CryptoKey} into a Node.js {KeyObject}. | `'NODE-DSA'` 1 | ✔ | ✔ | ✔ | | | `'NODE-DH'` 1 | ✔ | ✔ | | | | `'NODE-SCRYPT'` 1 | | | | | +| `'NODE-ED25519'` 1 | ✔ | ✔ | ✔ | ✔ | +| `'NODE-ED448'` 1 | ✔ | ✔ | ✔ | ✔ | 1 Node.js-specific extension @@ -629,7 +655,7 @@ added: v15.0.0 --> -* `algorithm`: {RsaHashedKeyGenParams|EcKeyGenParams|HmacKeyGenParams|AesKeyGenParams|NodeDsaKeyGenParams|NodeDhKeyGenParams} +* `algorithm`: {RsaHashedKeyGenParams|EcKeyGenParams|HmacKeyGenParams|AesKeyGenParams|NodeDsaKeyGenParams|NodeDhKeyGenParams|NodeEdKeyGenParams} * `extractable`: {boolean} * `keyUsages`: {string[]} See [Key usages][]. @@ -649,6 +675,8 @@ include: * `'ECDH'` * `'NODE-DSA'` 1 * `'NODE-DH'` 1 +* `'NODE-ED25519'` 1 +* `'NODE-ED448'` 1 The {CryptoKey} (secret key) generating algorithms supported include: @@ -669,7 +697,7 @@ added: v15.0.0 `node.keyObject`. * `keyData`: {ArrayBuffer|TypedArray|DataView|Buffer|KeyObject} -* `algorithm`: {RsaHashedImportParams|EcKeyImportParams|HmacImportParams|AesImportParams|Pbkdf2ImportParams|NodeDsaImportParams|NodeDhImportParams|NodeScryptImportParams} +* `algorithm`: {RsaHashedImportParams|EcKeyImportParams|HmacImportParams|AesImportParams|Pbkdf2ImportParams|NodeDsaImportParams|NodeDhImportParams|NodeScryptImportParams|NodeEdKeyImportParams} * `extractable`: {boolean} * `keyUsages`: {string[]} See [Key usages][]. @@ -704,6 +732,8 @@ The algorithms currently supported include: | `'NODE-DSA'` 1 | ✔ | ✔ | ✔ | | | `'NODE-DH'` 1 | ✔ | ✔ | | | | `'NODE-SCRYPT'` 1 | | | | ✔ | +| `'NODE-ED25519'` 1 | ✔ | ✔ | ✔ | ✔ | +| `'NODE-ED448'` 1 | ✔ | ✔ | ✔ | ✔ | 1 Node.js-specific extension @@ -731,6 +761,8 @@ The algorithms currently supported include: * `'ECDSA'` * `'HMAC'` * `'NODE-DSA'`1 +* `'NODE-ED25519'`1 +* `'NODE-ED448'`1 1 Non-standadrd Node.js extension @@ -809,6 +841,8 @@ The algorithms currently supported include: * `'ECDSA'` * `'HMAC'` * `'NODE-DSA'`1 +* `'NODE-ED25519'`1 +* `'NODE-ED448'`1 1 Non-standard Node.js extension @@ -1062,7 +1096,8 @@ added: v15.0.0 added: v15.0.0 --> -* Type: {string} Must be one of `'P-256'`, `'P-384'` or `'P-521'`. +* Type: {string} Must be one of `'P-256'`, `'P-384'`, `'P-521'`, + `'NODE-ED25519'`, `'NODE-ED448'`, `'NODE-X25519'`, or `'NODE-X448'`. ### Class: `EcKeyImportParams` -* Type: {string} Must be one of `'P-256'`, `'P-384'` or `'P-521'`. +* Type: {string} Must be one of `'P-256'`, `'P-384'`, `'P-521'`, + `'NODE-ED25519'`, `'NODE-ED448'`, `'NODE-X25519'`, or `'NODE-X448'`. ### Class: `HkdfParams` + +#### Class: `NodeEdKeyGenParams` + + +##### `nodeEdKeyGenParams.name` + + +* Type: {string} Must be one of `'NODE-ED25519'`, `'NODE-ED448'` or `'ECDH'`. + +##### `nodeEdKeyGenParams.namedCurve` + + +* Type: {string} Must be one of `'NODE-ED25519'`, `'NODE-ED448'`, + `'NODE-X25519'`, or `'NODE-X448'`. + +#### Class: `NodeEdKeyImportParams` + + +##### `nodeEdKeyImportParams.name` + + +* Type: {string} Must be one of `'NODE-ED25519'` or `'NODE-ED448'` + if importing an `Ed25519` or `Ed448` key, or `'ECDH'` if importing + an `X25519` or `X448` key. + +##### `nodeEdKeyImportParams.namedCurve` + + +* Type: {string} Must be one of `'NODE-ED25519'`, `'NODE-ED448'`, + `'NODE-X25519'`, or `'NODE-X448'`. + +##### `nodeEdKeyImportParams.public` + + +* Type: {boolean} + +The `public` parameter is used to specify that the key is to be interpreted +as a public key. + ### `NODE-SCRYPT` Algorithm