GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_cipher.cc Lines: 446 488 91.4 %
Date: 2021-09-21 04:13:38 Branches: 346 483 71.6 %

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::FunctionCallbackInfo;
16
using v8::FunctionTemplate;
17
using v8::HandleScope;
18
using v8::Int32;
19
using v8::Local;
20
using v8::Object;
21
using v8::Uint32;
22
using v8::Value;
23
24
namespace crypto {
25
#ifdef OPENSSL_NO_OCB
26
# define IS_OCB_MODE(mode) false
27
#else
28
# define IS_OCB_MODE(mode) ((mode) == EVP_CIPH_OCB_MODE)
29
#endif
30
31
namespace {
32
3365
bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
33
3365
  const int mode = EVP_CIPHER_mode(cipher);
34
  // Check `chacha20-poly1305` separately, it is also an AEAD cipher,
35
  // but its mode is 0 which doesn't indicate
36
3365
  return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305 ||
37
3322
         mode == EVP_CIPH_CCM_MODE ||
38

7993
         mode == EVP_CIPH_GCM_MODE ||
39
4671
         IS_OCB_MODE(mode);
40
}
41
42
1485
bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
43
1485
  const EVP_CIPHER* cipher = EVP_CIPHER_CTX_cipher(ctx);
44
1485
  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
382
void GetCipherInfo(const FunctionCallbackInfo<Value>& args) {
53
382
  Environment* env = Environment::GetCurrent(args);
54
382
  CHECK(args[0]->IsObject());
55
764
  Local<Object> info = args[0].As<Object>();
56
57

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



380
  switch (mode) {
77
101
    case EVP_CIPH_CBC_MODE: mode_label = "cbc"; break;
78
27
    case EVP_CIPH_CCM_MODE: mode_label = "ccm"; break;
79
80
    case EVP_CIPH_CFB_MODE: mode_label = "cfb"; break;
80
20
    case EVP_CIPH_CTR_MODE: mode_label = "ctr"; break;
81
40
    case EVP_CIPH_ECB_MODE: mode_label = "ecb"; break;
82
18
    case EVP_CIPH_GCM_MODE: mode_label = "gcm"; break;
83
22
    case EVP_CIPH_OCB_MODE: mode_label = "ocb"; break;
84
36
    case EVP_CIPH_OFB_MODE: mode_label = "ofb"; break;
85
22
    case EVP_CIPH_WRAP_MODE: mode_label = "wrap"; break;
86
4
    case EVP_CIPH_XTS_MODE: mode_label = "xts"; break;
87
10
    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

758
  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
750
  if (mode_label != nullptr &&
141
375
      info->Set(
142
          env->context(),
143
          FIXED_ONE_BYTE_STRING(env->isolate(), "mode"),
144

1875
          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
750
  if (info->Set(
151
          env->context(),
152
          env->name_string(),
153
          OneByteString(
154
            env->isolate(),
155
1500
            OBJ_nid2sn(EVP_CIPHER_nid(cipher)))).IsNothing()) {
156
    return;
157
  }
158
159
750
  if (info->Set(
160
          env->context(),
161
          FIXED_ONE_BYTE_STRING(env->isolate(), "nid"),
162
1500
          Int32::New(env->isolate(), EVP_CIPHER_nid(cipher))).IsNothing()) {
163
    return;
164
  }
165
166
  // Stream ciphers do not have a meaningful block size
167
740
  if (mode != EVP_CIPH_STREAM_CIPHER &&
168
375
      info->Set(
169
          env->context(),
170
          FIXED_ONE_BYTE_STRING(env->isolate(), "blockSize"),
171

1835
          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
700
  if (iv_length != 0 &&
177
375
      info->Set(
178
          env->context(),
179
          FIXED_ONE_BYTE_STRING(env->isolate(), "ivLength"),
180

1675
          Int32::New(env->isolate(), iv_length)).IsNothing()) {
181
    return;
182
  }
183
184
750
  if (info->Set(
185
          env->context(),
186
          FIXED_ONE_BYTE_STRING(env->isolate(), "keyLength"),
187
1500
          Int32::New(env->isolate(), key_length)).IsNothing()) {
188
    return;
189
  }
190
191
750
  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
2
  SSLCtxPointer ctx(SSL_CTX_new(TLS_method()));
199
1
  CHECK(ctx);
200
201
2
  SSLPointer ssl(SSL_new(ctx.get()));
202
1
  CHECK(ssl);
203
204
1
  STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl.get());
205
206
  // TLSv1.3 ciphers aren't listed by EVP. There are only 5, we could just
207
  // document them, but since there are only 5, easier to just add them manually
208
  // and not have to explain their absence in the API docs. They are lower-cased
209
  // because the docs say they will be.
210
  static const char* TLS13_CIPHERS[] = {
211
    "tls_aes_256_gcm_sha384",
212
    "tls_chacha20_poly1305_sha256",
213
    "tls_aes_128_gcm_sha256",
214
    "tls_aes_128_ccm_8_sha256",
215
    "tls_aes_128_ccm_sha256"
216
  };
217
218
1
  const int n = sk_SSL_CIPHER_num(ciphers);
219
1
  std::vector<Local<Value>> arr(n + arraysize(TLS13_CIPHERS));
220
221
61
  for (int i = 0; i < n; ++i) {
222
60
    const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
223
120
    arr[i] = OneByteString(env->isolate(), SSL_CIPHER_get_name(cipher));
224
  }
225
226
6
  for (unsigned i = 0; i < arraysize(TLS13_CIPHERS); ++i) {
227
5
    const char* name = TLS13_CIPHERS[i];
228
10
    arr[n + i] = OneByteString(env->isolate(), name);
229
  }
230
231
2
  args.GetReturnValue().Set(Array::New(env->isolate(), arr.data(), arr.size()));
232
1
}
233
234
3
void CipherBase::GetCiphers(const FunctionCallbackInfo<Value>& args) {
235
3
  Environment* env = Environment::GetCurrent(args);
236
3
  CipherPushContext ctx(env);
237
3
  EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
238
6
  args.GetReturnValue().Set(ctx.ToJSArray());
239
3
}
240
241
1273
CipherBase::CipherBase(Environment* env,
242
                       Local<Object> wrap,
243
1273
                       CipherKind kind)
244
    : BaseObject(env, wrap),
245
      ctx_(nullptr),
246
      kind_(kind),
247
      auth_tag_state_(kAuthTagUnknown),
248
      auth_tag_len_(kNoAuthTagLength),
249
1273
      pending_auth_failed_(false) {
250
1273
  MakeWeak();
251
1273
}
252
253
void CipherBase::MemoryInfo(MemoryTracker* tracker) const {
254
  tracker->TrackFieldWithSize("context", ctx_ ? kSizeOf_EVP_CIPHER_CTX : 0);
255
}
256
257
4276
void CipherBase::Initialize(Environment* env, Local<Object> target) {
258
4276
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
259
260
8552
  t->InstanceTemplate()->SetInternalFieldCount(
261
      CipherBase::kInternalFieldCount);
262
4276
  t->Inherit(BaseObject::GetConstructorTemplate(env));
263
264
4276
  env->SetProtoMethod(t, "init", Init);
265
4276
  env->SetProtoMethod(t, "initiv", InitIv);
266
4276
  env->SetProtoMethod(t, "update", Update);
267
4276
  env->SetProtoMethod(t, "final", Final);
268
4276
  env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding);
269
4276
  env->SetProtoMethodNoSideEffect(t, "getAuthTag", GetAuthTag);
270
4276
  env->SetProtoMethod(t, "setAuthTag", SetAuthTag);
271
4276
  env->SetProtoMethod(t, "setAAD", SetAAD);
272
4276
  env->SetConstructorFunction(target, "CipherBase", t);
273
274
4276
  env->SetMethodNoSideEffect(target, "getSSLCiphers", GetSSLCiphers);
275
4276
  env->SetMethodNoSideEffect(target, "getCiphers", GetCiphers);
276
277
4276
  env->SetMethod(target, "publicEncrypt",
278
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
279
                                         EVP_PKEY_encrypt_init,
280
                                         EVP_PKEY_encrypt>);
281
4276
  env->SetMethod(target, "privateDecrypt",
282
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
283
                                         EVP_PKEY_decrypt_init,
284
                                         EVP_PKEY_decrypt>);
285
4276
  env->SetMethod(target, "privateEncrypt",
286
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
287
                                         EVP_PKEY_sign_init,
288
                                         EVP_PKEY_sign>);
289
4276
  env->SetMethod(target, "publicDecrypt",
290
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
291
                                         EVP_PKEY_verify_recover_init,
292
                                         EVP_PKEY_verify_recover>);
293
294
4276
  env->SetMethodNoSideEffect(target, "getCipherInfo", GetCipherInfo);
295
296
12828
  NODE_DEFINE_CONSTANT(target, kWebCryptoCipherEncrypt);
297
8552
  NODE_DEFINE_CONSTANT(target, kWebCryptoCipherDecrypt);
298
4276
}
299
300
1273
void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
301
1273
  CHECK(args.IsConstructCall());
302
1273
  Environment* env = Environment::GetCurrent(args);
303

2546
  new CipherBase(env, args.This(), args[0]->IsTrue() ? kCipher : kDecipher);
304
1273
}
305
306
697
void CipherBase::CommonInit(const char* cipher_type,
307
                            const EVP_CIPHER* cipher,
308
                            const unsigned char* key,
309
                            int key_len,
310
                            const unsigned char* iv,
311
                            int iv_len,
312
                            unsigned int auth_tag_len) {
313
697
  CHECK(!ctx_);
314
697
  ctx_.reset(EVP_CIPHER_CTX_new());
315
316
697
  const int mode = EVP_CIPHER_mode(cipher);
317
697
  if (mode == EVP_CIPH_WRAP_MODE)
318
18
    EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
319
320
697
  const bool encrypt = (kind_ == kCipher);
321
697
  if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
322
                             nullptr, nullptr, encrypt)) {
323
    return ThrowCryptoError(env(), ERR_get_error(),
324
                            "Failed to initialize cipher");
325
  }
326
327
697
  if (IsSupportedAuthenticatedMode(cipher)) {
328
576
    CHECK_GE(iv_len, 0);
329
576
    if (!InitAuthenticated(cipher_type, iv_len, auth_tag_len))
330
72
      return;
331
  }
332
333
625
  if (!EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len)) {
334
1
    ctx_.reset();
335
1
    return THROW_ERR_CRYPTO_INVALID_KEYLEN(env());
336
  }
337
338
624
  if (1 != EVP_CipherInit_ex(ctx_.get(), nullptr, nullptr, key, iv, encrypt)) {
339
    return ThrowCryptoError(env(), ERR_get_error(),
340
                            "Failed to initialize cipher");
341
  }
342
}
343
344
89
void CipherBase::Init(const char* cipher_type,
345
                      const ArrayBufferOrViewContents<unsigned char>& key_buf,
346
                      unsigned int auth_tag_len) {
347
89
  HandleScope scope(env()->isolate());
348
89
  MarkPopErrorOnReturn mark_pop_error_on_return;
349
#if OPENSSL_VERSION_MAJOR >= 3
350
  if (EVP_default_properties_is_fips_enabled(nullptr)) {
351
#else
352
89
  if (FIPS_mode()) {
353
#endif
354
    return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
355
        "crypto.createCipher() is not supported in FIPS mode.");
356
  }
357
358
89
  const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
359
89
  if (cipher == nullptr)
360
    return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
361
362
  unsigned char key[EVP_MAX_KEY_LENGTH];
363
  unsigned char iv[EVP_MAX_IV_LENGTH];
364
365
89
  int key_len = EVP_BytesToKey(cipher,
366
                               EVP_md5(),
367
                               nullptr,
368
                               key_buf.data(),
369
89
                               key_buf.size(),
370
                               1,
371
                               key,
372
89
                               iv);
373
89
  CHECK_NE(key_len, 0);
374
375
89
  const int mode = EVP_CIPHER_mode(cipher);
376

89
  if (kind_ == kCipher && (mode == EVP_CIPH_CTR_MODE ||
377
43
                           mode == EVP_CIPH_GCM_MODE ||
378
                           mode == EVP_CIPH_CCM_MODE)) {
379
    // Ignore the return value (i.e. possible exception) because we are
380
    // not calling back into JS anyway.
381
    ProcessEmitWarning(env(),
382
                       "Use Cipheriv for counter mode of %s",
383
24
                       cipher_type);
384
  }
385
386
89
  CommonInit(cipher_type, cipher, key, key_len, iv,
387
             EVP_CIPHER_iv_length(cipher), auth_tag_len);
388
}
389
390
89
void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
391
  CipherBase* cipher;
