@@ -3165,12 +3165,49 @@ bool SSLCtxPointer::setCipherSuites(const char* ciphers) {
31653165
31663166// ============================================================================
31673167
3168+ #if OPENSSL_VERSION_MAJOR >= 3
3169+ Cipher::Cipher (EVP_CIPHER* cipher)
3170+ : cipher_ (cipher), fetched_cipher_ (cipher, EVP_CIPHER_free) {}
3171+ #else
3172+ Cipher::Cipher (EVP_CIPHER* cipher) : cipher_ (cipher) {}
3173+ #endif
3174+
31683175const Cipher Cipher::FromName (const char * name) {
3169- return Cipher (EVP_get_cipherbyname (name));
3176+ const EVP_CIPHER* cipher = EVP_get_cipherbyname (name);
3177+ if (cipher != nullptr ) return Cipher (cipher);
3178+
3179+ #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
3180+ EVP_CIPHER* fetched = EVP_CIPHER_fetch (nullptr , name, nullptr );
3181+ if (fetched == nullptr ) return Cipher ();
3182+
3183+ const int mode = EVP_CIPHER_mode (fetched);
3184+ const bool is_siv_mode =
3185+ #if OPENSSL_WITH_AES_SIV
3186+ mode == EVP_CIPH_SIV_MODE ||
3187+ #endif
3188+ #if OPENSSL_WITH_AES_GCM_SIV
3189+ mode == EVP_CIPH_GCM_SIV_MODE ||
3190+ #endif
3191+ false ;
3192+ if (is_siv_mode) return Cipher (fetched);
3193+
3194+ EVP_CIPHER_free (fetched);
3195+ return Cipher ();
3196+ #else
3197+ return Cipher ();
3198+ #endif
31703199}
31713200
31723201const Cipher Cipher::FromNid (int nid) {
3173- return Cipher (EVP_get_cipherbynid (nid));
3202+ const EVP_CIPHER* cipher = EVP_get_cipherbynid (nid);
3203+ if (cipher != nullptr ) return Cipher (cipher);
3204+
3205+ #if OPENSSL_VERSION_MAJOR >= 3
3206+ const char * name = OBJ_nid2sn (nid);
3207+ if (name != nullptr ) return FromName (name);
3208+ #endif
3209+
3210+ return Cipher ();
31743211}
31753212
31763213const Cipher Cipher::FromCtx (const CipherCtxPointer& ctx) {
@@ -3224,6 +3261,24 @@ bool Cipher::isOcbMode() const {
32243261 return getMode () == EVP_CIPH_OCB_MODE;
32253262}
32263263
3264+ bool Cipher::isSivMode () const {
3265+ if (!cipher_) return false ;
3266+ #if OPENSSL_WITH_AES_SIV
3267+ return getMode () == EVP_CIPH_SIV_MODE;
3268+ #else
3269+ return false ;
3270+ #endif
3271+ }
3272+
3273+ bool Cipher::isGcmSivMode () const {
3274+ if (!cipher_) return false ;
3275+ #if OPENSSL_WITH_AES_GCM_SIV
3276+ return getMode () == EVP_CIPH_GCM_SIV_MODE;
3277+ #else
3278+ return false ;
3279+ #endif
3280+ }
3281+
32273282bool Cipher::isStreamMode () const {
32283283 if (!cipher_) return false ;
32293284 return getMode () == EVP_CIPH_STREAM_CIPHER;
@@ -3278,6 +3333,14 @@ std::string_view Cipher::getModeLabel() const {
32783333 return " ocb" ;
32793334 case EVP_CIPH_OFB_MODE:
32803335 return " ofb" ;
3336+ #if OPENSSL_WITH_AES_SIV
3337+ case EVP_CIPH_SIV_MODE:
3338+ return " siv" ;
3339+ #endif
3340+ #if OPENSSL_WITH_AES_GCM_SIV
3341+ case EVP_CIPH_GCM_SIV_MODE:
3342+ return " gcm-siv" ;
3343+ #endif
32813344 case EVP_CIPH_WRAP_MODE:
32823345 return " wrap" ;
32833346 case EVP_CIPH_XTS_MODE:
@@ -3292,7 +3355,16 @@ const char* Cipher::getName() const {
32923355 if (!cipher_) return {};
32933356 // OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
32943357 // EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
3295- return OBJ_nid2sn (getNid ());
3358+ const int nid = getNid ();
3359+ if (nid != NID_undef) {
3360+ const char * name = OBJ_nid2sn (nid);
3361+ if (name != nullptr ) return name;
3362+ }
3363+ #if OPENSSL_VERSION_MAJOR >= 3
3364+ return EVP_CIPHER_get0_name (cipher_);
3365+ #else
3366+ return {};
3367+ #endif
32963368}
32973369
32983370bool Cipher::isSupportedAuthenticatedMode () const {
@@ -3301,6 +3373,12 @@ bool Cipher::isSupportedAuthenticatedMode() const {
33013373 case EVP_CIPH_GCM_MODE:
33023374#ifndef OPENSSL_NO_OCB
33033375 case EVP_CIPH_OCB_MODE:
3376+ #endif
3377+ #if OPENSSL_WITH_AES_SIV
3378+ case EVP_CIPH_SIV_MODE:
3379+ #endif
3380+ #if OPENSSL_WITH_AES_GCM_SIV
3381+ case EVP_CIPH_GCM_SIV_MODE:
33043382#endif
33053383 return true ;
33063384 case EVP_CIPH_STREAM_CIPHER:
@@ -3414,6 +3492,24 @@ bool CipherCtxPointer::isWrapMode() const {
34143492 return getMode () == EVP_CIPH_WRAP_MODE;
34153493}
34163494
3495+ bool CipherCtxPointer::isSivMode () const {
3496+ if (!ctx_) return false ;
3497+ #if OPENSSL_WITH_AES_SIV
3498+ return getMode () == EVP_CIPH_SIV_MODE;
3499+ #else
3500+ return false ;
3501+ #endif
3502+ }
3503+
3504+ bool CipherCtxPointer::isGcmSivMode () const {
3505+ if (!ctx_) return false ;
3506+ #if OPENSSL_WITH_AES_GCM_SIV
3507+ return getMode () == EVP_CIPH_GCM_SIV_MODE;
3508+ #else
3509+ return false ;
3510+ #endif
3511+ }
3512+
34173513bool CipherCtxPointer::isChaCha20Poly1305 () const {
34183514 if (!ctx_) return false ;
34193515 return getNid () == NID_chacha20_poly1305;
@@ -4242,6 +4338,21 @@ struct CipherCallbackContext {
42424338 void operator ()(const char * name) { cb (name); }
42434339};
42444340
4341+ #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4342+ constexpr const char * kProviderOnlyCiphers [] = {
4343+ #if OPENSSL_WITH_AES_SIV
4344+ " aes-128-siv" ,
4345+ " aes-192-siv" ,
4346+ " aes-256-siv" ,
4347+ #endif
4348+ #if OPENSSL_WITH_AES_GCM_SIV
4349+ " aes-128-gcm-siv" ,
4350+ " aes-192-gcm-siv" ,
4351+ " aes-256-gcm-siv" ,
4352+ #endif
4353+ };
4354+ #endif
4355+
42454356#if OPENSSL_VERSION_MAJOR >= 3
42464357template <class TypeName ,
42474358 TypeName* fetch_type (OSSL_LIB_CTX*, const char *, const char *),
@@ -4308,6 +4419,14 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
43084419 array_push_back<EVP_CIPHER>,
43094420#endif
43104421 &context);
4422+ #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
4423+ for (const char * name : kProviderOnlyCiphers ) {
4424+ EVP_CIPHER* cipher = EVP_CIPHER_fetch (nullptr , name, nullptr );
4425+ if (cipher == nullptr ) continue ;
4426+ EVP_CIPHER_free (cipher);
4427+ context.cb (name);
4428+ }
4429+ #endif
43114430#endif
43124431}
43134432
0 commit comments