Skip to content
File

Blob: src/workerd/api/node/crypto.h

cpp604 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4#pragma once
5 
6#include <workerd/api/crypto/crypto.h>
7#include <workerd/api/crypto/dh.h>
8#include <workerd/api/crypto/digest.h>
9#include <workerd/api/crypto/x509.h>
10#include <workerd/jsg/jsg.h>
11#include <workerd/jsg/jsvalue.h>
12 
13#include <ncrypto/aead.h>
14 
15namespace workerd::api::node {
16 
17class CryptoImpl final: public jsg::Object {
18 public:
19 // DH
20 class DiffieHellmanHandle final: public jsg::Object {
21 public:
22 DiffieHellmanHandle(DiffieHellman dh);
23 
24 static jsg::Ref<DiffieHellmanHandle> constructor(jsg::Lock& js,
25 kj::OneOf<kj::Array<kj::byte>, int> sizeOrKey,
26 kj::OneOf<kj::Array<kj::byte>, int> generator);
27 
28 void setPrivateKey(kj::Array<kj::byte> key);
29 void setPublicKey(kj::Array<kj::byte> key);
30 jsg::JsUint8Array getPublicKey(jsg::Lock& js);
31 jsg::JsUint8Array getPrivateKey(jsg::Lock& js);
32 jsg::JsUint8Array getGenerator(jsg::Lock& js);
33 jsg::JsUint8Array getPrime(jsg::Lock& js);
34 jsg::JsUint8Array computeSecret(jsg::Lock& js, kj::Array<kj::byte> key);
35 jsg::JsUint8Array generateKeys(jsg::Lock& js);
36 int getVerifyError();
37 
38 JSG_RESOURCE_TYPE(DiffieHellmanHandle) {
39 JSG_METHOD(setPublicKey);
40 JSG_METHOD(setPrivateKey);
41 JSG_METHOD(getPublicKey);
42 JSG_METHOD(getPrivateKey);
43 JSG_METHOD(getGenerator);
44 JSG_METHOD(getPrime);
45 JSG_METHOD(computeSecret);
46 JSG_METHOD(generateKeys);
47 JSG_METHOD(getVerifyError);
48 };
49 
50 private:
51 DiffieHellman dh;
52 int verifyError;
53 };
54 
55 jsg::Ref<DiffieHellmanHandle> DiffieHellmanGroupHandle(jsg::Lock& js, kj::String name);
56 
57 jsg::JsUint8Array statelessDH(
58 jsg::Lock& js, jsg::Ref<CryptoKey> privateKey, jsg::Ref<CryptoKey> publicKey);
59 
60 // Primes
61 jsg::JsArrayBuffer randomPrime(jsg::Lock& js,
62 uint32_t size,
63 bool safe,
64 jsg::Optional<kj::Array<kj::byte>> add,
65 jsg::Optional<kj::Array<kj::byte>> rem);
66 bool checkPrimeSync(kj::Array<kj::byte> bufferView, uint32_t num_checks);
67 
68 // Hash
69 class HashHandle final: public jsg::Object {
70 public:
71 HashHandle(HashContext ctx): ctx(kj::mv(ctx)) {}
72 
73 static jsg::Ref<HashHandle> constructor(
74 jsg::Lock& js, kj::String algorithm, kj::Maybe<uint32_t> xofLen);
75 static jsg::JsUint8Array oneshot(
76 jsg::Lock&, kj::String algorithm, kj::Array<kj::byte> data, kj::Maybe<uint32_t> xofLen);
77 
78 jsg::Ref<HashHandle> copy(jsg::Lock& js, kj::Maybe<uint32_t> xofLen);
79 int update(kj::Array<kj::byte> data);
80 jsg::JsUint8Array digest(jsg::Lock& js);
81 
82 JSG_RESOURCE_TYPE(HashHandle) {
83 JSG_METHOD(update);
84 JSG_METHOD(digest);
85 JSG_METHOD(copy);
86 JSG_STATIC_METHOD(oneshot);
87 };
88 
89 void visitForMemoryInfo(jsg::MemoryTracker& tracker) const;
90 
91 private:
92 HashContext ctx;
93 };
94 
95 // Hmac
96 class HmacHandle final: public jsg::Object {
97 public:
98 using KeyParam = kj::OneOf<kj::Array<kj::byte>, jsg::Ref<CryptoKey>>;
99 
100 HmacHandle(HmacContext ctx): ctx(kj::mv(ctx)) {};
101 
102 static jsg::Ref<HmacHandle> constructor(jsg::Lock& js, kj::String algorithm, KeyParam key);
103 
104 // Efficiently implement one-shot HMAC that avoids multiple calls
105 // across the C++/JS boundary.
106 static jsg::JsUint8Array oneshot(
107 jsg::Lock& js, kj::String algorithm, KeyParam key, kj::Array<kj::byte> data);
108 
109 int update(kj::Array<kj::byte> data);
110 jsg::JsUint8Array digest(jsg::Lock& js);
111 
112 JSG_RESOURCE_TYPE(HmacHandle) {
113 JSG_METHOD(update);
114 JSG_METHOD(digest);
115 JSG_STATIC_METHOD(oneshot);
116 };
117 
118 void visitForMemoryInfo(jsg::MemoryTracker& tracker) const;
119 
120 private:
121 HmacContext ctx;
122 };
123 
124 // Hkdf
125 jsg::JsArrayBuffer getHkdf(jsg::Lock& js,
126 kj::String hash,
127 kj::Array<const kj::byte> key,
128 kj::Array<const kj::byte> salt,
129 kj::Array<const kj::byte> info,
130 uint32_t length);
131 
132 // Pbkdf2
133 jsg::JsArrayBuffer getPbkdf(jsg::Lock& js,
134 kj::Array<const kj::byte> password,
135 kj::Array<const kj::byte> salt,
136 uint32_t num_iterations,
137 uint32_t keylen,
138 kj::String name);
139 
140 // Scrypt
141 jsg::JsArrayBuffer getScrypt(jsg::Lock& js,
142 kj::Array<const kj::byte> password,
143 kj::Array<const kj::byte> salt,
144 uint32_t N,
145 uint32_t r,
146 uint32_t p,
147 uint32_t maxmem,
148 uint32_t keylen);
149 
150 // Keys
151 struct KeyExportOptions {
152 jsg::Optional<kj::String> type;
153 jsg::Optional<kj::String> format;
154 jsg::Optional<kj::String> cipher;
155 jsg::Optional<kj::Array<kj::byte>> passphrase;
156 JSG_STRUCT(type, format, cipher, passphrase);
157 };
158 
159 struct GenerateKeyPairOptions {
160 jsg::Optional<uint32_t> modulusLength;
161 jsg::Optional<uint64_t> publicExponent;
162 jsg::Optional<kj::String> hashAlgorithm;
163 jsg::Optional<kj::String> mgf1HashAlgorithm;
164 jsg::Optional<uint32_t> saltLength;
165 jsg::Optional<uint32_t> divisorLength;
166 jsg::Optional<kj::String> namedCurve;
167 jsg::Optional<kj::Array<kj::byte>> prime;
168 jsg::Optional<uint32_t> primeLength;
169 jsg::Optional<uint32_t> generator;
170 jsg::Optional<kj::String> groupName;
171 jsg::Optional<kj::String> paramEncoding; // one of either 'named' or 'explicit'
172 jsg::Optional<KeyExportOptions> publicKeyEncoding;
173 jsg::Optional<KeyExportOptions> privateKeyEncoding;
174 
175 JSG_STRUCT(modulusLength,
176 publicExponent,
177 hashAlgorithm,
178 mgf1HashAlgorithm,
179 saltLength,
180 divisorLength,
181 namedCurve,
182 prime,
183 primeLength,
184 generator,
185 groupName,
186 paramEncoding,
187 publicKeyEncoding,
188 privateKeyEncoding);
189 };
190 
191 struct CreateAsymmetricKeyOptions {
192 kj::OneOf<jsg::JsRef<jsg::JsBufferSource>, SubtleCrypto::JsonWebKey, jsg::Ref<api::CryptoKey>>
193 key;
194 kj::String format;
195 jsg::Optional<kj::String> type;
196 jsg::Optional<jsg::JsRef<jsg::JsBufferSource>> passphrase;
197 // The passphrase is only used for private keys. The format, type, and passphrase
198 // options are only used if the key is a kj::Array<kj::byte>.
199 JSG_STRUCT(key, format, type, passphrase);
200 };
201 
202 CryptoImpl() = default;
203 CryptoImpl(jsg::Lock&, const jsg::Url&) {}
204 
205 kj::OneOf<kj::String, jsg::JsArrayBuffer, SubtleCrypto::JsonWebKey> exportKey(
206 jsg::Lock& js, jsg::Ref<CryptoKey> key, jsg::Optional<KeyExportOptions> options);
207 
208 bool equals(jsg::Lock& js, jsg::Ref<CryptoKey> key, jsg::Ref<CryptoKey> otherKey);
209 
210 CryptoKey::AsymmetricKeyDetails getAsymmetricKeyDetail(jsg::Lock& js, jsg::Ref<CryptoKey> key);
211 kj::StringPtr getAsymmetricKeyType(jsg::Lock& js, jsg::Ref<CryptoKey> key);
212 
213 jsg::Ref<CryptoKey> createSecretKey(jsg::Lock& js, jsg::JsBufferSource keyData);
214 jsg::Ref<CryptoKey> createPrivateKey(jsg::Lock& js, CreateAsymmetricKeyOptions options);
215 jsg::Ref<CryptoKey> createPublicKey(jsg::Lock& js, CreateAsymmetricKeyOptions options);
216 static kj::Maybe<ncrypto::EVPKeyPointer> tryGetKey(jsg::Ref<CryptoKey>& key);
217 static kj::Maybe<kj::ArrayPtr<const kj::byte>> tryGetSecretKeyData(jsg::Ref<CryptoKey>& key);
218 
219 struct RsaKeyPairOptions {
220 kj::String type;
221 uint32_t modulusLength;
222 uint32_t publicExponent;
223 jsg::Optional<uint32_t> saltLength;
224 jsg::Optional<kj::String> hashAlgorithm;
225 jsg::Optional<kj::String> mgf1HashAlgorithm;
226 JSG_STRUCT(type, modulusLength, publicExponent, saltLength, hashAlgorithm, mgf1HashAlgorithm);
227 };
228 
229 struct DsaKeyPairOptions {
230 uint32_t modulusLength;
231 jsg::Optional<uint32_t> divisorLength;
232 JSG_STRUCT(modulusLength, divisorLength);
233 };
234 
235 struct EcKeyPairOptions {
236 kj::String namedCurve;
237 kj::String paramEncoding;
238 JSG_STRUCT(namedCurve, paramEncoding);
239 };
240 
241 struct EdKeyPairOptions {
242 kj::String type;
243 JSG_STRUCT(type);
244 };
245 
246 struct DhKeyPairOptions {
247 kj::OneOf<jsg::JsRef<jsg::JsBufferSource>, uint32_t, kj::String> primeOrGroup;
248 jsg::Optional<uint32_t> generator;
249 JSG_STRUCT(primeOrGroup, generator);
250 };
251 
252 CryptoKeyPair generateRsaKeyPair(jsg::Lock& js, RsaKeyPairOptions options);
253 CryptoKeyPair generateDsaKeyPair(jsg::Lock& js, DsaKeyPairOptions options);
254 CryptoKeyPair generateEcKeyPair(jsg::Lock& js, EcKeyPairOptions options);
255 CryptoKeyPair generateEdKeyPair(jsg::Lock& js, EdKeyPairOptions options);
256 CryptoKeyPair generateDhKeyPair(jsg::Lock& js, DhKeyPairOptions options);
257 
258 // Sign/Verify
259 class SignHandle final: public jsg::Object {
260 public:
261 SignHandle(ncrypto::EVPMDCtxPointer ctx);
262 static jsg::Ref<SignHandle> constructor(jsg::Lock& js, kj::String algorithm);
263 
264 void update(jsg::Lock& js, jsg::JsBufferSource data);
265 jsg::JsUint8Array sign(jsg::Lock& js,
266 jsg::Ref<CryptoKey> key,
267 jsg::Optional<int> rsaPadding,
268 jsg::Optional<int> pssSaltLength,
269 jsg::Optional<int> dsaSigEnc);
270 
271 JSG_RESOURCE_TYPE(SignHandle) {
272 JSG_METHOD(update);
273 JSG_METHOD(sign);
274 }
275 
276 private:
277 ncrypto::EVPMDCtxPointer ctx;
278 };
279 class VerifyHandle final: public jsg::Object {
280 public:
281 VerifyHandle(ncrypto::EVPMDCtxPointer ctx);
282 static jsg::Ref<VerifyHandle> constructor(jsg::Lock& js, kj::String algorithm);
283 
284 void update(jsg::Lock& js, jsg::JsBufferSource data);
285 bool verify(jsg::Lock& js,
286 jsg::Ref<CryptoKey> key,
287 jsg::JsBufferSource signature,
288 jsg::Optional<int> rsaPadding,
289 jsg::Optional<int> pssSaltLength,
290 jsg::Optional<int> dsaSigEnc);
291 
292 JSG_RESOURCE_TYPE(VerifyHandle) {
293 JSG_METHOD(update);
294 JSG_METHOD(verify);
295 }
296 
297 private:
298 ncrypto::EVPMDCtxPointer ctx;
299 };
300 
301 jsg::JsUint8Array signOneShot(jsg::Lock& js,
302 jsg::Ref<CryptoKey> key,
303 jsg::Optional<kj::String> algorithm,
304 jsg::JsBufferSource data,
305 jsg::Optional<int> rsaPadding,
306 jsg::Optional<int> pssSaltLength,
307 jsg::Optional<int> dsaSigEnc);
308 bool verifyOneShot(jsg::Lock& js,
309 jsg::Ref<CryptoKey> key,
310 jsg::Optional<kj::String> algorithm,
311 jsg::JsBufferSource data,
312 jsg::JsBufferSource signature,
313 jsg::Optional<int> rsaPadding,
314 jsg::Optional<int> pssSaltLength,
315 jsg::Optional<int> dsaSigEnc);
316 
317 // Cipher/Decipher
318 enum class CipherMode { CIPHER, DECIPHER };
319 class CipherHandle final: public jsg::Object {
320 public:
321 struct AuthenticatedInfo {
322 unsigned int auth_tag_len = 0;
323 unsigned int max_message_size = INT_MAX;
324 };
325 
326 CipherHandle(CipherMode mode,
327 ncrypto::CipherCtxPointer ctx,
328 jsg::Ref<CryptoKey> key,
329 kj::Array<kj::byte> iv,
330 kj::Maybe<AuthenticatedInfo> maybeAuthInfo);
331 
332 static jsg::Ref<CipherHandle> construct(jsg::Lock& js,
333 CipherMode mode,
334 kj::StringPtr algorithm,
335 ncrypto::Cipher cipher,
336 jsg::Ref<CryptoKey> key,
337 jsg::JsBufferSource iv,
338 jsg::Optional<uint32_t> maybeAuthTagLength);
339 
340 jsg::JsUint8Array update(jsg::Lock& js, jsg::JsBufferSource data);
341 jsg::JsUint8Array final(jsg::Lock& js);
342 void setAAD(
343 jsg::Lock& js, jsg::JsBufferSource aad, jsg::Optional<uint32_t> maybePlaintextLength);
344 void setAutoPadding(jsg::Lock& js, bool autoPadding);
345 void setAuthTag(jsg::Lock& js, jsg::JsBufferSource authTag);
346 jsg::JsUint8Array getAuthTag(jsg::Lock& js);
347 
348 JSG_RESOURCE_TYPE(CipherHandle) {
349 JSG_METHOD(update);
350 JSG_METHOD(final);
351 JSG_METHOD(setAAD);
352 JSG_METHOD(setAutoPadding);
353 JSG_METHOD(setAuthTag);
354 JSG_METHOD(getAuthTag);
355 };
356 
357 private:
358 CipherMode mode;
359 ncrypto::CipherCtxPointer ctx;
360 jsg::Ref<CryptoKey> key;
361 kj::Array<kj::byte> iv;
362 kj::Maybe<kj::Array<kj::byte>> maybeAuthTag;
363 kj::Maybe<AuthenticatedInfo> maybeAuthInfo;
364 bool authTagPassed = false;
365 bool pendingAuthFailed = false;
366 };
367 
368 /*
369 * AeadHandle implements a public interface matching CipherHandle, based on the BoringSSL-specific
370 * EVP_AEAD API instead of the EVP_CIPHER API.
371 *
372 * It's essential to note that BoringSSL's EVP_AEAD API is *one-shot*, and will encrypt or decrypt
373 * the entire ciphertext at once, and doesn't provide support for streaming operations. This is
374 * for good reason, as it prevents a dangerous mistake from being made. Consider a decryption
375 * operation: While it's technically possible to begin streaming chunks of decrypted data, it
376 * is not safe to act on any of the data until the entire message is decrypted, validated and
377 * released. If any part of the message is invalid, all of that decrypted data must be discarded.
378 *
379 * As a result, it's only possible to call update() once when using an AEAD algorithm, followed
380 * by final(). If using the streaming interface, it is permitted to either call write() once
381 * followed by end() without data; or to call end() once with a chunk of data.
382 *
383 * This restriction applies for certain algorithms even in the original NodeJS implementation
384 * backed by OpenSSL. For example, see the note in the original documentation about CCM modes
385 * of operation: <https://nodejs.org/api/crypto.html#ccm-mode>
386 *
387 * However, in our implementation, this restriction applies for *all* AEAD algorithms, which
388 * differs from the behaviour of NodeJS.
389 *
390 * In principle, it's possible to allow multiple update() calls if required for a particular use
391 * case, by buffering all the data supplied in memory, then invoking BoringSSL when final() is
392 * called. This might not be as troubling as it sounds, as AEADs are usually used to protect
393 * reasonably-sized messages used by an application, and aren't used to handle large quantities
394 * of data. However, this is not yet implemented, until we see a convincing use case.
395 */
396 class AeadHandle final: public jsg::Object {
397 public:
398 struct AuthenticatedInfo {
399 unsigned int auth_tag_len = 0;
400 unsigned int max_message_size = INT_MAX;
401 };
402 
403 AeadHandle(CipherMode mode,
404 ncrypto::Aead aead,
405 ncrypto::AeadCtxPointer ctx,
406 jsg::Ref<CryptoKey> key,
407 kj::Array<kj::byte> iv,
408 kj::Maybe<AuthenticatedInfo> maybeAuthInfo);
409 
410 static jsg::Ref<AeadHandle> construct(jsg::Lock& js,
411 CipherMode mode,
412 kj::StringPtr algorithm,
413 ncrypto::Aead aead,
414 jsg::Ref<CryptoKey> key,
415 jsg::JsBufferSource iv,
416 jsg::Optional<uint32_t> maybeAuthTagLength);
417 
418 jsg::JsUint8Array update(jsg::Lock& js, jsg::JsBufferSource data);
419 jsg::JsUint8Array final(jsg::Lock& js);
420 void setAAD(
421 jsg::Lock& js, jsg::JsBufferSource aad, jsg::Optional<uint32_t> maybePlaintextLength);
422 void setAutoPadding(jsg::Lock&, bool);
423 void setAuthTag(jsg::Lock& js, jsg::JsBufferSource authTag);
424 jsg::JsUint8Array getAuthTag(jsg::Lock& js);
425 
426 JSG_RESOURCE_TYPE(AeadHandle) {
427 JSG_METHOD(update);
428 JSG_METHOD(final);
429 JSG_METHOD(setAAD);
430 JSG_METHOD(setAutoPadding);
431 JSG_METHOD(setAuthTag);
432 JSG_METHOD(getAuthTag);
433 };
434 
435 private:
436 CipherMode mode;
437 ncrypto::Aead aead;
438 ncrypto::AeadCtxPointer ctx;
439 jsg::Ref<CryptoKey> key;
440 kj::Array<kj::byte> iv;
441 kj::Maybe<kj::Array<kj::byte>> maybeAuthTag;
442 kj::Maybe<AuthenticatedInfo> maybeAuthInfo;
443 kj::Maybe<kj::Array<kj::byte>> maybeAad;
444 bool updated = false;
445 };
446 
447 kj::OneOf<jsg::Ref<CipherHandle>, jsg::Ref<AeadHandle>> newHandle(jsg::Lock& js,
448 kj::uint mode,
449 kj::String algorithm,
450 jsg::Ref<CryptoKey> key,
451 jsg::JsBufferSource iv,
452 jsg::Optional<uint32_t> maybeAuthTagLength);
453 
454 struct PublicPrivateCipherOptions {
455 int padding;
456 kj::String oaepHash;
457 jsg::Optional<jsg::JsRef<jsg::JsBufferSource>> oaepLabel;
458 JSG_STRUCT(padding, oaepHash, oaepLabel);
459 };
460 
461 jsg::JsUint8Array publicEncrypt(jsg::Lock& js,
462 jsg::Ref<CryptoKey> key,
463 jsg::JsBufferSource buffer,
464 PublicPrivateCipherOptions options);
465 jsg::JsUint8Array publicDecrypt(jsg::Lock& js,
466 jsg::Ref<CryptoKey> key,
467 jsg::JsBufferSource buffer,
468 PublicPrivateCipherOptions options);
469 jsg::JsUint8Array privateEncrypt(jsg::Lock& js,
470 jsg::Ref<CryptoKey> key,
471 jsg::JsBufferSource buffer,
472 PublicPrivateCipherOptions options);
473 jsg::JsUint8Array privateDecrypt(jsg::Lock& js,
474 jsg::Ref<CryptoKey> key,
475 jsg::JsBufferSource buffer,
476 PublicPrivateCipherOptions options);
477 
478 struct CipherInfo {
479 kj::String name;
480 int nid;
481 jsg::Optional<int> blockSize;
482 jsg::Optional<int> ivLength;
483 int keyLength;
484 kj::String mode; // 'cbc', 'ccm', 'cfb', 'ctr', 'ecb', 'gcm', 'ocb',
485 // 'ofb', 'stream', 'wrap', 'xts'
486 JSG_STRUCT(name, nid, blockSize, ivLength, keyLength, mode)
487 };
488 
489 struct GetCipherInfoOptions {
490 jsg::Optional<int> keyLength;
491 jsg::Optional<int> ivLength;
492 JSG_STRUCT(keyLength, ivLength);
493 };
494 
495 jsg::Optional<CipherInfo> getCipherInfo(
496 kj::OneOf<kj::String, int> nameOrNid, GetCipherInfoOptions options);
497 
498 kj::ArrayPtr<kj::StringPtr> getCiphers();
499 
500 // SPKAC
501 bool verifySpkac(kj::Array<const kj::byte> input);
502 kj::Maybe<jsg::JsUint8Array> exportPublicKey(jsg::Lock& js, kj::Array<const kj::byte> input);
503 kj::Maybe<jsg::JsUint8Array> exportChallenge(jsg::Lock& js, kj::Array<const kj::byte> input);
504 
505 // ECDH
506 class ECDHHandle final: public jsg::Object {
507 public:
508 ECDHHandle(ncrypto::ECKeyPointer key);
509 static jsg::Ref<ECDHHandle> constructor(jsg::Lock& js, kj::String curveName);
510 
511 static jsg::JsUint8Array convertKey(
512 jsg::Lock& js, jsg::JsBufferSource key, kj::String curveName, kj::String format);
513 
514 jsg::JsUint8Array computeSecret(jsg::Lock& js, jsg::JsBufferSource otherPublicKey);
515 void generateKeys();
516 jsg::JsUint8Array getPrivateKey(jsg::Lock& js);
517 jsg::JsUint8Array getPublicKey(jsg::Lock& js, kj::String format);
518 void setPrivateKey(jsg::Lock& js, jsg::JsBufferSource key);
519 
520 JSG_RESOURCE_TYPE(ECDHHandle) {
521 JSG_STATIC_METHOD(convertKey);
522 JSG_METHOD(computeSecret);
523 JSG_METHOD(generateKeys);
524 JSG_METHOD(getPrivateKey);
525 JSG_METHOD(getPublicKey);
526 JSG_METHOD(setPrivateKey);
527 }
528 
529 private:
530 ncrypto::ECKeyPointer key_;
531 const EC_GROUP* group_;
532 };
533 
534 JSG_RESOURCE_TYPE(CryptoImpl) {
535 // DH
536 JSG_NESTED_TYPE(DiffieHellmanHandle);
537 JSG_METHOD(DiffieHellmanGroupHandle);
538 JSG_METHOD(statelessDH);
539 // ECDH
540 JSG_NESTED_TYPE(ECDHHandle);
541 // Primes
542 JSG_METHOD(randomPrime);
543 JSG_METHOD(checkPrimeSync);
544 // Hash and Hmac
545 JSG_NESTED_TYPE(HashHandle);
546 JSG_NESTED_TYPE(HmacHandle);
547 // Hkdf
548 JSG_METHOD(getHkdf);
549 // Pbkdf2
550 JSG_METHOD(getPbkdf);
551 // Scrypt
552 JSG_METHOD(getScrypt);
553 // Keys
554 JSG_METHOD(exportKey);
555 JSG_METHOD(equals);
556 JSG_METHOD(getAsymmetricKeyDetail);
557 JSG_METHOD(getAsymmetricKeyType);
558 JSG_METHOD(createSecretKey);
559 JSG_METHOD(createPrivateKey);
560 JSG_METHOD(createPublicKey);
561 // Spkac
562 JSG_METHOD(verifySpkac);
563 JSG_METHOD(exportPublicKey);
564 JSG_METHOD(exportChallenge);
565 // X509
566 JSG_NESTED_TYPE(X509Certificate);
567 // Key generation
568 JSG_METHOD(generateRsaKeyPair);
569 JSG_METHOD(generateDsaKeyPair);
570 JSG_METHOD(generateEcKeyPair);
571 JSG_METHOD(generateEdKeyPair);
572 JSG_METHOD(generateDhKeyPair);
573 // Sign/Verify
574 JSG_NESTED_TYPE(SignHandle);
575 JSG_NESTED_TYPE(VerifyHandle);
576 JSG_METHOD(signOneShot);
577 JSG_METHOD(verifyOneShot);
578 // Cipher/Decipher
579 JSG_NESTED_TYPE(CipherHandle);
580 JSG_NESTED_TYPE(AeadHandle);
581 JSG_METHOD(newHandle);
582 JSG_METHOD(publicEncrypt);
583 JSG_METHOD(publicDecrypt);
584 JSG_METHOD(privateEncrypt);
585 JSG_METHOD(privateDecrypt);
586 JSG_METHOD(getCipherInfo);
587 JSG_METHOD(getCiphers);
588 }
589};
590 
591#define EW_NODE_CRYPTO_ISOLATE_TYPES \
592 api::node::CryptoImpl, api::node::CryptoImpl::DiffieHellmanHandle, \
593 api::node::CryptoImpl::HashHandle, api::node::CryptoImpl::HmacHandle, \
594 api::node::CryptoImpl::KeyExportOptions, api::node::CryptoImpl::GenerateKeyPairOptions, \
595 api::node::CryptoImpl::CreateAsymmetricKeyOptions, api::node::CryptoImpl::RsaKeyPairOptions, \
596 api::node::CryptoImpl::DsaKeyPairOptions, api::node::CryptoImpl::EcKeyPairOptions, \
597 api::node::CryptoImpl::EdKeyPairOptions, api::node::CryptoImpl::DhKeyPairOptions, \
598 api::node::CryptoImpl::SignHandle, api::node::CryptoImpl::VerifyHandle, \
599 api::node::CryptoImpl::CipherHandle, api::node::CryptoImpl::PublicPrivateCipherOptions, \
600 api::node::CryptoImpl::CipherInfo, api::node::CryptoImpl::GetCipherInfoOptions, \
601 api::node::CryptoImpl::ECDHHandle, api::node::CryptoImpl::AeadHandle, \
602 EW_CRYPTO_X509_ISOLATE_TYPES
603} // namespace workerd::api::node