GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_cipher.cc Lines: 484 526 92.0 %
Date: 2022-04-11 04:20:14 Branches: 322 422 76.3 %

Line Branch Exec Source
1
#include "crypto/crypto_cipher.h"
2
#include "crypto/crypto_util.h"
3
#include "allocated_buffer-inl.h"
4
#include "base_object-inl.h"
5
#include "env-inl.h"
6
#include "memory_tracker-inl.h"
7
#include "node_buffer.h"
8
#include "node_internals.h"
9
#include "node_process-inl.h"
10
#include "v8.h"
11
12
namespace node {
13
14
using v8::Array;
15
using v8::ArrayBuffer;
16
using v8::BackingStore;
17
using v8::FunctionCallbackInfo;
18
using v8::FunctionTemplate;
19
using v8::HandleScope;
20
using v8::Int32;
21
using v8::Local;
22
using v8::Object;
23
using v8::Uint32;
24
using v8::Value;
25
26
namespace crypto {
27
namespace {
28
4742
bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
29
4742
  switch (EVP_CIPHER_mode(cipher)) {
30
1857
  case EVP_CIPH_CCM_MODE:
31
  case EVP_CIPH_GCM_MODE:
32
#ifndef OPENSSL_NO_OCB
33
  case EVP_CIPH_OCB_MODE:
34
#endif
35
1857
    return true;
36
1747
  case EVP_CIPH_STREAM_CIPHER:
37
1747
    return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305;
38
1138
  default:
39
1138
    return false;
40
  }
41
}
42
43
2442
bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
44
2442
  const EVP_CIPHER* cipher = EVP_CIPHER_CTX_cipher(ctx);
45
2442
  return IsSupportedAuthenticatedMode(cipher);
46
}
47
48
66
bool IsValidGCMTagLength(unsigned int tag_len) {
49


66
  return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16);
50
}
51
52
// Collects and returns information on the given cipher
53
425
void GetCipherInfo(const FunctionCallbackInfo<Value>& args) {
54
425
  Environment* env = Environment::GetCurrent(args);
55
425
  CHECK(args[0]->IsObject());
56
850
  Local<Object> info = args[0].As<Object>();
57
58

982
  CHECK(args[1]->IsString() || args[1]->IsInt32());
59
60
  const EVP_CIPHER* cipher;
61
850
  if (args[1]->IsString()) {
62
586
    Utf8Value name(env->isolate(), args[1]);
63
293
    cipher = EVP_get_cipherbyname(*name);
64
  } else {
65
264
    int nid = args[1].As<Int32>()->Value();
66
132
    cipher = EVP_get_cipherbynid(nid);
67
  }
68
69
425
  if (cipher == nullptr)
70
7
    return;
71
72
423
  int mode = EVP_CIPHER_mode(cipher);
73
423
  int iv_length = EVP_CIPHER_iv_length(cipher);
74
423
  int key_length = EVP_CIPHER_key_length(cipher);
75
423
  int block_length = EVP_CIPHER_block_size(cipher);
76
423
  const char* mode_label = nullptr;
77



423
  switch (mode) {
78
86
    case EVP_CIPH_CBC_MODE: mode_label = "cbc"; break;
79
36
    case EVP_CIPH_CCM_MODE: mode_label = "ccm"; break;
80
96
    case EVP_CIPH_CFB_MODE: mode_label = "cfb"; break;
81
30
    case EVP_CIPH_CTR_MODE: mode_label = "ctr"; break;
82
42
    case EVP_CIPH_ECB_MODE: mode_label = "ecb"; break;
83
27
    case EVP_CIPH_GCM_MODE: mode_label = "gcm"; break;
84
25
    case EVP_CIPH_OCB_MODE: mode_label = "ocb"; break;
85
36
    case EVP_CIPH_OFB_MODE: mode_label = "ofb"; break;
86
33
    case EVP_CIPH_WRAP_MODE: mode_label = "wrap"; break;
87
6
    case EVP_CIPH_XTS_MODE: mode_label = "xts"; break;
88
6
    case EVP_CIPH_STREAM_CIPHER: mode_label = "stream"; break;
89
  }
90
91
  // If the testKeyLen and testIvLen arguments are specified,
92
  // then we will make an attempt to see if they are usable for
93
  // the cipher in question, returning undefined if they are not.
94
  // If they are, the info object will be returned with the values
95
  // given.
96

844
  if (args[2]->IsInt32() || args[3]->IsInt32()) {
97
    // Test and input IV or key length to determine if it's acceptable.
98
    // If it is, then the getCipherInfo will succeed with the given
99
    // values.
100
29
    CipherCtxPointer ctx(EVP_CIPHER_CTX_new());
101
29
    if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr, 1))
102
      return;
103
104
29
    if (args[2]->IsInt32()) {
105
4
      int check_len = args[2].As<Int32>()->Value();
106
2
      if (!EVP_CIPHER_CTX_set_key_length(ctx.get(), check_len))
107
1
        return;
108
1
      key_length = check_len;
109
    }
