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