392
89
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
393
89
  Environment* env = Environment::GetCurrent(args);
394
395
89
  CHECK_GE(args.Length(), 3);
396
397
89
  const Utf8Value cipher_type(args.GetIsolate(), args[0]);
398
89
  ArrayBufferOrViewContents<unsigned char> key_buf(args[1]);
399
89
  if (!key_buf.CheckSizeInt32())
400
    return THROW_ERR_OUT_OF_RANGE(env, "password is too large");
401
402
  // Don't assign to cipher->auth_tag_len_ directly; the value might not
403
  // represent a valid length at this point.
404
  unsigned int auth_tag_len;
405
89
  if (args[2]->IsUint32()) {
406
70
    auth_tag_len = args[2].As<Uint32>()->Value();
407
  } else {
408

162
    CHECK(args[2]->IsInt32() && args[2].As<Int32>()->Value() == -1);
409
54
    auth_tag_len = kNoAuthTagLength;
410
  }
411
412
89
  cipher->Init(*cipher_type, key_buf, auth_tag_len);
413
}
414
415
1184
void CipherBase::InitIv(const char* cipher_type,
416
                        const ByteSource& key_buf,
417
                        const ArrayBufferOrViewContents<unsigned char>& iv_buf,
418
                        unsigned int auth_tag_len) {
419
1184
  HandleScope scope(env()->isolate());
420
1184
  MarkPopErrorOnReturn mark_pop_error_on_return;
421
422
1184
  const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
423
1184
  if (cipher == nullptr)
424
1
    return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
425
426
1183
  const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
427
1183
  const bool is_authenticated_mode = IsSupportedAuthenticatedMode(cipher);
428
1183
  const bool has_iv = iv_buf.size() > 0;
429
430
  // Throw if no IV was passed and the cipher requires an IV
431

1183
  if (!has_iv && expected_iv_len != 0)
432
61
    return THROW_ERR_CRYPTO_INVALID_IV(env());
433
434
  // Throw if an IV was passed which does not match the cipher's fixed IV length
435
  // static_cast<int> for the iv_buf.size() is safe because we've verified
436
  // prior that the value is not larger than MAX_INT.
437
588
  if (!is_authenticated_mode &&
438

1710
      has_iv &&
439
577
      static_cast<int>(iv_buf.size()) != expected_iv_len) {
440
509
    return THROW_ERR_CRYPTO_INVALID_IV(env());
441
  }
442
443
613
  if (EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305) {
444
11
    CHECK(has_iv);
445
    // Check for invalid IV lengths, since OpenSSL does not under some
446
    // conditions:
447
    //   https://www.openssl.org/news/secadv/20190306.txt.
448
11
    if (iv_buf.size() > 12)
449
5
      return THROW_ERR_CRYPTO_INVALID_IV(env());
450
  }
451
452
1216
  CommonInit(
453
      cipher_type,
454
      cipher,
455
      key_buf.data<unsigned char>(),
456
608
      key_buf.size(),
457
      iv_buf.data(),
458
608
      iv_buf.size(),
459
      auth_tag_len);
460
}
461
462
1184
void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
463
  CipherBase* cipher;