110
111
28
    if (args[3]->IsInt32()) {
112
54
      int check_len = args[3].As<Int32>()->Value();
113
      // For CCM modes, the IV may be between 7 and 13 bytes.
114
      // For GCM and OCB modes, we'll check by attempting to
115
      // set the value. For everything else, just check that
116
      // check_len == iv_length.
117
27
      switch (mode) {
118
9
        case EVP_CIPH_CCM_MODE:
119

9
          if (check_len < 7 || check_len > 13)
120
2
            return;
121
7
          break;
122
16
        case EVP_CIPH_GCM_MODE:
123
          // Fall through
124
        case EVP_CIPH_OCB_MODE:
125
16
          if (!EVP_CIPHER_CTX_ctrl(
126
                  ctx.get(),
127
                  EVP_CTRL_AEAD_SET_IVLEN,
128
                  check_len,
129
                  nullptr)) {
130
1
            return;
131
          }
132
15
          break;
133
2
        default:
134
2
          if (check_len != iv_length)
135
1
            return;
136
      }
137
23
      iv_length = check_len;
138
    }
139
  }
140
141
836
  if (mode_label != nullptr &&
142
418
      info->Set(
143
          env->context(),
144
          FIXED_ONE_BYTE_STRING(env->isolate(), "mode"),
145

2090
          OneByteString(env->isolate(), mode_label)).IsNothing()) {
146
    return;
147
  }
148
149
  // OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
150
  // EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
151
836
  if (info->Set(
152
          env->context(),
153
          env->name_string(),
154
          OneByteString(
155
            env->isolate(),
156
1672
            OBJ_nid2sn(EVP_CIPHER_nid(cipher)))).IsNothing()) {
157
    return;
158
  }
159
160
836
  if (info->Set(
161
          env->context(),
162
          FIXED_ONE_BYTE_STRING(env->isolate(), "nid"),
163
1672
          Int32::New(env->isolate(), EVP_CIPHER_nid(cipher))).IsNothing()) {
164
    return;
165
  }
166
167
  // Stream ciphers do not have a meaningful block size
168
830
  if (mode != EVP_CIPH_STREAM_CIPHER &&
169
418
      info->Set(
170
          env->context(),
171
          FIXED_ONE_BYTE_STRING(env->isolate(), "blockSize"),
172

2066
          Int32::New(env->isolate(), block_length)).IsNothing()) {
173
    return;
174
  }
175
176
  // Ciphers that do not use an IV shouldn't report a length
177
788
  if (iv_length != 0 &&
178
418
      info->Set(
179
          env->context(),
180
          FIXED_ONE_BYTE_STRING(env->isolate(), "ivLength"),
181

1898
          Int32::New(env->isolate(), iv_length)).IsNothing()) {
182
    return;
183
  }
184
185
836
  if (info->Set(
186
          env->context(),
187
          FIXED_ONE_BYTE_STRING(env->isolate(), "keyLength"),
188
1672
          Int32::New(env->isolate(), key_length)).IsNothing()) {
189
    return;
190
  }
191
192
836
  args.GetReturnValue().Set(info);
193
}
194
}  // namespace
195
196
1
void CipherBase::GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
197
1
  Environment* env = Environment::GetCurrent(args);
198
199
2
  SSLCtxPointer ctx(SSL_CTX_new(TLS_method()));
200
1
  CHECK(ctx);
201
202
2
  SSLPointer ssl(SSL_new(ctx.get()));
203
1
  CHECK(ssl);
204
205
1
  STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl.get());
206
207
  // TLSv1.3 ciphers aren't listed by EVP. There are only 5, we could just
208
  // document them, but since there are only 5, easier to just add them manually
209
  // and not have to explain their absence in the API docs. They are lower-cased
210
  // because the docs say they will be.
211
  static const char* TLS13_CIPHERS[] = {
212
    "tls_aes_256_gcm_sha384",
213
    "tls_chacha20_poly1305_sha256",
214
    "tls_aes_128_gcm_sha256",
215
    "tls_aes_128_ccm_8_sha256",
216
    "tls_aes_128_ccm_sha256"
217
  };
218
219
1
  const int n = sk_SSL_CIPHER_num(ciphers);
220
1
  std::vector<Local<Value>> arr(n + arraysize(TLS13_CIPHERS));
221
222
61
  for (int i = 0; i < n; ++i) {
223
60
    const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
224
120
    arr[i] = OneByteString(env->isolate(), SSL_CIPHER_get_name(cipher));
225
  }
226
227
6
  for (unsigned i = 0; i < arraysize(TLS13_CIPHERS); ++i) {
228
5
    const char* name = TLS13_CIPHERS[i];
229
10
    arr[n + i] = OneByteString(env->isolate(), name);
230
  }
231
232
2
  args.GetReturnValue().Set(Array::New(env->isolate(), arr.data(), arr.size()));
233
1
}
234
235
3
void CipherBase::GetCiphers(const FunctionCallbackInfo<Value>& args) {
236
3
  Environment* env = Environment::GetCurrent(args);
237
6
  MarkPopErrorOnReturn mark_pop_error_on_return;
238
3
  CipherPushContext ctx(env);
239
3
  EVP_CIPHER_do_all_sorted(
240
#if OPENSSL_VERSION_MAJOR >= 3
241
    array_push_back<EVP_CIPHER,
242
                    EVP_CIPHER_fetch,
243
                    EVP_CIPHER_free,
244
                    EVP_get_cipherbyname,
245
                    EVP_CIPHER_get0_name>,
246
#else
247
    array_push_back<EVP_CIPHER>,
248
#endif
249
    &ctx);
250
6
  args.GetReturnValue().Set(ctx.ToJSArray());
251
3
}
252
253
1483
CipherBase::CipherBase(Environment* env,
254
                       Local<Object> wrap,
255
1483
                       CipherKind kind)
