Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/e2e-android-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ on:
paths:
- '.github/workflows/e2e-android-test.yml'
- 'example/**'
- 'cpp/**'
- 'nitrogen/**'
- 'src/**'
- 'packages/react-native-quick-crypto/cpp/**'
- 'packages/react-native-quick-crypto/nitrogen/**'
- 'packages/react-native-quick-crypto/src/**'
- 'packages/react-native-quick-crypto/android/**'
push:
branches: [main]
paths:
- 'example/**'
- 'cpp/**'
- 'nitrogen/**'
- 'src/**'
- 'packages/react-native-quick-crypto/cpp/**'
- 'packages/react-native-quick-crypto/nitrogen/**'
- 'packages/react-native-quick-crypto/src/**'
- 'packages/react-native-quick-crypto/android/**'

env:
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/e2e-ios-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ on:
paths:
- '.github/workflows/e2e-ios-test.yml'
- 'example/**'
- 'cpp/**'
- 'nitrogen/**'
- 'src/**'
- 'packages/react-native-quick-crypto/cpp/**'
- 'packages/react-native-quick-crypto/nitrogen/**'
- 'packages/react-native-quick-crypto/src/**'
- 'packages/react-native-quick-crypto/ios/**'
push:
branches: [main]
paths:
- 'example/**'
- 'cpp/**'
- 'nitrogen/**'
- 'src/**'
- 'packages/react-native-quick-crypto/cpp/**'
- 'packages/react-native-quick-crypto/nitrogen/**'
- 'packages/react-native-quick-crypto/src/**'
- 'packages/react-native-quick-crypto/ios/**'

jobs:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <NitroModules/ArrayBuffer.hpp>
#include <cstring>
#include <memory>
#include <stdexcept>

#include "QuickCryptoUtils.hpp"
Expand Down Expand Up @@ -67,10 +68,11 @@ std::shared_ptr<ArrayBuffer> HybridBlake3::digest(std::optional<double> length)
outLen = static_cast<size_t>(len);
}

auto output = new uint8_t[outLen];
blake3_hasher_finalize(&hasher, output, outLen);
auto output = std::make_unique<uint8_t[]>(outLen);
blake3_hasher_finalize(&hasher, output.get(), outLen);

return std::make_shared<margelo::nitro::NativeArrayBuffer>(output, outLen, [=]() { delete[] output; });
uint8_t* raw_ptr = output.get();
return std::make_shared<margelo::nitro::NativeArrayBuffer>(output.release(), outLen, [raw_ptr]() { delete[] raw_ptr; });
}