464
1184
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
465
1184
  Environment* env = cipher->env();
466
467
1184
  CHECK_GE(args.Length(), 4);
468
469
1184
  const Utf8Value cipher_type(env->isolate(), args[0]);
470
471
  // The argument can either be a KeyObjectHandle or a byte source
472
  // (e.g. ArrayBuffer, TypedArray, etc). Whichever it is, grab the
473
  // raw bytes and proceed...
474
1184
  const ByteSource key_buf = ByteSource::FromSecretKeyBytes(env, args[1]);
475
476
1184
  if (UNLIKELY(key_buf.size() > INT_MAX))
477
    return THROW_ERR_OUT_OF_RANGE(env, "key is too big");
478
479
1184
  ArrayBufferOrViewContents<unsigned char> iv_buf;
480
2368
  if (!args[2]->IsNull())
481
1178
    iv_buf = ArrayBufferOrViewContents<unsigned char>(args[2]);
482
483
1184
  if (UNLIKELY(!iv_buf.CheckSizeInt32()))
484
    return THROW_ERR_OUT_OF_RANGE(env, "iv is too big");
485
486
  // Don't assign to cipher->auth_tag_len_ directly; the value might not
487
  // represent a valid length at this point.
488
  unsigned int auth_tag_len;
489
1184
  if (args[3]->IsUint32()) {
490
376
    auth_tag_len = args[3].As<Uint32>()->Value();
491
  } else {
492

2988
    CHECK(args[3]->IsInt32() && args[3].As<Int32>()->Value() == -1);
493
996
    auth_tag_len = kNoAuthTagLength;
494
  }