256
    : BaseObject(env, wrap),
257
      ctx_(nullptr),
258
      kind_(kind),
259
      auth_tag_state_(kAuthTagUnknown),
260
      auth_tag_len_(kNoAuthTagLength),
261
1483
      pending_auth_failed_(false) {
262
1483
  MakeWeak();
263
1483
}
264
265
void CipherBase::MemoryInfo(MemoryTracker* tracker) const {
266
  tracker->TrackFieldWithSize("context", ctx_ ? kSizeOf_EVP_CIPHER_CTX : 0);
267
}
268
269
622
void CipherBase::Initialize(Environment* env, Local<Object> target) {
270
622
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
271
272
1244
  t->InstanceTemplate()->SetInternalFieldCount(
273
      CipherBase::kInternalFieldCount);
274
622
  t->Inherit(BaseObject::GetConstructorTemplate(env));
275
276
622
  env->SetProtoMethod(t, "init", Init);
277
622
  env->SetProtoMethod(t, "initiv", InitIv);
278
622
  env->SetProtoMethod(t, "update", Update);
279
622
  env->SetProtoMethod(t, "final", Final);
280
622
  env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding);
281
622
  env->SetProtoMethodNoSideEffect(t, "getAuthTag", GetAuthTag);
282
622
  env->SetProtoMethod(t, "setAuthTag", SetAuthTag);
283
622
  env->SetProtoMethod(t, "setAAD", SetAAD);
284
622
  env->SetConstructorFunction(target, "CipherBase", t);
285
286
622
  env->SetMethodNoSideEffect(target, "getSSLCiphers", GetSSLCiphers);
287
622
  env->SetMethodNoSideEffect(target, "getCiphers", GetCiphers);
288
289
622
  env->SetMethod(target, "publicEncrypt",
290
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
291
                                         EVP_PKEY_encrypt_init,
292
                                         EVP_PKEY_encrypt>);
293
622
  env->SetMethod(target, "privateDecrypt",
294
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
295
                                         EVP_PKEY_decrypt_init,
296
                                         EVP_PKEY_decrypt>);
297
622
  env->SetMethod(target, "privateEncrypt",
298
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
299
                                         EVP_PKEY_sign_init,
300
                                         EVP_PKEY_sign>);
301
622
  env->SetMethod(target, "publicDecrypt",
302
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
303
                                         EVP_PKEY_verify_recover_init,
304
                                         EVP_PKEY_verify_recover>);
305
306
622
  env->SetMethodNoSideEffect(target, "getCipherInfo", GetCipherInfo);
307
308
1866
  NODE_DEFINE_CONSTANT(target, kWebCryptoCipherEncrypt);
309
1244
  NODE_DEFINE_CONSTANT(target, kWebCryptoCipherDecrypt);
310
622
}
311
312
4982
void CipherBase::RegisterExternalReferences(
313
    ExternalReferenceRegistry* registry) {
314
4982
  registry->Register(New);
315
316
4982
  registry->Register(Init);
317
4982
  registry->Register(InitIv);
318
4982
  registry->Register(Update);
319
4982
  registry->Register(Final);
320
4982
  registry->Register(SetAutoPadding);
321
4982
  registry->Register(GetAuthTag);
322
4982
  registry->Register(SetAuthTag);
323
4982
  registry->Register(SetAAD);
324
325
4982
  registry->Register(GetSSLCiphers);
326
4982
  registry->Register(GetCiphers);
327
328
4982
  registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
329
                                             EVP_PKEY_encrypt_init,
330
                                             EVP_PKEY_encrypt>);
331
4982
  registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
332
                                             EVP_PKEY_decrypt_init,
333
                                             EVP_PKEY_decrypt>);
334
4982
  registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
335
                                             EVP_PKEY_sign_init,
336
                                             EVP_PKEY_sign>);
337
4982
  registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
338
                                             EVP_PKEY_verify_recover_init,
339
                                             EVP_PKEY_verify_recover>);
340
341
4982
  registry->Register(GetCipherInfo);
342
4982
}
343
344
1483
void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
345
1483
  CHECK(args.IsConstructCall());
346
1483
  Environment* env = Environment::GetCurrent(args);
347

2966
  new CipherBase(env, args.This(), args[0]->IsTrue() ? kCipher : kDecipher);
348
1483
}
349
350
907
void CipherBase::CommonInit(const char* cipher_type,
351
                            const EVP_CIPHER* cipher,
352
                            const unsigned char* key,
353
                            int key_len,
354
                            const unsigned char* iv,
355
                            int iv_len,
356
                            unsigned int auth_tag_len) {
357
907
  CHECK(!ctx_);
358
907
  ctx_.reset(EVP_CIPHER_CTX_new());
359
360
907
  const int mode = EVP_CIPHER_mode(cipher);
361
907
  if (mode == EVP_CIPH_WRAP_MODE)
362
29
    EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
363
364
907
  const bool encrypt = (kind_ == kCipher);
365
907
  if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
366
                             nullptr, nullptr, encrypt)) {
367
    return ThrowCryptoError(env(), ERR_get_error(),
368
                            "Failed to initialize cipher");
369
  }
370
371
907
  if (IsSupportedAuthenticatedMode(cipher)) {
372
679
    CHECK_GE(iv_len, 0);
373
679
    if (!InitAuthenticated(cipher_type, iv_len, auth_tag_len))
374
74
      return;
375
  }
