1212namespace node {
1313
1414using v8::Array;
15+ using v8::ArrayBuffer;
16+ using v8::BackingStore;
1517using v8::FunctionCallbackInfo;
1618using v8::FunctionTemplate;
1719using v8::HandleScope;
@@ -720,7 +722,7 @@ void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
720722CipherBase::UpdateResult CipherBase::Update (
721723 const char * data,
722724 size_t len,
723- AllocatedBuffer * out) {
725+ std::unique_ptr<BackingStore> * out) {
724726 if (!ctx_ || len > INT_MAX)
725727 return kErrorState ;
726728 MarkPopErrorOnReturn mark_pop_error_on_return;
@@ -747,15 +749,22 @@ CipherBase::UpdateResult CipherBase::Update(
747749 return kErrorState ;
748750 }
749751
750- *out = AllocatedBuffer::AllocateManaged (env (), buf_len);
752+ {
753+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
754+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), buf_len);
755+ }
756+
751757 int r = EVP_CipherUpdate (ctx_.get (),
752- reinterpret_cast <unsigned char *>(out-> data ()),
758+ static_cast <unsigned char *>((* out)-> Data ()),
753759 &buf_len,
754760 reinterpret_cast <const unsigned char *>(data),
755761 len);
756762
757- CHECK_LE (static_cast <size_t >(buf_len), out->size ());
758- out->Resize (buf_len);
763+ CHECK_LE (static_cast <size_t >(buf_len), (*out)->ByteLength ());
764+ if (buf_len == 0 )
765+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), 0 );
766+ else
767+ *out = BackingStore::Reallocate (env ()->isolate (), std::move (*out), buf_len);
759768
760769 // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
761770 // invalid. In that case, remember the error and throw in final().
@@ -770,7 +779,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
770779 Decode<CipherBase>(args, [](CipherBase* cipher,
771780 const FunctionCallbackInfo<Value>& args,
772781 const char * data, size_t size) {
773- AllocatedBuffer out;
782+ std::unique_ptr<BackingStore> out;
774783 Environment* env = Environment::GetCurrent (args);
775784
776785 if (UNLIKELY (size > INT_MAX))
@@ -786,8 +795,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
786795 return ;
787796 }
788797
789- CHECK (out.data () != nullptr || out.size () == 0 );
790- args.GetReturnValue ().Set (out.ToBuffer ().FromMaybe (Local<Value>()));
798+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
799+ args.GetReturnValue ().Set (
800+ Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
791801 });
792802}
793803
@@ -806,36 +816,40 @@ void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
806816 args.GetReturnValue ().Set (b); // Possibly report invalid state failure
807817}
808818
809- bool CipherBase::Final (AllocatedBuffer * out) {
819+ bool CipherBase::Final (std::unique_ptr<BackingStore> * out) {
810820 if (!ctx_)
811821 return false ;
812822
813823 const int mode = EVP_CIPHER_CTX_mode (ctx_.get ());
814824
815- *out = AllocatedBuffer::AllocateManaged (
816- env (),
817- static_cast <size_t >(EVP_CIPHER_CTX_block_size (ctx_.get ())));
825+ {
826+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
827+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (),
828+ static_cast <size_t >(EVP_CIPHER_CTX_block_size (ctx_.get ())));
829+ }
818830
819- if (kind_ == kDecipher && IsSupportedAuthenticatedMode (ctx_.get ())) {
831+ if (kind_ == kDecipher && IsSupportedAuthenticatedMode (ctx_.get ()))
820832 MaybePassAuthTagToOpenSSL ();
821- }
822833
823834 // In CCM mode, final() only checks whether authentication failed in update().
824835 // EVP_CipherFinal_ex must not be called and will fail.
825836 bool ok;
826837 if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
827838 ok = !pending_auth_failed_;
828- *out = AllocatedBuffer::AllocateManaged (env (), 0 ); // Empty buffer.
839+ *out = ArrayBuffer::NewBackingStore (env ()-> isolate () , 0 );
829840 } else {
830- int out_len = out-> size ();
841+ int out_len = (* out)-> ByteLength ();
831842 ok = EVP_CipherFinal_ex (ctx_.get (),
832- reinterpret_cast <unsigned char *>(out-> data ()),
843+ static_cast <unsigned char *>((* out)-> Data ()),
833844 &out_len) == 1 ;
834845
835- if (out_len >= 0 )
836- out->Resize (out_len);
837- else
838- *out = AllocatedBuffer (); // *out will not be used.
846+ CHECK_LE (static_cast <size_t >(out_len), (*out)->ByteLength ());
847+ if (out_len > 0 ) {
848+ *out =
849+ BackingStore::Reallocate (env ()->isolate (), std::move (*out), out_len);
850+ } else {
851+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), 0 );
852+ }
839853
840854 if (ok && kind_ == kCipher && IsAuthenticatedMode ()) {
841855 // In GCM mode, the authentication tag length can be specified in advance,
@@ -864,7 +878,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
864878 if (cipher->ctx_ == nullptr )
865879 return THROW_ERR_CRYPTO_INVALID_STATE (env);
866880
867- AllocatedBuffer out;
881+ std::unique_ptr<BackingStore> out;
868882
869883 // Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
870884 const bool is_auth_mode = cipher->IsAuthenticatedMode ();
@@ -878,7 +892,9 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
878892 return ThrowCryptoError (env, ERR_get_error (), msg);
879893 }
880894
881- args.GetReturnValue ().Set (out.ToBuffer ().FromMaybe (Local<Value>()));
895+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
896+ args.GetReturnValue ().Set (
897+ Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
882898}
883899
884900template <PublicKeyCipher::Operation operation,
@@ -891,7 +907,7 @@ bool PublicKeyCipher::Cipher(
891907 const EVP_MD* digest,
892908 const ArrayBufferOrViewContents<unsigned char >& oaep_label,
893909 const ArrayBufferOrViewContents<unsigned char >& data,
894- AllocatedBuffer * out) {
910+ std::unique_ptr<BackingStore> * out) {
895911 EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
896912 if (!ctx)
897913 return false ;
@@ -927,18 +943,26 @@ bool PublicKeyCipher::Cipher(
927943 return false ;
928944 }
929945
930- *out = AllocatedBuffer::AllocateManaged (env, out_len);
946+ {
947+ NoArrayBufferZeroFillScope no_zero_fill_scope (env->isolate_data ());
948+ *out = ArrayBuffer::NewBackingStore (env->isolate (), out_len);
949+ }
931950
932951 if (EVP_PKEY_cipher (
933952 ctx.get (),
934- reinterpret_cast <unsigned char *>(out-> data ()),
953+ static_cast <unsigned char *>((* out)-> Data ()),
935954 &out_len,
936955 data.data (),
937956 data.size ()) <= 0 ) {
938957 return false ;
939958 }
940959
941- out->Resize (out_len);
960+ CHECK_LE (out_len, (*out)->ByteLength ());
961+ if (out_len > 0 )
962+ *out = BackingStore::Reallocate (env->isolate (), std::move (*out), out_len);
963+ else
964+ *out = ArrayBuffer::NewBackingStore (env->isolate (), 0 );
965+
942966 return true ;
943967}
944968
@@ -977,15 +1001,15 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
9771001 return THROW_ERR_OUT_OF_RANGE (env, " oaep_label is too big" );
9781002 }
9791003
980- AllocatedBuffer out;
1004+ std::unique_ptr<BackingStore> out;
9811005 if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
9821006 env, pkey, padding, digest, oaep_label, buf, &out)) {
9831007 return ThrowCryptoError (env, ERR_get_error ());
9841008 }
9851009
986- Local<Value> result ;
987- if (out. ToBuffer ().ToLocal (&result))
988- args. GetReturnValue (). Set (result );
1010+ Local<ArrayBuffer> ab = ArrayBuffer::New (env-> isolate (), std::move (out)) ;
1011+ args. GetReturnValue ().Set (
1012+ Buffer::New (env, ab, 0 , ab-> ByteLength ()). FromMaybe (Local<Value>()) );
9891013}
9901014
9911015} // namespace crypto
0 commit comments