Skip to content

Commit

Permalink
src: move scrypto to ncrypto
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell committed Sep 7, 2024
1 parent bf54858 commit 9b4a431
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 33 deletions.
32 changes: 31 additions & 1 deletion deps/ncrypto/ncrypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,7 @@ DataPointer DHPointer::stateless(const EVPKeyPointer& ourKey,
}

// ============================================================================
// HKDF
// KDF

const EVP_MD* getDigestByName(const std::string_view name) {
return EVP_get_digestbyname(name.data());
Expand All @@ -1275,6 +1275,8 @@ DataPointer hkdf(const EVP_MD* md,
const Buffer<const unsigned char>& info,
const Buffer<const unsigned char>& salt,
size_t length) {
ClearErrorOnReturn clearErrorOnReturn;

if (!checkHkdfLength(md, length) ||
info.len > INT_MAX ||
salt.len > INT_MAX) {
Expand Down Expand Up @@ -1331,4 +1333,32 @@ DataPointer hkdf(const EVP_MD* md,
return buf;
}

bool checkScryptParams(uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem) {
return EVP_PBE_scrypt(nullptr, 0, nullptr, 0, N, r, p, maxmem, nullptr, 0) == 1;
}

DataPointer scrypt(const Buffer<const char>& pass,
const Buffer<const unsigned char>& salt,
uint64_t N,
uint64_t r,
uint64_t p,
uint64_t maxmem,
size_t length) {
ClearErrorOnReturn clearErrorOnReturn;

if (pass.len > INT_MAX ||
salt.len > INT_MAX) {
return {};
}

auto dp = DataPointer::Alloc(length);
if (dp && EVP_PBE_scrypt(
pass.data, pass.len, salt.data, salt.len, N, r, p, maxmem,
reinterpret_cast<unsigned char*>(dp.get()), length)) {
return dp;
}

return {};
}

} // namespace ncrypto
12 changes: 11 additions & 1 deletion deps/ncrypto/ncrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ BIOPointer ExportPublicKey(const char* input, size_t length);
Buffer<char> ExportChallenge(const char* input, size_t length);

// ============================================================================
// HKDF
// KDF

const EVP_MD* getDigestByName(const std::string_view name);

Expand All @@ -604,6 +604,16 @@ DataPointer hkdf(const EVP_MD* md,
const Buffer<const unsigned char>& salt,
size_t length);

bool checkScryptParams(uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem);

DataPointer scrypt(const Buffer<const char>& pass,
const Buffer<const unsigned char>& salt,
uint64_t N,
uint64_t r,
uint64_t p,
uint64_t maxmem,
size_t length);

// ============================================================================
// Version metadata
#define NCRYPTO_VERSION "0.0.1"
Expand Down
58 changes: 28 additions & 30 deletions src/crypto/crypto_scrypt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,10 @@ Maybe<bool> ScryptTraits::AdditionalConfig(
params->p = args[offset + 4].As<Uint32>()->Value();
params->maxmem = args[offset + 5]->IntegerValue(env->context()).ToChecked();

if (EVP_PBE_scrypt(
nullptr,
0,
nullptr,
0,
params->N,
params->r,
params->p,
params->maxmem,
nullptr,
0) != 1) {
params->length = args[offset + 6].As<Int32>()->Value();
CHECK_GE(params->length, 0);

if (!ncrypto::checkScryptParams(params->N, params->r, params->p, params->maxmem)) {
// Do not use CryptoErrorStore or ThrowCryptoError here in order to maintain
// backward compatibility with ERR_CRYPTO_INVALID_SCRYPT_PARAMS.
uint32_t err = ERR_peek_last_error();
Expand All @@ -118,33 +111,38 @@ Maybe<bool> ScryptTraits::AdditionalConfig(
return Nothing<bool>();
}

params->length = args[offset + 6].As<Int32>()->Value();
CHECK_GE(params->length, 0);

return Just(true);
}

bool ScryptTraits::DeriveBits(
Environment* env,
const ScryptConfig& params,
ByteSource* out) {
ByteSource::Builder buf(params.length);

// Both the pass and salt may be zero-length at this point

if (!EVP_PBE_scrypt(params.pass.data<char>(),
params.pass.size(),
params.salt.data<unsigned char>(),
params.salt.size(),
params.N,
params.r,
params.p,
params.maxmem,
buf.data<unsigned char>(),
params.length)) {
return false;

// If the params.length is zero-length, just return an empty buffer.
// It's useless, yes, but allowed via the API.
if (params.length == 0) {
*out = ByteSource();
return true;
}
*out = std::move(buf).release();

auto dp = ncrypto::scrypt(
ncrypto::Buffer<const char> {
.data = params.pass.data<char>(),
.len = params.pass.size(),
},
ncrypto::Buffer<const unsigned char> {
.data = params.salt.data<unsigned char>(),
.len = params.salt.size(),
},
params.N,
params.r,
params.p,
params.maxmem,
params.length);

if (!dp) return false;
*out = ByteSource::Allocated(dp.release());
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-crypto-scrypt.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Flags: --expose-internals
// Flags: --expose-internals --no-warnings
'use strict';
const common = require('../common');
if (!common.hasCrypto)
Expand Down

0 comments on commit 9b4a431

Please sign in to comment.