Skip to content

Commit 9841890

Browse files
committed
src,crypto: remove AllocatedBuffer from crypto_cipher.cc
Signed-off-by: Darshan Sen <[email protected]>
1 parent 8a58fce commit 9841890

File tree

2 files changed

+62
-34
lines changed

2 files changed

+62
-34
lines changed

src/crypto/crypto_cipher.cc

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
namespace node {
1313

1414
using v8::Array;
15+
using v8::ArrayBuffer;
16+
using v8::BackingStore;
1517
using v8::FunctionCallbackInfo;
1618
using v8::FunctionTemplate;
1719
using v8::HandleScope;
1820
using v8::Int32;
21+
using v8::Isolate;
1922
using v8::Local;
2023
using v8::Object;
2124
using v8::Uint32;
@@ -720,7 +723,9 @@ void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
720723
CipherBase::UpdateResult CipherBase::Update(
721724
const char* data,
722725
size_t len,
723-
AllocatedBuffer* out) {
726+
std::unique_ptr<BackingStore>* out) {
727+
Environment* env = this->env();
728+
Isolate* isolate = env->isolate();
724729
if (!ctx_ || len > INT_MAX)
725730
return kErrorState;
726731
MarkPopErrorOnReturn mark_pop_error_on_return;
@@ -747,15 +752,22 @@ CipherBase::UpdateResult CipherBase::Update(
747752
return kErrorState;
748753
}
749754

750-
*out = AllocatedBuffer::AllocateManaged(env(), buf_len);
755+
{
756+
NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
757+
*out = ArrayBuffer::NewBackingStore(isolate, buf_len);
758+
}
759+
751760
int r = EVP_CipherUpdate(ctx_.get(),
752-
reinterpret_cast<unsigned char*>(out->data()),
761+
static_cast<unsigned char*>((*out)->Data()),
753762
&buf_len,
754763
reinterpret_cast<const unsigned char*>(data),
755764
len);
756765

757-
CHECK_LE(static_cast<size_t>(buf_len), out->size());
758-
out->Resize(buf_len);
766+
CHECK_LE(static_cast<size_t>(buf_len), (*out)->ByteLength());
767+
if (buf_len == 0)
768+
*out = ArrayBuffer::NewBackingStore(isolate, 0);
769+
else
770+
*out = BackingStore::Reallocate(isolate, std::move(*out), buf_len);
759771

760772
// When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
761773
// invalid. In that case, remember the error and throw in final().
@@ -770,7 +782,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
770782
Decode<CipherBase>(args, [](CipherBase* cipher,
771783
const FunctionCallbackInfo<Value>& args,
772784
const char* data, size_t size) {
773-
AllocatedBuffer out;
785+
std::unique_ptr<BackingStore> out;
774786
Environment* env = Environment::GetCurrent(args);
775787

776788
if (UNLIKELY(size > INT_MAX))
@@ -786,8 +798,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
786798
return;
787799
}
788800

789-
CHECK(out.data() != nullptr || out.size() == 0);
790-
args.GetReturnValue().Set(out.ToBuffer().FromMaybe(Local<Value>()));
801+
Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
802+
args.GetReturnValue().Set(
803+
Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
791804
});
792805
}
793806

@@ -806,36 +819,40 @@ void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
806819
args.GetReturnValue().Set(b); // Possibly report invalid state failure
807820
}
808821

809-
bool CipherBase::Final(AllocatedBuffer* out) {
822+
bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
823+
Environment* env = this->env();
824+
Isolate* isolate = env->isolate();
810825
if (!ctx_)
811826
return false;
812827

813828
const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
814829

815-
*out = AllocatedBuffer::AllocateManaged(
816-
env(),
817-
static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
830+
{
831+
NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
832+
*out = ArrayBuffer::NewBackingStore(isolate,
833+
static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
834+
}
818835

819-
if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get())) {
836+
if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get()))
820837
MaybePassAuthTagToOpenSSL();
821-
}
822838

