GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_cipher.cc Lines: 483 527 91.7 %
Date: 2022-06-23 04:15:39 Branches: 322 422 76.3 %

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


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

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



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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

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

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

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


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