Skip to content
Open
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
134 changes: 131 additions & 3 deletions deps/ncrypto/ncrypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3165,12 +3165,47 @@ bool SSLCtxPointer::setCipherSuites(const char* ciphers) {

// ============================================================================

#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
Cipher::Cipher(EVP_CIPHER* cipher)
: cipher_(cipher), fetched_cipher_(cipher, EVP_CIPHER_free) {}
#endif

const Cipher Cipher::FromName(const char* name) {
return Cipher(EVP_get_cipherbyname(name));
const EVP_CIPHER* cipher = EVP_get_cipherbyname(name);
if (cipher != nullptr) return Cipher(cipher);

#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
EVP_CIPHER* fetched = EVP_CIPHER_fetch(nullptr, name, nullptr);
if (fetched == nullptr) return Cipher();

const int mode = EVP_CIPHER_mode(fetched);
const bool is_siv_mode =
#if OPENSSL_WITH_AES_SIV
mode == EVP_CIPH_SIV_MODE ||
#endif
#if OPENSSL_WITH_AES_GCM_SIV
mode == EVP_CIPH_GCM_SIV_MODE ||
#endif
false;
if (is_siv_mode) return Cipher(fetched);

EVP_CIPHER_free(fetched);
return Cipher();
#else
return Cipher();
#endif
}

const Cipher Cipher::FromNid(int nid) {
return Cipher(EVP_get_cipherbynid(nid));
const EVP_CIPHER* cipher = EVP_get_cipherbynid(nid);
if (cipher != nullptr) return Cipher(cipher);

#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
const char* name = OBJ_nid2sn(nid);
if (name != nullptr) return FromName(name);
#endif

return Cipher();
}

const Cipher Cipher::FromCtx(const CipherCtxPointer& ctx) {
Expand Down Expand Up @@ -3224,6 +3259,24 @@ bool Cipher::isOcbMode() const {
return getMode() == EVP_CIPH_OCB_MODE;
}

bool Cipher::isSivMode() const {
if (!cipher_) return false;
#if OPENSSL_WITH_AES_SIV
return getMode() == EVP_CIPH_SIV_MODE;
#else
return false;
#endif
}

bool Cipher::isGcmSivMode() const {
if (!cipher_) return false;
#if OPENSSL_WITH_AES_GCM_SIV
return getMode() == EVP_CIPH_GCM_SIV_MODE;
#else
return false;
#endif
}

bool Cipher::isStreamMode() const {
if (!cipher_) return false;
return getMode() == EVP_CIPH_STREAM_CIPHER;
Expand Down Expand Up @@ -3278,6 +3331,14 @@ std::string_view Cipher::getModeLabel() const {
return "ocb";
case EVP_CIPH_OFB_MODE:
return "ofb";
#if OPENSSL_WITH_AES_SIV
case EVP_CIPH_SIV_MODE:
return "siv";
#endif
#if OPENSSL_WITH_AES_GCM_SIV
case EVP_CIPH_GCM_SIV_MODE:
return "gcm-siv";
#endif
case EVP_CIPH_WRAP_MODE:
return "wrap";
case EVP_CIPH_XTS_MODE:
Expand All @@ -3292,7 +3353,16 @@ const char* Cipher::getName() const {
if (!cipher_) return {};
// OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
// EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
return OBJ_nid2sn(getNid());
const int nid = getNid();
if (nid != NID_undef) {
const char* name = OBJ_nid2sn(nid);
if (name != nullptr) return name;
}
#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
return EVP_CIPHER_get0_name(cipher_);
#else
return {};
#endif
}

bool Cipher::isSupportedAuthenticatedMode() const {
Expand All @@ -3301,6 +3371,12 @@ bool Cipher::isSupportedAuthenticatedMode() const {
case EVP_CIPH_GCM_MODE:
#ifndef OPENSSL_NO_OCB
case EVP_CIPH_OCB_MODE:
#endif
#if OPENSSL_WITH_AES_SIV
case EVP_CIPH_SIV_MODE:
#endif
#if OPENSSL_WITH_AES_GCM_SIV
case EVP_CIPH_GCM_SIV_MODE:
#endif
return true;
case EVP_CIPH_STREAM_CIPHER:
Expand Down Expand Up @@ -3414,6 +3490,24 @@ bool CipherCtxPointer::isWrapMode() const {
return getMode() == EVP_CIPH_WRAP_MODE;
}

bool CipherCtxPointer::isSivMode() const {
if (!ctx_) return false;
#if OPENSSL_WITH_AES_SIV
return getMode() == EVP_CIPH_SIV_MODE;
#else
return false;
#endif
}

bool CipherCtxPointer::isGcmSivMode() const {
if (!ctx_) return false;
#if OPENSSL_WITH_AES_GCM_SIV
return getMode() == EVP_CIPH_GCM_SIV_MODE;
#else
return false;
#endif
}

bool CipherCtxPointer::isChaCha20Poly1305() const {
if (!ctx_) return false;
return getNid() == NID_chacha20_poly1305;
Expand Down Expand Up @@ -4242,6 +4336,22 @@ struct CipherCallbackContext {
void operator()(const char* name) { cb(name); }
};

#if OPENSSL_WITH_AES_SIV
constexpr const char* kProviderOnlyAesSivCiphers[] = {
"aes-128-siv",
"aes-192-siv",
"aes-256-siv",
};
#endif

#if OPENSSL_WITH_AES_GCM_SIV
constexpr const char* kProviderOnlyAesGcmSivCiphers[] = {
"aes-128-gcm-siv",
"aes-192-gcm-siv",
"aes-256-gcm-siv",
};
#endif

#if OPENSSL_VERSION_MAJOR >= 3
template <class TypeName,
TypeName* fetch_type(OSSL_LIB_CTX*, const char*, const char*),
Expand Down Expand Up @@ -4308,6 +4418,24 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
array_push_back<EVP_CIPHER>,
#endif
&context);
#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
auto maybe_push_provider_only_cipher = [&](const char* name) {
EVP_CIPHER* cipher = EVP_CIPHER_fetch(nullptr, name, nullptr);
if (cipher == nullptr) return;
EVP_CIPHER_free(cipher);
context.cb(name);
};
#endif
#if OPENSSL_WITH_AES_SIV
for (const char* name : kProviderOnlyAesSivCiphers) {
maybe_push_provider_only_cipher(name);
}
#endif
#if OPENSSL_WITH_AES_GCM_SIV
for (const char* name : kProviderOnlyAesGcmSivCiphers) {
maybe_push_provider_only_cipher(name);
}
#endif
#endif
}

Expand Down
23 changes: 23 additions & 0 deletions deps/ncrypto/ncrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@
#define OPENSSL_WITH_KMAC 0
#endif

#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 0)
#define OPENSSL_WITH_AES_SIV 1
#else
#define OPENSSL_WITH_AES_SIV 0
#endif

#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 2)
#define OPENSSL_WITH_AES_GCM_SIV 1
#else
#define OPENSSL_WITH_AES_GCM_SIV 0
#endif

#if defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_PREREQ(3, 2)
#define OPENSSL_WITH_SIGNATURE_CONTEXT_STRING 1
#else
Expand Down Expand Up @@ -402,6 +414,9 @@ class Cipher final {
Cipher(const Cipher&) = default;
Cipher& operator=(const Cipher&) = default;
inline Cipher& operator=(const EVP_CIPHER* cipher) {
#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
fetched_cipher_.reset();
#endif
cipher_ = cipher;
return *this;
}
Expand All @@ -424,6 +439,8 @@ class Cipher final {
bool isCtrMode() const;
bool isCcmMode() const;
bool isOcbMode() const;
bool isSivMode() const;
bool isGcmSivMode() const;
bool isStreamMode() const;
bool isChaCha20Poly1305() const;

Expand Down Expand Up @@ -494,6 +511,10 @@ class Cipher final {

private:
const EVP_CIPHER* cipher_ = nullptr;
#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
explicit Cipher(EVP_CIPHER* cipher);
std::shared_ptr<EVP_CIPHER> fetched_cipher_;
#endif
};

// ============================================================================
Expand Down Expand Up @@ -833,6 +854,8 @@ class CipherCtxPointer final {
bool isOcbMode() const;
bool isCcmMode() const;
bool isWrapMode() const;
bool isSivMode() const;
bool isGcmSivMode() const;
bool isChaCha20Poly1305() const;

bool update(const Buffer<const unsigned char>& in,
Expand Down
Loading
Loading