diff --git a/perl/NGCP/Rtpclient/SRTP.pm b/perl/NGCP/Rtpclient/SRTP.pm index dbe4d52b4..2f5ec825e 100644 --- a/perl/NGCP/Rtpclient/SRTP.pm +++ b/perl/NGCP/Rtpclient/SRTP.pm @@ -231,11 +231,11 @@ sub aes_cm_iv_rtp { } sub aes_cm_iv_rtcp { - my ($ctx, $r) = @_; + my ($r, $ssalt, $idx) = @_; - my $idx = $$ctx{rtcp_index} || 0; + $idx ||= 0; my ($hdr, $ssrc) = unpack('a4a4', $r); - my $iv = xor_128($$ctx{rtcp_session_salt} . "\0\0", + my $iv = xor_128($ssalt . "\0\0", $ssrc . "\0\0\0\0\0\0\0\0", pack("Nn", $idx, 0)); return $iv; } @@ -249,10 +249,10 @@ sub aes_f8_iv_rtp { } sub aes_f8_iv_rtcp { - my ($ctx, $r) = @_; + my ($r, $ssalt, $idx) = @_; my ($fields) = unpack('a8', $r); - my $iv = pack('a*Na*', "\0\0\0\0", (($$ctx{rtcp_index} || 0) | 0x80000000), $fields); + my $iv = pack('a*Na*', "\0\0\0\0", (($idx || 0) | 0x80000000), $fields); return $iv; } @@ -313,6 +313,52 @@ sub decrypt_rtp { return ($pkt, $roc, $auth_tag, $hmac); } +sub encrypt_rtcp { + my ($suite, $skey, $ssalt, $sauth, $idx, $mki, $mki_len, $unenc_srtcp, $packet) = @_; + + my $iv = $suite->{iv_rtcp}->($packet, $ssalt, $idx); + my ($hdr, $to_enc) = unpack('a8a*', $packet); + my $enc = $unenc_srtcp ? $to_enc : + $suite->{enc_func}->($to_enc, $skey, + $iv, $ssalt); + my $pkt = $hdr . $enc; + $pkt .= pack("N", (($idx || 0) | ($unenc_srtcp ? 0 : 0x80000000))); + + my $hmac = hmac_sha1($pkt, $sauth); + + append_mki(\$pkt, $mki_len, $mki); + + #$pkt .= pack("N", 1); # mki + $pkt .= substr($hmac, 0, 10); + + $idx++; + + return ($pkt, $idx); +} + +sub decrypt_rtcp { + my ($suite, $skey, $ssalt, $sauth, $packet) = @_; + + # XXX MKI, session parameters + + my $plen = length($packet); + my $auth_tag = substr($packet, $plen - 10, 10); + my $idx_raw = substr($packet, $plen - 4 - 10, 4); + my ($idx) = unpack('N', $idx_raw); + $idx &= 0x7fffffff; + $packet = substr($packet, 0, $plen - 10 - 4); + + my $iv = $suite->{iv_rtcp}->($packet, $ssalt, $idx); + my ($hdr, $to_enc) = unpack('a8a*', $packet); + my $enc = $suite->{enc_func}->($to_enc, $skey, + $iv, $ssalt); + my $pkt = $hdr . $enc; + + my $hmac = hmac_sha1($packet, $sauth); + + return ($pkt, $idx, $auth_tag, $hmac); +} + sub append_mki { my ($pack_r, $mki_len, $mki) = @_; diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 2dd6d29b5..a2ee67a1d 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -130,22 +130,9 @@ sub rtcp_encrypt { ($NOENC && $NOENC{rtcp_packet}) and return $NOENC{rtcp_packet}; - my $iv = $$dctx{crypto_suite}{iv_rtcp}->($dctx, $r); - my ($hdr, $to_enc) = unpack('a8a*', $r); - my $enc = $$dctx{unenc_srtcp} ? $to_enc : - $$dctx{crypto_suite}{enc_func}->($to_enc, $$dctx{rtcp_session_key}, - $iv, $$dctx{rtcp_session_salt}); - my $pkt = $hdr . $enc; - $pkt .= pack("N", (($$dctx{rtcp_index} || 0) | ($$dctx{unenc_srtcp} ? 0 : 0x80000000))); - - my $hmac = hmac_sha1($pkt, $$dctx{rtcp_session_auth_key}); - - NGCP::Rtpclient::SRTP::append_mki(\$pkt, @$dctx{qw(rtp_mki_len rtp_mki)}); - - #$pkt .= pack("N", 1); # mki - $pkt .= substr($hmac, 0, 10); - - $$dctx{rtcp_index}++; + my ($pkt, $idx) = NGCP::Rtpclient::SRTP::encrypt_rtcp(@$dctx{qw(crypto_suite rtcp_session_key + rtcp_session_salt rtcp_session_auth_key rtcp_index rtp_mki rtp_mki_len unenc_srtcp)}, $r); + $$dctx{rtcp_index} = $idx; $NOENC{rtcp_packet} = $pkt;