376
377
833
  if (!EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len)) {
378
1
    ctx_.reset();
379
1
    return THROW_ERR_CRYPTO_INVALID_KEYLEN(env());
380
  }
381
382
832
  if (1 != EVP_CipherInit_ex(ctx_.get(), nullptr, nullptr, key, iv, encrypt)) {
383
    return ThrowCryptoError(env(), ERR_get_error(),
384
                            "Failed to initialize cipher");
385
  }
386
}
387
388
89
void CipherBase::Init(const char* cipher_type,
389
                      const ArrayBufferOrViewContents<unsigned char>& key_buf,
390
                      unsigned int auth_tag_len) {
391
89
  HandleScope scope(env()->isolate());
392
89
  MarkPopErrorOnReturn mark_pop_error_on_return;
393
#if OPENSSL_VERSION_MAJOR >= 3
394
89
  if (EVP_default_properties_is_fips_enabled(nullptr)) {
395
#else
396
  if (FIPS_mode()) {
397
#endif
398
    return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
399
        "crypto.createCipher() is not supported in FIPS mode.");
400
  }
401
402
89
  const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
403
89
  if (cipher == nullptr)
404
    return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
405
406
  unsigned char key[EVP_MAX_KEY_LENGTH];
407
  unsigned char iv[EVP_MAX_IV_LENGTH];
408
409
89
  int key_len = EVP_BytesToKey(cipher,
410
                               EVP_md5(),
411
                               nullptr,
412
                               key_buf.data(),
413
89
                               key_buf.size(),
414
                               1,
415
                               key,
416
89
                               iv);
417
89
  CHECK_NE(key_len, 0);
418
419
89
  const int mode = EVP_CIPHER_mode(cipher);
420

89
  if (kind_ == kCipher && (mode == EVP_CIPH_CTR_MODE ||
421
43
                           mode == EVP_CIPH_GCM_MODE ||
422
                           mode == EVP_CIPH_CCM_MODE)) {
423
    // Ignore the return value (i.e. possible exception) because we are
424
    // not calling back into JS anyway.
425
    ProcessEmitWarning(env(),
426
                       "Use Cipheriv for counter mode of %s",
427
24
                       cipher_type);
428
  }
429
430
89
  CommonInit(cipher_type, cipher, key, key_len, iv,
431
             EVP_CIPHER_iv_length(cipher), auth_tag_len);
432
}
433
434
89
void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
435
  CipherBase* cipher;
436
89
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
437
89
  Environment* env = Environment::GetCurrent(args);
438
439
89
  CHECK_GE(args.Length(), 3);
440
441
89
  const Utf8Value cipher_type(args.GetIsolate(), args[0]);
442
89
  ArrayBufferOrViewContents<unsigned char> key_buf(args[1]);
443
89
  if (!key_buf.CheckSizeInt32())
444
    return THROW_ERR_OUT_OF_RANGE(env, "password is too large");
445
446
  // Don't assign to cipher->auth_tag_len_ directly; the value might not
447
  // represent a valid length at this point.
448
  unsigned int auth_tag_len;
449
89
  if (args[2]->IsUint32()) {
450
70
    auth_tag_len = args[2].As<Uint32>()->Value();
451
  } else {
452

162
    CHECK(args[2]->IsInt32() && args[2].As<Int32>()->Value() == -1);
453
54
    auth_tag_len = kNoAuthTagLength;
454
  }
455
456
89
  cipher->Init(*cipher_type, key_buf, auth_tag_len);
457
}
458
459
1394
void CipherBase::InitIv(const char* cipher_type,
460
                        const ByteSource& key_buf,
461
                        const ArrayBufferOrViewContents<unsigned char>& iv_buf,
462
                        unsigned int auth_tag_len) {
463
1394
  HandleScope scope(env()->isolate());
464
1394
  MarkPopErrorOnReturn mark_pop_error_on_return;
465
466
1394
  const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
467
1394
  if (cipher == nullptr)
468
1
    return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
469
470
1393
  const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
471
1393
  const bool is_authenticated_mode = IsSupportedAuthenticatedMode(cipher);
472
1393
  const bool has_iv = iv_buf.size() > 0;
473
474
  // Throw if no IV was passed and the cipher requires an IV
475

1393
  if (!has_iv && expected_iv_len != 0)
476
61
    return THROW_ERR_CRYPTO_INVALID_IV(env());
477
478
  // Throw if an IV was passed which does not match the cipher's fixed IV length
479
  // static_cast<int> for the iv_buf.size() is safe because we've verified
480
  // prior that the value is not larger than MAX_INT.
481
695
  if (!is_authenticated_mode &&
482

2027
      has_iv &&
483
670
      static_cast<int>(iv_buf.size()) != expected_iv_len) {
484
509
    return THROW_ERR_CRYPTO_INVALID_IV(env());
485
  }
486
487
823
  if (EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305) {
488
292
    CHECK(has_iv);
489
    // Check for invalid IV lengths, since OpenSSL does not under some
490
    // conditions:
491
    //   https://www.openssl.org/news/secadv/20190306.txt.
492
292
    if (iv_buf.size() > 12)
493
5
      return THROW_ERR_CRYPTO_INVALID_IV(env());
494
  }
495
496
1636
  CommonInit(
497
      cipher_type,
498
      cipher,
499
      key_buf.data<unsigned char>(),
500
818
      key_buf.size(),
501
      iv_buf.data(),
502
818
      iv_buf.size(),
503
      auth_tag_len);
504
}
505
506
1394
void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
507
  CipherBase* cipher;
