@@ -4406,13 +4406,38 @@ bool SSLCtxPointer::setCipherSuites(const char* ciphers) {
44064406
44074407// ============================================================================
44084408
4409- #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4409+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
4410+ namespace {
4411+ bool IsSupportedCipher (const EVP_CIPHER * cipher) {
4412+ if (cipher == nullptr || EVP_CIPHER_is_a (cipher, " NULL" )) return false ;
4413+
4414+ constexpr auto kUnsupportedFlags =
4415+ EVP_CIPH_FLAG_CIPHER_WITH_MAC | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK ;
4416+ if ((EVP_CIPHER_get_flags (cipher) & kUnsupportedFlags ) != 0 ) return false ;
4417+
4418+ #ifdef OSSL_CIPHER_PARAM_ENCRYPT_THEN_MAC
4419+ int encrypt_then_mac = 0 ;
4420+ OSSL_PARAM params[] = {
4421+ OSSL_PARAM_construct_int (OSSL_CIPHER_PARAM_ENCRYPT_THEN_MAC ,
4422+ &encrypt_then_mac),
4423+ OSSL_PARAM_construct_end (),
4424+ };
4425+ if (EVP_CIPHER_get_params (const_cast <EVP_CIPHER *>(cipher), params) == 1 &&
4426+ encrypt_then_mac != 0 ) {
4427+ return false ;
4428+ }
4429+ #endif
4430+
4431+ return true ;
4432+ }
4433+ } // namespace
4434+
44104435Cipher::Cipher (DeleteFnPtr<EVP_CIPHER , EVP_CIPHER_free> cipher)
44114436 : cipher_ (cipher.get ()), fetched_cipher_ (std::move (cipher)) {}
44124437#endif
44134438
44144439Cipher::Cipher (const Cipher& other) : cipher_ (other.cipher_ ) {
4415- #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4440+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
44164441 if (other.fetched_cipher_ != nullptr ) {
44174442 if (EVP_CIPHER_up_ref (other.fetched_cipher_ .get ()) == 1 ) {
44184443 fetched_cipher_.reset (other.fetched_cipher_ .get ());
@@ -4425,7 +4450,7 @@ Cipher::Cipher(const Cipher& other) : cipher_(other.cipher_) {
44254450
44264451Cipher& Cipher::operator =(const Cipher& other) {
44274452 if (this == &other) return *this ;
4428- #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4453+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
44294454 if (other.fetched_cipher_ != nullptr ) {
44304455 if (EVP_CIPHER_up_ref (other.fetched_cipher_ .get ()) == 1 ) {
44314456 fetched_cipher_.reset (other.fetched_cipher_ .get ());
@@ -4444,36 +4469,34 @@ Cipher& Cipher::operator=(const Cipher& other) {
44444469
44454470const Cipher Cipher::FromName (const char * name) {
44464471 const EVP_CIPHER * cipher = EVP_get_cipherbyname (name);
4447- if (cipher != nullptr ) return Cipher (cipher);
4472+ if (cipher != nullptr ) {
4473+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
4474+ if (!IsSupportedCipher (cipher)) return Cipher ();
4475+ #endif
4476+ return Cipher (cipher);
4477+ }
44484478
4449- #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4479+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
44504480 MarkPopErrorOnReturn mark_pop_error_on_return;
44514481 DeleteFnPtr<EVP_CIPHER , EVP_CIPHER_free> fetched (
44524482 EVP_CIPHER_fetch (nullptr , name, nullptr ));
4453- if (fetched == nullptr ) return Cipher ();
4454-
4455- const int mode = EVP_CIPHER_mode (fetched.get ());
4456- const bool is_siv_mode =
4457- #if OPENSSL_WITH_AES_SIV
4458- mode == EVP_CIPH_SIV_MODE ||
4459- #endif
4460- #if OPENSSL_WITH_AES_GCM_SIV
4461- mode == EVP_CIPH_GCM_SIV_MODE ||
4462- #endif
4463- false ;
4464- if (is_siv_mode) return Cipher (std::move (fetched));
4465-
4466- return Cipher ();
4483+ if (!IsSupportedCipher (fetched.get ())) return Cipher ();
4484+ return Cipher (std::move (fetched));
44674485#else
44684486 return Cipher ();
44694487#endif
44704488}
44714489
44724490const Cipher Cipher::FromNid (int nid) {
44734491 const EVP_CIPHER * cipher = EVP_get_cipherbynid (nid);
4474- if (cipher != nullptr ) return Cipher (cipher);
4492+ if (cipher != nullptr ) {
4493+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
4494+ if (!IsSupportedCipher (cipher)) return Cipher ();
4495+ #endif
4496+ return Cipher (cipher);
4497+ }
44754498
4476- #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4499+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
44774500 const char * name = OBJ_nid2sn (nid);
44784501 if (name != nullptr ) return FromName (name);
44794502#endif
@@ -4527,6 +4550,15 @@ bool Cipher::isCcmMode() const {
45274550 return getMode () == EVP_CIPH_CCM_MODE ;
45284551}
45294552
4553+ bool Cipher::isCtsMode () const {
4554+ if (!cipher_) return false ;
4555+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
4556+ return (EVP_CIPHER_get_flags (cipher_) & EVP_CIPH_FLAG_CTS ) != 0 ;
4557+ #else
4558+ return false ;
4559+ #endif
4560+ }
4561+
45304562bool Cipher::isOcbMode () const {
45314563 if (!cipher_) return false ;
45324564 return getMode () == EVP_CIPH_OCB_MODE ;
@@ -4631,7 +4663,7 @@ const char* Cipher::getName() const {
46314663 const char * name = OBJ_nid2sn (nid);
46324664 if (name != nullptr ) return name;
46334665 }
4634- #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4666+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
46354667 return EVP_CIPHER_get0_name (cipher_);
46364668#else
46374669 return {};
@@ -4758,6 +4790,11 @@ bool CipherCtxPointer::isCcmMode() const {
47584790 return getMode () == EVP_CIPH_CCM_MODE ;
47594791}
47604792
4793+ bool CipherCtxPointer::isCtsMode () const {
4794+ if (!ctx_) return false ;
4795+ return Cipher::FromCtx (*this ).isCtsMode ();
4796+ }
4797+
47614798bool CipherCtxPointer::isWrapMode () const {
47624799 if (!ctx_) return false ;
47634800 return getMode () == EVP_CIPH_WRAP_MODE ;
@@ -6229,23 +6266,7 @@ struct CipherCallbackContext {
62296266 void operator ()(const char * name) { cb (name); }
62306267};
62316268
6232- #if OPENSSL_WITH_AES_SIV
6233- constexpr const char * kProviderOnlyAesSivCiphers [] = {
6234- " aes-128-siv" ,
6235- " aes-192-siv" ,
6236- " aes-256-siv" ,
6237- };
6238- #endif
6239-
6240- #if OPENSSL_WITH_AES_GCM_SIV
6241- constexpr const char * kProviderOnlyAesGcmSivCiphers [] = {
6242- " aes-128-gcm-siv" ,
6243- " aes-192-gcm-siv" ,
6244- " aes-256-gcm-siv" ,
6245- };
6246- #endif
6247-
6248- #if OPENSSL_VERSION_MAJOR >= 3
6269+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
62496270template <class TypeName ,
62506271 TypeName* fetch_type (OSSL_LIB_CTX *, const char *, const char *),
62516272 void free_type(TypeName*),
@@ -6269,13 +6290,34 @@ void array_push_back(const TypeName* evp_ref,
62696290 // instance if the algorithm is supported by the public OpenSSL APIs (some
62706291 // algorithms are used internally by OpenSSL and are also passed to this
62716292 // callback).
6272- TypeName* fetched = fetch_type (nullptr , real_name, nullptr );
6273- if (fetched == nullptr ) return ;
6293+ DeleteFnPtr<TypeName, free_type> fetched (
6294+ fetch_type (nullptr , real_name, nullptr ));
6295+ if (!IsSupportedCipher (fetched.get ())) return ;
62746296
6275- free_type (fetched);
62766297 auto & cb = *(static_cast <CipherCallbackContext*>(arg));
62776298 cb (from);
62786299}
6300+
6301+ void array_push_back_provider (EVP_CIPHER * cipher, void * arg) {
6302+ const char * name = EVP_CIPHER_get0_name (cipher);
6303+ if (name == nullptr ) return ;
6304+
6305+ DeleteFnPtr<EVP_CIPHER , EVP_CIPHER_free> fetched (
6306+ EVP_CIPHER_fetch (nullptr , name, nullptr ));
6307+ if (!IsSupportedCipher (fetched.get ())) return ;
6308+
6309+ name = EVP_CIPHER_get0_name (fetched.get ());
6310+ if (name == nullptr ) return ;
6311+
6312+ std::string normalized_name (name);
6313+ std::transform (
6314+ normalized_name.begin (),
6315+ normalized_name.end (),
6316+ normalized_name.begin (),
6317+ [](unsigned char c) { return static_cast <char >(std::tolower (c)); });
6318+ auto & cb = *(static_cast <CipherCallbackContext*>(arg));
6319+ cb (normalized_name.c_str ());
6320+ }
62796321#else
62806322template <class TypeName >
62816323void array_push_back (const TypeName* evp_ref,
@@ -6301,7 +6343,7 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
63016343 }
63026344#else
63036345 EVP_CIPHER_do_all_sorted (
6304- #if OPENSSL_VERSION_MAJOR >= 3
6346+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
63056347 array_push_back<EVP_CIPHER ,
63066348 EVP_CIPHER_fetch,
63076349 EVP_CIPHER_free,
@@ -6311,23 +6353,8 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
63116353 array_push_back<EVP_CIPHER >,
63126354#endif
63136355 &context);
6314- #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
6315- auto maybe_push_provider_only_cipher = [&](const char * name) {
6316- EVP_CIPHER * cipher = EVP_CIPHER_fetch (nullptr , name, nullptr );
6317- if (cipher == nullptr ) return ;
6318- EVP_CIPHER_free (cipher);
6319- context.cb (name);
6320- };
6321- #endif
6322- #if OPENSSL_WITH_AES_SIV
6323- for (const char * name : kProviderOnlyAesSivCiphers ) {
6324- maybe_push_provider_only_cipher (name);
6325- }
6326- #endif
6327- #if OPENSSL_WITH_AES_GCM_SIV
6328- for (const char * name : kProviderOnlyAesGcmSivCiphers ) {
6329- maybe_push_provider_only_cipher (name);
6330- }
6356+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
6357+ EVP_CIPHER_do_all_provided (nullptr , array_push_back_provider, &context);
63316358#endif
63326359#endif
63336360}
0 commit comments