void HybridBlake3::reset() {
Expand Down
5 changes: 3 additions & 2 deletions packages/react-native-quick-crypto/cpp/cipher/CCMCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,9 @@ std::shared_ptr<ArrayBuffer> CCMCipher::final() {
// CCM decryption does not use final. Verification happens in the last update call.
if (!is_cipher) {
is_finalized = true;
unsigned char* empty_output = new unsigned char[0];
return std::make_shared<NativeArrayBuffer>(empty_output, 0, [=]() { delete[] empty_output; });
auto empty_output = std::make_unique<unsigned char[]>(0);
unsigned char* raw_ptr = empty_output.get();
return std::make_shared<NativeArrayBuffer>(empty_output.release(), 0, [raw_ptr]() { delete[] raw_ptr; });
}

// Proceed only for encryption
Expand Down
13 changes: 7 additions & 6 deletions packages/react-native-quick-crypto/cpp/cipher/ChaCha20Cipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,28 @@ std::shared_ptr<ArrayBuffer> ChaCha20Cipher::update(const std::shared_ptr<ArrayB

// For ChaCha20, output size equals input size since it's a stream cipher
int out_len = in_len;
uint8_t* out = new uint8_t[out_len];
auto out_buf = std::make_unique<uint8_t[]>(out_len);

// Perform the cipher update operation
if (EVP_CipherUpdate(ctx.get(), out, &out_len, native_data->data(), in_len) != 1) {
delete[] out;
if (EVP_CipherUpdate(ctx.get(), out_buf.get(), &out_len, native_data->data(), in_len) != 1) {
unsigned long err = ERR_get_error();
char err_buf[256];
ERR_error_string_n(err, err_buf, sizeof(err_buf));
throw std::runtime_error("ChaCha20Cipher: Failed to update: " + std::string(err_buf));
}

// Create and return a new buffer of exact size needed
return std::make_shared<NativeArrayBuffer>(out, out_len, [=]() { delete[] out; });
uint8_t* raw_ptr = out_buf.get();
return std::make_shared<NativeArrayBuffer>(out_buf.release(), out_len, [raw_ptr]() { delete[] raw_ptr; });
}

std::shared_ptr<ArrayBuffer> ChaCha20Cipher::final() {
checkCtx();
checkNotFinalized();
is_finalized = true;
unsigned char* empty_output = new unsigned char[0];
return std::make_shared<NativeArrayBuffer>(empty_output, 0, [=]() { delete[] empty_output; });
auto empty_buf = std::make_unique<unsigned char[]>(0);
unsigned char* raw_ptr = empty_buf.get();
return std::make_shared<NativeArrayBuffer>(empty_buf.release(), 0, [raw_ptr]() { delete[] raw_ptr; });
}

} // namespace margelo::nitro::crypto
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,19 @@ std::shared_ptr<ArrayBuffer> ChaCha20Poly1305Cipher::update(const std::shared_pt

// For ChaCha20-Poly1305, output size equals input size since it's a stream cipher
int out_len = in_len;
uint8_t* out = new uint8_t[out_len];
auto out_buf = std::make_unique<uint8_t[]>(out_len);

// Perform the cipher update operation
if (EVP_CipherUpdate(ctx.get(), out, &out_len, native_data->data(), in_len) != 1) {
delete[] out;
if (EVP_CipherUpdate(ctx.get(), out_buf.get(), &out_len, native_data->data(), in_len) != 1) {
unsigned long err = ERR_get_error();
char err_buf[256];
ERR_error_string_n(err, err_buf, sizeof(err_buf));
throw std::runtime_error("ChaCha20Poly1305Cipher: Failed to update: " + std::string(err_buf));
}

// Create and return a new buffer of exact size needed
return std::make_shared<NativeArrayBuffer>(out, out_len, [=]() { delete[] out; });
uint8_t* raw_ptr = out_buf.get();
return std::make_shared<NativeArrayBuffer>(out_buf.release(), out_len, [raw_ptr]() { delete[] raw_ptr; });
}

std::shared_ptr<ArrayBuffer> ChaCha20Poly1305Cipher::final() {
Expand All @@ -90,18 +90,18 @@ std::shared_ptr<ArrayBuffer> ChaCha20Poly1305Cipher::final() {

// For ChaCha20-Poly1305, we need to call final to generate the tag
int out_len = 0;
unsigned char* out = new unsigned char[0];
auto out_buf = std::make_unique<unsigned char[]>(0);

if (EVP_CipherFinal_ex(ctx.get(), out, &out_len) != 1) {
delete[] out;
if (EVP_CipherFinal_ex(ctx.get(), out_buf.get(), &out_len) != 1) {
unsigned long err = ERR_get_error();
char err_buf[256];
ERR_error_string_n(err, err_buf, sizeof(err_buf));
throw std::runtime_error("ChaCha20Poly1305Cipher: Failed to finalize: " + std::string(err_buf));
}

is_finalized = true;
return std::make_shared<NativeArrayBuffer>(out, out_len, [=]() { delete[] out; });
unsigned char* raw_ptr = out_buf.get();
return std::make_shared<NativeArrayBuffer>(out_buf.release(), out_len, [raw_ptr]() { delete[] raw_ptr; });
}

bool ChaCha20Poly1305Cipher::setAAD(const std::shared_ptr<ArrayBuffer>& data, std::optional<double> plaintextLength) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,21 +106,21 @@ std::shared_ptr<ArrayBuffer> HybridCipher::update(const std::shared_ptr<ArrayBuf
}

int out_len = in_len + EVP_CIPHER_CTX_block_size(ctx.get());
uint8_t* out = new uint8_t[out_len];
auto out_buf = std::make_unique<uint8_t[]>(out_len);
// Perform the cipher update operation. The real size of the output is
// returned in out_len
int ret = EVP_CipherUpdate(ctx.get(), out, &out_len, native_data->data(), in_len);
int ret = EVP_CipherUpdate(ctx.get(), out_buf.get(), &out_len, native_data->data(), in_len);

if (!ret) {
unsigned long err = ERR_get_error();
char err_buf[256];
ERR_error_string_n(err, err_buf, sizeof(err_buf));
delete[] out;
throw std::runtime_error("Cipher update failed: " + std::string(err_buf));
}

// Create and return a new buffer of exact size needed
return std::make_shared<NativeArrayBuffer>(out, out_len, [=]() { delete[] out; });
uint8_t* raw_ptr = out_buf.get();
return std::make_shared<NativeArrayBuffer>(out_buf.release(), out_len, [raw_ptr]() { delete[] raw_ptr; });
}

std::shared_ptr<ArrayBuffer> HybridCipher::final() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,9 @@ std::shared_ptr<ArrayBuffer> HybridRsaCipher::publicDecrypt(const std::shared_pt

if (outlen == 0) {
EVP_PKEY_CTX_free(ctx);
uint8_t* empty_buf = new uint8_t[1];
return std::make_shared<NativeArrayBuffer>(empty_buf, 0, [empty_buf]() { delete[] empty_buf; });
auto empty_buf = std::make_unique<uint8_t[]>(1);
uint8_t* raw_ptr = empty_buf.get();
return std::make_shared<NativeArrayBuffer>(empty_buf.release(), 0, [raw_ptr]() { delete[] raw_ptr; });
}

auto out_buf = std::make_unique<uint8_t[]>(outlen);
Expand All @@ -306,8 +307,9 @@ std::shared_ptr<ArrayBuffer> HybridRsaCipher::publicDecrypt(const std::shared_pt
if ((err & 0xFFFFFFF) == 0x1C880004 || (err & 0xFF) == 0x04) {
ERR_clear_error();
EVP_PKEY_CTX_free(ctx);
uint8_t* empty_buf = new uint8_t[1];
return std::make_shared<NativeArrayBuffer>(empty_buf, 0, [empty_buf]() { delete[] empty_buf; });
auto empty_buf = std::make_unique<uint8_t[]>(1);
uint8_t* raw_ptr = empty_buf.get();
return std::make_shared<NativeArrayBuffer>(empty_buf.release(), 0, [raw_ptr]() { delete[] raw_ptr; });
}
EVP_PKEY_CTX_free(ctx);
throwOpaqueDecryptFailure();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,42 +70,42 @@ std::shared_ptr<ArrayBuffer> XChaCha20Poly1305Cipher::final() {
throw std::runtime_error("XChaCha20Poly1305Cipher: libsodium must be enabled (BLSALLOC_SODIUM)");
#else
if (is_cipher) {
uint8_t* ciphertext = new uint8_t[data_buffer_.size()];
auto ciphertext = std::make_unique<uint8_t[]>(data_buffer_.size());

int result =
crypto_aead_xchacha20poly1305_ietf_encrypt_detached(ciphertext, auth_tag_, nullptr, data_buffer_.data(), data_buffer_.size(),
crypto_aead_xchacha20poly1305_ietf_encrypt_detached(ciphertext.get(), auth_tag_, nullptr, data_buffer_.data(), data_buffer_.size(),
aad_.empty() ? nullptr : aad_.data(), aad_.size(), nullptr, nonce_, key_);

if (result != 0) {
sodium_memzero(ciphertext, data_buffer_.size());
delete[] ciphertext;
sodium_memzero(ciphertext.get(), data_buffer_.size());
throw std::runtime_error("XChaCha20Poly1305Cipher: encryption failed");
}

is_finalized = true;
size_t ct_len = data_buffer_.size();
return std::make_shared<NativeArrayBuffer>(ciphertext, ct_len, [=]() { delete[] ciphertext; });
uint8_t* raw_ptr = ciphertext.get();
return std::make_shared<NativeArrayBuffer>(ciphertext.release(), ct_len, [raw_ptr]() { delete[] raw_ptr; });
} else {
if (data_buffer_.empty()) {
is_finalized = true;
return std::make_shared<NativeArrayBuffer>(nullptr, 0, nullptr);
}

uint8_t* plaintext = new uint8_t[data_buffer_.size()];
auto plaintext = std::make_unique<uint8_t[]>(data_buffer_.size());

int result =
crypto_aead_xchacha20poly1305_ietf_decrypt_detached(plaintext, nullptr, data_buffer_.data(), data_buffer_.size(), auth_tag_,
crypto_aead_xchacha20poly1305_ietf_decrypt_detached(plaintext.get(), nullptr, data_buffer_.data(), data_buffer_.size(), auth_tag_,
aad_.empty() ? nullptr : aad_.data(), aad_.size(), nonce_, key_);

if (result != 0) {
sodium_memzero(plaintext, data_buffer_.size());
delete[] plaintext;
sodium_memzero(plaintext.get(), data_buffer_.size());
throw std::runtime_error("XChaCha20Poly1305Cipher: decryption failed - authentication tag mismatch");
}

is_finalized = true;
size_t pt_len = data_buffer_.size();
return std::make_shared<NativeArrayBuffer>(plaintext, pt_len, [=]() { delete[] plaintext; });
uint8_t* raw_ptr = plaintext.get();
return std::make_shared<NativeArrayBuffer>(plaintext.release(), pt_len, [raw_ptr]() { delete[] raw_ptr; });
}
#endif
}
Expand All @@ -132,9 +132,10 @@ std::shared_ptr<ArrayBuffer> XChaCha20Poly1305Cipher::getAuthTag() {
throw std::runtime_error("getAuthTag must be called after final()");
}

uint8_t* tag_copy = new uint8_t[kTagSize];
std::memcpy(tag_copy, auth_tag_, kTagSize);
return std::make_shared<NativeArrayBuffer>(tag_copy, kTagSize, [=]() { delete[] tag_copy; });
auto tag_copy = std::make_unique<uint8_t[]>(kTagSize);
std::memcpy(tag_copy.get(), auth_tag_, kTagSize);
uint8_t* raw_ptr = tag_copy.get();
return std::make_shared<NativeArrayBuffer>(tag_copy.release(), kTagSize, [raw_ptr]() { delete[] raw_ptr; });
#endif
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,38 +60,38 @@ std::shared_ptr<ArrayBuffer> XSalsa20Poly1305Cipher::final() {
throw std::runtime_error("XSalsa20Poly1305Cipher: libsodium must be enabled (BLSALLOC_SODIUM)");
#else
if (is_cipher) {
uint8_t* ciphertext = new uint8_t[data_buffer_.size()];
auto ciphertext = std::make_unique<uint8_t[]>(data_buffer_.size());

int result = crypto_secretbox_detached(ciphertext, auth_tag_, data_buffer_.data(), data_buffer_.size(), nonce_, key_);
int result = crypto_secretbox_detached(ciphertext.get(), auth_tag_, data_buffer_.data(), data_buffer_.size(), nonce_, key_);

if (result != 0) {
sodium_memzero(ciphertext, data_buffer_.size());
delete[] ciphertext;
sodium_memzero(ciphertext.get(), data_buffer_.size());
throw std::runtime_error("XSalsa20Poly1305Cipher: encryption failed");
}

is_finalized = true;
size_t ct_len = data_buffer_.size();
return std::make_shared<NativeArrayBuffer>(ciphertext, ct_len, [=]() { delete[] ciphertext; });
uint8_t* raw_ptr = ciphertext.get();
return std::make_shared<NativeArrayBuffer>(ciphertext.release(), ct_len, [raw_ptr]() { delete[] raw_ptr; });
} else {
if (data_buffer_.empty()) {
is_finalized = true;
return std::make_shared<NativeArrayBuffer>(nullptr, 0, nullptr);
}

uint8_t* plaintext = new uint8_t[data_buffer_.size()];
auto plaintext = std::make_unique<uint8_t[]>(data_buffer_.size());

int result = crypto_secretbox_open_detached(plaintext, data_buffer_.data(), auth_tag_, data_buffer_.size(), nonce_, key_);
int result = crypto_secretbox_open_detached(plaintext.get(), data_buffer_.data(), auth_tag_, data_buffer_.size(), nonce_, key_);

if (result != 0) {
sodium_memzero(plaintext, data_buffer_.size());
delete[] plaintext;
sodium_memzero(plaintext.get(), data_buffer_.size());
throw std::runtime_error("XSalsa20Poly1305Cipher: decryption failed - authentication tag mismatch");
}

is_finalized = true;
size_t pt_len = data_buffer_.size();
return std::make_shared<NativeArrayBuffer>(plaintext, pt_len, [=]() { delete[] plaintext; });
uint8_t* raw_ptr = plaintext.get();
return std::make_shared<NativeArrayBuffer>(plaintext.release(), pt_len, [raw_ptr]() { delete[] raw_ptr; });
}
#endif
}
Expand All @@ -111,9 +111,10 @@ std::shared_ptr<ArrayBuffer> XSalsa20Poly1305Cipher::getAuthTag() {
throw std::runtime_error("getAuthTag must be called after final()");
}

uint8_t* tag_copy = new uint8_t[kTagSize];
std::memcpy(tag_copy, auth_tag_, kTagSize);
return std::make_shared<NativeArrayBuffer>(tag_copy, kTagSize, [=]() { delete[] tag_copy; });
auto tag_copy = std::make_unique<uint8_t[]>(kTagSize);
std::memcpy(tag_copy.get(), auth_tag_, kTagSize);
uint8_t* raw_ptr = tag_copy.get();
return std::make_shared<NativeArrayBuffer>(tag_copy.release(), kTagSize, [raw_ptr]() { delete[] raw_ptr; });
#endif
}

Expand Down
Loading
Loading