sipwise / rtpengine

The Sipwise media proxy for Kamailio
GNU General Public License v3.0
790 stars 371 forks source link

Possible libsrtp 2.x incompatibility #700

Closed korayvt closed 5 years ago

korayvt commented 5 years ago

I have a problem with the calls from WebRTC client to linphone based sip client with libsrtp 2.x version.

Linphone logs a lot of srtcp unprotect failures:

srtp_unprotect_rtcp() failed (7) on stream ctx [0xabfd2d40] Request sending of FIR on videostream [0xabbaf6c0] Request sending of PLI on videostream [0xabbaf6c0] VP8 frame dropped because keyframe has not been received yet. Unhandled event 1074070784 Stun packet sent on rtcp for session [0xabf52920] Request sending of FIR on videostream [0xabbaf6c0] Request sending of PLI on videostream [0xabbaf6c0] VP8 frame dropped because keyframe has not been received yet. Unhandled event 1074070784

And rtp stats report shows no rtcp packets received during the call, because of those failures :

         AUDIO SESSION'S RTP STATISTICS                

sent 1225 packets 0 duplicated packets 27940 bytes
received 614 packets 0 duplicated packets 66395 bytes
incoming delivered to the app 66395 bytes
incoming cumulative lost 0 packets incoming received too late 0 packets incoming bad formatted 0 packets incoming discarded (queue overflow) 0 packets sent rtcp 6 packets received rtcp 0 packets

         VIDEO SESSION'S RTP STATISTICS                

sent 1477 packets 0 duplicated packets 530728 bytes
received 1122 packets 0 duplicated packets 911058 bytes
incoming delivered to the app 911058 bytes
incoming cumulative lost 0 packets incoming received too late 0 packets incoming bad formatted 0 packets incoming discarded (queue overflow) 0 packets sent rtcp 132 packets received rtcp 0 packets

After I learned that this client has libsrtp 2.x version, I made a call to a client with libsrtp 1.x. I got no srtcp errors in the log and I got expected rtp stats:

         AUDIO SESSION'S RTP STATISTICS                

sent 1098 packets 0 duplicated packets 24083 bytes
received 551 packets 0 duplicated packets 58610 bytes
incoming delivered to the app 58610 bytes
incoming cumulative lost 0 packets incoming received too late 0 packets incoming bad formatted 0 packets incoming discarded (queue overflow) 0 packets sent rtcp 5 packets received rtcp 6 packets

         VIDEO SESSION'S RTP STATISTICS                

sent 1268 packets 0 duplicated packets 441022 bytes
received 1486 packets 0 duplicated packets 1388811 bytes
incoming delivered to the app 1370992 bytes
incoming cumulative lost 1 packets incoming received too late 0 packets incoming bad formatted 0 packets incoming discarded (queue overflow) 0 packets sent rtcp 10 packets received rtcp 111 packets

What might be the problem?

I attached the rtpengine logs for the failed and success calls.

fail-4gfhid5l58l71lo33esb.log success-9p0i6cl7obqdadhao2hs.log

rfuchs commented 5 years ago

Can you make a pcap of the two cases (working and failing) each?

rfuchs commented 5 years ago

To clarify: ideal would be a pcap together with a full log for the same call

korayvt commented 5 years ago

I couldn't attach pcap files here. So I archived 2 logs and 2 pcaps in a zip file.

working-failing.zip

rfuchs commented 5 years ago

Yeah, so the encryption is almost definitely broken in the failed case you've uploaded.

To confirm, I've decoded and auth checked some RTCP packets from the working case. In particular:

1) Packet 3744 using crypto AES_CM_128_HMAC_SHA1_80 vo3IUo+HXG+8AlmjHcwwENYWoqHh/jQ17wg91id5

$ perl -Iperl utils/srtcp-debug-helper AES_CM_128_HMAC_SHA1_80 vo3IUo+HXG+8AlmjHcwwENYWoqHh/jQ17wg91id5 81c8000c7dea59bcb2cc5fbb28409c112fed69b170fb31d935fd16285ce772ad285d23a4880da265b651ab1702b74f64655872c679b10f3e22bde41f12ca835ca33952f116beeccdc0c79f5ae6d8553a9b98076671736dd514872103ff5c7dc48f9d50a898cbf5b1777a9d4f4e2d54978ce15cc43885c4c009f03692800000070004b0238cdd79c9c41b
Master key:            be8dc8528f875c6fbc0259a31dcc3010
Master salt:           d616a2a1e1fe3435ef083dd62779
RTCP session key:      47b07da3333a71c9dae0f78c75cf553e
RTCP session auth key: 5a04772edbb841e7a371461122c7eb6593f7dc55
RTCP session salt:     00da9d9b17b35d209107cad7e454
Packet length:         138 bytes
Auth tag from packet:  0004b0238cdd79c9c41b
Computed auth tag:     0004b0238cdd79c9c41be22779074d761329c64e
Decoded packet:        81c8000c7dea59bce003b7ea1b68be2fdb7f829c000001da00031b0a328f2d7d000000020000808200000361b7eaa89400002e6881ca000e7dea59bc012e7369703a39303533353230323639343540746573747369702e74766f69702e7475726b63656c6c2e636f6d2e74720000000081ce00027dea59bc328f2d7d
Index:                 7

which checks out (auth tag matches what it should be).

