@@ -3165,12 +3165,51 @@ bool SSLCtxPointer::setCipherSuites(const char* ciphers) {
31653165
31663166// ============================================================================
31673167
3168+ #if OPENSSL_VERSION_MAJOR >= 3
3169+ Cipher::Cipher (EVP_CIPHER* cipher)
3170+ : cipher_ (cipher),
3171+ fetched_cipher_ (cipher, EVP_CIPHER_free) {}
3172+ #else
3173+ Cipher::Cipher (EVP_CIPHER* cipher)
3174+ : cipher_ (cipher) {}
3175+ #endif
3176+
31683177const Cipher Cipher::FromName (const char * name) {
3169- return Cipher (EVP_get_cipherbyname (name));
3178+ const EVP_CIPHER* cipher = EVP_get_cipherbyname (name);
3179+ if (cipher != nullptr ) return Cipher (cipher);
3180+
3181+ #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
3182+ EVP_CIPHER* fetched = EVP_CIPHER_fetch (nullptr , name, nullptr );
3183+ if (fetched == nullptr ) return Cipher ();
3184+
3185+ const int mode = EVP_CIPHER_mode (fetched);
3186+ const bool is_siv_mode =
3187+ #if OPENSSL_WITH_AES_SIV
3188+ mode == EVP_CIPH_SIV_MODE ||
3189+ #endif
3190+ #if OPENSSL_WITH_AES_GCM_SIV
3191+ mode == EVP_CIPH_GCM_SIV_MODE ||
3192+ #endif
3193+ false ;
3194+ if (is_siv_mode) return Cipher (fetched);
3195+
3196+ EVP_CIPHER_free (fetched);
3197+ return Cipher ();
3198+ #else
3199+ return Cipher ();
3200+ #endif
31703201}
31713202
31723203const Cipher Cipher::FromNid (int nid) {
3173- return Cipher (EVP_get_cipherbynid (nid));
3204+ const EVP_CIPHER* cipher = EVP_get_cipherbynid (nid);
3205+ if (cipher != nullptr ) return Cipher (cipher);
3206+
3207+ #if OPENSSL_VERSION_MAJOR >= 3
3208+ const char * name = OBJ_nid2sn (nid);
3209+ if (name != nullptr ) return FromName (name);
3210+ #endif
3211+
3212+ return Cipher ();
31743213}
31753214
31763215const Cipher Cipher::FromCtx (const CipherCtxPointer& ctx) {
@@ -3224,6 +3263,24 @@ bool Cipher::isOcbMode() const {
32243263 return getMode () == EVP_CIPH_OCB_MODE;
32253264}
32263265
3266+ bool Cipher::isSivMode () const {
3267+ if (!cipher_) return false ;
3268+ #if OPENSSL_WITH_AES_SIV
3269+ return getMode () == EVP_CIPH_SIV_MODE;
3270+ #else
3271+ return false ;
3272+ #endif
3273+ }
3274+
3275+ bool Cipher::isGcmSivMode () const {
3276+ if (!cipher_) return false ;
3277+ #if OPENSSL_WITH_AES_GCM_SIV
3278+ return getMode () == EVP_CIPH_GCM_SIV_MODE;
3279+ #else
3280+ return false ;
3281+ #endif
3282+ }
3283+
32273284bool Cipher::isStreamMode () const {
32283285 if (!cipher_) return false ;
32293286 return getMode () == EVP_CIPH_STREAM_CIPHER;
@@ -3278,6 +3335,14 @@ std::string_view Cipher::getModeLabel() const {
32783335 return " ocb" ;
32793336 case EVP_CIPH_OFB_MODE:
32803337 return " ofb" ;
3338+ #if OPENSSL_WITH_AES_SIV
3339+ case EVP_CIPH_SIV_MODE:
3340+ return " siv" ;
3341+ #endif
3342+ #if OPENSSL_WITH_AES_GCM_SIV
3343+ case EVP_CIPH_GCM_SIV_MODE:
3344+ return " gcm-siv" ;
3345+ #endif
32813346 case EVP_CIPH_WRAP_MODE:
32823347 return " wrap" ;
32833348 case EVP_CIPH_XTS_MODE:
@@ -3292,7 +3357,16 @@ const char* Cipher::getName() const {
32923357 if (!cipher_) return {};
32933358 // OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
32943359 // EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
3295- return OBJ_nid2sn (getNid ());
3360+ const int nid = getNid ();
3361+ if (nid != NID_undef) {
3362+ const char * name = OBJ_nid2sn (nid);
3363+ if (name != nullptr ) return name;
3364+ }
3365+ #if OPENSSL_VERSION_MAJOR >= 3
3366+ return EVP_CIPHER_get0_name (cipher_);
3367+ #else
3368+ return {};
3369+ #endif
32963370}
32973371
32983372bool Cipher::isSupportedAuthenticatedMode () const {
@@ -3301,6 +3375,12 @@ bool Cipher::isSupportedAuthenticatedMode() const {
33013375 case EVP_CIPH_GCM_MODE:
33023376#ifndef OPENSSL_NO_OCB
33033377 case EVP_CIPH_OCB_MODE:
3378+ #endif
3379+ #if OPENSSL_WITH_AES_SIV
3380+ case EVP_CIPH_SIV_MODE:
3381+ #endif
3382+ #if OPENSSL_WITH_AES_GCM_SIV
3383+ case EVP_CIPH_GCM_SIV_MODE:
33043384#endif
33053385 return true ;
33063386 case EVP_CIPH_STREAM_CIPHER:
@@ -3414,6 +3494,24 @@ bool CipherCtxPointer::isWrapMode() const {
34143494 return getMode () == EVP_CIPH_WRAP_MODE;
34153495}
34163496
3497+ bool CipherCtxPointer::isSivMode () const {
3498+ if (!ctx_) return false ;
3499+ #if OPENSSL_WITH_AES_SIV
3500+ return getMode () == EVP_CIPH_SIV_MODE;
3501+ #else
3502+ return false ;
3503+ #endif
3504+ }
3505+
3506+ bool CipherCtxPointer::isGcmSivMode () const {
3507+ if (!ctx_) return false ;
3508+ #if OPENSSL_WITH_AES_GCM_SIV
3509+ return getMode () == EVP_CIPH_GCM_SIV_MODE;
3510+ #else
3511+ return false ;
3512+ #endif
3513+ }
3514+
34173515bool CipherCtxPointer::isChaCha20Poly1305 () const {
34183516 if (!ctx_) return false ;
34193517 return getNid () == NID_chacha20_poly1305;
@@ -4242,6 +4340,21 @@ struct CipherCallbackContext {
42424340 void operator ()(const char * name) { cb (name); }
42434341};
42444342
4343+ #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4344+ constexpr const char * kProviderOnlyCiphers [] = {
4345+ #if OPENSSL_WITH_AES_SIV
4346+ " aes-128-siv" ,
4347+ " aes-192-siv" ,
4348+ " aes-256-siv" ,
4349+ #endif
4350+ #if OPENSSL_WITH_AES_GCM_SIV
4351+ " aes-128-gcm-siv" ,
4352+ " aes-192-gcm-siv" ,
4353+ " aes-256-gcm-siv" ,
4354+ #endif
4355+ };
4356+ #endif
4357+
42454358#if OPENSSL_VERSION_MAJOR >= 3
42464359template <class TypeName ,
42474360 TypeName* fetch_type (OSSL_LIB_CTX*, const char *, const char *),
@@ -4308,6 +4421,14 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
43084421 array_push_back<EVP_CIPHER>,
43094422#endif
43104423 &context);
4424+ #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4425+ for (const char * name : kProviderOnlyCiphers ) {
4426+ EVP_CIPHER* cipher = EVP_CIPHER_fetch (nullptr , name, nullptr );
4427+ if (cipher == nullptr ) continue ;
4428+ EVP_CIPHER_free (cipher);
4429+ context.cb (name);
4430+ }
4431+ #endif
43114432#endif
43124433}
43134434
0 commit comments