GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_cipher.cc Lines: 485 529 91.7 %
Date: 2022-08-02 04:16:51 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::Context;
17
using v8::FunctionCallbackInfo;
18
using v8::FunctionTemplate;
19
using v8::HandleScope;
20
using v8::Int32;
21
using v8::Isolate;
22
using v8::Local;
23
using v8::Object;
24
using v8::Uint32;
25
using v8::Value;
26
27
namespace crypto {
28
namespace {
29
4742
bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
30
4742
  switch (EVP_CIPHER_mode(cipher)) {
31
1857
  case EVP_CIPH_CCM_MODE:
32
  case EVP_CIPH_GCM_MODE:
33
#ifndef OPENSSL_NO_OCB
34
  case EVP_CIPH_OCB_MODE:
35
#endif
36
1857
    return true;
37
1747
  case EVP_CIPH_STREAM_CIPHER:
38
1747
    return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305;
39
1138
  default:
40
1138
    return false;
41
  }
42
}
43
44
2442
bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
45
2442
  const EVP_CIPHER* cipher = EVP_CIPHER_CTX_cipher(ctx);
46
2442
  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
1
  SSLCtxPointer ctx(SSL_CTX_new(TLS_method()));
201
1
  if (!ctx) {
202
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new");
203
  }
204
205
1
  SSLPointer ssl(SSL_new(ctx.get()));
206
1
  if (!ssl) {
207
    return ThrowCryptoError(env, ERR_get_error(), "SSL_new");
208
  }
209
210
1
  STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl.get());
211
212
  // TLSv1.3 ciphers aren't listed by EVP. There are only 5, we could just
213
  // document them, but since there are only 5, easier to just add them manually
214
  // and not have to explain their absence in the API docs. They are lower-cased
215
  // because the docs say they will be.
216
  static const char* TLS13_CIPHERS[] = {
217
    "tls_aes_256_gcm_sha384",
218
    "tls_chacha20_poly1305_sha256",
219
    "tls_aes_128_gcm_sha256",
220
    "tls_aes_128_ccm_8_sha256",
221
    "tls_aes_128_ccm_sha256"
222
  };
223
224
1
  const int n = sk_SSL_CIPHER_num(ciphers);
225
1
  std::vector<Local<Value>> arr(n + arraysize(TLS13_CIPHERS));
226
227
61
  for (int i = 0; i < n; ++i) {
228
60
    const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
229
120
    arr[i] = OneByteString(env->isolate(), SSL_CIPHER_get_name(cipher));
230
  }
231
232
6
  for (unsigned i = 0; i < arraysize(TLS13_CIPHERS); ++i) {
233
5
    const char* name = TLS13_CIPHERS[i];
234
10
    arr[n + i] = OneByteString(env->isolate(), name);
235
  }
236
237
2
  args.GetReturnValue().Set(Array::New(env->isolate(), arr.data(), arr.size()));
238
}
239
240
3
void CipherBase::GetCiphers(const FunctionCallbackInfo<Value>& args) {
241
3
  Environment* env = Environment::GetCurrent(args);
242
6
  MarkPopErrorOnReturn mark_pop_error_on_return;
243
3
  CipherPushContext ctx(env);
244
3
  EVP_CIPHER_do_all_sorted(
245
#if OPENSSL_VERSION_MAJOR >= 3
246
    array_push_back<EVP_CIPHER,
247
                    EVP_CIPHER_fetch,
248
                    EVP_CIPHER_free,
249
                    EVP_get_cipherbyname,
250
                    EVP_CIPHER_get0_name>,
251
#else
252
    array_push_back<EVP_CIPHER>,
253
#endif
254
    &ctx);
255
6
  args.GetReturnValue().Set(ctx.ToJSArray());
256
3
}
257
258
1483
CipherBase::CipherBase(Environment* env,
259
                       Local<Object> wrap,
260
1483
                       CipherKind kind)
261
    : BaseObject(env, wrap),
262
      ctx_(nullptr),
263
      kind_(kind),
264
      auth_tag_state_(kAuthTagUnknown),
