Skip to content

Commit e2064b4

Browse files
committed
src: move more crypto impl details into ncrypto
1 parent 4c446ad commit e2064b4

File tree

7 files changed

+172
-98
lines changed

7 files changed

+172
-98
lines changed

deps/ncrypto/ncrypto.cc

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,17 +1669,17 @@ const EVP_CIPHER* getCipherByName(const std::string_view name) {
16691669
return EVP_get_cipherbyname(name.data());
16701670
}
16711671

1672-
bool checkHkdfLength(const EVP_MD* md, size_t length) {
1672+
bool checkHkdfLength(const Digest& md, size_t length) {
16731673
// HKDF-Expand computes up to 255 HMAC blocks, each having as many bits as
16741674
// the output of the hash function. 255 is a hard limit because HKDF appends
16751675
// an 8-bit counter to each HMAC'd message, starting at 1.
16761676
static constexpr size_t kMaxDigestMultiplier = 255;
1677-
size_t max_length = EVP_MD_size(md) * kMaxDigestMultiplier;
1677+
size_t max_length = md.size() * kMaxDigestMultiplier;
16781678
if (length > max_length) return false;
16791679
return true;
16801680
}
16811681

1682-
DataPointer hkdf(const EVP_MD* md,
1682+
DataPointer hkdf(const Digest& md,
16831683
const Buffer<const unsigned char>& key,
16841684
const Buffer<const unsigned char>& info,
16851685
const Buffer<const unsigned char>& salt,
@@ -1703,7 +1703,7 @@ DataPointer hkdf(const EVP_MD* md,
17031703
if (salt.len > 0) {
17041704
actual_salt = {reinterpret_cast<const char*>(salt.data), salt.len};
17051705
} else {
1706-
actual_salt = {default_salt, static_cast<unsigned>(EVP_MD_size(md))};
1706+
actual_salt = {default_salt, static_cast<unsigned>(md.size())};
17071707
}
17081708

17091709
// We do not use EVP_PKEY_HKDF_MODE_EXTRACT_AND_EXPAND because and instead
@@ -2786,6 +2786,11 @@ bool Cipher::isStreamMode() const {
27862786
return getMode() == EVP_CIPH_STREAM_CIPHER;
27872787
}
27882788

2789+
bool Cipher::isChaCha20Poly1305() const {
2790+
if (!cipher_) return false;
2791+
return getNid() == NID_chacha20_poly1305;
2792+
}
2793+
27892794
int Cipher::getMode() const {
27902795
if (!cipher_) return 0;
27912796
return EVP_CIPHER_mode(cipher_);
@@ -2862,6 +2867,14 @@ bool Cipher::isSupportedAuthenticatedMode() const {
28622867
}
28632868
}
28642869

2870+
int Cipher::bytesToKey(const Digest& digest,
2871+
const Buffer<const unsigned char>& input,
2872+
unsigned char* key,
2873+
unsigned char* iv) const {
2874+
return EVP_BytesToKey(
2875+
*this, Digest::MD5, nullptr, input.data, input.len, 1, key, iv);
2876+
}
2877+
28652878
// ============================================================================
28662879

28672880
CipherCtxPointer CipherCtxPointer::New() {
@@ -2938,6 +2951,26 @@ int CipherCtxPointer::getMode() const {
29382951
return EVP_CIPHER_CTX_mode(ctx_.get());
29392952
}
29402953

2954+
bool CipherCtxPointer::isGcmMode() const {
2955+
if (!ctx_) return false;
2956+
return getMode() == EVP_CIPH_GCM_MODE;
2957+
}
2958+
2959+
bool CipherCtxPointer::isCcmMode() const {
2960+
if (!ctx_) return false;
2961+
return getMode() == EVP_CIPH_CCM_MODE;
2962+
}
2963+
2964+
bool CipherCtxPointer::isWrapMode() const {
2965+
if (!ctx_) return false;
2966+
return getMode() == EVP_CIPH_WRAP_MODE;
2967+
}
2968+
2969+
bool CipherCtxPointer::isChaCha20Poly1305() const {
2970+
if (!ctx_) return false;
2971+
return getNid() == NID_chacha20_poly1305;
2972+
}
2973+
29412974
int CipherCtxPointer::getNid() const {
29422975
if (!ctx_) return 0;
29432976
return EVP_CIPHER_CTX_nid(ctx_.get());
@@ -3720,9 +3753,7 @@ DataPointer Cipher::recover(const EVPKeyPointer& key,
37203753
namespace {
37213754
struct CipherCallbackContext {
37223755
Cipher::CipherNameCallback cb;
3723-
void operator()(std::string_view name) {
3724-
cb(name);
3725-
}
3756+
void operator()(std::string_view name) { cb(name); }
37263757
};
37273758

37283759
#if OPENSSL_VERSION_MAJOR >= 3
@@ -3759,9 +3790,9 @@ void array_push_back(const TypeName* evp_ref,
37593790
#else
37603791
template <class TypeName>
37613792
void array_push_back(const TypeName* evp_ref,
3762-
const char* from,
3763-
const char* to,
3764-
void* arg) {
3793+
const char* from,
3794+
const char* to,
3795+
void* arg) {
37653796
if (!from) return;
37663797
auto& cb = *(static_cast<CipherCallbackContext*>(arg));
37673798
cb(from);
@@ -3776,15 +3807,15 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
37763807

37773808
EVP_CIPHER_do_all_sorted(
37783809
#if OPENSSL_VERSION_MAJOR >= 3
3779-
array_push_back<EVP_CIPHER,
3780-
EVP_CIPHER_fetch,
3781-
EVP_CIPHER_free,
3782-
EVP_get_cipherbyname,
3783-
EVP_CIPHER_get0_name>,
3810+
array_push_back<EVP_CIPHER,
3811+
EVP_CIPHER_fetch,
3812+
EVP_CIPHER_free,
3813+
EVP_get_cipherbyname,
3814+
EVP_CIPHER_get0_name>,
37843815
#else
3785-
array_push_back<EVP_CIPHER>,
3816+
array_push_back<EVP_CIPHER>,
37863817
#endif
3787-
&context);
3818+
&context);
37883819
}
37893820

37903821
// ============================================================================
@@ -4143,4 +4174,21 @@ size_t Dsa::getDivisorLength() const {
41434174
return BignumPointer::GetBitCount(getQ());
41444175
}
41454176

4177+
// ============================================================================
4178+
4179+
size_t Digest::size() const {
4180+
if (md_ == nullptr) return 0;
4181+
return EVP_MD_size(md_);
4182+
}
4183+
4184+
const Digest Digest::MD5 = Digest(EVP_md5());
4185+
const Digest Digest::SHA1 = Digest(EVP_sha1());
4186+
const Digest Digest::SHA256 = Digest(EVP_sha256());
4187+
const Digest Digest::SHA384 = Digest(EVP_sha384());
4188+
const Digest Digest::SHA512 = Digest(EVP_sha512());
4189+
4190+
const Digest Digest::FromName(std::string_view name) {
4191+
return ncrypto::getDigestByName(name);
4192+
}
4193+
41464194
} // namespace ncrypto

deps/ncrypto/ncrypto.h

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,44 @@ struct Buffer {
247247
size_t len = 0;
248248
};
249249

250+
class Digest final {
251+
public:
252+
Digest() = default;
253+
Digest(const EVP_MD* md) : md_(md) {}
254+
Digest(const Digest&) = default;
255+
Digest& operator=(const Digest&) = default;
256+
inline Digest& operator=(const EVP_MD* md) {
257+
md_ = md;
258+
return *this;
259+
}
260+
NCRYPTO_DISALLOW_MOVE(Digest)
261+
262+
size_t size() const;
263+
264+
inline const EVP_MD* get() const { return md_; }
265+
inline operator const EVP_MD*() const { return md_; }
266+
inline operator bool() const { return md_ != nullptr; }
267+
268+
static const Digest MD5;
269+
static const Digest SHA1;
270+
static const Digest SHA256;
271+
static const Digest SHA384;
272+
static const Digest SHA512;
273+
274+
static const Digest FromName(std::string_view name);
275+
276+
private:
277+
const EVP_MD* md_ = nullptr;
278+
};
279+
250280
DataPointer hashDigest(const Buffer<const unsigned char>& data,
251281
const EVP_MD* md);
252282

253283
class Cipher final {
254284
public:
285+
static constexpr size_t MAX_KEY_LENGTH = EVP_MAX_KEY_LENGTH;
286+
static constexpr size_t MAX_IV_LENGTH = EVP_MAX_IV_LENGTH;
287+
255288
Cipher() = default;
256289
Cipher(const EVP_CIPHER* cipher) : cipher_(cipher) {}
257290
Cipher(const Cipher&) = default;
@@ -280,9 +313,15 @@ class Cipher final {
280313
bool isCcmMode() const;
281314
bool isOcbMode() const;
282315
bool isStreamMode() const;
316+
bool isChaCha20Poly1305() const;
283317

284318
bool isSupportedAuthenticatedMode() const;
285319

320+
int bytesToKey(const Digest& digest,
321+
const Buffer<const unsigned char>& input,
322+
unsigned char* key,
323+
unsigned char* iv) const;
324+
286325
static const Cipher FromName(std::string_view name);
287326
static const Cipher FromNid(int nid);
288327
static const Cipher FromCtx(const CipherCtxPointer& ctx);
@@ -644,6 +683,11 @@ class CipherCtxPointer final {
644683
int getMode() const;
645684
int getNid() const;
646685

686+
bool isGcmMode() const;
687+
bool isCcmMode() const;
688+
bool isWrapMode() const;
689+
bool isChaCha20Poly1305() const;
690+
647691
bool update(const Buffer<const unsigned char>& in,
648692
unsigned char* out,
649693
int* out_len,
@@ -1420,13 +1464,13 @@ const EVP_CIPHER* getCipherByName(const std::string_view name);
14201464
// Verify that the specified HKDF output length is valid for the given digest.
14211465
// The maximum length for HKDF output for a given digest is 255 times the
14221466
// hash size for the given digest algorithm.
1423-
bool checkHkdfLength(const EVP_MD* md, size_t length);
1467+
bool checkHkdfLength(const Digest& digest, size_t length);
14241468

14251469
bool extractP1363(const Buffer<const unsigned char>& buf,
14261470
unsigned char* dest,
14271471
size_t n);
14281472

1429-
DataPointer hkdf(const EVP_MD* md,
1473+
DataPointer hkdf(const Digest& md,
14301474
const Buffer<const unsigned char>& key,
14311475
const Buffer<const unsigned char>& info,
14321476
const Buffer<const unsigned char>& salt,

src/crypto/crypto_aes.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ Maybe<void> AESCipherTraits::AdditionalConfig(
484484
return Nothing<void>();
485485
}
486486

487-
if (params->cipher.isWrapMode()) {
487+
if (!params->cipher.isWrapMode()) {
488488
if (!ValidateIV(env, mode, args[offset + 1], params)) {
489489
return Nothing<void>();
490490
}

0 commit comments

Comments
 (0)