New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 627748 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Oct 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug-Security



Sign in to add a comment

Security: libsrtp uses a non-constant-time HMAC comparison

Project Member Reported by katrielc@chromium.org, Jul 13 2016

Issue description

Chromium uses libsrtp to handle {en,de}cryption of RTP streams for WebRTC. libsrtp supports various modes, but the one currently used is AES-CTR (aka ICM) with an HMAC tag for authentication.

HMAC validation is done in libsrtp by string comparison (https://cs.chromium.org/chromium/src/third_party/libsrtp/srtp/crypto/math/math.c?q=octet_string_&sq=package:chromium&l=761). Unfortunately this is a relatively simple timing channel and this sort of thing has been exploited in the wild (see e.g. https://rdist.root.org/2010/07/19/exploiting-remote-timing-attacks/).

There are various standard strategies for mitigating these channels. Probably the easiest is to use AES-GCM; new Intel processors have constant-time instructions for it. It's also possible to rewrite libsrtp's string comparison function to be constant-time, but optimising compilers don't always play nice.
 
Cc: sergeyu@chromium.org phoglund@chromium.org pthatcher@chromium.org pbos@chromium.org mattdr@chromium.org
(cc-ing random people since there's no OWNER of libsrtp in Chromium)

Comment 2 by ta...@google.com, Jul 13 2016

Labels: Security_Severity-High Security_Impact-Head

Comment 3 by ta...@google.com, Jul 13 2016

Status: Available (was: Unconfirmed)
Project Member

Comment 4 by sheriffbot@chromium.org, Jul 14 2016

Labels: M-53
Project Member

Comment 5 by sheriffbot@chromium.org, Jul 14 2016

Labels: ReleaseBlock-Beta
This issue is a security regression. If you are not able to fix this quickly, please revert the change that introduced it.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Project Member

Comment 6 by sheriffbot@chromium.org, Jul 14 2016

Labels: Pri-1

Comment 7 by pbos@chromium.org, Jul 14 2016

Cc: tommi@chromium.org juberti@chromium.org
This is not a regression at all. tommi@/juberti@ can you help triage? I have no idea who would own something like this.

Comment 8 by tommi@chromium.org, Jul 14 2016

Cc: mflodman@chromium.org
Owner: holmer@chromium.org
Adding holmer and mflodman.  I think it makes sense for webrtc to own this in general.

Comment 9 by tommi@chromium.org, Jul 14 2016

Cc: holmer@chromium.org
Owner: mattdr@chromium.org
also adding Matt :)  - Is this something you can take a look at?

Comment 10 by pbos@chromium.org, Jul 14 2016

Cc: terelius@chromium.org
As far as I can see, the SRTP library does not use Intel AES instructions; not for AEC-GCM nor for AES-CTR. Enabling it would require a fair bit of assembly code, I think. 

Constant time algorithms would also require some assembly in order to dodge too clever compilers from optimizing the code. I'd suggest a branch-free C-code solution as an interim fix.
Status: WontFix (was: Available)
This doesn't affect Chromium since we use the BoringSSL crypto primitives there (and in all of our mobile clients).

GCM support just landed recently; Matt can comment on when we can start using that.
I'm not sure using BoringSSL is sufficient here. The problem is that libsrtp computes (perhaps in a constant-time fashion) the value that it expects the packet HMAC to take, and then compares the expected and actual HMAC values one byte at a time.

As far as I can tell the only place BoringSSL is used (grep OPENSSL srtp.c) is for AES-GCM crypto policies. I can build a custom version of Chromium when I get in tomorrow to check whether octet_string_is_eq is hit, but from looking at the code I think it is.
Status: Assigned (was: WontFix)
Yes, this code is hit regardless of whether we've plugged in BoringSSL. It's only skipped for AES-GCM (independent of the backing AES-GCM implementation):
https://github.com/cisco/libsrtp/blob/f97b18d7686b6e9a750e55f93dc4bc1153ddee52/srtp/srtp.c#L1949
https://github.com/cisco/libsrtp/blob/f97b18d7686b6e9a750e55f93dc4bc1153ddee52/srtp/srtp.c#L3493

That said, any attack that involves using a timing sidechannel to brute force the HMAC is significantly mitigated by the fact that SRTP does replay detection *before* checking the HMAC, and the sequence number that's used for replay detection is included in the authenticated data.

"""
   5. For message authentication and replay protection, first check if
      the packet has been replayed (Section 3.3.2), using the Replay
      List and the index as determined in Step 2.  If the packet is
      judged to be replayed, then the packet MUST be discarded, and the
      event SHOULD be logged.
"""

https://tools.ietf.org/html/rfc3711#section-3.3

As such, I think this merits "Security-Low" at best. It's definitely not "Security-High".

We should submit a fix upstream and then merge it into our local tree. As for the fix itself, I expect something modeled after CRYPTO_memcmp would be best.
https://github.com/google/boringssl/blob/19fdcb523402ed13ab798cf811fb0119e3e7b104/crypto/mem.c#L126


Oh, and just a digression, written here because it ate half an hour of my time:

WebRTC has a macro called "ENABLE_EXTERNAL_AUTH". If it's set, it appears that we install this "external_hmac" auth provider, which returns a static value for all packets:
https://cs.chromium.org/chromium/src/third_party/webrtc/pc/srtpfilter.cc?type=cs&sq=package:chromium&rcl=1468509561&l=729
https://cs.chromium.org/chromium/src/third_party/webrtc/pc/externalhmac.h
https://cs.chromium.org/chromium/src/third_party/webrtc/pc/externalhmac.cc

Then computes its own HMAC-SHA1:
https://cs.chromium.org/chromium/src/third_party/webrtc/media/base/rtputils.cc?dr=C&sq=package:chromium&rcl=1468509561&l=102

See Piper (internal) CL 61902071.

But this is *only on outbound*, so it doesn't mitigate this bug. It *will* cause some interesting behavior if we try to move to AES-GCM because we just summarily override the crypto policy's choice of auth. That work is happening in https://codereview.webrtc.org/1528843005/. I've left a comment there.

Labels: -Security_Severity-High Security_Severity-Low
Agreed that this isn't high severity.
Agree that this is low-severity and with the proposed fix (can we just call BoringSSL's crypto_memcmp?) No idea why sheriffbot thinks this is ReleaseBlock-Beta or Pri-1?

Nice writeup on ENABLE_EXTERNAL_AUTH, I just looked at it a couple of weeks ago and got confused. Moving to GCM will make this much nicer and leave the crypto to the crypto library where it belongs :)
Labels: -Pri-1 -ReleaseBlock-Beta -Security_Impact-Head Security_Impact-Stable Pri-2
Sheriffbot marked it appropriately for a high severity regression, but as we've decided since then it wasn't triaged properly. I'm assuming that this has been around for a while.
Moving to GCM may be contingent on deleting the ENABLE_EXTERNAL_AUTH code. Filed https://bugs.chromium.org/p/chromium/issues/detail?id=628400.
We can't delete the ENABLE_EXTERNAL_AUTH code until we sunset receive-side BWE (I believe). We recompute the HMAC in the browser process so that we can ensure the packet timestamp is as accurate as possible. Happy to explain more if this is unclear.

But yes, this will not play well with GCM.

Comment 21 by pbos@chromium.org, Jul 18 2016

I believe socket-side packet timestamping applies equally to send-side BWE.
No, this shouldn't be an issue with send-side BWE since the timestamp doesn't have to be transmitted to the receiver. Instead we currently transmit a packet id with each packet, which is only added once and never updated.
Labels: WebRTCTriaged
Project Member

Comment 24 by sheriffbot@chromium.org, Oct 13 2016

Labels: -M-53 M-54
Status: Fixed (was: Assigned)
libsrtp in Chromium is now up-to-date with master and includes this fix.

See octet_string_is_eq here:
https://cs.chromium.org/chromium/src/third_party/libsrtp/crypto/math/datatypes.c

The discussion about ENABLE_EXTERNAL_AUTH will continue in https://bugs.chromium.org/p/chromium/issues/detail?id=628400.
Project Member

Comment 26 by sheriffbot@chromium.org, Oct 25 2016

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
Project Member

Comment 27 by sheriffbot@chromium.org, Jan 31 2017

Labels: -Restrict-View-SecurityNotify allpublic
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot

Sign in to add a comment