GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_cipher.cc Lines: 480 522 92.0 %
Date: 2022-03-21 03:14:50 Branches: 325 425 76.5 %

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
#ifdef OPENSSL_NO_OCB
28
# define IS_OCB_MODE(mode) false
29
#else
30
# define IS_OCB_MODE(mode) ((mode) == EVP_CIPH_OCB_MODE)
31
#endif
32
33
namespace {
34
3049
bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
35
3049
  const int mode = EVP_CIPHER_mode(cipher);
36
  // Check `chacha20-poly1305` separately, it is also an AEAD cipher,
37
  // but its mode is 0 which doesn't indicate
38
3049
  return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305 ||
39
2997
         mode == EVP_CIPH_CCM_MODE ||
40

7570
         mode == EVP_CIPH_GCM_MODE ||
41
4573
         IS_OCB_MODE(mode);
42
}
43
44
1305
bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
45
1305
  const EVP_CIPHER* cipher = EVP_CIPHER_CTX_cipher(ctx);
46
1305
  return IsSupportedAuthenticatedMode(cipher);
47
}
48
49
66
bool IsValidGCMTagLength(unsigned int tag_len) {
50


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

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



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

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

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

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

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

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

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

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

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

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

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

2739
    CHECK(args[3]->IsInt32() && args[3].As<Int32>()->Value() == -1);
538
913
    auth_tag_len = kNoAuthTagLength;
539
  }
540
541
1116
  cipher->InitIv(*cipher_type, key_buf, iv_buf, auth_tag_len);
542
}
543
544
401
bool CipherBase::InitAuthenticated(
545
    const char* cipher_type,
546
    int iv_len,
547
    unsigned int auth_tag_len) {
548
401
  CHECK(IsAuthenticatedMode());
549
802
  MarkPopErrorOnReturn mark_pop_error_on_return;
550
551
401
  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
552
                           EVP_CTRL_AEAD_SET_IVLEN,
553
                           iv_len,
554
                           nullptr)) {
555
    THROW_ERR_CRYPTO_INVALID_IV(env());
556
    return false;
557
  }
558
559
401
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
560
401
  if (mode == EVP_CIPH_GCM_MODE) {
561
184
    if (auth_tag_len != kNoAuthTagLength) {
562
24
      if (!IsValidGCMTagLength(auth_tag_len)) {
563
16
        THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
564
          env(),
565
          "Invalid authentication tag length: %u",
566
          auth_tag_len);
567
16
        return false;
568
      }
569
570
      // Remember the given authentication tag length for later.
571
8
      auth_tag_len_ = auth_tag_len;
572
    }
573
  } else {
574
217
    if (auth_tag_len == kNoAuthTagLength) {
575
8
      THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
576
        env(), "authTagLength required for %s", cipher_type);
577
8
      return false;
578
    }
579
580
    // TODO(tniessen) Support CCM decryption in FIPS mode
581
582
#if OPENSSL_VERSION_MAJOR >= 3
583


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

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

231
      cipher->kind_ != kCipher ||
642
86
      cipher->auth_tag_len_ == kNoAuthTagLength) {
643
60
    return;
644
  }
645
646
85
  args.GetReturnValue().Set(
647
170
      Buffer::Copy(env, cipher->auth_tag_, cipher->auth_tag_len_)
648
          .FromMaybe(Local<Value>()));
649
}
650
651
98
void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
652
  CipherBase* cipher;
653
111
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
654
98
  Environment* env = Environment::GetCurrent(args);
655
656
98
  if (!cipher->ctx_ ||
657
97
      !cipher->IsAuthenticatedMode() ||
658

292
      cipher->kind_ != kDecipher ||
659
97
      cipher->auth_tag_state_ != kAuthTagUnknown) {
660
8
    return args.GetReturnValue().Set(false);
661
  }
662
663
94
  ArrayBufferOrViewContents<char> auth_tag(args[0]);
664
94
  if (UNLIKELY(!auth_tag.CheckSizeInt32()))
665
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
666
667
94
  unsigned int tag_len = auth_tag.size();
668
669
94
  const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
670
  bool is_valid;
671
94
  if (mode == EVP_CIPH_GCM_MODE) {
672
    // Restrict GCM tag lengths according to NIST 800-38d, page 9.
673
43
    is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
674

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

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

328
  if (!ctx_ || len > INT_MAX)
771
    return kErrorState;
772
656
  MarkPopErrorOnReturn mark_pop_error_on_return;
773
774
328
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
775
776

328
  if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength(len))
777
2
    return kErrorMessageSize;
778
779
  // Pass the authentication tag to OpenSSL if possible. This will only happen
780
  // once, usually on the first update.
781

326
  if (kind_ == kDecipher && IsAuthenticatedMode())
782
85
    CHECK(MaybePassAuthTagToOpenSSL());
783
784
326
  int buf_len = len + EVP_CIPHER_CTX_block_size(ctx_.get());
785
  // For key wrapping algorithms, get output size by calling
786
  // EVP_CipherUpdate() with null output.
787


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

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

36
  bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue());
860
36
  args.GetReturnValue().Set(b);  // Possibly report invalid state failure
861
}
862
863
254
bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
864
254
  if (!ctx_)
865
    return false;
866
867
254
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
868
869
  {
870
254
    NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
871
508
    *out = ArrayBuffer::NewBackingStore(env()->isolate(),
872
508
        static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
873
  }
874
875

254
  if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get()))
876
85
    MaybePassAuthTagToOpenSSL();
877
878
  // In CCM mode, final() only checks whether authentication failed in update().
879
  // EVP_CipherFinal_ex must not be called and will fail.
880
  bool ok;
881

254
  if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
882
29
    ok = !pending_auth_failed_;
883
29
    *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
884
  } else {
885
225
    int out_len = (*out)->ByteLength();
886
225
    ok = EVP_CipherFinal_ex(ctx_.get(),
887
225
                            static_cast<unsigned char*>((*out)->Data()),
888
                            &out_len) == 1;
889
890
225
    CHECK_LE(static_cast<size_t>(out_len), (*out)->ByteLength());
891
225
    if (out_len > 0) {
892
      *out =
893
73
        BackingStore::Reallocate(env()->isolate(), std::move(*out), out_len);
894
    } else {
895
152
      *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
896
    }
897
898


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