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