• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "node_revert.h"
10 #include "v8.h"
11 
12 namespace node {
13 
14 using v8::Array;
15 using v8::ArrayBuffer;
16 using v8::BackingStore;
17 using v8::Context;
18 using v8::FunctionCallbackInfo;
19 using v8::FunctionTemplate;
20 using v8::HandleScope;
21 using v8::Int32;
22 using v8::Isolate;
23 using v8::Local;
24 using v8::Object;
25 using v8::Uint32;
26 using v8::Value;
27 
28 namespace crypto {
29 namespace {
IsSupportedAuthenticatedMode(const EVP_CIPHER * cipher)30 bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
31   switch (EVP_CIPHER_mode(cipher)) {
32   case EVP_CIPH_CCM_MODE:
33   case EVP_CIPH_GCM_MODE:
34 #ifndef OPENSSL_NO_OCB
35   case EVP_CIPH_OCB_MODE:
36 #endif
37     return true;
38   case EVP_CIPH_STREAM_CIPHER:
39     return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305;
40   default:
41     return false;
42   }
43 }
44 
IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX * ctx)45 bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
46   const EVP_CIPHER* cipher = EVP_CIPHER_CTX_cipher(ctx);
47   return IsSupportedAuthenticatedMode(cipher);
48 }
49 
IsValidGCMTagLength(unsigned int tag_len)50 bool IsValidGCMTagLength(unsigned int tag_len) {
51   return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16);
52 }
53 
54 // Collects and returns information on the given cipher
GetCipherInfo(const FunctionCallbackInfo<Value> & args)55 void GetCipherInfo(const FunctionCallbackInfo<Value>& args) {
56   Environment* env = Environment::GetCurrent(args);
57   CHECK(args[0]->IsObject());
58   Local<Object> info = args[0].As<Object>();
59 
60   CHECK(args[1]->IsString() || args[1]->IsInt32());
61 
62   const EVP_CIPHER* cipher;
63   if (args[1]->IsString()) {
64     Utf8Value name(env->isolate(), args[1]);
65     cipher = EVP_get_cipherbyname(*name);
66   } else {
67     int nid = args[1].As<Int32>()->Value();
68     cipher = EVP_get_cipherbynid(nid);
69   }
70 
71   if (cipher == nullptr)
72     return;
73 
74   int mode = EVP_CIPHER_mode(cipher);
75   int iv_length = EVP_CIPHER_iv_length(cipher);
76   int key_length = EVP_CIPHER_key_length(cipher);
77   int block_length = EVP_CIPHER_block_size(cipher);
78   const char* mode_label = nullptr;
79   switch (mode) {
80     case EVP_CIPH_CBC_MODE: mode_label = "cbc"; break;
81     case EVP_CIPH_CCM_MODE: mode_label = "ccm"; break;
82     case EVP_CIPH_CFB_MODE: mode_label = "cfb"; break;
83     case EVP_CIPH_CTR_MODE: mode_label = "ctr"; break;
84     case EVP_CIPH_ECB_MODE: mode_label = "ecb"; break;
85     case EVP_CIPH_GCM_MODE: mode_label = "gcm"; break;
86     case EVP_CIPH_OCB_MODE: mode_label = "ocb"; break;
87     case EVP_CIPH_OFB_MODE: mode_label = "ofb"; break;
88     case EVP_CIPH_WRAP_MODE: mode_label = "wrap"; break;
89     case EVP_CIPH_XTS_MODE: mode_label = "xts"; break;
90     case EVP_CIPH_STREAM_CIPHER: mode_label = "stream"; break;
91   }
92 
93   // If the testKeyLen and testIvLen arguments are specified,
94   // then we will make an attempt to see if they are usable for
95   // the cipher in question, returning undefined if they are not.
96   // If they are, the info object will be returned with the values
97   // given.
98   if (args[2]->IsInt32() || args[3]->IsInt32()) {
99     // Test and input IV or key length to determine if it's acceptable.
100     // If it is, then the getCipherInfo will succeed with the given
101     // values.
102     CipherCtxPointer ctx(EVP_CIPHER_CTX_new());
103     if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr, 1))
104       return;
105 
106     if (args[2]->IsInt32()) {
107       int check_len = args[2].As<Int32>()->Value();
108       if (!EVP_CIPHER_CTX_set_key_length(ctx.get(), check_len))
109         return;
110       key_length = check_len;
111     }
112 
113     if (args[3]->IsInt32()) {
114       int check_len = args[3].As<Int32>()->Value();
115       // For CCM modes, the IV may be between 7 and 13 bytes.
116       // For GCM and OCB modes, we'll check by attempting to
117       // set the value. For everything else, just check that
118       // check_len == iv_length.
119       switch (mode) {
120         case EVP_CIPH_CCM_MODE:
121           if (check_len < 7 || check_len > 13)
122             return;
123           break;
124         case EVP_CIPH_GCM_MODE:
125           // Fall through
126         case EVP_CIPH_OCB_MODE:
127           if (!EVP_CIPHER_CTX_ctrl(
128                   ctx.get(),
129                   EVP_CTRL_AEAD_SET_IVLEN,
130                   check_len,
131                   nullptr)) {
132             return;
133           }
134           break;
135         default:
136           if (check_len != iv_length)
137             return;
138       }
139       iv_length = check_len;
140     }
141   }
142 
143   if (mode_label != nullptr &&
144       info->Set(
145           env->context(),
146           FIXED_ONE_BYTE_STRING(env->isolate(), "mode"),
147           OneByteString(env->isolate(), mode_label)).IsNothing()) {
148     return;
149   }
150 
151   // OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
152   // EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
153   if (info->Set(
154           env->context(),
155           env->name_string(),
156           OneByteString(
157             env->isolate(),
158             OBJ_nid2sn(EVP_CIPHER_nid(cipher)))).IsNothing()) {
159     return;
160   }
161 
162   if (info->Set(
163           env->context(),
164           FIXED_ONE_BYTE_STRING(env->isolate(), "nid"),
165           Int32::New(env->isolate(), EVP_CIPHER_nid(cipher))).IsNothing()) {
166     return;
167   }
168 
169   // Stream ciphers do not have a meaningful block size
170   if (mode != EVP_CIPH_STREAM_CIPHER &&
171       info->Set(
172           env->context(),
173           FIXED_ONE_BYTE_STRING(env->isolate(), "blockSize"),
174           Int32::New(env->isolate(), block_length)).IsNothing()) {
175     return;
176   }
177 
178   // Ciphers that do not use an IV shouldn't report a length
179   if (iv_length != 0 &&
180       info->Set(
181           env->context(),
182           FIXED_ONE_BYTE_STRING(env->isolate(), "ivLength"),
183           Int32::New(env->isolate(), iv_length)).IsNothing()) {
184     return;
185   }
186 
187   if (info->Set(
188           env->context(),
189           FIXED_ONE_BYTE_STRING(env->isolate(), "keyLength"),
190           Int32::New(env->isolate(), key_length)).IsNothing()) {
191     return;
192   }
193 
194   args.GetReturnValue().Set(info);
195 }
196 }  // namespace
197 
GetSSLCiphers(const FunctionCallbackInfo<Value> & args)198 void CipherBase::GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
199   Environment* env = Environment::GetCurrent(args);
200 
201   SSLCtxPointer ctx(SSL_CTX_new(TLS_method()));
202   if (!ctx) {
203     return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new");
204   }
205 
206   SSLPointer ssl(SSL_new(ctx.get()));
207   if (!ssl) {
208     return ThrowCryptoError(env, ERR_get_error(), "SSL_new");
209   }
210 
211   STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl.get());
212 
213   // TLSv1.3 ciphers aren't listed by EVP. There are only 5, we could just
214   // document them, but since there are only 5, easier to just add them manually
215   // and not have to explain their absence in the API docs. They are lower-cased
216   // because the docs say they will be.
217   static const char* TLS13_CIPHERS[] = {
218     "tls_aes_256_gcm_sha384",
219     "tls_chacha20_poly1305_sha256",
220     "tls_aes_128_gcm_sha256",
221     "tls_aes_128_ccm_8_sha256",
222     "tls_aes_128_ccm_sha256"
223   };
224 
225   const int n = sk_SSL_CIPHER_num(ciphers);
226   std::vector<Local<Value>> arr(n + arraysize(TLS13_CIPHERS));
227 
228   for (int i = 0; i < n; ++i) {
229     const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
230     arr[i] = OneByteString(env->isolate(), SSL_CIPHER_get_name(cipher));
231   }
232 
233   for (unsigned i = 0; i < arraysize(TLS13_CIPHERS); ++i) {
234     const char* name = TLS13_CIPHERS[i];
235     arr[n + i] = OneByteString(env->isolate(), name);
236   }
237 
238   args.GetReturnValue().Set(Array::New(env->isolate(), arr.data(), arr.size()));
239 }
240 
GetCiphers(const FunctionCallbackInfo<Value> & args)241 void CipherBase::GetCiphers(const FunctionCallbackInfo<Value>& args) {
242   Environment* env = Environment::GetCurrent(args);
243   MarkPopErrorOnReturn mark_pop_error_on_return;
244   CipherPushContext ctx(env);
245   EVP_CIPHER_do_all_sorted(
246 #if OPENSSL_VERSION_MAJOR >= 3
247     array_push_back<EVP_CIPHER,
248                     EVP_CIPHER_fetch,
249                     EVP_CIPHER_free,
250                     EVP_get_cipherbyname,
251                     EVP_CIPHER_get0_name>,
252 #else
253     array_push_back<EVP_CIPHER>,
254 #endif
255     &ctx);
256   args.GetReturnValue().Set(ctx.ToJSArray());
257 }
258 
CipherBase(Environment * env,Local<Object> wrap,CipherKind kind)259 CipherBase::CipherBase(Environment* env,
260                        Local<Object> wrap,
261                        CipherKind kind)
262     : BaseObject(env, wrap),
263       ctx_(nullptr),
264       kind_(kind),
265       auth_tag_state_(kAuthTagUnknown),
266       auth_tag_len_(kNoAuthTagLength),
267       pending_auth_failed_(false) {
268   MakeWeak();
269 }
270 
MemoryInfo(MemoryTracker * tracker) const271 void CipherBase::MemoryInfo(MemoryTracker* tracker) const {
272   tracker->TrackFieldWithSize("context", ctx_ ? kSizeOf_EVP_CIPHER_CTX : 0);
273 }
274 
Initialize(Environment * env,Local<Object> target)275 void CipherBase::Initialize(Environment* env, Local<Object> target) {
276   Isolate* isolate = env->isolate();
277   Local<Context> context = env->context();
278 
279   Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New);
280 
281   t->InstanceTemplate()->SetInternalFieldCount(
282       CipherBase::kInternalFieldCount);
283   t->Inherit(BaseObject::GetConstructorTemplate(env));
284 
285   SetProtoMethod(isolate, t, "init", Init);
286   SetProtoMethod(isolate, t, "initiv", InitIv);
287   SetProtoMethod(isolate, t, "update", Update);
288   SetProtoMethod(isolate, t, "final", Final);
289   SetProtoMethod(isolate, t, "setAutoPadding", SetAutoPadding);
290   SetProtoMethodNoSideEffect(isolate, t, "getAuthTag", GetAuthTag);
291   SetProtoMethod(isolate, t, "setAuthTag", SetAuthTag);
292   SetProtoMethod(isolate, t, "setAAD", SetAAD);
293   SetConstructorFunction(context, target, "CipherBase", t);
294 
295   SetMethodNoSideEffect(context, target, "getSSLCiphers", GetSSLCiphers);
296   SetMethodNoSideEffect(context, target, "getCiphers", GetCiphers);
297 
298   SetMethod(context,
299             target,
300             "publicEncrypt",
301             PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
302                                     EVP_PKEY_encrypt_init,
303                                     EVP_PKEY_encrypt>);
304   SetMethod(context,
305             target,
306             "privateDecrypt",
307             PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
308                                     EVP_PKEY_decrypt_init,
309                                     EVP_PKEY_decrypt>);
310   SetMethod(context,
311             target,
312             "privateEncrypt",
313             PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
314                                     EVP_PKEY_sign_init,
315                                     EVP_PKEY_sign>);
316   SetMethod(context,
317             target,
318             "publicDecrypt",
319             PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
320                                     EVP_PKEY_verify_recover_init,
321                                     EVP_PKEY_verify_recover>);
322 
323   SetMethodNoSideEffect(context, target, "getCipherInfo", GetCipherInfo);
324 
325   NODE_DEFINE_CONSTANT(target, kWebCryptoCipherEncrypt);
326   NODE_DEFINE_CONSTANT(target, kWebCryptoCipherDecrypt);
327 }
328 
RegisterExternalReferences(ExternalReferenceRegistry * registry)329 void CipherBase::RegisterExternalReferences(
330     ExternalReferenceRegistry* registry) {
331   registry->Register(New);
332 
333   registry->Register(Init);
334   registry->Register(InitIv);
335   registry->Register(Update);
336   registry->Register(Final);
337   registry->Register(SetAutoPadding);
338   registry->Register(GetAuthTag);
339   registry->Register(SetAuthTag);
340   registry->Register(SetAAD);
341 
342   registry->Register(GetSSLCiphers);
343   registry->Register(GetCiphers);
344 
345   registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
346                                              EVP_PKEY_encrypt_init,
347                                              EVP_PKEY_encrypt>);
348   registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
349                                              EVP_PKEY_decrypt_init,
350                                              EVP_PKEY_decrypt>);
351   registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
352                                              EVP_PKEY_sign_init,
353                                              EVP_PKEY_sign>);
354   registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
355                                              EVP_PKEY_verify_recover_init,
356                                              EVP_PKEY_verify_recover>);
357 
358   registry->Register(GetCipherInfo);
359 }
360 
New(const FunctionCallbackInfo<Value> & args)361 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
362   CHECK(args.IsConstructCall());
363   Environment* env = Environment::GetCurrent(args);
364   new CipherBase(env, args.This(), args[0]->IsTrue() ? kCipher : kDecipher);
365 }
366 
CommonInit(const char * cipher_type,const EVP_CIPHER * cipher,const unsigned char * key,int key_len,const unsigned char * iv,int iv_len,unsigned int auth_tag_len)367 void CipherBase::CommonInit(const char* cipher_type,
368                             const EVP_CIPHER* cipher,
369                             const unsigned char* key,
370                             int key_len,
371                             const unsigned char* iv,
372                             int iv_len,
373                             unsigned int auth_tag_len) {
374   CHECK(!ctx_);
375   ctx_.reset(EVP_CIPHER_CTX_new());
376 
377   const int mode = EVP_CIPHER_mode(cipher);
378   if (mode == EVP_CIPH_WRAP_MODE)
379     EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
380 
381   const bool encrypt = (kind_ == kCipher);
382   if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
383                              nullptr, nullptr, encrypt)) {
384     return ThrowCryptoError(env(), ERR_get_error(),
385                             "Failed to initialize cipher");
386   }
387 
388   if (IsSupportedAuthenticatedMode(cipher)) {
389     CHECK_GE(iv_len, 0);
390     if (!InitAuthenticated(cipher_type, iv_len, auth_tag_len))
391       return;
392   }
393 
394   if (!EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len)) {
395     ctx_.reset();
396     return THROW_ERR_CRYPTO_INVALID_KEYLEN(env());
397   }
398 
399   if (1 != EVP_CipherInit_ex(ctx_.get(), nullptr, nullptr, key, iv, encrypt)) {
400     return ThrowCryptoError(env(), ERR_get_error(),
401                             "Failed to initialize cipher");
402   }
403 }
404 
Init(const char * cipher_type,const ArrayBufferOrViewContents<unsigned char> & key_buf,unsigned int auth_tag_len)405 void CipherBase::Init(const char* cipher_type,
406                       const ArrayBufferOrViewContents<unsigned char>& key_buf,
407                       unsigned int auth_tag_len) {
408   HandleScope scope(env()->isolate());
409   MarkPopErrorOnReturn mark_pop_error_on_return;
410 #if OPENSSL_VERSION_MAJOR >= 3
411   if (EVP_default_properties_is_fips_enabled(nullptr)) {
412 #else
413   if (FIPS_mode()) {
414 #endif
415     return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
416         "crypto.createCipher() is not supported in FIPS mode.");
417   }
418 
419   const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
420   if (cipher == nullptr)
421     return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
422 
423   unsigned char key[EVP_MAX_KEY_LENGTH];
424   unsigned char iv[EVP_MAX_IV_LENGTH];
425 
426   int key_len = EVP_BytesToKey(cipher,
427                                EVP_md5(),
428                                nullptr,
429                                key_buf.data(),
430                                key_buf.size(),
431                                1,
432                                key,
433                                iv);
434   CHECK_NE(key_len, 0);
435 
436   const int mode = EVP_CIPHER_mode(cipher);
437   if (kind_ == kCipher && (mode == EVP_CIPH_CTR_MODE ||
438                            mode == EVP_CIPH_GCM_MODE ||
439                            mode == EVP_CIPH_CCM_MODE)) {
440     // Ignore the return value (i.e. possible exception) because we are
441     // not calling back into JS anyway.
442     ProcessEmitWarning(env(),
443                        "Use Cipheriv for counter mode of %s",
444                        cipher_type);
445   }
446 
447   CommonInit(cipher_type, cipher, key, key_len, iv,
448              EVP_CIPHER_iv_length(cipher), auth_tag_len);
449 }
450 
451 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
452   CipherBase* cipher;
453   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
454   Environment* env = Environment::GetCurrent(args);
455 
456   CHECK_GE(args.Length(), 3);
457 
458   const Utf8Value cipher_type(args.GetIsolate(), args[0]);
459   ArrayBufferOrViewContents<unsigned char> key_buf(args[1]);
460   if (!key_buf.CheckSizeInt32())
461     return THROW_ERR_OUT_OF_RANGE(env, "password is too large");
462 
463   // Don't assign to cipher->auth_tag_len_ directly; the value might not
464   // represent a valid length at this point.
465   unsigned int auth_tag_len;
466   if (args[2]->IsUint32()) {
467     auth_tag_len = args[2].As<Uint32>()->Value();
468   } else {
469     CHECK(args[2]->IsInt32() && args[2].As<Int32>()->Value() == -1);
470     auth_tag_len = kNoAuthTagLength;
471   }
472 
473   cipher->Init(*cipher_type, key_buf, auth_tag_len);
474 }
475 
476 void CipherBase::InitIv(const char* cipher_type,
477                         const ByteSource& key_buf,
478                         const ArrayBufferOrViewContents<unsigned char>& iv_buf,
479                         unsigned int auth_tag_len) {
480   HandleScope scope(env()->isolate());
481   MarkPopErrorOnReturn mark_pop_error_on_return;
482 
483   const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
484   if (cipher == nullptr)
485     return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
486 
487   const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
488   const bool is_authenticated_mode = IsSupportedAuthenticatedMode(cipher);
489   const bool has_iv = iv_buf.size() > 0;
490 
491   // Throw if no IV was passed and the cipher requires an IV
492   if (!has_iv && expected_iv_len != 0)
493     return THROW_ERR_CRYPTO_INVALID_IV(env());
494 
495   // Throw if an IV was passed which does not match the cipher's fixed IV length
496   // static_cast<int> for the iv_buf.size() is safe because we've verified
497   // prior that the value is not larger than INT_MAX.
498   if (!is_authenticated_mode &&
499       has_iv &&
500       static_cast<int>(iv_buf.size()) != expected_iv_len) {
501     return THROW_ERR_CRYPTO_INVALID_IV(env());
502   }
503 
504   if (EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305) {
505     CHECK(has_iv);
506     // Check for invalid IV lengths, since OpenSSL does not under some
507     // conditions:
508     //   https://www.openssl.org/news/secadv/20190306.txt.
509     if (iv_buf.size() > 12)
510       return THROW_ERR_CRYPTO_INVALID_IV(env());
511   }
512 
513   CommonInit(
514       cipher_type,
515       cipher,
516       key_buf.data<unsigned char>(),
517       key_buf.size(),
518       iv_buf.data(),
519       iv_buf.size(),
520       auth_tag_len);
521 }
522 
523 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
524   CipherBase* cipher;
525   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
526   Environment* env = cipher->env();
527 
528   CHECK_GE(args.Length(), 4);
529 
530   const Utf8Value cipher_type(env->isolate(), args[0]);
531 
532   // The argument can either be a KeyObjectHandle or a byte source
533   // (e.g. ArrayBuffer, TypedArray, etc). Whichever it is, grab the
534   // raw bytes and proceed...
535   const ByteSource key_buf = ByteSource::FromSecretKeyBytes(env, args[1]);
536 
537   if (UNLIKELY(key_buf.size() > INT_MAX))
538     return THROW_ERR_OUT_OF_RANGE(env, "key is too big");
539 
540   ArrayBufferOrViewContents<unsigned char> iv_buf(
541       !args[2]->IsNull() ? args[2] : Local<Value>());
542 
543   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   if (args[3]->IsUint32()) {
550     auth_tag_len = args[3].As<Uint32>()->Value();
551   } else {
552     CHECK(args[3]->IsInt32() && args[3].As<Int32>()->Value() == -1);
553     auth_tag_len = kNoAuthTagLength;
554   }
555 
556   cipher->InitIv(*cipher_type, key_buf, iv_buf, auth_tag_len);
557 }
558 
559 bool CipherBase::InitAuthenticated(
560     const char* cipher_type,
561     int iv_len,
562     unsigned int auth_tag_len) {
563   CHECK(IsAuthenticatedMode());
564   MarkPopErrorOnReturn mark_pop_error_on_return;
565 
566   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   const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
575   if (mode == EVP_CIPH_GCM_MODE) {
576     if (auth_tag_len != kNoAuthTagLength) {
577       if (!IsValidGCMTagLength(auth_tag_len)) {
578         THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
579           env(),
580           "Invalid authentication tag length: %u",
581           auth_tag_len);
582         return false;
583       }
584 
585       // Remember the given authentication tag length for later.
586       auth_tag_len_ = auth_tag_len;
587     }
588   } else {
589     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       if (EVP_CIPHER_CTX_nid(ctx_.get()) == NID_chacha20_poly1305) {
595         auth_tag_len = 16;
596       } else {
597         THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
598           env(), "authTagLength required for %s", cipher_type);
599         return false;
600       }
601     }
602 
603     // TODO(tniessen) Support CCM decryption in FIPS mode
604 
605 #if OPENSSL_VERSION_MAJOR >= 3
606     if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher &&
607         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     if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
618                              nullptr)) {
619       THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
620           env(), "Invalid authentication tag length: %u", auth_tag_len);
621       return false;
622     }
623 
624     // Remember the given authentication tag length for later.
625     auth_tag_len_ = auth_tag_len;
626 
627     if (mode == EVP_CIPH_CCM_MODE) {
628       // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes.
629       CHECK(iv_len >= 7 && iv_len <= 13);
630       max_message_size_ = INT_MAX;
631       if (iv_len == 12) max_message_size_ = 16777215;
632       if (iv_len == 13) max_message_size_ = 65535;
633     }
634   }
635 
636   return true;
637 }
638 
639 bool CipherBase::CheckCCMMessageLength(int message_len) {
640   CHECK(ctx_);
641   CHECK(EVP_CIPHER_CTX_mode(ctx_.get()) == EVP_CIPH_CCM_MODE);
642 
643   if (message_len > max_message_size_) {
644     THROW_ERR_CRYPTO_INVALID_MESSAGELEN(env());
645     return false;
646   }
647 
648   return true;
649 }
650 
651 bool CipherBase::IsAuthenticatedMode() const {
652   // Check if this cipher operates in an AEAD mode that we support.
653   CHECK(ctx_);
654   return IsSupportedAuthenticatedMode(ctx_.get());
655 }
656 
657 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
658   Environment* env = Environment::GetCurrent(args);
659   CipherBase* cipher;
660   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
661 
662   // Only callable after Final and if encrypting.
663   if (cipher->ctx_ ||
664       cipher->kind_ != kCipher ||
665       cipher->auth_tag_len_ == kNoAuthTagLength) {
666     return;
667   }
668 
669   args.GetReturnValue().Set(
670       Buffer::Copy(env, cipher->auth_tag_, cipher->auth_tag_len_)
671           .FromMaybe(Local<Value>()));
672 }
673 
674 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
675   CipherBase* cipher;
676   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
677   Environment* env = Environment::GetCurrent(args);
678 
679   if (!cipher->ctx_ ||
680       !cipher->IsAuthenticatedMode() ||
681       cipher->kind_ != kDecipher ||
682       cipher->auth_tag_state_ != kAuthTagUnknown) {
683     return args.GetReturnValue().Set(false);
684   }
685 
686   ArrayBufferOrViewContents<char> auth_tag(args[0]);
687   if (UNLIKELY(!auth_tag.CheckSizeInt32()))
688     return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
689 
690   unsigned int tag_len = auth_tag.size();
691 
692   const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
693   bool is_valid;
694   if (mode == EVP_CIPH_GCM_MODE) {
695     // Restrict GCM tag lengths according to NIST 800-38d, page 9.
696     is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
697                 cipher->auth_tag_len_ == tag_len) &&
698                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     CHECK(IsSupportedAuthenticatedMode(cipher->ctx_.get()));
703     CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength);
704     is_valid = cipher->auth_tag_len_ == tag_len;
705   }
706 
707   if (!is_valid) {
708     return THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
709       env, "Invalid authentication tag length: %u", tag_len);
710   }
711 
712   cipher->auth_tag_len_ = tag_len;
713   cipher->auth_tag_state_ = kAuthTagKnown;
714   CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
715 
716   memset(cipher->auth_tag_, 0, sizeof(cipher->auth_tag_));
717   auth_tag.CopyTo(cipher->auth_tag_, cipher->auth_tag_len_);
718 
719   args.GetReturnValue().Set(true);
720 }
721 
722 bool CipherBase::MaybePassAuthTagToOpenSSL() {
723   if (auth_tag_state_ == kAuthTagKnown) {
724     if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
725                              EVP_CTRL_AEAD_SET_TAG,
726                              auth_tag_len_,
727                              reinterpret_cast<unsigned char*>(auth_tag_))) {
728       return false;
729     }
730     auth_tag_state_ = kAuthTagPassedToOpenSSL;
731   }
732   return true;
733 }
734 
735 bool CipherBase::SetAAD(
736     const ArrayBufferOrViewContents<unsigned char>& data,
737     int plaintext_len) {
738   if (!ctx_ || !IsAuthenticatedMode())
739     return false;
740   MarkPopErrorOnReturn mark_pop_error_on_return;
741 
742   int outlen;
743   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   if (mode == EVP_CIPH_CCM_MODE) {
748     if (plaintext_len < 0) {
749       THROW_ERR_MISSING_ARGS(env(),
750           "options.plaintextLength required for CCM mode with AAD");
751       return false;
752     }
753 
754     if (!CheckCCMMessageLength(plaintext_len))
755       return false;
756 
757     if (kind_ == kDecipher) {
758       if (!MaybePassAuthTagToOpenSSL())
759         return false;
760     }
761 
762     // Specify the plaintext length.
763     if (!EVP_CipherUpdate(ctx_.get(), nullptr, &outlen, nullptr, plaintext_len))
764       return false;
765   }
766 
767   return 1 == EVP_CipherUpdate(ctx_.get(),
768                                nullptr,
769                                &outlen,
770                                data.data(),
771                                data.size());
772 }
773 
774 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
775   CipherBase* cipher;
776   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
777   Environment* env = Environment::GetCurrent(args);
778 
779   CHECK_EQ(args.Length(), 2);
780   CHECK(args[1]->IsInt32());
781   int plaintext_len = args[1].As<Int32>()->Value();
782   ArrayBufferOrViewContents<unsigned char> buf(args[0]);
783 
784   if (UNLIKELY(!buf.CheckSizeInt32()))
785     return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
786   args.GetReturnValue().Set(cipher->SetAAD(buf, plaintext_len));
787 }
788 
789 CipherBase::UpdateResult CipherBase::Update(
790     const char* data,
791     size_t len,
792     std::unique_ptr<BackingStore>* out) {
793   if (!ctx_ || len > INT_MAX)
794     return kErrorState;
795   MarkPopErrorOnReturn mark_pop_error_on_return;
796 
797   const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
798 
799   if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength(len))
800     return kErrorMessageSize;
801 
802   // Pass the authentication tag to OpenSSL if possible. This will only happen
803   // once, usually on the first update.
804   if (kind_ == kDecipher && IsAuthenticatedMode())
805     CHECK(MaybePassAuthTagToOpenSSL());
806 
807   const int block_size = EVP_CIPHER_CTX_block_size(ctx_.get());
808   CHECK_GT(block_size, 0);
809   if (len + block_size > INT_MAX) return kErrorState;
810   int buf_len = len + block_size;
811 
812   // For key wrapping algorithms, get output size by calling
813   // EVP_CipherUpdate() with null output.
814   if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE &&
815       EVP_CipherUpdate(ctx_.get(),
816                        nullptr,
817                        &buf_len,
818                        reinterpret_cast<const unsigned char*>(data),
819                        len) != 1) {
820     return kErrorState;
821   }
822 
823   {
824     NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
825     *out = ArrayBuffer::NewBackingStore(env()->isolate(), buf_len);
826   }
827 
828   int r = EVP_CipherUpdate(ctx_.get(),
829                            static_cast<unsigned char*>((*out)->Data()),
830                            &buf_len,
831                            reinterpret_cast<const unsigned char*>(data),
832                            len);
833 
834   CHECK_LE(static_cast<size_t>(buf_len), (*out)->ByteLength());
835   if (buf_len == 0)
836     *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
837   else
838     *out = BackingStore::Reallocate(env()->isolate(), std::move(*out), buf_len);
839 
840   // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
841   // invalid. In that case, remember the error and throw in final().
842   if (!r && kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
843     pending_auth_failed_ = true;
844     return kSuccess;
845   }
846   return r == 1 ? kSuccess : kErrorState;
847 }
848 
849 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
850   Decode<CipherBase>(args, [](CipherBase* cipher,
851                               const FunctionCallbackInfo<Value>& args,
852                               const char* data, size_t size) {
853     std::unique_ptr<BackingStore> out;
854     Environment* env = Environment::GetCurrent(args);
855 
856     if (UNLIKELY(size > INT_MAX))
857       return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
858 
859     UpdateResult r = cipher->Update(data, size, &out);
860 
861     if (r != kSuccess) {
862       if (r == kErrorState) {
863         ThrowCryptoError(env, ERR_get_error(),
864                          "Trying to add data in unsupported state");
865       }
866       return;
867     }
868 
869     Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
870     args.GetReturnValue().Set(
871         Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
872   });
873 }
874 
875 bool CipherBase::SetAutoPadding(bool auto_padding) {
876   if (!ctx_)
877     return false;
878   MarkPopErrorOnReturn mark_pop_error_on_return;
879   return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
880 }
881 
882 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
883   CipherBase* cipher;
884   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
885 
886   bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue());
887   args.GetReturnValue().Set(b);  // Possibly report invalid state failure
888 }
889 
890 bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
891   if (!ctx_)
892     return false;
893 
894   const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
895 
896   {
897     NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
898     *out = ArrayBuffer::NewBackingStore(env()->isolate(),
899         static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
900   }
901 
902   if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get()))
903     MaybePassAuthTagToOpenSSL();
904 
905   // OpenSSL v1.x doesn't verify the presence of the auth tag so do
906   // it ourselves, see https://github.com/nodejs/node/issues/45874.
907   if (OPENSSL_VERSION_NUMBER < 0x30000000L && kind_ == kDecipher &&
908       NID_chacha20_poly1305 == EVP_CIPHER_CTX_nid(ctx_.get()) &&
909       auth_tag_state_ != kAuthTagPassedToOpenSSL) {
910     return false;
911   }
912 
913   // In CCM mode, final() only checks whether authentication failed in update().
914   // EVP_CipherFinal_ex must not be called and will fail.
915   bool ok;
916   if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
917     ok = !pending_auth_failed_;
918     *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
919   } else {
920     int out_len = (*out)->ByteLength();
921     ok = EVP_CipherFinal_ex(ctx_.get(),
922                             static_cast<unsigned char*>((*out)->Data()),
923                             &out_len) == 1;
924 
925     CHECK_LE(static_cast<size_t>(out_len), (*out)->ByteLength());
926     if (out_len > 0) {
927       *out =
928         BackingStore::Reallocate(env()->isolate(), std::move(*out), out_len);
929     } else {
930       *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
931     }
932 
933     if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
934       // In GCM mode, the authentication tag length can be specified in advance,
935       // but defaults to 16 bytes when encrypting. In CCM and OCB mode, it must
936       // always be given by the user.
937       if (auth_tag_len_ == kNoAuthTagLength) {
938         CHECK(mode == EVP_CIPH_GCM_MODE);
939         auth_tag_len_ = sizeof(auth_tag_);
940       }
941       ok = (1 == EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
942                      auth_tag_len_,
943                      reinterpret_cast<unsigned char*>(auth_tag_)));
944     }
945   }
946 
947   ctx_.reset();
948 
949   return ok;
950 }
951 
952 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
953   Environment* env = Environment::GetCurrent(args);
954 
955   CipherBase* cipher;
956   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
957   if (cipher->ctx_ == nullptr)
958     return THROW_ERR_CRYPTO_INVALID_STATE(env);
959 
960   std::unique_ptr<BackingStore> out;
961 
962   // Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
963   const bool is_auth_mode = cipher->IsAuthenticatedMode();
964   bool r = cipher->Final(&out);
965 
966   if (!r) {
967     const char* msg = is_auth_mode
968                           ? "Unsupported state or unable to authenticate data"
969                           : "Unsupported state";
970 
971     return ThrowCryptoError(env, ERR_get_error(), msg);
972   }
973 
974   Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
975   args.GetReturnValue().Set(
976       Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
977 }
978 
979 template <PublicKeyCipher::Operation operation,
980           PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
981           PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
982 bool PublicKeyCipher::Cipher(
983     Environment* env,
984     const ManagedEVPPKey& pkey,
985     int padding,
986     const EVP_MD* digest,
987     const ArrayBufferOrViewContents<unsigned char>& oaep_label,
988     const ArrayBufferOrViewContents<unsigned char>& data,
989     std::unique_ptr<BackingStore>* out) {
990   EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
991   if (!ctx)
992     return false;
993   if (EVP_PKEY_cipher_init(ctx.get()) <= 0)
994     return false;
995   if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), padding) <= 0)
996     return false;
997 
998   if (digest != nullptr) {
999     if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), digest) <= 0)
1000       return false;
1001   }
1002 
1003   if (!SetRsaOaepLabel(ctx, oaep_label.ToByteSource())) return false;
1004 
1005   size_t out_len = 0;
1006   if (EVP_PKEY_cipher(
1007           ctx.get(),
1008           nullptr,
1009           &out_len,
1010           data.data(),
1011           data.size()) <= 0) {
1012     return false;
1013   }
1014 
1015   {
1016     NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
1017     *out = ArrayBuffer::NewBackingStore(env->isolate(), out_len);
1018   }
1019 
1020   if (EVP_PKEY_cipher(
1021           ctx.get(),
1022           static_cast<unsigned char*>((*out)->Data()),
1023           &out_len,
1024           data.data(),
1025           data.size()) <= 0) {
1026     return false;
1027   }
1028 
1029   CHECK_LE(out_len, (*out)->ByteLength());
1030   if (out_len > 0)
1031     *out = BackingStore::Reallocate(env->isolate(), std::move(*out), out_len);
1032   else
1033     *out = ArrayBuffer::NewBackingStore(env->isolate(), 0);
1034 
1035   return true;
1036 }
1037 
1038 template <PublicKeyCipher::Operation operation,
1039           PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
1040           PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
1041 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
1042   MarkPopErrorOnReturn mark_pop_error_on_return;
1043   Environment* env = Environment::GetCurrent(args);
1044 
1045   unsigned int offset = 0;
1046   ManagedEVPPKey pkey =
1047       ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
1048   if (!pkey)
1049     return;
1050 
1051   ArrayBufferOrViewContents<unsigned char> buf(args[offset]);
1052   if (UNLIKELY(!buf.CheckSizeInt32()))
1053     return THROW_ERR_OUT_OF_RANGE(env, "buffer is too long");
1054 
1055   uint32_t padding;
1056   if (!args[offset + 1]->Uint32Value(env->context()).To(&padding)) return;
1057 
1058   if (EVP_PKEY_cipher == EVP_PKEY_decrypt &&
1059       operation == PublicKeyCipher::kPrivate && padding == RSA_PKCS1_PADDING &&
1060       !IsReverted(SECURITY_REVERT_CVE_2023_46809)) {
1061     EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
1062     CHECK(ctx);
1063 
1064     if (EVP_PKEY_decrypt_init(ctx.get()) <= 0) {
1065       return ThrowCryptoError(env, ERR_get_error());
1066     }
1067 
1068     int rsa_pkcs1_implicit_rejection =
1069         EVP_PKEY_CTX_ctrl_str(ctx.get(), "rsa_pkcs1_implicit_rejection", "1");
1070     // From the doc -2 means that the option is not supported.
1071     // The default for the option is enabled and if it has been
1072     // specifically disabled we want to respect that so we will
1073     // not throw an error if the option is supported regardless
1074     // of how it is set. The call to set the value
1075     // will not affect what is used since a different context is
1076     // used in the call if the option is supported
1077     if (rsa_pkcs1_implicit_rejection <= 0) {
1078       return THROW_ERR_INVALID_ARG_VALUE(
1079           env,
1080           "RSA_PKCS1_PADDING is no longer supported for private decryption,"
1081           " this can be reverted with --security-revert=CVE-2023-46809");
1082     }
1083   }
1084 
1085   const EVP_MD* digest = nullptr;
1086   if (args[offset + 2]->IsString()) {
1087     const Utf8Value oaep_str(env->isolate(), args[offset + 2]);
1088     digest = EVP_get_digestbyname(*oaep_str);
1089     if (digest == nullptr)
1090       return THROW_ERR_OSSL_EVP_INVALID_DIGEST(env);
1091   }
1092 
1093   ArrayBufferOrViewContents<unsigned char> oaep_label(
1094       !args[offset + 3]->IsUndefined() ? args[offset + 3] : Local<Value>());
1095   if (UNLIKELY(!oaep_label.CheckSizeInt32()))
1096     return THROW_ERR_OUT_OF_RANGE(env, "oaepLabel is too big");
1097 
1098   std::unique_ptr<BackingStore> out;
1099   if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
1100           env, pkey, padding, digest, oaep_label, buf, &out)) {
1101     return ThrowCryptoError(env, ERR_get_error());
1102   }
1103 
1104   Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
1105   args.GetReturnValue().Set(
1106       Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
1107 }
1108 
1109 }  // namespace crypto
1110 }  // namespace node
1111