@@ -4611,6 +4611,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
46114611 srtp_master_key_t * * mkis = NULL ;
46124612 srtp_master_key_t * mki = NULL ;
46134613 int mki_idx = 0 ;
4614+ int prev_recv_mki = rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_RECV_MKI ] ? 1 : 0 ;
4615+ int prev_send_mki = rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_SEND_MKI ] ? 1 : 0 ;
46144616
46154617 keysalt_len = switch_core_media_crypto_keysalt_len (ssec -> crypto_type );
46164618
@@ -4873,7 +4875,31 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
48734875 policy -> ssrc .type = ssrc_any_inbound ;
48744876
48754877 if (rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_RECV ] && idx == 0 && rtp_session -> recv_ctx [idx ]) {
4876- rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_RECV_RESET ] = 1 ;
4878+ /* Check if crypto suite and key material have actually changed - if not, preserve SRTP session state (ROC, replay window) */
4879+ switch_rtp_crypto_key_t * prev_key = crypto_key -> next ;
4880+ int key_changed = 1 ;
4881+ int mki_changed = 0 ;
4882+ int new_mki_used = rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_RECV_MKI ] ? 1 : 0 ;
4883+
4884+ if (prev_recv_mki != new_mki_used ) {
4885+ mki_changed = 1 ;
4886+ switch_log_printf (SWITCH_CHANNEL_SESSION_LOG (rtp_session -> session ), SWITCH_LOG_INFO ,
4887+ "CRYPTO: RECV MKI usage changed (was=%d, now=%d) - resetting SRTP context\n" ,
4888+ prev_recv_mki , new_mki_used );
4889+ }
4890+
4891+ if (!mki_changed && prev_key && prev_key -> type == crypto_key -> type &&
4892+ memcmp (prev_key -> keysalt , crypto_key -> keysalt , keysalt_len ) == 0 ) {
4893+ key_changed = 0 ;
4894+ }
4895+
4896+ if (key_changed || mki_changed ) {
4897+ switch_log_printf (SWITCH_CHANNEL_SESSION_LOG (rtp_session -> session ), SWITCH_LOG_INFO ,
4898+ "CRYPTO: RECV key changed (tag=%u->%u, type=%d->%d, mki_changed=%d) - resetting SRTP context\n" ,
4899+ prev_key ? prev_key -> index : 0 , index ,
4900+ prev_key ? prev_key -> type : 0 , crypto_key -> type , mki_changed );
4901+ rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_RECV_RESET ] = 1 ;
4902+ }
48774903 } else {
48784904 if ((stat = srtp_create (& rtp_session -> recv_ctx [idx ], policy )) || !rtp_session -> recv_ctx [idx ]) {
48794905 status = SWITCH_STATUS_FALSE ;
@@ -4895,7 +4921,31 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
48954921 //policy->ssrc.value = rtp_session->ssrc;
48964922
48974923 if (rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_SEND ] && idx == 0 && rtp_session -> send_ctx [idx ]) {
4898- rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_SEND_RESET ] = 1 ;
4924+ /* Check if crypto suite and key material have actually changed - if not, preserve SRTP session state */
4925+ switch_rtp_crypto_key_t * prev_key = crypto_key -> next ;
4926+ int key_changed = 1 ;
4927+ int mki_changed = 0 ;
4928+ int new_mki_used = rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_SEND_MKI ] ? 1 : 0 ;
4929+
4930+ if (prev_send_mki != new_mki_used ) {
4931+ mki_changed = 1 ;
4932+ switch_log_printf (SWITCH_CHANNEL_SESSION_LOG (rtp_session -> session ), SWITCH_LOG_INFO ,
4933+ "CRYPTO: SEND MKI usage changed (was=%d, now=%d) - resetting SRTP context\n" ,
4934+ prev_send_mki , new_mki_used );
4935+ }
4936+
4937+ if (!mki_changed && prev_key && prev_key -> type == crypto_key -> type &&
4938+ memcmp (prev_key -> keysalt , crypto_key -> keysalt , keysalt_len ) == 0 ) {
4939+ key_changed = 0 ;
4940+ }
4941+
4942+ if (key_changed || mki_changed ) {
4943+ switch_log_printf (SWITCH_CHANNEL_SESSION_LOG (rtp_session -> session ), SWITCH_LOG_INFO ,
4944+ "CRYPTO: SEND key changed (tag=%u->%u, type=%d->%d, mki_changed=%d) - resetting SRTP context\n" ,
4945+ prev_key ? prev_key -> index : 0 , index ,
4946+ prev_key ? prev_key -> type : 0 , crypto_key -> type , mki_changed );
4947+ rtp_session -> flags [SWITCH_RTP_FLAG_SECURE_SEND_RESET ] = 1 ;
4948+ }
48994949 } else {
49004950 if ((stat = srtp_create (& rtp_session -> send_ctx [idx ], policy )) || !rtp_session -> send_ctx [idx ]) {
49014951 status = SWITCH_STATUS_FALSE ;
0 commit comments