495
496
1184
  cipher->InitIv(*cipher_type, key_buf, iv_buf, auth_tag_len);
497
}
498
499
576
bool CipherBase::InitAuthenticated(
500
    const char* cipher_type,
501
    int iv_len,
502
    unsigned int auth_tag_len) {
503
576
  CHECK(IsAuthenticatedMode());
504
1152
  MarkPopErrorOnReturn mark_pop_error_on_return;
505
506
576
  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
507
                           EVP_CTRL_AEAD_SET_IVLEN,
508
                           iv_len,
509
                           nullptr)) {
510
    THROW_ERR_CRYPTO_INVALID_IV(env());
511
    return false;
512
  }
513
514
576
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
515
576
  if (mode == EVP_CIPH_GCM_MODE) {
516
374
    if (auth_tag_len != kNoAuthTagLength) {
517
24
      if (!IsValidGCMTagLength(auth_tag_len)) {
518
16
        THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
519
          env(),
520
          "Invalid authentication tag length: %u",
521
          auth_tag_len);
522
16
        return false;
523
      }
524
525
      // Remember the given authentication tag length for later.
526
8
      auth_tag_len_ = auth_tag_len;
527
    }
528
  } else {
529
202
    if (auth_tag_len == kNoAuthTagLength) {
530
8
      THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
531
        env(), "authTagLength required for %s", cipher_type);
532
8
      return false;
533
    }