265
      auth_tag_len_(kNoAuthTagLength),
266
1483
      pending_auth_failed_(false) {
267
1483
  MakeWeak();
268
1483
}
269
270
void CipherBase::MemoryInfo(MemoryTracker* tracker) const {
271
  tracker->TrackFieldWithSize("context", ctx_ ? kSizeOf_EVP_CIPHER_CTX : 0);
272
}
273
274
1303
void CipherBase::Initialize(Environment* env, Local<Object> target) {
275
1303
  Isolate* isolate = env->isolate();
276
1303
  Local<Context> context = env->context();
277
278
1303
  Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New);
279
280
2606
  t->InstanceTemplate()->SetInternalFieldCount(
281
      CipherBase::kInternalFieldCount);
282
1303
  t->Inherit(BaseObject::GetConstructorTemplate(env));
283
284
1303
  SetProtoMethod(isolate, t, "init", Init);
285
1303
  SetProtoMethod(isolate, t, "initiv", InitIv);
286
1303
  SetProtoMethod(isolate, t, "update", Update);
287
1303
  SetProtoMethod(isolate, t, "final", Final);
288
1303
  SetProtoMethod(isolate, t, "setAutoPadding", SetAutoPadding);
289
1303
  SetProtoMethodNoSideEffect(isolate, t, "getAuthTag", GetAuthTag);
290
1303
  SetProtoMethod(isolate, t, "setAuthTag", SetAuthTag);
291
1303
  SetProtoMethod(isolate, t, "setAAD", SetAAD);
292
1303
  SetConstructorFunction(context, target, "CipherBase", t);
293
294
1303
  SetMethodNoSideEffect(context, target, "getSSLCiphers", GetSSLCiphers);
295
1303
  SetMethodNoSideEffect(context, target, "getCiphers", GetCiphers);
296
297
1303
  SetMethod(context,
298
            target,
299
            "publicEncrypt",
300
            PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
301
                                    EVP_PKEY_encrypt_init,
302
                                    EVP_PKEY_encrypt>);
303
1303
  SetMethod(context,
304
            target,
305
            "privateDecrypt",
306
            PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
307
                                    EVP_PKEY_decrypt_init,
308
                                    EVP_PKEY_decrypt>);
309
1303
  SetMethod(context,
310
            target,
311
            "privateEncrypt",
312
            PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
313
                                    EVP_PKEY_sign_init,
314
                                    EVP_PKEY_sign>);
315
1303
  SetMethod(context,
316
            target,
317
            "publicDecrypt",
318
            PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
319
                                    EVP_PKEY_verify_recover_init,
320
                                    EVP_PKEY_verify_recover>);
321
322
1303
  SetMethodNoSideEffect(context, target, "getCipherInfo", GetCipherInfo);
323
324
3909
  NODE_DEFINE_CONSTANT(target, kWebCryptoCipherEncrypt);
325
2606
  NODE_DEFINE_CONSTANT(target, kWebCryptoCipherDecrypt);
326
1303
}
327
328
5300
void CipherBase::RegisterExternalReferences(
329
    ExternalReferenceRegistry* registry) {
330
5300
  registry->Register(New);
331
332
5300
  registry->Register(Init);
333
5300
  registry->Register(InitIv);
334
5300
  registry->Register(Update);
335
5300
  registry->Register(Final);
336
5300
  registry->Register(SetAutoPadding);
337
5300
  registry->Register(GetAuthTag);
338
5300
  registry->Register(SetAuthTag);
339
5300
  registry->Register(SetAAD);
340
341
5300
  registry->Register(GetSSLCiphers);
342
5300
  registry->Register(GetCiphers);
343
344
5300
  registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
345
                                             EVP_PKEY_encrypt_init,
346
                                             EVP_PKEY_encrypt>);
347
5300
  registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
348
                                             EVP_PKEY_decrypt_init,
349
                                             EVP_PKEY_decrypt>);
350
5300
  registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
351
                                             EVP_PKEY_sign_init,
352
                                             EVP_PKEY_sign>);
353
5300
  registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
354
                                             EVP_PKEY_verify_recover_init,
