crypto: forward auth tag to OpenSSL immediately · nodejs/node@cec9d9d
@@ -514,9 +514,9 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
514514ASSIGN_OR_RETURN_UNWRAP(&cipher, args.This());
515515516516// Only callable after Final and if encrypting.
517-if (cipher->ctx_ ||
518- cipher->kind_ != kCipher ||
519- cipher->auth_tag_len_ == kNoAuthTagLength) {
517+if (cipher->ctx_ || cipher->kind_ != kCipher ||
518+ cipher->auth_tag_len_ == kNoAuthTagLength ||
519+ cipher->auth_tag_state_ != kAuthTagComputed) {
520520return;
521521 }
522522@@ -577,29 +577,16 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
577577 }
578578579579 cipher->auth_tag_len_ = tag_len;
580- cipher->auth_tag_state_ = kAuthTagKnown;
581-CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
580+CHECK_LE(cipher->auth_tag_len_, ncrypto::Cipher::MAX_AUTH_TAG_LENGTH);
582581583-memset(cipher->auth_tag_, 0, sizeof(cipher->auth_tag_));
584- auth_tag.CopyTo(cipher->auth_tag_, cipher->auth_tag_len_);
582+if (!cipher->ctx_.setAeadTag({auth_tag.data(), cipher->auth_tag_len_})) {
583+return args.GetReturnValue().Set(false);
584+ }
585+ cipher->auth_tag_state_ = kAuthTagSetByUser;
585586586587 args.GetReturnValue().Set(true);
587588}
588589589-bool CipherBase::MaybePassAuthTagToOpenSSL() {
590-if (auth_tag_state_ == kAuthTagKnown) {
591- ncrypto::Buffer<const char> buffer{
592- .data = auth_tag_,
593- .len = auth_tag_len_,
594- };
595-if (!ctx_.setAeadTag(buffer)) {
596-return false;
597- }
598- auth_tag_state_ = kAuthTagPassedToOpenSSL;
599- }
600-return true;
601-}
602-603590bool CipherBase::SetAAD(
604591const ArrayBufferOrViewContents<unsigned char>& data,
605592int plaintext_len) {
@@ -622,10 +609,6 @@ bool CipherBase::SetAAD(
622609return false;
623610 }
624611625-if (kind_ == kDecipher && !MaybePassAuthTagToOpenSSL()) {
626-return false;
627- }
628-629612 ncrypto::Buffer<const unsigned char> buffer{
630613 .data = nullptr,
631614 .len = static_cast<size_t>(plaintext_len),
@@ -670,12 +653,6 @@ CipherBase::UpdateResult CipherBase::Update(
670653return kErrorMessageSize;
671654 }
672655673-// Pass the authentication tag to OpenSSL if possible. This will only happen
674-// once, usually on the first update.
675-if (kind_ == kDecipher && IsAuthenticatedMode()) {
676-CHECK(MaybePassAuthTagToOpenSSL());
677- }
678-679656const int block_size = ctx_.getBlockSize();
680657CHECK_GT(block_size, 0);
681658if (len + block_size > INT_MAX) return kErrorState;
@@ -777,16 +754,11 @@ bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
777754static_cast<size_t>(ctx_.getBlockSize()),
778755 BackingStoreInitializationMode::kUninitialized);
779756780-if (kind_ == kDecipher &&
781-Cipher::FromCtx(ctx_).isSupportedAuthenticatedMode()) {
782-MaybePassAuthTagToOpenSSL();
783- }
784-785757#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
786758// OpenSSL v1.x doesn't verify the presence of the auth tag so do
787759// it ourselves, see https://github.com/nodejs/node/issues/45874.
788760if (kind_ == kDecipher && ctx_.isChaCha20Poly1305() &&
789- auth_tag_state_ != kAuthTagPassedToOpenSSL) {
761+ auth_tag_state_ != kAuthTagSetByUser) {
790762return false;
791763 }
792764#endif
@@ -824,6 +796,9 @@ bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
824796 }
825797 ok = ctx_.getAeadTag(auth_tag_len_,
826798reinterpret_cast<unsigned char*>(auth_tag_));
799+if (ok) {
800+ auth_tag_state_ = kAuthTagComputed;
801+ }
827802 }
828803 }
829804