diff --git a/perl/NGCP/Rtpclient/SRTP.pm b/perl/NGCP/Rtpclient/SRTP.pm index bfb0d9b41..6c6bb4451 100644 --- a/perl/NGCP/Rtpclient/SRTP.pm +++ b/perl/NGCP/Rtpclient/SRTP.pm @@ -16,6 +16,8 @@ our @crypto_suites = ( enc_func => \&aes_cm, iv_rtp => \&aes_cm_iv_rtp, iv_rtcp => \&aes_cm_iv_rtcp, + key_length => 16, + salt_length => 14, }, { str => 'AES_CM_128_HMAC_SHA1_32', @@ -24,6 +26,8 @@ our @crypto_suites = ( enc_func => \&aes_cm, iv_rtp => \&aes_cm_iv_rtp, iv_rtcp => \&aes_cm_iv_rtcp, + key_length => 16, + salt_length => 14, }, { str => 'F8_128_HMAC_SHA1_80', @@ -31,6 +35,28 @@ our @crypto_suites = ( enc_func => \&aes_f8, iv_rtp => \&aes_f8_iv_rtp, iv_rtcp => \&aes_f8_iv_rtcp, + key_length => 16, + salt_length => 14, + }, + { + str => 'AES_CM_192_HMAC_SHA1_80', + #dtls_name => 'SRTP_AES128_CM_SHA1_80', + auth_tag => 10, + enc_func => \&aes_cm, + iv_rtp => \&aes_cm_iv_rtp, + iv_rtcp => \&aes_cm_iv_rtcp, + key_length => 24, + salt_length => 14, + }, + { + str => 'AES_CM_256_HMAC_SHA1_80', + #dtls_name => 'SRTP_AES128_CM_SHA1_80', + auth_tag => 10, + enc_func => \&aes_cm, + iv_rtp => \&aes_cm_iv_rtp, + iv_rtcp => \&aes_cm_iv_rtcp, + key_length => 32, + salt_length => 14, }, ); our %crypto_suites = map {$$_{str} => $_} @crypto_suites; @@ -142,7 +168,8 @@ sub xor_128 { sub gen_rtp_session_keys { my ($master_key, $master_salt) = @_; - my $session_key = prf_n(128, $master_key, xor_112($master_salt, "\0\0\0\0\0\0\0")); + # this assumes session key length identical to master key length + my $session_key = prf_n(length($master_key) * 8, $master_key, xor_112($master_salt, "\0\0\0\0\0\0\0")); my $auth_key = prf_n(160, $master_key, xor_112($master_salt, "\1\0\0\0\0\0\0")); my $session_salt = prf_n(112, $master_key, xor_112($master_salt, "\2\0\0\0\0\0\0")); if ($SRTP_DEBUG) { @@ -159,7 +186,8 @@ sub gen_rtp_session_keys { sub gen_rtcp_session_keys { my ($master_key, $master_salt) = @_; - my $session_key = prf_n(128, $master_key, xor_112($master_salt, "\3\0\0\0\0\0\0")); + # this assumes session key length identical to master key length + my $session_key = prf_n(length($master_key) * 8, $master_key, xor_112($master_salt, "\3\0\0\0\0\0\0")); my $auth_key = prf_n(160, $master_key, xor_112($master_salt, "\4\0\0\0\0\0\0")); my $session_salt = prf_n(112, $master_key, xor_112($master_salt, "\5\0\0\0\0\0\0")); if ($SRTP_DEBUG) { @@ -209,10 +237,10 @@ sub aes_f8_iv_rtcp { } sub decode_inline_base64 { - my ($b64) = @_; + my ($b64, $cs) = @_; my $ks = decode_base64($b64); - length($ks) == 30 or die; - my @ret = unpack('a16a14', $ks); + length($ks) == ($cs->{key_length} + $cs->{salt_length}) or die; + my @ret = unpack("a$cs->{key_length}a$cs->{salt_length}", $ks); return @ret; } diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 4f71a7227..e112bad9e 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -185,6 +185,7 @@ sub savp_sdp { else { $$ctx{out}{crypto_suite} = $NGCP::Rtpclient::SRTP::crypto_suites[rand(@NGCP::Rtpclient::SRTP::crypto_suites)]; + print("using crypto suite $$ctx{out}{crypto_suite}{str}\n"); $$ctx{out}{crypto_tag} = int(rand(100)); $$ctx{out}{unenc_srtp} = rand() < .5 ? 0 : 1; $$ctx{out}{unenc_srtcp} = rand() < .5 ? 0 : 1; @@ -203,8 +204,8 @@ sub savp_sdp { if (!$$ctx{out}{rtp_master_key} || rand() < .2) { $$ctx{out}{rtp_master_key} and print("new key\n"); - $$ctx{out}{rtp_master_key} = rand_str(16); - $$ctx{out}{rtp_master_salt} = rand_str(14); + $$ctx{out}{rtp_master_key} = rand_str($$ctx{out}{crypto_suite}{key_length}); + $$ctx{out}{rtp_master_salt} = rand_str($$ctx{out}{crypto_suite}{salt_length}); undef($$ctx{out}{rtp_session_key}); undef($$ctx{out}{rtcp_session_key}); if ($NOENC && $NOENC{rtp_master_key}) { @@ -328,14 +329,14 @@ sub rtp_savp { sub savp_crypto { my ($sdp, $ctx, $ctx_o) = @_; - my @a = $sdp =~ /[\r\n]a=crypto:(\d+) (\w+) inline:([\w\/+]{40})(?:\|(?:2\^(\d+)|(\d+)))?(?:\|(\d+):(\d+))?(?: (.*?))?[\r\n]/sig; + my @a = $sdp =~ /[\r\n]a=crypto:(\d+) (\w+) inline:([\w\/+=]{40,})(?:\|(?:2\^(\d+)|(\d+)))?(?:\|(\d+):(\d+))?(?: (.*?))?[\r\n]/sig; @a or die; my $i = 0; while (@a >= 8) { $$ctx[$i]{in}{crypto_suite} = $NGCP::Rtpclient::SRTP::crypto_suites{$a[1]} or die; $$ctx[$i]{in}{crypto_tag} = $a[0]; ($$ctx[$i]{in}{rtp_master_key}, $$ctx[$i]{in}{rtp_master_salt}) - = NGCP::Rtpclient::SRTP::decode_inline_base64($a[2]); + = NGCP::Rtpclient::SRTP::decode_inline_base64($a[2], $$ctx[$i]{in}{crypto_suite}); $$ctx[$i]{in}{rtp_mki} = $a[5]; $$ctx[$i]{in}{rtp_mki_len} = $a[6]; undef($$ctx[$i]{in}{rtp_session_key});