355
                                             EVP_PKEY_verify_recover>);
356
357
5300
  registry->Register(GetCipherInfo);
358
5300
}
359
360
1483
void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
361
1483
  CHECK(args.IsConstructCall());
362
1483
  Environment* env = Environment::GetCurrent(args);
363

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

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

162
    CHECK(args[2]->IsInt32() && args[2].As<Int32>()->Value() == -1);
469
54
    auth_tag_len = kNoAuthTagLength;
470
  }
471
472
89
  cipher->Init(*cipher_type, key_buf, auth_tag_len);
473
}
474
475
1394
void CipherBase::InitIv(const char* cipher_type,
476
                        const ByteSource& key_buf,
477
                        const ArrayBufferOrViewContents<unsigned char>& iv_buf,
478
                        unsigned int auth_tag_len) {
479
1394
  HandleScope scope(env()->isolate());
480
1394
  MarkPopErrorOnReturn mark_pop_error_on_return;
481
482
1394
  const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
483
1394
  if (cipher == nullptr)
484
1
    return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
485
486
1393
  const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
487
1393
  const bool is_authenticated_mode = IsSupportedAuthenticatedMode(cipher);
488
1393
  const bool has_iv = iv_buf.size() > 0;
489
490
  // Throw if no IV was passed and the cipher requires an IV
491

1393
  if (!has_iv && expected_iv_len != 0)
492
61
    return THROW_ERR_CRYPTO_INVALID_IV(env());
493
494
  // Throw if an IV was passed which does not match the cipher's fixed IV length
495
  // static_cast<int> for the iv_buf.size() is safe because we've verified
496
  // prior that the value is not larger than MAX_INT.
497
695
  if (!is_authenticated_mode &&
498

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

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


541
    if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher &&
607
54
        EVP_default_properties_is_fips_enabled(nullptr)) {
608
#else
609
    if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) {
610
#endif
611
      THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
612
          "CCM encryption not supported in FIPS mode");
613
      return false;
614
    }
615
616
    // Tell OpenSSL about the desired length.
617
487
    if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
618
                             nullptr)) {
619
50
      THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
620
          env(), "Invalid authentication tag length: %u", auth_tag_len);
621
50
      return false;
622
    }
623
624
    // Remember the given authentication tag length for later.
625
437
    auth_tag_len_ = auth_tag_len;
626
627
437
    if (mode == EVP_CIPH_CCM_MODE) {
628
      // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes.
629

90
      CHECK(iv_len >= 7 && iv_len <= 13);
630
90
      max_message_size_ = INT_MAX;
631
90
      if (iv_len == 12) max_message_size_ = 16777215;
632
90
      if (iv_len == 13) max_message_size_ = 65535;
633
    }
634
  }
635
636
605
  return true;
637
}
638
639
127
bool CipherBase::CheckCCMMessageLength(int message_len) {
640
127
  CHECK(ctx_);
641
127
  CHECK(EVP_CIPHER_CTX_mode(ctx_.get()) == EVP_CIPH_CCM_MODE);
642
643
127
  if (message_len > max_message_size_) {
644
4
    THROW_ERR_CRYPTO_INVALID_MESSAGELEN(env());
645
4
    return false;
646
  }
647
648
123
  return true;
649
}
650
651
1986
bool CipherBase::IsAuthenticatedMode() const {
652
  // Check if this cipher operates in an AEAD mode that we support.
653
1986
  CHECK(ctx_);
654
1986
  return IsSupportedAuthenticatedMode(ctx_.get());
655
}
656
657
164
void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
658
164
  Environment* env = Environment::GetCurrent(args);
659
  CipherBase* cipher;
660
224
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
661
662
  // Only callable after Final and if encrypting.
663
433
  if (cipher->ctx_ ||
664

269
      cipher->kind_ != kCipher ||
665
105
      cipher->auth_tag_len_ == kNoAuthTagLength) {
666
60
    return;
667
  }
668
669
104
  args.GetReturnValue().Set(
670
208
      Buffer::Copy(env, cipher->auth_tag_, cipher->auth_tag_len_)
671
          .FromMaybe(Local<Value>()));