508
1394
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
509
1394
  Environment* env = cipher->env();
510
511
1394
  CHECK_GE(args.Length(), 4);
512
513
1394
  const Utf8Value cipher_type(env->isolate(), args[0]);
514
515
  // The argument can either be a KeyObjectHandle or a byte source
516
  // (e.g. ArrayBuffer, TypedArray, etc). Whichever it is, grab the
517
  // raw bytes and proceed...
518
1394
  const ByteSource key_buf = ByteSource::FromSecretKeyBytes(env, args[1]);
519
520
1394
  if (UNLIKELY(key_buf.size() > INT_MAX))
521
    return THROW_ERR_OUT_OF_RANGE(env, "key is too big");
522
523
1394
  ArrayBufferOrViewContents<unsigned char> iv_buf;
524
2788
  if (!args[2]->IsNull())
525
1388
    iv_buf = ArrayBufferOrViewContents<unsigned char>(args[2]);
526
527
1394
  if (UNLIKELY(!iv_buf.CheckSizeInt32()))
528
    return THROW_ERR_OUT_OF_RANGE(env, "iv is too big");
529
530
  // Don't assign to cipher->auth_tag_len_ directly; the value might not
531
  // represent a valid length at this point.
532
  unsigned int auth_tag_len;
533
1394
  if (args[3]->IsUint32()) {
534
932
    auth_tag_len = args[3].As<Uint32>()->Value();
535
  } else {
536

2784
    CHECK(args[3]->IsInt32() && args[3].As<Int32>()->Value() == -1);
537
928
    auth_tag_len = kNoAuthTagLength;
538
  }
539
540
1394
  cipher->InitIv(*cipher_type, key_buf, iv_buf, auth_tag_len);
541
}
542
543
679
bool CipherBase::InitAuthenticated(
544
    const char* cipher_type,
545
    int iv_len,
546
    unsigned int auth_tag_len) {
547
679
  CHECK(IsAuthenticatedMode());
548
1358
  MarkPopErrorOnReturn mark_pop_error_on_return;
549
550
679
  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
551
                           EVP_CTRL_AEAD_SET_IVLEN,
552
                           iv_len,
553
                           nullptr)) {
554
    THROW_ERR_CRYPTO_INVALID_IV(env());
555
    return false;
556
  }
557
558
679
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
559
679
  if (mode == EVP_CIPH_GCM_MODE) {
560
184
    if (auth_tag_len != kNoAuthTagLength) {
561
24
      if (!IsValidGCMTagLength(auth_tag_len)) {
562
16
        THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
563
          env(),
564
          "Invalid authentication tag length: %u",
565
          auth_tag_len);
566
16
        return false;
567
      }
568
569
      // Remember the given authentication tag length for later.
570
8
      auth_tag_len_ = auth_tag_len;
571
    }
572
  } else {
573
495
    if (auth_tag_len == kNoAuthTagLength) {
574
      // We treat ChaCha20-Poly1305 specially. Like GCM, the authentication tag
575
      // length defaults to 16 bytes when encrypting. Unlike GCM, the
576
      // authentication tag length also defaults to 16 bytes when decrypting,
577
      // whereas GCM would accept any valid authentication tag length.
578
18
      if (EVP_CIPHER_CTX_nid(ctx_.get()) == NID_chacha20_poly1305) {
579
10
        auth_tag_len = 16;
580
      } else {
581
8
        THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
582
          env(), "authTagLength required for %s", cipher_type);
583
8
        return false;
584
      }
585
    }
586
587
    // TODO(tniessen) Support CCM decryption in FIPS mode
588
589
#if OPENSSL_VERSION_MAJOR >= 3
590


541
    if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher &&
591
54
        EVP_default_properties_is_fips_enabled(nullptr)) {
592
#else
593
    if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) {
594
#endif
595
      THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
596
          "CCM encryption not supported in FIPS mode");
597
      return false;
598
    }
599
600
    // Tell OpenSSL about the desired length.
601
487
    if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
602
                             nullptr)) {
603
50
      THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
604
          env(), "Invalid authentication tag length: %u", auth_tag_len);
605
50
      return false;
606
    }
607
608
    // Remember the given authentication tag length for later.
609
437
    auth_tag_len_ = auth_tag_len;
610
611
437
    if (mode == EVP_CIPH_CCM_MODE) {
612
      // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes.
613

90
      CHECK(iv_len >= 7 && iv_len <= 13);
614
90
      max_message_size_ = INT_MAX;
615
90
      if (iv_len == 12) max_message_size_ = 16777215;
616
90
      if (iv_len == 13) max_message_size_ = 65535;
617
    }
618
  }
619
620
605
  return true;
621
}
622
623
127
bool CipherBase::CheckCCMMessageLength(int message_len) {
624
127
  CHECK(ctx_);
625
127
  CHECK(EVP_CIPHER_CTX_mode(ctx_.get()) == EVP_CIPH_CCM_MODE);
626
627
127
  if (message_len > max_message_size_) {
628
4
    THROW_ERR_CRYPTO_INVALID_MESSAGELEN(env());
629
4
    return false;
630
  }
631
632
123
  return true;
633
}
634
635
1986
bool CipherBase::IsAuthenticatedMode() const {
636
  // Check if this cipher operates in an AEAD mode that we support.
637
1986
  CHECK(ctx_);
638
1986
  return IsSupportedAuthenticatedMode(ctx_.get());
639
}
640
641
164
void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
642
164
  Environment* env = Environment::GetCurrent(args);
