• 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 "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 {
IsSupportedAuthenticatedMode(const EVP_CIPHER * cipher)29 bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
30   switch (EVP_CIPHER_mode(cipher)) {
31   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     return true;
37   case EVP_CIPH_STREAM_CIPHER:
38     return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305;
39   default:
40     return false;
41   }
42 }
43 
IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX * ctx)44 bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
45   const EVP_CIPHER* cipher = EVP_CIPHER_CTX_cipher(ctx);
46   return IsSupportedAuthenticatedMode(cipher);
47 }
48 
IsValidGCMTagLength(unsigned int tag_len)49 bool IsValidGCMTagLength(unsigned int tag_len) {
50   return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16);
51 }
52 
53 // Collects and returns information on the given cipher
GetCipherInfo(const FunctionCallbackInfo<Value> & args)54 void GetCipherInfo(const FunctionCallbackInfo<Value>& args) {
55   Environment* env = Environment::GetCurrent(args);
56   CHECK(args[0]->IsObject());
57   Local<Object> info = args[0].As<Object>();
58 
59   CHECK(args[1]->IsString() || args[1]->IsInt32());
60 
61   const EVP_CIPHER* cipher;
62   if (args[1]->IsString()) {
63     Utf8Value name(env->isolate(), args[1]);
64     cipher = EVP_get_cipherbyname(*name);
65   } else {
66     int nid = args[1].As<Int32>()->Value();
67     cipher = EVP_get_cipherbynid(nid);
68   }
69 
70   if (cipher == nullptr)
71     return;
72 
73   int mode = EVP_CIPHER_mode(cipher);
74   int iv_length = EVP_CIPHER_iv_length(cipher);
75   int key_length = EVP_CIPHER_key_length(cipher);
76   int block_length = EVP_CIPHER_block_size(cipher);
77   const char* mode_label = nullptr;
78   switch (mode) {
79     case EVP_CIPH_CBC_MODE: mode_label = "cbc"; break;
80     case EVP_CIPH_CCM_MODE: mode_label = "ccm"; break;
81     case EVP_CIPH_CFB_MODE: mode_label = "cfb"; break;
82     case EVP_CIPH_CTR_MODE: mode_label = "ctr"; break;
83     case EVP_CIPH_ECB_MODE: mode_label = "ecb"; break;
84     case EVP_CIPH_GCM_MODE: mode_label = "gcm"; break;
85     case EVP_CIPH_OCB_MODE: mode_label = "ocb"; break;
86     case EVP_CIPH_OFB_MODE: mode_label = "ofb"; break;
87     case EVP_CIPH_WRAP_MODE: mode_label = "wrap"; break;
88     case EVP_CIPH_XTS_MODE: mode_label = "xts"; break;
89     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   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     CipherCtxPointer ctx(EVP_CIPHER_CTX_new());
102     if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr, 1))
103       return;
104 
105     if (args[2]->IsInt32()) {
106       int check_len = args[2].As<Int32>()->Value();
107       if (!EVP_CIPHER_CTX_set_key_length(ctx.get(), check_len))
108         return;
109       key_length = check_len;
110     }
111 
112     if (args[3]->IsInt32()) {
113       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       switch (mode) {
119         case EVP_CIPH_CCM_MODE:
120           if (check_len < 7 || check_len > 13)
121             return;
122           break;
123         case EVP_CIPH_GCM_MODE:
124           // Fall through
125         case EVP_CIPH_OCB_MODE:
126           if (!EVP_CIPHER_CTX_ctrl(
127                   ctx.get(),
128                   EVP_CTRL_AEAD_SET_IVLEN,
129                   check_len,
130                   nullptr)) {
131             return;
132           }
133           break;
134         default:
135           if (check_len != iv_length)
136             return;
137       }
138       iv_length = check_len;
139     }
140   }
141 
142   if (mode_label != nullptr &&
143       info->Set(
144           env->context(),
145           FIXED_ONE_BYTE_STRING(env->isolate(), "mode"),
146           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   if (info->Set(
153           env->context(),
154           env->name_string(),
155           OneByteString(
156             env->isolate(),
157             OBJ_nid2sn(EVP_CIPHER_nid(cipher)))).IsNothing()) {
158     return;
159   }
160 
161   if (info->Set(
162           env->context(),
163           FIXED_ONE_BYTE_STRING(env->isolate(), "nid"),
164           Int32::New(env->isolate(), EVP_CIPHER_nid(cipher))).IsNothing()) {
165     return;
166   }
167 
168   // Stream ciphers do not have a meaningful block size
169   if (mode != EVP_CIPH_STREAM_CIPHER &&
170       info->Set(
171           env->context(),
172           FIXED_ONE_BYTE_STRING(env->isolate(), "blockSize"),
173           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   if (iv_length != 0 &&
179       info->Set(
180           env->context(),
181           FIXED_ONE_BYTE_STRING(env->isolate(), "ivLength"),
182           Int32::New(env->isolate(), iv_length)).IsNothing()) {
183     return;
184   }
185 
186   if (info->Set(
187           env->context(),
188           FIXED_ONE_BYTE_STRING(env->isolate(), "keyLength"),
189           Int32::New(env->isolate(), key_length)).IsNothing()) {
190     return;
191   }
192 
193   args.GetReturnValue().Set(info);
194 }
195 }  // namespace
196 
GetSSLCiphers(const FunctionCallbackInfo<Value> & args)197 void CipherBase::GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
198   Environment* env = Environment::GetCurrent(args);
199 
200   SSLCtxPointer ctx(SSL_CTX_new(TLS_method()));
201   if (!ctx) {
202     return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new");
203   }
204 
205   SSLPointer ssl(SSL_new(ctx.get()));
206   if (!ssl) {
207     return ThrowCryptoError(env, ERR_get_error(), "SSL_new");
208   }
209 
210   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   const int n = sk_SSL_CIPHER_num(ciphers);
225   std::vector<Local<Value>> arr(n + arraysize(TLS13_CIPHERS));
226 
227   for (int i = 0; i < n; ++i) {
228     const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
229     arr[i] = OneByteString(env->isolate(), SSL_CIPHER_get_name(cipher));
230   }
231 
232   for (unsigned i = 0; i < arraysize(TLS13_CIPHERS); ++i) {
233     const char* name = TLS13_CIPHERS[i];
234     arr[n + i] = OneByteString(env->isolate(), name);
235   }
236 
237   args.GetReturnValue().Set(Array::New(env->isolate(), arr.data(), arr.size()));
238 }
239 
GetCiphers(const FunctionCallbackInfo<Value> & args)240 void CipherBase::GetCiphers(const FunctionCallbackInfo<Value>& args) {
241   Environment* env = Environment::GetCurrent(args);
242   MarkPopErrorOnReturn mark_pop_error_on_return;
243   CipherPushContext ctx(env);
244   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   args.GetReturnValue().Set(ctx.ToJSArray());
256 }
257 
CipherBase(Environment * env,Local<Object> wrap,CipherKind kind)258 CipherBase::CipherBase(Environment* env,
259                        Local<Object> wrap,
260                        CipherKind kind)
261     : BaseObject(env, wrap),
262       ctx_(nullptr),
263       kind_(kind),
264       auth_tag_state_(kAuthTagUnknown),
265       auth_tag_len_(kNoAuthTagLength),
266       pending_auth_failed_(false) {
267   MakeWeak();
268 }
269 
MemoryInfo(MemoryTracker * tracker) const270 void CipherBase::MemoryInfo(MemoryTracker* tracker) const {
271   tracker->TrackFieldWithSize("context", ctx_ ? kSizeOf_EVP_CIPHER_CTX : 0);
272 }
273 
Initialize(Environment * env,Local<Object> target)274 void CipherBase::Initialize(Environment* env, Local<Object> target) {
275   Isolate* isolate = env->isolate();
276   Local<Context> context = env->context();
277 
278   Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New);
279 
280   t->InstanceTemplate()->SetInternalFieldCount(
281       CipherBase::kInternalFieldCount);
282   t->Inherit(BaseObject::GetConstructorTemplate(env));
283 
284   SetProtoMethod(isolate, t, "init", Init);
285   SetProtoMethod(isolate, t, "initiv", InitIv);
286   SetProtoMethod(isolate, t, "update", Update);
287   SetProtoMethod(isolate, t, "final", Final);
288   SetProtoMethod(isolate, t, "setAutoPadding", SetAutoPadding);
289   SetProtoMethodNoSideEffect(isolate, t, "getAuthTag", GetAuthTag);
290   SetProtoMethod(isolate, t, "setAuthTag", SetAuthTag);
291   SetProtoMethod(isolate, t, "setAAD", SetAAD);
292   SetConstructorFunction(context, target, "CipherBase", t);
293 
294   SetMethodNoSideEffect(context, target, "getSSLCiphers", GetSSLCiphers);
295   SetMethodNoSideEffect(context, target, "getCiphers", GetCiphers);
296 
297   SetMethod(context,
298             target,
299             "publicEncrypt",
300             PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
301                                     EVP_PKEY_encrypt_init,
302                                     EVP_PKEY_encrypt>);
303   SetMethod(context,
304             target,
305             "privateDecrypt",
306             PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
307                                     EVP_PKEY_decrypt_init,
308                                     EVP_PKEY_decrypt>);
309   SetMethod(context,
310             target,
311             "privateEncrypt",
312             PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
313                                     EVP_PKEY_sign_init,
314                                     EVP_PKEY_sign>);
315   SetMethod(context,
316             target,
317             "publicDecrypt",
318             PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
319                                     EVP_PKEY_verify_recover_init,
320                                     EVP_PKEY_verify_recover>);
321 
322   SetMethodNoSideEffect(context, target, "getCipherInfo", GetCipherInfo);
323 
324   NODE_DEFINE_CONSTANT(target, kWebCryptoCipherEncrypt);
325   NODE_DEFINE_CONSTANT(target, kWebCryptoCipherDecrypt);
326 }
327 
RegisterExternalReferences(ExternalReferenceRegistry * registry)328 void CipherBase::RegisterExternalReferences(
329     ExternalReferenceRegistry* registry) {
330   registry->Register(New);
331 
332   registry->Register(Init);
333   registry->Register(InitIv);
334   registry->Register(Update);
335   registry->Register(Final);
336   registry->Register(SetAutoPadding);
337   registry->Register(GetAuthTag);
338   registry->Register(SetAuthTag);
339   registry->Register(SetAAD);
340 
341   registry->Register(GetSSLCiphers);
342   registry->Register(GetCiphers);
343 
344   registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
345                                              EVP_PKEY_encrypt_init,
346                                              EVP_PKEY_encrypt>);
347   registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
348                                              EVP_PKEY_decrypt_init,
349                                              EVP_PKEY_decrypt>);
350   registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
351                                              EVP_PKEY_sign_init,
352                                              EVP_PKEY_sign>);
353   registry->Register(PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
354                                              EVP_PKEY_verify_recover_init,
355                                              EVP_PKEY_verify_recover>);
356 
357   registry->Register(GetCipherInfo);
358 }
359 
New(const FunctionCallbackInfo<Value> & args)360 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
361   CHECK(args.IsConstructCall());
362   Environment* env = Environment::GetCurrent(args);
363   new CipherBase(env, args.This(), args[0]->IsTrue() ? kCipher : kDecipher);
364 }
365 
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)366 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   CHECK(!ctx_);
374   ctx_.reset(EVP_CIPHER_CTX_new());
375 
376   const int mode = EVP_CIPHER_mode(cipher);
377   if (mode == EVP_CIPH_WRAP_MODE)
378     EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
379 
380   const bool encrypt = (kind_ == kCipher);
381   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   if (IsSupportedAuthenticatedMode(cipher)) {
388     CHECK_GE(iv_len, 0);
389     if (!InitAuthenticated(cipher_type, iv_len, auth_tag_len))
390       return;
391   }
392 
393   if (!EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len)) {
394     ctx_.reset();
395     return THROW_ERR_CRYPTO_INVALID_KEYLEN(env());
396   }
397 
398   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 
Init(const char * cipher_type,const ArrayBufferOrViewContents<unsigned char> & key_buf,unsigned int auth_tag_len)404 void CipherBase::Init(const char* cipher_type,
405                       const ArrayBufferOrViewContents<unsigned char>& key_buf,
406                       unsigned int auth_tag_len) {
407   HandleScope scope(env()->isolate());
408   MarkPopErrorOnReturn mark_pop_error_on_return;
409 #if OPENSSL_VERSION_MAJOR >= 3
410   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   const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
419   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   int key_len = EVP_BytesToKey(cipher,
426                                EVP_md5(),
427                                nullptr,
428                                key_buf.data(),
429                                key_buf.size(),
430                                1,
431                                key,
432                                iv);
433   CHECK_NE(key_len, 0);
434 
435   const int mode = EVP_CIPHER_mode(cipher);
436   if (kind_ == kCipher && (mode == EVP_CIPH_CTR_MODE ||
437                            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                        cipher_type);
444   }
445 
446   CommonInit(cipher_type, cipher, key, key_len, iv,
447              EVP_CIPHER_iv_length(cipher), auth_tag_len);
448 }
449 
450 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
451   CipherBase* cipher;
452   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
453   Environment* env = Environment::GetCurrent(args);
454 
455   CHECK_GE(args.Length(), 3);
456 
457   const Utf8Value cipher_type(args.GetIsolate(), args[0]);
458   ArrayBufferOrViewContents<unsigned char> key_buf(args[1]);
459   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   if (args[2]->IsUint32()) {
466     auth_tag_len = args[2].As<Uint32>()->Value();
467   } else {
468     CHECK(args[2]->IsInt32() && args[2].As<Int32>()->Value() == -1);
469     auth_tag_len = kNoAuthTagLength;
470   }
471 
472   cipher->Init(*cipher_type, key_buf, auth_tag_len);
473 }
474 
475 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   HandleScope scope(env()->isolate());
480   MarkPopErrorOnReturn mark_pop_error_on_return;
481 
482   const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
483   if (cipher == nullptr)
484     return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
485 
486   const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
487   const bool is_authenticated_mode = IsSupportedAuthenticatedMode(cipher);
488   const bool has_iv = iv_buf.size() > 0;
489 
490   // Throw if no IV was passed and the cipher requires an IV
491   if (!has_iv && expected_iv_len != 0)
492     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 INT_MAX.
497   if (!is_authenticated_mode &&
498       has_iv &&
499       static_cast<int>(iv_buf.size()) != expected_iv_len) {
500     return THROW_ERR_CRYPTO_INVALID_IV(env());
501   }
502 
503   if (EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305) {
504     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     if (iv_buf.size() > 12)
509       return THROW_ERR_CRYPTO_INVALID_IV(env());
510   }
511 
512   CommonInit(
513       cipher_type,
514       cipher,
515       key_buf.data<unsigned char>(),
516       key_buf.size(),
517       iv_buf.data(),
518       iv_buf.size(),
519       auth_tag_len);
520 }
521 
522 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
523   CipherBase* cipher;
524   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
525   Environment* env = cipher->env();
526 
527   CHECK_GE(args.Length(), 4);
528 
529   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   const ByteSource key_buf = ByteSource::FromSecretKeyBytes(env, args[1]);
535 
536   if (UNLIKELY(key_buf.size() > INT_MAX))
537     return THROW_ERR_OUT_OF_RANGE(env, "key is too big");
538 
539   ArrayBufferOrViewContents<unsigned char> iv_buf(
540       !args[2]->IsNull() ? args[2] : Local<Value>());
541 
542   if (UNLIKELY(!iv_buf.CheckSizeInt32()))
543     return THROW_ERR_OUT_OF_RANGE(env, "iv is too big");
544 
545   // Don't assign to cipher->auth_tag_len_ directly; the value might not
546   // represent a valid length at this point.
547   unsigned int auth_tag_len;
548   if (args[3]->IsUint32()) {
549     auth_tag_len = args[3].As<Uint32>()->Value();
550   } else {
551     CHECK(args[3]->IsInt32() && args[3].As<Int32>()->Value() == -1);
552     auth_tag_len = kNoAuthTagLength;
553   }
554 
555   cipher->InitIv(*cipher_type, key_buf, iv_buf, auth_tag_len);
556 }
557 
558 bool CipherBase::InitAuthenticated(
559     const char* cipher_type,
560     int iv_len,
561     unsigned int auth_tag_len) {
562   CHECK(IsAuthenticatedMode());
563   MarkPopErrorOnReturn mark_pop_error_on_return;
564 
565   if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
566                            EVP_CTRL_AEAD_SET_IVLEN,
567                            iv_len,
568                            nullptr)) {
569     THROW_ERR_CRYPTO_INVALID_IV(env());
570     return false;
571   }
572 
573   const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
574   if (mode == EVP_CIPH_GCM_MODE) {
575     if (auth_tag_len != kNoAuthTagLength) {
576       if (!IsValidGCMTagLength(auth_tag_len)) {
577         THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
578           env(),
579           "Invalid authentication tag length: %u",
580           auth_tag_len);
581         return false;
582       }
583 
584       // Remember the given authentication tag length for later.
585       auth_tag_len_ = auth_tag_len;
586     }
587   } else {
588     if (auth_tag_len == kNoAuthTagLength) {
589       // We treat ChaCha20-Poly1305 specially. Like GCM, the authentication tag
590       // length defaults to 16 bytes when encrypting. Unlike GCM, the
591       // authentication tag length also defaults to 16 bytes when decrypting,
592       // whereas GCM would accept any valid authentication tag length.
593       if (EVP_CIPHER_CTX_nid(ctx_.get()) == NID_chacha20_poly1305) {
594         auth_tag_len = 16;
595       } else {
596         THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
597           env(), "authTagLength required for %s", cipher_type);
598         return false;
599       }
600     }
601 
602     // TODO(tniessen) Support CCM decryption in FIPS mode
603 
604 #if OPENSSL_VERSION_MAJOR >= 3
605     if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher &&
606         EVP_default_properties_is_fips_enabled(nullptr)) {
607 #else
608     if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) {
609 #endif
610       THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
611           "CCM encryption not supported in FIPS mode");
612       return false;
613     }
614 
615     // Tell OpenSSL about the desired length.
616     if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
617                              nullptr)) {
618       THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
619           env(), "Invalid authentication tag length: %u", auth_tag_len);
620       return false;
621     }
622 
623     // Remember the given authentication tag length for later.
624     auth_tag_len_ = auth_tag_len;
625 
626     if (mode == EVP_CIPH_CCM_MODE) {
627       // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes.
628       CHECK(iv_len >= 7 && iv_len <= 13);
629       max_message_size_ = INT_MAX;
630       if (iv_len == 12) max_message_size_ = 16777215;
631       if (iv_len == 13) max_message_size_ = 65535;
632     }
633   }
634 
635   return true;
636 }
637 
638 bool CipherBase::CheckCCMMessageLength(int message_len) {
639   CHECK(ctx_);
640   CHECK(EVP_CIPHER_CTX_mode(ctx_.get()) == EVP_CIPH_CCM_MODE);
641 
642   if (message_len > max_message_size_) {
643     THROW_ERR_CRYPTO_INVALID_MESSAGELEN(env());
644     return false;
645   }
646 
647   return true;
648 }
649 
650 bool CipherBase::IsAuthenticatedMode() const {
651   // Check if this cipher operates in an AEAD mode that we support.
652   CHECK(ctx_);
653   return IsSupportedAuthenticatedMode(ctx_.get());
654 }
655 
656 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
657   Environment* env = Environment::GetCurrent(args);
658   CipherBase* cipher;
659   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
660 
661   // Only callable after Final and if encrypting.
662   if (cipher->ctx_ ||
663       cipher->kind_ != kCipher ||
664       cipher->auth_tag_len_ == kNoAuthTagLength) {
665     return;
666   }
667 
668   args.GetReturnValue().Set(
669       Buffer::Copy(env, cipher->auth_tag_, cipher->auth_tag_len_)
670           .FromMaybe(Local<Value>()));
671 }
672 
673 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
674   CipherBase* cipher;
675   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
676   Environment* env = Environment::GetCurrent(args);
677 
678   if (!cipher->ctx_ ||
679       !cipher->IsAuthenticatedMode() ||
680       cipher->kind_ != kDecipher ||
681       cipher->auth_tag_state_ != kAuthTagUnknown) {
682     return args.GetReturnValue().Set(false);
683   }
684 
685   ArrayBufferOrViewContents<char> auth_tag(args[0]);
686   if (UNLIKELY(!auth_tag.CheckSizeInt32()))
687     return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
688 
689   unsigned int tag_len = auth_tag.size();
690 
691   const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
692   bool is_valid;
693   if (mode == EVP_CIPH_GCM_MODE) {
694     // Restrict GCM tag lengths according to NIST 800-38d, page 9.
695     is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
696                 cipher->auth_tag_len_ == tag_len) &&
697                IsValidGCMTagLength(tag_len);
698   } else {
699     // At this point, the tag length is already known and must match the
700     // length of the given authentication tag.
701     CHECK(IsSupportedAuthenticatedMode(cipher->ctx_.get()));
702     CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength);
703     is_valid = cipher->auth_tag_len_ == tag_len;
704   }
705 
706   if (!is_valid) {
707     return THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
708       env, "Invalid authentication tag length: %u", tag_len);
709   }
710 
711   cipher->auth_tag_len_ = tag_len;
712   cipher->auth_tag_state_ = kAuthTagKnown;
713   CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
714 
715   memset(cipher->auth_tag_, 0, sizeof(cipher->auth_tag_));
716   auth_tag.CopyTo(cipher->auth_tag_, cipher->auth_tag_len_);
717 
718   args.GetReturnValue().Set(true);
719 }
720 
721 bool CipherBase::MaybePassAuthTagToOpenSSL() {
722   if (auth_tag_state_ == kAuthTagKnown) {
723     if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
724                              EVP_CTRL_AEAD_SET_TAG,
725                              auth_tag_len_,
726                              reinterpret_cast<unsigned char*>(auth_tag_))) {
727       return false;
728     }
729     auth_tag_state_ = kAuthTagPassedToOpenSSL;
730   }
731   return true;
732 }
733 
734 bool CipherBase::SetAAD(
735     const ArrayBufferOrViewContents<unsigned char>& data,
736     int plaintext_len) {
737   if (!ctx_ || !IsAuthenticatedMode())
738     return false;
739   MarkPopErrorOnReturn mark_pop_error_on_return;
740 
741   int outlen;
742   const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
743 
744   // When in CCM mode, we need to set the authentication tag and the plaintext
745   // length in advance.
746   if (mode == EVP_CIPH_CCM_MODE) {
747     if (plaintext_len < 0) {
748       THROW_ERR_MISSING_ARGS(env(),
749           "options.plaintextLength required for CCM mode with AAD");
750       return false;
751     }
752 
753     if (!CheckCCMMessageLength(plaintext_len))
754       return false;
755 
756     if (kind_ == kDecipher) {
757       if (!MaybePassAuthTagToOpenSSL())
758         return false;
759     }
760 
761     // Specify the plaintext length.
762     if (!EVP_CipherUpdate(ctx_.get(), nullptr, &outlen, nullptr, plaintext_len))
763       return false;
764   }
765 
766   return 1 == EVP_CipherUpdate(ctx_.get(),
767                                nullptr,
768                                &outlen,
769                                data.data(),
770                                data.size());
771 }
772 
773 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
774   CipherBase* cipher;
775   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
776   Environment* env = Environment::GetCurrent(args);
777 
778   CHECK_EQ(args.Length(), 2);
779   CHECK(args[1]->IsInt32());
780   int plaintext_len = args[1].As<Int32>()->Value();
781   ArrayBufferOrViewContents<unsigned char> buf(args[0]);
782 
783   if (UNLIKELY(!buf.CheckSizeInt32()))
784     return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
785   args.GetReturnValue().Set(cipher->SetAAD(buf, plaintext_len));
786 }
787 
788 CipherBase::UpdateResult CipherBase::Update(
789     const char* data,
790     size_t len,
791     std::unique_ptr<BackingStore>* out) {
792   if (!ctx_ || len > INT_MAX)
793     return kErrorState;
794   MarkPopErrorOnReturn mark_pop_error_on_return;
795 
796   const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
797 
798   if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength(len))
799     return kErrorMessageSize;
800 
801   // Pass the authentication tag to OpenSSL if possible. This will only happen
802   // once, usually on the first update.
803   if (kind_ == kDecipher && IsAuthenticatedMode())
804     CHECK(MaybePassAuthTagToOpenSSL());
805 
806   const int block_size = EVP_CIPHER_CTX_block_size(ctx_.get());
807   CHECK_GT(block_size, 0);
808   if (len + block_size > INT_MAX) return kErrorState;
809   int buf_len = len + block_size;
810 
811   // For key wrapping algorithms, get output size by calling
812   // EVP_CipherUpdate() with null output.
813   if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE &&
814       EVP_CipherUpdate(ctx_.get(),
815                        nullptr,
816                        &buf_len,
817                        reinterpret_cast<const unsigned char*>(data),
818                        len) != 1) {
819     return kErrorState;
820   }
821 
822   {
823     NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
824     *out = ArrayBuffer::NewBackingStore(env()->isolate(), buf_len);
825   }
826 
827   int r = EVP_CipherUpdate(ctx_.get(),
828                            static_cast<unsigned char*>((*out)->Data()),
829                            &buf_len,
830                            reinterpret_cast<const unsigned char*>(data),
831                            len);
832 
833   CHECK_LE(static_cast<size_t>(buf_len), (*out)->ByteLength());
834   if (buf_len == 0)
835     *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
836   else
837     *out = BackingStore::Reallocate(env()->isolate(), std::move(*out), buf_len);
838 
839   // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
840   // invalid. In that case, remember the error and throw in final().
841   if (!r && kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
842     pending_auth_failed_ = true;
843     return kSuccess;
844   }
845   return r == 1 ? kSuccess : kErrorState;
846 }
847 
848 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
849   Decode<CipherBase>(args, [](CipherBase* cipher,
850                               const FunctionCallbackInfo<Value>& args,
851                               const char* data, size_t size) {
852     std::unique_ptr<BackingStore> out;
853     Environment* env = Environment::GetCurrent(args);
854 
855     if (UNLIKELY(size > INT_MAX))
856       return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
857 
858     UpdateResult r = cipher->Update(data, size, &out);
859 
860     if (r != kSuccess) {
861       if (r == kErrorState) {
862         ThrowCryptoError(env, ERR_get_error(),
863                          "Trying to add data in unsupported state");
864       }
865       return;
866     }
867 
868     Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
869     args.GetReturnValue().Set(
870         Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
871   });
872 }
873 
874 bool CipherBase::SetAutoPadding(bool auto_padding) {
875   if (!ctx_)
876     return false;
877   MarkPopErrorOnReturn mark_pop_error_on_return;
878   return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
879 }
880 
881 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
882   CipherBase* cipher;
883   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
884 
885   bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue());
886   args.GetReturnValue().Set(b);  // Possibly report invalid state failure
887 }
888 
889 bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
890   if (!ctx_)
891     return false;
892 
893   const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
894 
895   {
896     NoArrayBufferZeroFillScope no_zero_fill_scope(env()->isolate_data());
897     *out = ArrayBuffer::NewBackingStore(env()->isolate(),
898         static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
899   }
900 
901   if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get()))
902     MaybePassAuthTagToOpenSSL();
903 
904   // OpenSSL v1.x doesn't verify the presence of the auth tag so do
905   // it ourselves, see https://github.com/nodejs/node/issues/45874.
906   if (OPENSSL_VERSION_NUMBER < 0x30000000L && kind_ == kDecipher &&
907       NID_chacha20_poly1305 == EVP_CIPHER_CTX_nid(ctx_.get()) &&
908       auth_tag_state_ != kAuthTagPassedToOpenSSL) {
909     return false;
910   }
911 
912   // In CCM mode, final() only checks whether authentication failed in update().
913   // EVP_CipherFinal_ex must not be called and will fail.
914   bool ok;
915   if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
916     ok = !pending_auth_failed_;
917     *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
918   } else {
919     int out_len = (*out)->ByteLength();
920     ok = EVP_CipherFinal_ex(ctx_.get(),
921                             static_cast<unsigned char*>((*out)->Data()),
922                             &out_len) == 1;
923 
924     CHECK_LE(static_cast<size_t>(out_len), (*out)->ByteLength());
925     if (out_len > 0) {
926       *out =
927         BackingStore::Reallocate(env()->isolate(), std::move(*out), out_len);
928     } else {
929       *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0);
930     }
931 
932     if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
933       // In GCM mode, the authentication tag length can be specified in advance,
934       // but defaults to 16 bytes when encrypting. In CCM and OCB mode, it must
935       // always be given by the user.
936       if (auth_tag_len_ == kNoAuthTagLength) {
937         CHECK(mode == EVP_CIPH_GCM_MODE);
938         auth_tag_len_ = sizeof(auth_tag_);
939       }
940       ok = (1 == EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
941                      auth_tag_len_,
942                      reinterpret_cast<unsigned char*>(auth_tag_)));
943     }
944   }
945 
946   ctx_.reset();
947 
948   return ok;
949 }
950 
951 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
952   Environment* env = Environment::GetCurrent(args);
953 
954   CipherBase* cipher;
955   ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
956   if (cipher->ctx_ == nullptr)
957     return THROW_ERR_CRYPTO_INVALID_STATE(env);
958 
959   std::unique_ptr<BackingStore> out;
960 
961   // Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
962   const bool is_auth_mode = cipher->IsAuthenticatedMode();
963   bool r = cipher->Final(&out);
964 
965   if (!r) {
966     const char* msg = is_auth_mode
967                           ? "Unsupported state or unable to authenticate data"
968                           : "Unsupported state";
969 
970     return ThrowCryptoError(env, ERR_get_error(), msg);
971   }
972 
973   Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
974   args.GetReturnValue().Set(
975       Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
976 }
977 
978 template <PublicKeyCipher::Operation operation,
979           PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
980           PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
981 bool PublicKeyCipher::Cipher(
982     Environment* env,
983     const ManagedEVPPKey& pkey,
984     int padding,
985     const EVP_MD* digest,
986     const ArrayBufferOrViewContents<unsigned char>& oaep_label,
987     const ArrayBufferOrViewContents<unsigned char>& data,
988     std::unique_ptr<BackingStore>* out) {
989   EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
990   if (!ctx)
991     return false;
992   if (EVP_PKEY_cipher_init(ctx.get()) <= 0)
993     return false;
994   if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), padding) <= 0)
995     return false;
996 
997   if (digest != nullptr) {
998     if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), digest) <= 0)
999       return false;
1000   }
1001 
1002   if (!SetRsaOaepLabel(ctx, oaep_label.ToByteSource())) return false;
1003 
1004   size_t out_len = 0;
1005   if (EVP_PKEY_cipher(
1006           ctx.get(),
1007           nullptr,
1008           &out_len,
1009           data.data(),
1010           data.size()) <= 0) {
1011     return false;
1012   }
1013 
1014   {
1015     NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
1016     *out = ArrayBuffer::NewBackingStore(env->isolate(), out_len);
1017   }
1018 
1019   if (EVP_PKEY_cipher(
1020           ctx.get(),
1021           static_cast<unsigned char*>((*out)->Data()),
1022           &out_len,
1023           data.data(),
1024           data.size()) <= 0) {
1025     return false;
1026   }
1027 
1028   CHECK_LE(out_len, (*out)->ByteLength());
1029   if (out_len > 0)
1030     *out = BackingStore::Reallocate(env->isolate(), std::move(*out), out_len);
1031   else
1032     *out = ArrayBuffer::NewBackingStore(env->isolate(), 0);
1033 
1034   return true;
1035 }
1036 
1037 template <PublicKeyCipher::Operation operation,
1038           PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
1039           PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
1040 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
1041   MarkPopErrorOnReturn mark_pop_error_on_return;
1042   Environment* env = Environment::GetCurrent(args);
1043 
1044   unsigned int offset = 0;
1045   ManagedEVPPKey pkey =
1046       ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
1047   if (!pkey)
1048     return;
1049 
1050   ArrayBufferOrViewContents<unsigned char> buf(args[offset]);
1051   if (UNLIKELY(!buf.CheckSizeInt32()))
1052     return THROW_ERR_OUT_OF_RANGE(env, "buffer is too long");
1053 
1054   uint32_t padding;
1055   if (!args[offset + 1]->Uint32Value(env->context()).To(&padding)) return;
1056 
1057   const EVP_MD* digest = nullptr;
1058   if (args[offset + 2]->IsString()) {
1059     const Utf8Value oaep_str(env->isolate(), args[offset + 2]);
1060     digest = EVP_get_digestbyname(*oaep_str);
1061     if (digest == nullptr)
1062       return THROW_ERR_OSSL_EVP_INVALID_DIGEST(env);
1063   }
1064 
1065   ArrayBufferOrViewContents<unsigned char> oaep_label(
1066       !args[offset + 3]->IsUndefined() ? args[offset + 3] : Local<Value>());
1067   if (UNLIKELY(!oaep_label.CheckSizeInt32()))
1068     return THROW_ERR_OUT_OF_RANGE(env, "oaepLabel is too big");
1069 
1070   std::unique_ptr<BackingStore> out;
1071   if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
1072           env, pkey, padding, digest, oaep_label, buf, &out)) {
1073     return ThrowCryptoError(env, ERR_get_error());
1074   }
1075 
1076   Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
1077   args.GetReturnValue().Set(
1078       Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
1079 }
1080 
1081 }  // namespace crypto
1082 }  // namespace node
1083