672
}
673
674
357
void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
675
  CipherBase* cipher;
676
610
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
677
357
  Environment* env = Environment::GetCurrent(args);
678
679
357
  if (!cipher->ctx_ ||
680
356
      !cipher->IsAuthenticatedMode() ||
681

1069
      cipher->kind_ != kDecipher ||
682
356
      cipher->auth_tag_state_ != kAuthTagUnknown) {
683
8
    return args.GetReturnValue().Set(false);
684
  }
685
686
353
  ArrayBufferOrViewContents<char> auth_tag(args[0]);
687
353
  if (UNLIKELY(!auth_tag.CheckSizeInt32()))
688
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
689
690
353
  unsigned int tag_len = auth_tag.size();
691
692
353
  const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
693
  bool is_valid;
694
353
  if (mode == EVP_CIPH_GCM_MODE) {
695
    // Restrict GCM tag lengths according to NIST 800-38d, page 9.
696
43
    is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
697

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

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

606
  if (!ctx_ || len > INT_MAX)
794
    return kErrorState;
795
1212
  MarkPopErrorOnReturn mark_pop_error_on_return;
796
797
606
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
798
799

606
  if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength(len))
800
2
    return kErrorMessageSize;
801
802
  // Pass the authentication tag to OpenSSL if possible. This will only happen
803
  // once, usually on the first update.
804

604
  if (kind_ == kDecipher && IsAuthenticatedMode())
805
344
    CHECK(MaybePassAuthTagToOpenSSL());
806
807
604
  int buf_len = len + EVP_CIPHER_CTX_block_size(ctx_.get());
808
  // For key wrapping algorithms, get output size by calling
809
  // EVP_CipherUpdate() with null output.
810


613
  if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE &&
811
9
      EVP_CipherUpdate(ctx_.get(),
812
                       nullptr,
813
                       &buf_len,
814
                       reinterpret_cast<const unsigned char*>(data),
815
                       len) != 1) {
816
    return kErrorState;
817
  }
818
819
  {
820
604
    NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
821
604
    *out = ArrayBuffer::NewBackingStore(env()->isolate(), buf_len);
822
  }
823
824
604
  int r = EVP_CipherUpdate(ctx_.get(),
825
604
                           static_cast<unsigned char*>((*out)->Data()),
826
                           &buf_len,
827
                           reinterpret_cast<const unsigned char*>(data),
828
                           len);
829
830
604
  CHECK_LE(static_cast<size_t>(buf_len), (*out)->ByteLength());
831
604
  if (buf_len == 0)
832
67
    *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
833
  else
834
537
    *out = BackingStore::Reallocate(env()->isolate(), std::move(*out), buf_len);
835
836
  // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
837
  // invalid. In that case, remember the error and throw in final().
838

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

36
  bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue());
883
36
  args.GetReturnValue().Set(b);  // Possibly report invalid state failure
884
}
885
886
292
bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
887
292
  if (!ctx_)
888
    return false;
889
890
292
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
891
892
  {
893
292
    NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
894
584
    *out = ArrayBuffer::NewBackingStore(env()->isolate(),
895
584
        static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
896
  }
897
898

292
  if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get()))
899
104
    MaybePassAuthTagToOpenSSL();
900
901
  // In CCM mode, final() only checks whether authentication failed in update().
902
  // EVP_CipherFinal_ex must not be called and will fail.
903
  bool ok;
904

292
  if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
905
29
    ok = !pending_auth_failed_;
906
29
    *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
907
  } else {
908
263
    int out_len = (*out)->ByteLength();
909
263
    ok = EVP_CipherFinal_ex(ctx_.get(),
910
263
                            static_cast<unsigned char*>((*out)->Data()),
911
                            &out_len) == 1;
912
913
263
    CHECK_LE(static_cast<size_t>(out_len), (*out)->ByteLength());
914
263
    if (out_len > 0) {
915
      *out =
916
73
        BackingStore::Reallocate(env()->isolate(), std::move(*out), out_len);
917
    } else {
918
190
      *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
919
    }
920
921


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