1212namespace node {
1313
1414using v8::Array;
15+ using v8::ArrayBuffer;
16+ using v8::BackingStore;
1517using v8::FunctionCallbackInfo;
1618using v8::FunctionTemplate;
1719using v8::HandleScope;
@@ -752,7 +754,7 @@ void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
752754CipherBase::UpdateResult CipherBase::Update (
753755 const char * data,
754756 size_t len,
755- AllocatedBuffer * out) {
757+ std::unique_ptr<BackingStore> * out) {
756758 if (!ctx_ || len > INT_MAX)
757759 return kErrorState ;
758760 MarkPopErrorOnReturn mark_pop_error_on_return;
@@ -779,15 +781,22 @@ CipherBase::UpdateResult CipherBase::Update(
779781 return kErrorState ;
780782 }
781783
782- *out = AllocatedBuffer::AllocateManaged (env (), buf_len);
784+ {
785+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
786+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), buf_len);
787+ }
788+
783789 int r = EVP_CipherUpdate (ctx_.get (),
784- reinterpret_cast <unsigned char *>(out-> data ()),
790+ static_cast <unsigned char *>((* out)-> Data ()),
785791 &buf_len,
786792 reinterpret_cast <const unsigned char *>(data),
787793 len);
788794
789- CHECK_LE (static_cast <size_t >(buf_len), out->size ());
790- out->Resize (buf_len);
795+ CHECK_LE (static_cast <size_t >(buf_len), (*out)->ByteLength ());
796+ if (buf_len == 0 )
797+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), 0 );
798+ else
799+ *out = BackingStore::Reallocate (env ()->isolate (), std::move (*out), buf_len);
791800
792801 // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
793802 // invalid. In that case, remember the error and throw in final().
@@ -802,7 +811,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
802811 Decode<CipherBase>(args, [](CipherBase* cipher,
803812 const FunctionCallbackInfo<Value>& args,
804813 const char * data, size_t size) {
805- AllocatedBuffer out;
814+ std::unique_ptr<BackingStore> out;
806815 Environment* env = Environment::GetCurrent (args);
807816
808817 if (UNLIKELY (size > INT_MAX))
@@ -818,8 +827,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
818827 return ;
819828 }
820829
821- CHECK (out.data () != nullptr || out.size () == 0 );
822- args.GetReturnValue ().Set (out.ToBuffer ().FromMaybe (Local<Value>()));
830+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
831+ args.GetReturnValue ().Set (
832+ Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
823833 });
824834}
825835
@@ -838,36 +848,40 @@ void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
838848 args.GetReturnValue ().Set (b); // Possibly report invalid state failure
839849}
840850
841- bool CipherBase::Final (AllocatedBuffer * out) {
851+ bool CipherBase::Final (std::unique_ptr<BackingStore> * out) {
842852 if (!ctx_)
843853 return false ;
844854
845855 const int mode = EVP_CIPHER_CTX_mode (ctx_.get ());
846856
847- *out = AllocatedBuffer::AllocateManaged (
848- env (),
849- static_cast <size_t >(EVP_CIPHER_CTX_block_size (ctx_.get ())));
857+ {
858+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
859+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (),
860+ static_cast <size_t >(EVP_CIPHER_CTX_block_size (ctx_.get ())));
861+ }
850862
851- if (kind_ == kDecipher && IsSupportedAuthenticatedMode (ctx_.get ())) {
863+ if (kind_ == kDecipher && IsSupportedAuthenticatedMode (ctx_.get ()))
852864 MaybePassAuthTagToOpenSSL ();
853- }
854865
855866 // In CCM mode, final() only checks whether authentication failed in update().
856867 // EVP_CipherFinal_ex must not be called and will fail.
857868 bool ok;
858869 if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
859870 ok = !pending_auth_failed_;
860- *out = AllocatedBuffer::AllocateManaged (env (), 0 ); // Empty buffer.
871+ *out = ArrayBuffer::NewBackingStore (env ()-> isolate () , 0 );
861872 } else {
862- int out_len = out-> size ();
873+ int out_len = (* out)-> ByteLength ();
863874 ok = EVP_CipherFinal_ex (ctx_.get (),
864- reinterpret_cast <unsigned char *>(out-> data ()),
875+ static_cast <unsigned char *>((* out)-> Data ()),
865876 &out_len) == 1 ;
866877
867- if (out_len >= 0 )
868- out->Resize (out_len);
869- else
870- *out = AllocatedBuffer (); // *out will not be used.
878+ CHECK_LE (static_cast <size_t >(out_len), (*out)->ByteLength ());
879+ if (out_len > 0 ) {
880+ *out =
881+ BackingStore::Reallocate (env ()->isolate (), std::move (*out), out_len);
882+ } else {
883+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), 0 );
884+ }
871885
872886 if (ok && kind_ == kCipher && IsAuthenticatedMode ()) {
873887 // In GCM mode, the authentication tag length can be specified in advance,
@@ -896,7 +910,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
896910 if (cipher->ctx_ == nullptr )
897911 return THROW_ERR_CRYPTO_INVALID_STATE (env);
898912
899- AllocatedBuffer out;
913+ std::unique_ptr<BackingStore> out;
900914
901915 // Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
902916 const bool is_auth_mode = cipher->IsAuthenticatedMode ();
@@ -910,7 +924,9 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
910924 return ThrowCryptoError (env, ERR_get_error (), msg);
911925 }
912926
913- args.GetReturnValue ().Set (out.ToBuffer ().FromMaybe (Local<Value>()));
927+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
928+ args.GetReturnValue ().Set (
929+ Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
914930}
915931
916932template <PublicKeyCipher::Operation operation,
@@ -923,7 +939,7 @@ bool PublicKeyCipher::Cipher(
923939 const EVP_MD* digest,
924940 const ArrayBufferOrViewContents<unsigned char >& oaep_label,
925941 const ArrayBufferOrViewContents<unsigned char >& data,
926- AllocatedBuffer * out) {
942+ std::unique_ptr<BackingStore> * out) {
927943 EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
928944 if (!ctx)
929945 return false ;
@@ -959,18 +975,26 @@ bool PublicKeyCipher::Cipher(
959975 return false ;
960976 }
961977
962- *out = AllocatedBuffer::AllocateManaged (env, out_len);
978+ {
979+ NoArrayBufferZeroFillScope no_zero_fill_scope (env->isolate_data ());
980+ *out = ArrayBuffer::NewBackingStore (env->isolate (), out_len);
981+ }
963982
964983 if (EVP_PKEY_cipher (
965984 ctx.get (),
966- reinterpret_cast <unsigned char *>(out-> data ()),
985+ static_cast <unsigned char *>((* out)-> Data ()),
967986 &out_len,
968987 data.data (),
969988 data.size ()) <= 0 ) {
970989 return false ;
971990 }
972991
973- out->Resize (out_len);
992+ CHECK_LE (out_len, (*out)->ByteLength ());
993+ if (out_len > 0 )
994+ *out = BackingStore::Reallocate (env->isolate (), std::move (*out), out_len);
995+ else
996+ *out = ArrayBuffer::NewBackingStore (env->isolate (), 0 );
997+
974998 return true ;
975999}
9761000
@@ -1009,15 +1033,15 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
10091033 return THROW_ERR_OUT_OF_RANGE (env, " oaep_label is too big" );
10101034 }
10111035
1012- AllocatedBuffer out;
1036+ std::unique_ptr<BackingStore> out;
10131037 if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
10141038 env, pkey, padding, digest, oaep_label, buf, &out)) {
10151039 return ThrowCryptoError (env, ERR_get_error ());
10161040 }
10171041
1018- Local<Value> result ;
1019- if (out. ToBuffer ().ToLocal (&result))
1020- args. GetReturnValue (). Set (result );
1042+ Local<ArrayBuffer> ab = ArrayBuffer::New (env-> isolate (), std::move (out)) ;
1043+ args. GetReturnValue ().Set (
1044+ Buffer::New (env, ab, 0 , ab-> ByteLength ()). FromMaybe (Local<Value>()) );
10211045}
10221046
10231047} // namespace crypto
0 commit comments