643
  CipherBase* cipher;
644
224
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
645
646
  // Only callable after Final and if encrypting.
647
433
  if (cipher->ctx_ ||
648

269
      cipher->kind_ != kCipher ||
649
105
      cipher->auth_tag_len_ == kNoAuthTagLength) {
650
60
    return;
651
  }
652
653
104
  args.GetReturnValue().Set(
654
208
      Buffer::Copy(env, cipher->auth_tag_, cipher->auth_tag_len_)
655
          .FromMaybe(Local<Value>()));
656
}
657
658
357
void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
659
  CipherBase* cipher;
660
610
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
661
357
  Environment* env = Environment::GetCurrent(args);
662
663
357
  if (!cipher->ctx_ ||
664
356
      !cipher->IsAuthenticatedMode() ||
665

1069
      cipher->kind_ != kDecipher ||
666
356
      cipher->auth_tag_state_ != kAuthTagUnknown) {
667
8
    return args.GetReturnValue().Set(false);
668
  }
669
670
353
  ArrayBufferOrViewContents<char> auth_tag(args[0]);
671
353
  if (UNLIKELY(!auth_tag.CheckSizeInt32()))
672
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
673
674
353
  unsigned int tag_len = auth_tag.size();
675
676
353
  const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
677
  bool is_valid;
678
353
  if (mode == EVP_CIPH_GCM_MODE) {
679
    // Restrict GCM tag lengths according to NIST 800-38d, page 9.
680
43
    is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
681

85
                cipher->auth_tag_len_ == tag_len) &&
682
42
               IsValidGCMTagLength(tag_len);
683
  } else {
684
    // At this point, the tag length is already known and must match the
685
    // length of the given authentication tag.
686
310
    CHECK(IsSupportedAuthenticatedMode(cipher->ctx_.get()));
687
310
    CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength);
688
310
    is_valid = cipher->auth_tag_len_ == tag_len;
689
  }
690
691
353
  if (!is_valid) {
692
249
    return THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
693
249
      env, "Invalid authentication tag length: %u", tag_len);
694
  }
695
696
104
  cipher->auth_tag_len_ = tag_len;
697
104
  cipher->auth_tag_state_ = kAuthTagKnown;
698
104
  CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
699
700
104
  memset(cipher->auth_tag_, 0, sizeof(cipher->auth_tag_));
701
104
  auth_tag.CopyTo(cipher->auth_tag_, cipher->auth_tag_len_);
702
703
208
  args.GetReturnValue().Set(true);
704
}
705
706
474
bool CipherBase::MaybePassAuthTagToOpenSSL() {
707
474
  if (auth_tag_state_ == kAuthTagKnown) {
708
103
    if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
709
                             EVP_CTRL_AEAD_SET_TAG,
710
103
                             auth_tag_len_,
711
103
                             reinterpret_cast<unsigned char*>(auth_tag_))) {
712
      return false;
713
    }
714
103
    auth_tag_state_ = kAuthTagPassedToOpenSSL;
715
  }
716
474
  return true;
717
}
718
719
124
bool CipherBase::SetAAD(
720
    const ArrayBufferOrViewContents<unsigned char>& data,
721
    int plaintext_len) {
722

124
  if (!ctx_ || !IsAuthenticatedMode())
723
2
    return false;
724
244
  MarkPopErrorOnReturn mark_pop_error_on_return;
725
726
  int outlen;
727
122
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
728
729
  // When in CCM mode, we need to set the authentication tag and the plaintext
730
  // length in advance.
731
122
  if (mode == EVP_CIPH_CCM_MODE) {
732
55
    if (plaintext_len < 0) {
733
2
      THROW_ERR_MISSING_ARGS(env(),
734
          "options.plaintextLength required for CCM mode with AAD");
735
2
      return false;
736
    }
737
738
53
    if (!CheckCCMMessageLength(plaintext_len))
739
2
      return false;
740
741
51
    if (kind_ == kDecipher) {
742
26
      if (!MaybePassAuthTagToOpenSSL())
743
        return false;
744
    }
745
746
    // Specify the plaintext length.
747
51
    if (!EVP_CipherUpdate(ctx_.get(), nullptr, &outlen, nullptr, plaintext_len))
748
      return false;
749
  }
750
751
118
  return 1 == EVP_CipherUpdate(ctx_.get(),
752
                               nullptr,
753
                               &outlen,
754
                               data.data(),
755
236
                               data.size());
756
}
757
758
124
void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
759
  CipherBase* cipher;
760
124
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
761
124
  Environment* env = Environment::GetCurrent(args);
762
763
124
  CHECK_EQ(args.Length(), 2);
764
124
  CHECK(args[1]->IsInt32());
765
248
  int plaintext_len = args[1].As<Int32>()->Value();
766
124
  ArrayBufferOrViewContents<unsigned char> buf(args[0]);
767
768
124
  if (UNLIKELY(!buf.CheckSizeInt32()))
769
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
770
248
  args.GetReturnValue().Set(cipher->SetAAD(buf, plaintext_len));