2) Reverse direction, packet 3733, using crypto AES_CM_128_HMAC_SHA1_80 hIuvo0oudg9TOR2NRRaACaSFtyzE8t+1yTRDi2hK

$ perl -Iperl utils/srtcp-debug-helper AES_CM_128_HMAC_SHA1_80 hIuvo0oudg9TOR2NRRaACaSFtyzE8t+1yTRDi2hK 80c80006328f2d7d6ac1dea501f4534d73ec4e03e9c2b05d11f03fe66ae9e10200bbe2e97a251dca0166e10b254427b075adfa0377ee346918693a1ad02c99fbb5a47e324d754292082be37911ae387a80000038358b58213233f67a2efe
Master key:            848bafa34a2e760f53391d8d45168009
Master salt:           a485b72cc4f2dfb5c934438b684a
RTCP session key:      17ccd063b74085aafad9b836aeac1f3d
RTCP session auth key: e991b50c38ab71786a5316f3b8af2928fe8dd8bb
RTCP session salt:     5b0d7d28ff542c66a79ab0db3b42
Packet length:         94 bytes
Auth tag from packet:  358b58213233f67a2efe
Computed auth tag:     358b58213233f67a2efe546953fffd2d0c796773
Decoded packet:        80c80006328f2d7de003b7eadc55fbb5183f7bc6000001bd0005b2f581ca0006328f2d7d011034506b4e6f4d644f67355144552b764a00008fce0005328f2d7d0000000052454d42010649797dea59bc
Index:                 56

which also checks out.

3) From the failed case, I repeated the steps above. I checked packet 1781, which is a packet sent by rtpengine to the SRTP client, using crypto AES_CM_128_HMAC_SHA1_80 p4OHwopZaYD5pxYDhfjt0Fm5pu/j0Pzh1QhPAz2J

$ perl -Iperl utils/srtcp-debug-helper AES_CM_128_HMAC_SHA1_80 p4OHwopZaYD5pxYDhfjt0Fm5pu/j0Pzh1QhPAz2J 80c800069d6e2b37f6df3171c0df30ce1c732b86a02b8b875e546558457b0b255d84dd80cf15ee3371a9cc89f3684c8cd381c886abe3f4f88000000b2aafb1c69319baff3590
Master key:            a78387c28a596980f9a7160385f8edd0
Master salt:           59b9a6efe3d0fce1d5084f033d89
RTCP session key:      f8ab1e7335ee3c890ba250300ce3e801
RTCP session auth key: d47c62be35559e80355dbed3695593efb5b2437c
RTCP session salt:     25713bfffcb5e732cf70bf812803
Packet length:         70 bytes
Auth tag from packet:  2aafb1c69319baff3590
Computed auth tag:     2aafb1c69319baff3590d235e93a1d1c97bc0620
Decoded packet:        80c800069d6e2b37e003b4d65d4e0978a9beff16000000bc000238ad81ca00069d6e2b370110676d5a3966546557477579594739466f0000
Index:                 11

This one is OK.

4) For the reverse direction (from the SRTP client towards rtpengine), I looked at packet 1789, using crypto AES_CM_128_HMAC_SHA1_80 ZhO0pvTkgVGl2N+kq78Wlj4ZDvC+DZ0tL8KWbZ1Y

$ perl -Iperl utils/srtcp-debug-helper AES_CM_128_HMAC_SHA1_80 ZhO0pvTkgVGl2N+kq78Wlj4ZDvC+DZ0tL8KWbZ1Y 81c90007b872101595dbb6e856bf5871e52013eb86f4b0167796207be886b1db48fe52baa0eb16427391c6437433fe9a07f69b5a7dc5030e6acef592a9df3e76da7ef4c15286bfda224eaf3f7740b936d4c9a4cf96994b9d8b7cb0f638b35fdb67dd981d976789ea6d905908ecf6a1fcc643bf345f30bcbf3ea4f49caf7bcede14566d3480000015031b06f0da4054088ed2
Master key:            6613b4a6f4e48151a5d8dfa4abbf1696
Master salt:           3e190ef0be0d9d2d2fc2966d9d58
RTCP session key:      b15098b4e069db18f0d0a01b65aac50c
RTCP session auth key: 4e39d2d450bd32ef0296a2833b585bca72667a30
RTCP session salt:     1b098bdff065e8e229f50290d029
Packet length:         146 bytes
Auth tag from packet:  031b06f0da4054088ed2
Computed auth tag:     70b45392a977270b30f4cd9b8f99ad56153dc33e
Decoded packet:        81c90007b8721015f69d507f7f817cd95e78462ccd530192cad4dbcaa71de94dc2cbf7813f24952a6dd1c0bf162455837a58d7c9c2bab95fd116ea14d9dc9e3e5df7ce7dac239a3db2868cbc5e6b792daa588cb703081ad734c640a34d30c2bf4d6d898d81239ccd8ab1b40615d0822bbebba7a343766aa7f412feacef3f67b2fcc450f0
Index:                 21

And this is where it fails. The auth tag is mismatched and the packet doesn't decode correctly.

I looked at some other ones and those also fail. So it looks like libsrtp is doing something wrong with encryption and decryption here, but unfortunately I have no way of telling what it is.

rfuchs commented 5 years ago

I tried some other SRTP keys that appear in the log as well, but none work for decoding those packets. So I'm gonna call this a bug in libsrtp (or perhaps in the client using it) and close this.