534
535
    // TODO(tniessen) Support CCM decryption in FIPS mode
536
537
#if OPENSSL_VERSION_MAJOR >= 3
538
    if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher &&
539
        EVP_default_properties_is_fips_enabled(nullptr)) {
540
#else
541


194
    if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) {
542
#endif
543
      THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
544
          "CCM encryption not supported in FIPS mode");
545
      return false;
546
    }
547
548
    // Tell OpenSSL about the desired length.
549
194
    if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
550
                             nullptr)) {
551
48
      THROW_ERR_CRYPTO_INVALID_AUTH_TAG(env());
552
48
      return false;
553
    }
554
555
    // Remember the given authentication tag length for later.
556
146
    auth_tag_len_ = auth_tag_len;
557
558
146
    if (mode == EVP_CIPH_CCM_MODE) {
559
      // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes.
560

81
      CHECK(iv_len >= 7 && iv_len <= 13);
561
81
      max_message_size_ = INT_MAX;
562
81
      if (iv_len == 12) max_message_size_ = 16777215;
563
81
      if (iv_len == 13) max_message_size_ = 65535;
564
    }
565
  }
566
567
504
  return true;
568
}
569
570
127
bool CipherBase::CheckCCMMessageLength(int message_len) {
571
127
  CHECK(ctx_);
572
127
  CHECK(EVP_CIPHER_CTX_mode(ctx_.get()) == EVP_CIPH_CCM_MODE);
573
574
127
  if (message_len > max_message_size_) {
575
4
    THROW_ERR_CRYPTO_INVALID_MESSAGELEN(env());
576
4
    return false;
577
  }
578
579
123
  return true;
580
}
581
582
1306
bool CipherBase::IsAuthenticatedMode() const {
583
  // Check if this cipher operates in an AEAD mode that we support.
584
1306
  CHECK(ctx_);
585
1306
  return IsSupportedAuthenticatedMode(ctx_.get());
586
}
587
588
145
void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
589
145
  Environment* env = Environment::GetCurrent(args);
590
  CipherBase* cipher;
591
205
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
592
593
  // Only callable after Final and if encrypting.
594
376
  if (cipher->ctx_ ||
595

231
      cipher->kind_ != kCipher ||
596
86
      cipher->auth_tag_len_ == kNoAuthTagLength) {
597
60
    return;
598
  }
599
600
85
  args.GetReturnValue().Set(
601
170
      Buffer::Copy(env, cipher->auth_tag_, cipher->auth_tag_len_)
602
          .FromMaybe(Local<Value>()));
603
}
604
605
98
void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
606
  CipherBase* cipher;
607
111
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
608
98
  Environment* env = Environment::GetCurrent(args);
609
610
98
  if (!cipher->ctx_ ||
611
97
      !cipher->IsAuthenticatedMode() ||
612

292
      cipher->kind_ != kDecipher ||
613
97
      cipher->auth_tag_state_ != kAuthTagUnknown) {
614
8
    return args.GetReturnValue().Set(false);
615
  }
616
617
94
  ArrayBufferOrViewContents<char> auth_tag(args[0]);
618
94
  if (UNLIKELY(!auth_tag.CheckSizeInt32()))
619
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
620
621
94
  unsigned int tag_len = auth_tag.size();
622
623
94
  const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
624
  bool is_valid;
625
94
  if (mode == EVP_CIPH_GCM_MODE) {
626
    // Restrict GCM tag lengths according to NIST 800-38d, page 9.
627
43
    is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
628

85
                cipher->auth_tag_len_ == tag_len) &&
629
42
               IsValidGCMTagLength(tag_len);