771
}
772
773
606
CipherBase::UpdateResult CipherBase::Update(
774
    const char* data,
775
    size_t len,
776
    std::unique_ptr<BackingStore>* out) {
777

606
  if (!ctx_ || len > INT_MAX)
778
    return kErrorState;
779
1212
  MarkPopErrorOnReturn mark_pop_error_on_return;
780
781
606
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
782
783

606
  if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength(len))
784
2
    return kErrorMessageSize;
785
786
  // Pass the authentication tag to OpenSSL if possible. This will only happen
787
  // once, usually on the first update.
788

604
  if (kind_ == kDecipher && IsAuthenticatedMode())
789
344
    CHECK(MaybePassAuthTagToOpenSSL());
790
791
604
  int buf_len = len + EVP_CIPHER_CTX_block_size(ctx_.get());
792
  // For key wrapping algorithms, get output size by calling
793
  // EVP_CipherUpdate() with null output.
794


613
  if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE &&
795
9
      EVP_CipherUpdate(ctx_.get(),
796
                       nullptr,
797
                       &buf_len,
798
                       reinterpret_cast<const unsigned char*>(data),
799
                       len) != 1) {
800
    return kErrorState;
801
  }
802
803
  {
804
604
    NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
805
604
    *out = ArrayBuffer::NewBackingStore(env()->isolate(), buf_len);
806
  }
807
808
604
  int r = EVP_CipherUpdate(ctx_.get(),
809
604
                           static_cast<unsigned char*>((*out)->Data()),
810
                           &buf_len,
811
                           reinterpret_cast<const unsigned char*>(data),
812
                           len);
813
814
604
  CHECK_LE(static_cast<size_t>(buf_len), (*out)->ByteLength());
815
604
  if (buf_len == 0)
816
67
    *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
817
  else
818
537
    *out = BackingStore::Reallocate(env()->isolate(), std::move(*out), buf_len);
819
820
  // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
821
  // invalid. In that case, remember the error and throw in final().
822

604
  if (!r && kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
823
5
    pending_auth_failed_ = true;
824
5
    return kSuccess;
825
  }
826
599
  return r == 1 ? kSuccess : kErrorState;
827
}
828
829
606
void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
830
606
  Decode<CipherBase>(args, [](CipherBase* cipher,
831
                              const FunctionCallbackInfo<Value>& args,
832
606
                              const char* data, size_t size) {
833
606
    std::unique_ptr<BackingStore> out;
834
606
    Environment* env = Environment::GetCurrent(args);
835
836
606
    if (UNLIKELY(size > INT_MAX))
837
      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
838
839
606
    UpdateResult r = cipher->Update(data, size, &out);
840
841
606
    if (r != kSuccess) {
842
2
      if (r == kErrorState) {
843
        ThrowCryptoError(env, ERR_get_error(),
844
                         "Trying to add data in unsupported state");
845
      }
846
2
      return;
847
    }
848
849
604
    Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
850
1208
    args.GetReturnValue().Set(
851
1208
        Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
852
  });
853
606
}
854
855
18
bool CipherBase::SetAutoPadding(bool auto_padding) {
856
18
  if (!ctx_)
857
1
    return false;
858
17
  MarkPopErrorOnReturn mark_pop_error_on_return;
859
17
  return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
860
}
861
862
18
void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
863
  CipherBase* cipher;
864
18
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
865
866

36
  bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue());
867
36
  args.GetReturnValue().Set(b);  // Possibly report invalid state failure
868
}
869
870
292
bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
871
292
  if (!ctx_)
872
    return false;
873
874
292
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
875
876
  {
877
292
    NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
878
584
    *out = ArrayBuffer::NewBackingStore(env()->isolate(),
879
584
        static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
880
  }
881
882

292
  if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get()))
883
104
    MaybePassAuthTagToOpenSSL();
884
885
  // In CCM mode, final() only checks whether authentication failed in update().
886
  // EVP_CipherFinal_ex must not be called and will fail.
887
  bool ok;
888

292
  if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
889
29
    ok = !pending_auth_failed_;
890
29
    *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
891
  } else {
892
263
    int out_len = (*out)->ByteLength();
893
263
    ok = EVP_CipherFinal_ex(ctx_.get(),
894
263
                            static_cast<unsigned char*>((*out)->Data()),
895
                            &out_len) == 1;
896
897
263
    CHECK_LE(static_cast<size_t>(out_len), (*out)->ByteLength());
898
263
    if (out_len > 0) {
899
      *out =
900
73
        BackingStore::Reallocate(env()->isolate(), std::move(*out), out_len);
901
    } else {
902
190
      *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
903
    }
904
905


263
    if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
906
      // In GCM mode, the authentication tag length can be specified in advance,
907
      // but defaults to 16 bytes when encrypting. In CCM and OCB mode, it must
908
      // always be given by the user.
909
104
      if (auth_tag_len_ == kNoAuthTagLength) {
910
30
        CHECK(mode == EVP_CIPH_GCM_MODE);
911
30
        auth_tag_len_ = sizeof(auth_tag_);
912
      }
913
104
      ok = (1 == EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
914
104
                     auth_tag_len_,
915
104
                     reinterpret_cast<unsigned char*>(auth_tag_)));
916
    }
917
  }
918
919
292
  ctx_.reset();
920
921
292
  return ok;
