From f2ceb2088cd8241193e575e5a314619310440a92 Mon Sep 17 00:00:00 2001 From: Johan Pascal <johan.pascal@belledonne-communications.com> Date: Tue, 17 Oct 2023 11:26:45 +0200 Subject: [PATCH] Support for SRTP GCM mode in ZRTP + SRTP AES128-GCM is the default mode --- coreapi/linphonecore.c | 6 ++-- src/conference/session/audio-stream.cpp | 46 ++++++++++++++++++------- tester/call_secure_tester.cpp | 34 ++++++++++-------- 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d9d9c07c76..8dec9570d7 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -9708,9 +9708,9 @@ void linphone_core_set_srtp_crypto_suites(LinphoneCore *core, const char *suites } const char *linphone_core_get_srtp_crypto_suites(LinphoneCore *core) { - return linphone_config_get_string(core->config, "sip", "srtp_crypto_suites", - "AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_32, AES_256_CM_HMAC_SHA1_80, " - "AES_256_CM_HMAC_SHA1_32, AEAD_AES_128_GCM, AEAD_AES_256_GCM"); + return linphone_config_get_string( + core->config, "sip", "srtp_crypto_suites", + "AEAD_AES_128_GCM, AES_CM_128_HMAC_SHA1_80, AEAD_AES_256_GCM, AES_256_CM_HMAC_SHA1_80"); } #ifndef _MSC_VER diff --git a/src/conference/session/audio-stream.cpp b/src/conference/session/audio-stream.cpp index ac7aa3dc4a..ad5003f6d1 100644 --- a/src/conference/session/audio-stream.cpp +++ b/src/conference/session/audio-stream.cpp @@ -133,42 +133,62 @@ void MS2AudioStream::initZrtp() { void MS2AudioStream::setZrtpCryptoTypesParameters(MSZrtpParams *params, bool localIsOfferer) { const MSCryptoSuite *srtpSuites = linphone_core_get_srtp_crypto_suites_array(getCCore()); if (srtpSuites) { + bool aes1 = false; + bool aes3 = false; + bool hs32 = false; + bool hs80 = false; + bool gcm = false; for (int i = 0; (srtpSuites[i] != MS_CRYPTO_SUITE_INVALID) && (i < MS_MAX_ZRTP_CRYPTO_TYPES); i++) { switch (srtpSuites[i]) { case MS_AES_128_SHA1_32: - params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; - params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS32; + if (!aes1) params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + if (!hs32) params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS32; + aes1 = true; + hs32 = true; break; case MS_AES_128_SHA1_80_NO_AUTH: case MS_AES_128_SHA1_32_NO_AUTH: - params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + if (!aes1) params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + aes1 = true; break; case MS_AES_128_SHA1_80_SRTP_NO_CIPHER: case MS_AES_128_SHA1_80_SRTCP_NO_CIPHER: case MS_AES_128_SHA1_80_NO_CIPHER: - params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + if (!hs80) params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + hs80 = true; break; case MS_AES_128_SHA1_80: - params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; - params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + if (!aes1) params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + if (!hs80) params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + hs80 = true; + aes1 = true; break; case MS_AES_CM_256_SHA1_80: lWarning() << "Deprecated crypto suite MS_AES_CM_256_SHA1_80, use MS_AES_256_SHA1_80 instead"; BCTBX_NO_BREAK; case MS_AES_256_SHA1_80: - params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3; - params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + if (!aes3) params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3; + if (!hs80) params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + hs80 = true; + aes3 = true; break; case MS_AES_256_SHA1_32: - params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3; - params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS32; + if (!aes3) params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3; + if (!hs80) params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS32; + hs32 = true; + aes3 = true; break; - /* AEAD GCM suite not supported by ZRTP for now, just force the cipher setting according to key size */ case MS_AEAD_AES_128_GCM: - params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + if (!aes1) params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + if (!gcm) params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_GCM; + gcm = true; + aes1 = true; break; case MS_AEAD_AES_256_GCM: - params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3; + if (!aes3) params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3; + if (!gcm) params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_GCM; + gcm = true; + aes1 = true; break; case MS_CRYPTO_SUITE_INVALID: break; diff --git a/tester/call_secure_tester.cpp b/tester/call_secure_tester.cpp index d48861b440..63a4392f8e 100644 --- a/tester/call_secure_tester.cpp +++ b/tester/call_secure_tester.cpp @@ -208,8 +208,8 @@ ekt_call(MSEKTCipherType ekt_cipher, MSCryptoSuite crypto_suite, bool unmatching marie, pauline, ([marie, pauline, ekt_cipher, crypto_suite, unmatching_ekt, update_ekt](LinphoneCall *marieCall, LinphoneCall *paulineCall) { - BC_ASSERT_TRUE(srtp_check_call_stats(marieCall, paulineCall, MS_AES_128_SHA1_80, - MSSrtpKeySourceSDES)); // Default crypto suite is MS_AES_128_SHA1_80 + BC_ASSERT_TRUE(srtp_check_call_stats(marieCall, paulineCall, MS_AEAD_AES_128_GCM, + MSSrtpKeySourceSDES)); // Default crypto suite is MS_AEAD_AES_128_GCM MSEKTParametersSet ekt_params; generate_ekt(&ekt_params, ekt_cipher, crypto_suite, 0x1234); @@ -326,8 +326,8 @@ static void srtp_call(void) { mgr_calling_each_other( marie, pauline, ([](LinphoneCall *marieCall, LinphoneCall *paulineCall) { - // Default is MS_AES_128_SHA1_80, we use SDES - BC_ASSERT_TRUE(srtp_check_call_stats(marieCall, paulineCall, MS_AES_128_SHA1_80, MSSrtpKeySourceSDES)); + // Default is MS_AES_128_GCM, we use SDES + BC_ASSERT_TRUE(srtp_check_call_stats(marieCall, paulineCall, MS_AEAD_AES_128_GCM, MSSrtpKeySourceSDES)); })); // Test differents crypto suites : AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_32, AES_256_CM_HMAC_SHA1_80, @@ -389,7 +389,7 @@ static void srtp_call_with_different_crypto_suite(void) { // same test using mgr_calling_each_other so we can check during the call that the correct suite are used LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); // marie_rc does not specify any srtp crypto suite, propose all - // availables, default is AES128_SHA1-80 + // availables, default is AES128_GCM linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); @@ -1110,25 +1110,31 @@ static void zrtp_authtag_call(void) { ZrtpAlgoString paulineAlgo; ZrtpAlgoRes res; - // Default is HS80 + // Default is GCM // - this is a linphone internal default setting: SRTP crypto suite default is - // AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_32, AES_256_CM_HMAC_SHA1_80, AES_256_CM_HMAC_SHA1_32. - // So the default auth tag set by the audio-stream is HS80, HS32 - // - default in bzrtp is HS32, HS80 + // AEAD_AES_128_GCM, AES_CM_128_HMAC_SHA1_80, AEAD_AES_256_GCM, AES_256_CM_HMAC_SHA1_80 + // So the default auth tag set by the audio-stream is GCM + // - default in bzrtp is GCM, HS32, HS80 marieAlgo.auth_tag_algo = NULL; paulineAlgo.auth_tag_algo = NULL; - res.auth_tag_algo = {MS_ZRTP_AUTHTAG_HS80}; + res.auth_tag_algo = {MS_ZRTP_AUTHTAG_GCM}; + BC_ASSERT_EQUAL(zrtp_params_call(marieAlgo, paulineAlgo, res), 0, int, "%d"); + + // Call using GCM + marieAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_GCM"; + paulineAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_GCM"; + res.auth_tag_algo = {MS_ZRTP_AUTHTAG_GCM}; BC_ASSERT_EQUAL(zrtp_params_call(marieAlgo, paulineAlgo, res), 0, int, "%d"); // Call using HS80 - marieAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_HS80, MS_ZRTP_AUTHTAG_HS32"; - paulineAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_HS80, MS_ZRTP_AUTHTAG_HS32"; + marieAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_HS80, MS_ZRTP_AUTHTAG_HS32, MS_ZRTP_AUTHTAG_GCM"; + paulineAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_HS80, MS_ZRTP_AUTHTAG_HS32, MS_ZRTP_AUTHTAG_GCM"; res.auth_tag_algo = {MS_ZRTP_AUTHTAG_HS80}; BC_ASSERT_EQUAL(zrtp_params_call(marieAlgo, paulineAlgo, res), 0, int, "%d"); // Call using HS32 - marieAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_HS32, MS_ZRTP_AUTHTAG_HS80"; - paulineAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_HS32, MS_ZRTP_AUTHTAG_HS80"; + marieAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_HS32, MS_ZRTP_AUTHTAG_HS80, MS_ZRTP_AUTHTAG_GCM"; + paulineAlgo.auth_tag_algo = "MS_ZRTP_AUTHTAG_HS32, MS_ZRTP_AUTHTAG_HS80, MS_ZRTP_AUTHTAG_GCM"; res.auth_tag_algo = {MS_ZRTP_AUTHTAG_HS32}; BC_ASSERT_EQUAL(zrtp_params_call(marieAlgo, paulineAlgo, res), 0, int, "%d"); -- GitLab