630
  } else {
631
    // At this point, the tag length is already known and must match the
632
    // length of the given authentication tag.
633
51
    CHECK(IsSupportedAuthenticatedMode(cipher->ctx_.get()));
634
51
    CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength);
635
51
    is_valid = cipher->auth_tag_len_ == tag_len;
636
  }
637
638
94
  if (!is_valid) {
639
9
    return THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
640
9
      env, "Invalid authentication tag length: %u", tag_len);
641
  }
642
643
85
  cipher->auth_tag_len_ = tag_len;
644
85
  cipher->auth_tag_state_ = kAuthTagKnown;
645
85
  CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
646
647
85
  memset(cipher->auth_tag_, 0, sizeof(cipher->auth_tag_));
648
85
  auth_tag.CopyTo(cipher->auth_tag_, cipher->auth_tag_len_);
649
650
170
  args.GetReturnValue().Set(true);
651
}
652
653
196
bool CipherBase::MaybePassAuthTagToOpenSSL() {
654
196
  if (auth_tag_state_ == kAuthTagKnown) {
655
84
    if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
656
                             EVP_CTRL_AEAD_SET_TAG,
657
84
                             auth_tag_len_,
658
84
                             reinterpret_cast<unsigned char*>(auth_tag_))) {
659
      return false;
660
    }
661
84
    auth_tag_state_ = kAuthTagPassedToOpenSSL;
662
  }
663
196
  return true;
664
}
665
666
118
bool CipherBase::SetAAD(
667
    const ArrayBufferOrViewContents<unsigned char>& data,
668
    int plaintext_len) {
669

118
  if (!ctx_ || !IsAuthenticatedMode())
670
2
    return false;
671
232
  MarkPopErrorOnReturn mark_pop_error_on_return;
672
673
  int outlen;
674
116
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
675
676
  // When in CCM mode, we need to set the authentication tag and the plaintext
677
  // length in advance.
678
116
  if (mode == EVP_CIPH_CCM_MODE) {
679
55
    if (plaintext_len < 0) {
680
2
      THROW_ERR_MISSING_ARGS(env(),
681
          "options.plaintextLength required for CCM mode with AAD");
682
2
      return false;
683
    }
684
685
53
    if (!CheckCCMMessageLength(plaintext_len))
686
2
      return false;
687
688
51
    if (kind_ == kDecipher) {
689
26
      if (!MaybePassAuthTagToOpenSSL())
690
        return false;
691
    }
692
693
    // Specify the plaintext length.
694
51
    if (!EVP_CipherUpdate(ctx_.get(), nullptr, &outlen, nullptr, plaintext_len))
695
      return false;
696
  }
697
698
112
  return 1 == EVP_CipherUpdate(ctx_.get(),
699
                               nullptr,
700
                               &outlen,
701
                               data.data(),
702
224
                               data.size());
703
}
704
705
118
void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
706
  CipherBase* cipher;
707
118
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
708
118
  Environment* env = Environment::GetCurrent(args);
709
710
118
  CHECK_EQ(args.Length(), 2);
711
118
  CHECK(args[1]->IsInt32());
712
236
  int plaintext_len = args[1].As<Int32>()->Value();
713
118
  ArrayBufferOrViewContents<unsigned char> buf(args[0]);
714
715
118
  if (UNLIKELY(!buf.CheckSizeInt32()))
716
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
717
236
  args.GetReturnValue().Set(cipher->SetAAD(buf, plaintext_len));
718
}
719
720
330
CipherBase::UpdateResult CipherBase::Update(
721
    const char* data,
722
    size_t len,
723
    AllocatedBuffer* out) {
724

330
  if (!ctx_ || len > INT_MAX)
725
    return kErrorState;
726
660
  MarkPopErrorOnReturn mark_pop_error_on_return;
727
728
330
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
729
730

330
  if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength(len))
731
2
    return kErrorMessageSize;
732
733
  // Pass the authentication tag to OpenSSL if possible. This will only happen
734
  // once, usually on the first update.
735

328
  if (kind_ == kDecipher && IsAuthenticatedMode())
736
85
    CHECK(MaybePassAuthTagToOpenSSL());
737
738
328
  int buf_len = len + EVP_CIPHER_CTX_block_size(ctx_.get());
739
  // For key wrapping algorithms, get output size by calling
740
  // EVP_CipherUpdate() with null output.
741


337
  if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE &&