922
}
923
924
296
void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
925
296
  Environment* env = Environment::GetCurrent(args);
926
927
  CipherBase* cipher;
928
317
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
929
296
  if (cipher->ctx_ == nullptr)
930
4
    return THROW_ERR_CRYPTO_INVALID_STATE(env);
931
932
292
  std::unique_ptr<BackingStore> out;
933
934
  // Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
935
292
  const bool is_auth_mode = cipher->IsAuthenticatedMode();
936
292
  bool r = cipher->Final(&out);
937
938
292
  if (!r) {
939
17
    const char* msg = is_auth_mode
940
17
                          ? "Unsupported state or unable to authenticate data"
941
                          : "Unsupported state";
942
943
17
    return ThrowCryptoError(env, ERR_get_error(), msg);
944
  }
945
946
275
  Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
947
550
  args.GetReturnValue().Set(
948
550
      Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
949
}
950
951
template <PublicKeyCipher::Operation operation,
952
          PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
953
          PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
954
312
bool PublicKeyCipher::Cipher(
955
    Environment* env,
956
    const ManagedEVPPKey& pkey,
957
    int padding,
958
    const EVP_MD* digest,
959
    const ArrayBufferOrViewContents<unsigned char>& oaep_label,
960
    const ArrayBufferOrViewContents<unsigned char>& data,
961
    std::unique_ptr<BackingStore>* out) {
962
624
  EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
963
312
  if (!ctx)
964
    return false;
965
312
  if (EVP_PKEY_cipher_init(ctx.get()) <= 0)
966
2
    return false;
967
310
  if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), padding) <= 0)
968
    return false;
969
970
310
  if (digest != nullptr) {
971
42
    if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), digest) <= 0)
972
      return false;
973
  }
974
975
310
  if (oaep_label.size() != 0) {
976
    // OpenSSL takes ownership of the label, so we need to create a copy.
977
8
    void* label = OPENSSL_memdup(oaep_label.data(), oaep_label.size());
978
8
    CHECK_NOT_NULL(label);
979
8
    if (0 >= EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(),
980
                     static_cast<unsigned char*>(label),
981
8
                                      oaep_label.size())) {
982
      OPENSSL_free(label);
983
      return false;
984
    }
985
  }
986
987
310
  size_t out_len = 0;
988
310
  if (EVP_PKEY_cipher(
989
          ctx.get(),
990
          nullptr,
991
          &out_len,
992
          data.data(),
993
310
          data.size()) <= 0) {
994
    return false;
995
  }
996
997
  {
998
310
    NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
999
310
    *out = ArrayBuffer::NewBackingStore(env->isolate(), out_len);
1000
  }
1001
1002
620
  if (EVP_PKEY_cipher(
1003
          ctx.get(),
1004
310
          static_cast<unsigned char*>((*out)->Data()),
1005
          &out_len,
1006
          data.data(),
1007
310
          data.size()) <= 0) {
1008
2
    return false;
1009
  }
1010
1011
308
  CHECK_LE(out_len, (*out)->ByteLength());
1012
308
  if (out_len > 0)
1013
308
    *out = BackingStore::Reallocate(env->isolate(), std::move(*out), out_len);
1014
  else
1015
    *out = ArrayBuffer::NewBackingStore(env->isolate(), 0);
1016
1017
308
  return true;
1018
}
1019
1020
template <PublicKeyCipher::Operation operation,
1021
          PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
1022
          PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
1023
162
void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
1024
162
  MarkPopErrorOnReturn mark_pop_error_on_return;
1025
162
  Environment* env = Environment::GetCurrent(args);
1026
1027
162
  unsigned int offset = 0;
1028
162
  ManagedEVPPKey pkey =
1029
      ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
1030
162
  if (!pkey)
1031
4
    return;
1032
1033
316
  ArrayBufferOrViewContents<unsigned char> buf(args[offset]);
1034
158
  if (UNLIKELY(!buf.CheckSizeInt32()))
1035
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too long");
1036
1037
  uint32_t padding;
1038
474
  if (!args[offset + 1]->Uint32Value(env->context()).To(&padding)) return;
1039
1040
158
  const EVP_MD* digest = nullptr;
1041
474
  if (args[offset + 2]->IsString()) {
1042
46
    const Utf8Value oaep_str(env->isolate(), args[offset + 2]);
1043
23
    digest = EVP_get_digestbyname(*oaep_str);
1044
23
    if (digest == nullptr)
1045
2
      return THROW_ERR_OSSL_EVP_INVALID_DIGEST(env);
1046
  }
1047
1048
156
  ArrayBufferOrViewContents<unsigned char> oaep_label;
1049
468
  if (!args[offset + 3]->IsUndefined()) {
1050
8
    oaep_label = ArrayBufferOrViewContents<unsigned char>(args[offset + 3]);
1051
4
    if (UNLIKELY(!oaep_label.CheckSizeInt32()))
1052
      return THROW_ERR_OUT_OF_RANGE(env, "oaep_label is too big");
1053
  }
1054
1055
156
  std::unique_ptr<BackingStore> out;
1056
156
  if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
1057
          env, pkey, padding, digest, oaep_label, buf, &out)) {
1058
2
    return ThrowCryptoError(env, ERR_get_error());
1059
  }
1060
1061
154
  Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
1062
308
  args.GetReturnValue().Set(
1063
308
      Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
1064
}
1065
1066
}  // namespace crypto
1067
}  // namespace node