823839
// In CCM mode, final() only checks whether authentication failed in update().
824840
// EVP_CipherFinal_ex must not be called and will fail.
825841
bool ok;
826842
if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
827843
ok = !pending_auth_failed_;
828-
*out = AllocatedBuffer::AllocateManaged(env(), 0); // Empty buffer.
844+
*out = ArrayBuffer::NewBackingStore(isolate, 0);
829845
} else {
830-
int out_len = out->size();
846+
int out_len = (*out)->ByteLength();
831847
ok = EVP_CipherFinal_ex(ctx_.get(),
832-
reinterpret_cast<unsigned char*>(out->data()),
848+
static_cast<unsigned char*>((*out)->Data()),
833849
&out_len) == 1;
834850

835-
if (out_len >= 0)
836-
out->Resize(out_len);
851+
CHECK_LE(static_cast<size_t>(out_len), (*out)->ByteLength());
852+
if (out_len > 0)
853+
*out = BackingStore::Reallocate(isolate, std::move(*out), out_len);
837854
else
838-
*out = AllocatedBuffer(); // *out will not be used.
855+
*out = ArrayBuffer::NewBackingStore(isolate, 0);
839856

840857
if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
841858
// In GCM mode, the authentication tag length can be specified in advance,
@@ -864,7 +881,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
864881
if (cipher->ctx_ == nullptr)
865882
return THROW_ERR_CRYPTO_INVALID_STATE(env);
866883

867-
AllocatedBuffer out;
884+
std::unique_ptr<BackingStore> out;
868885

869886
// Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
870887
const bool is_auth_mode = cipher->IsAuthenticatedMode();
@@ -878,7 +895,9 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
878895
return ThrowCryptoError(env, ERR_get_error(), msg);
879896
}
880897

881-
args.GetReturnValue().Set(out.ToBuffer().FromMaybe(Local<Value>()));
898+
Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
899+
args.GetReturnValue().Set(
900+
Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
882901
}
883902

884903
template <PublicKeyCipher::Operation operation,
@@ -891,7 +910,8 @@ bool PublicKeyCipher::Cipher(
891910
const EVP_MD* digest,
892911
const ArrayBufferOrViewContents<unsigned char>& oaep_label,
893912
const ArrayBufferOrViewContents<unsigned char>& data,
894-
AllocatedBuffer* out) {
913+
std::unique_ptr<BackingStore>* out) {
914+
Isolate* isolate = env->isolate();
895915
EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
896916
if (!ctx)
897917
return false;
@@ -927,18 +947,26 @@ bool PublicKeyCipher::Cipher(
927947
return false;
928948
}
929949

930-
*out = AllocatedBuffer::AllocateManaged(env, out_len);
950+
{
951+
NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
952+
*out = ArrayBuffer::NewBackingStore(isolate, out_len);
953+
}
931954

932955
if (EVP_PKEY_cipher(
933956
ctx.get(),
934-
reinterpret_cast<unsigned char*>(out->data()),
957+
static_cast<unsigned char*>((*out)->Data()),
935958
&out_len,
936959
data.data(),
937960
data.size()) <= 0) {
938961
return false;
939962
}
940963

941-
out->Resize(out_len);
964+
CHECK_LE(out_len, (*out)->ByteLength());
965+
if (out_len > 0)
966+
*out = BackingStore::Reallocate(isolate, std::move(*out), out_len);
967+
else
968+
*out = ArrayBuffer::NewBackingStore(isolate, 0);
969+
942970
return true;
943971
}
944972

@@ -977,15 +1005,15 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
9771005
return THROW_ERR_OUT_OF_RANGE(env, "oaep_label is too big");
9781006
}
9791007

980-
AllocatedBuffer out;
1008+
std::unique_ptr<BackingStore> out;
9811009
if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
9821010
env, pkey, padding, digest, oaep_label, buf, &out)) {
9831011
return ThrowCryptoError(env, ERR_get_error());
9841012
}
9851013

986-
Local<Value> result;
987-
if (out.ToBuffer().ToLocal(&result))
988-
args.GetReturnValue().Set(result);
1014+
Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), std::move(out));
1015+
args.GetReturnValue().Set(
1016+
Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
9891017
}
9901018

9911019
} // namespace crypto

src/crypto/crypto_cipher.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include "crypto/crypto_keys.h"
77
#include "crypto/crypto_util.h"
8-
#include "allocated_buffer-inl.h"
98
#include "base_object.h"
109
#include "env.h"
1110
#include "memory_tracker.h"
@@ -60,8 +59,9 @@ class CipherBase : public BaseObject {
6059
bool InitAuthenticated(const char* cipher_type, int iv_len,
6160
unsigned int auth_tag_len);
6261
bool CheckCCMMessageLength(int message_len);
63-
UpdateResult Update(const char* data, size_t len, AllocatedBuffer* out);
64-
bool Final(AllocatedBuffer* out);
62+
UpdateResult Update(const char* data, size_t len,
63+
std::unique_ptr<v8::BackingStore>* out);
64+
bool Final(std::unique_ptr<v8::BackingStore>* out);
6565
bool SetAutoPadding(bool auto_padding);
6666

6767
bool IsAuthenticatedMode() const;
@@ -114,7 +114,7 @@ class PublicKeyCipher {
114114
const EVP_MD* digest,
115115
const ArrayBufferOrViewContents<unsigned char>& oaep_label,
116116
const ArrayBufferOrViewContents<unsigned char>& data,
117-
AllocatedBuffer* out);
117+
std::unique_ptr<v8::BackingStore>* out);
118118

119119
template <Operation operation,
120120
EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,

0 commit comments

Comments
 (0)