742
9
      EVP_CipherUpdate(ctx_.get(),
743
                       nullptr,
744
                       &buf_len,
745
                       reinterpret_cast<const unsigned char*>(data),
746
                       len) != 1) {
747
    return kErrorState;
748
  }
749
750
328
  *out = AllocatedBuffer::AllocateManaged(env(), buf_len);
751
328
  int r = EVP_CipherUpdate(ctx_.get(),
752
328
                           reinterpret_cast<unsigned char*>(out->data()),
753
                           &buf_len,
754
                           reinterpret_cast<const unsigned char*>(data),
755
                           len);
756
757
328
  CHECK_LE(static_cast<size_t>(buf_len), out->size());
758
328
  out->Resize(buf_len);
759
760
  // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
761
  // invalid. In that case, remember the error and throw in final().
762

328
  if (!r && kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
763
5
    pending_auth_failed_ = true;
764
5
    return kSuccess;
765
  }
766
323
  return r == 1 ? kSuccess : kErrorState;
767
}
768
769
330
void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
770
330
  Decode<CipherBase>(args, [](CipherBase* cipher,
771
                              const FunctionCallbackInfo<Value>& args,
772
330
                              const char* data, size_t size) {
773
330
    AllocatedBuffer out;
774
330
    Environment* env = Environment::GetCurrent(args);
775
776
330
    if (UNLIKELY(size > INT_MAX))
777
      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
778
779
330
    UpdateResult r = cipher->Update(data, size, &out);
780
781
330
    if (r != kSuccess) {
782
2
      if (r == kErrorState) {
783
        ThrowCryptoError(env, ERR_get_error(),
784
                         "Trying to add data in unsupported state");
785
      }
786
2
      return;
787
    }
788
789

328
    CHECK(out.data() != nullptr || out.size() == 0);
790
984
    args.GetReturnValue().Set(out.ToBuffer().FromMaybe(Local<Value>()));
791
  });
792
330
}
793
794
18
bool CipherBase::SetAutoPadding(bool auto_padding) {
795
18
  if (!ctx_)
796
1
    return false;
797
17
  MarkPopErrorOnReturn mark_pop_error_on_return;
798
17
  return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
799
}
800
801
18
void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
802
  CipherBase* cipher;
803
18
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
804
805

36
  bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue());
806
36
  args.GetReturnValue().Set(b);  // Possibly report invalid state failure
807
}
808
809
256
bool CipherBase::Final(AllocatedBuffer* out) {
810
256
  if (!ctx_)
811
    return false;
812
813
256
  const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
814
815
512
  *out = AllocatedBuffer::AllocateManaged(
816
      env(),
817
512
      static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
818
819

256
  if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get())) {
820
85
    MaybePassAuthTagToOpenSSL();
821
  }
822
823
  // In CCM mode, final() only checks whether authentication failed in update().
824
  // EVP_CipherFinal_ex must not be called and will fail.
825
  bool ok;
826

256
  if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
827
29
    ok = !pending_auth_failed_;
828
29
    *out = AllocatedBuffer::AllocateManaged(env(), 0);  // Empty buffer.
829
  } else {
830
227
    int out_len = out->size();
831
227
    ok = EVP_CipherFinal_ex(ctx_.get(),
832
227
                            reinterpret_cast<unsigned char*>(out->data()),
833
                            &out_len) == 1;
834
835
227
    if (out_len >= 0)
836
227
      out->Resize(out_len);
837
    else
838
      *out = AllocatedBuffer();  // *out will not be used.
839
840


227
    if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
841
      // In GCM mode, the authentication tag length can be specified in advance,
842
      // but defaults to 16 bytes when encrypting. In CCM and OCB mode, it must
843
      // always be given by the user.
844
85
      if (auth_tag_len_ == kNoAuthTagLength) {
845
30
        CHECK(mode == EVP_CIPH_GCM_MODE);
846
30
        auth_tag_len_ = sizeof(auth_tag_);
847
      }
848
85
      ok = (1 == EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
849
85
                     auth_tag_len_,
850
85
                     reinterpret_cast<unsigned char*>(auth_tag_)));
851
    }
852
  }
853
854
256
  ctx_.reset();
855
856
256
  return ok;
857
}
858
859
260
void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
860
260
  Environment* env = Environment::GetCurrent(args);
861
862
  CipherBase* cipher;
863
281
  ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
864
260
  if (cipher->ctx_ == nullptr)
865
4
    return THROW_ERR_CRYPTO_INVALID_STATE(env);
866
867
256
  AllocatedBuffer out;
868
869
  // Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
870
256
  const bool is_auth_mode = cipher->IsAuthenticatedMode();
871
256
  bool r = cipher->Final(&out);
872
873
256
  if (!r) {
874
17
    const char* msg = is_auth_mode
875
17
                          ? "Unsupported state or unable to authenticate data"
876
                          : "Unsupported state";
877
878
17
    return ThrowCryptoError(env, ERR_get_error(), msg);
879
  }
880
881
717
  args.GetReturnValue().Set(out.ToBuffer().FromMaybe(Local<Value>()));
882
}
883
884
template <PublicKeyCipher::Operation operation,
885
          PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
886
          PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
887
316
bool PublicKeyCipher::Cipher(
888
    Environment* env,
889
    const ManagedEVPPKey& pkey,
890
    int padding,
891
    const EVP_MD* digest,
892
    const ArrayBufferOrViewContents<unsigned char>& oaep_label,
893
    const ArrayBufferOrViewContents<unsigned char>& data,
894
    AllocatedBuffer* out) {
895
316
  EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
896


158
  if (!ctx)
897
    return false;
898


158
  if (EVP_PKEY_cipher_init(ctx.get()) <= 0)
899
1
    return false;
900


157
  if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), padding) <= 0)
901
    return false;
902
903


157
  if (digest != nullptr) {
904


21
    if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), digest) <= 0)
905
      return false;
906
  }
907
908


157
  if (oaep_label.size() != 0) {
909
    // OpenSSL takes ownership of the label, so we need to create a copy.
910
4
    void* label = OPENSSL_memdup(oaep_label.data(), oaep_label.size());
911


4
    CHECK_NOT_NULL(label);
912


4
    if (0 >= EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(),
913
                     static_cast<unsigned char*>(label),
914
                                      oaep_label.size())) {
915
      OPENSSL_free(label);
916
      return false;
917
    }
918
  }
919
920
157
  size_t out_len = 0;
921
157
  if (EVP_PKEY_cipher(
922
          ctx.get(),
923
          nullptr,
924
          &out_len,
925
          data.data(),
926


157
          data.size()) <= 0) {
927
    return false;
928
  }
929
930
157
  *out = AllocatedBuffer::AllocateManaged(env, out_len);
931
932
314
  if (EVP_PKEY_cipher(
933
          ctx.get(),
934
157
          reinterpret_cast<unsigned char*>(out->data()),
935
          &out_len,
936
          data.data(),
937


157
          data.size()) <= 0) {
938
1
    return false;
939
  }
940
941
156
  out->Resize(out_len);
942
156
  return true;
943
}
944
945
template <PublicKeyCipher::Operation operation,
946
          PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
947
          PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
948
164
void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
949
164
  MarkPopErrorOnReturn mark_pop_error_on_return;
950
164
  Environment* env = Environment::GetCurrent(args);
951
952
164
  unsigned int offset = 0;
953
164
  ManagedEVPPKey pkey =
954
      ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
955
164
  if (!pkey)
956
4
    return;
957
958
320
  ArrayBufferOrViewContents<unsigned char> buf(args[offset]);
959
160
  if (UNLIKELY(!buf.CheckSizeInt32()))
960
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too long");
961
962
  uint32_t padding;
963
480
  if (!args[offset + 1]->Uint32Value(env->context()).To(&padding)) return;
964
965
160
  const EVP_MD* digest = nullptr;
966
480
  if (args[offset + 2]->IsString()) {
967
46
    const Utf8Value oaep_str(env->isolate(), args[offset + 2]);
968
23
    digest = EVP_get_digestbyname(*oaep_str);
969
23
    if (digest == nullptr)
970
2
      return THROW_ERR_OSSL_EVP_INVALID_DIGEST(env);
971
  }
972
973
158
  ArrayBufferOrViewContents<unsigned char> oaep_label;
974
474
  if (!args[offset + 3]->IsUndefined()) {
975
8
    oaep_label = ArrayBufferOrViewContents<unsigned char>(args[offset + 3]);
976
4
    if (UNLIKELY(!oaep_label.CheckSizeInt32()))
977
      return THROW_ERR_OUT_OF_RANGE(env, "oaep_label is too big");
978
  }
979
980
158
  AllocatedBuffer out;
981
158
  if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
982
          env, pkey, padding, digest, oaep_label, buf, &out)) {
983
2
    return ThrowCryptoError(env, ERR_get_error());
984
  }
985
986
  Local<Value> result;
987
312
  if (out.ToBuffer().ToLocal(&result))
988
312
    args.GetReturnValue().Set(result);
989
}
990
991
}  // namespace crypto
992
}  // namespace node