Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/net/http2/hpack: optimize constantTimeStringCompare #19238

Closed
bradfitz opened this issue Feb 22, 2017 · 12 comments
Closed

x/net/http2/hpack: optimize constantTimeStringCompare #19238

bradfitz opened this issue Feb 22, 2017 · 12 comments

Comments

@bradfitz
Copy link
Contributor

hpack's constantTimeStringCompare shows up in profiles as slow.

Investigate optimizing it.

/cc @jeffallen @tombergan

@bradfitz bradfitz added this to the Go1.9Maybe milestone Feb 22, 2017
@ALTree
Copy link
Member

ALTree commented Feb 22, 2017

"Optimize" like in "call it less" or like in "make it faster"? If uglier code is fine, unrolling the loop gives a nice boost EDIT: yeah, need to benchmark better.

@bradfitz
Copy link
Contributor Author

"Optimize" like in "call it less" or like in "make it faster"?

Either/both?

@TocarIP
Copy link
Contributor

TocarIP commented Feb 22, 2017

How long are typical inputs to constantTimeStringCompare?
For long strings pseudo-simd can help:
x:= a[i+0] | a[1] << 8 .. //should compile to single bound check + machine-word sizedload
y:= b[i+0]...
z |= x^y
i+=8
However code will be different for little and big endian, and won't work on architectures requiring aligned loads. It will also be quite ugly. Alternatively unsafe (or even asm) can be used.
In any case representative benchmarks are needed as a first step.

@bradfitz
Copy link
Contributor Author

Inputs are HTTP header values, so typically less than 100 bytes. (The longest would probably be some random UUID/hex-looking session identifier.)

@gopherbot
Copy link

CL https://golang.org/cl/37329 mentions this issue.

@bradfitz
Copy link
Contributor Author

@tombergan, are you able to share a histogram of HTTP header value sizes from the Flywheel data?

I tried looking at https://telemetry.mozilla.org/ too but don't see it.

@tombergan
Copy link
Contributor

I'm not sure why constant time string comparison is needed in the first place. RFC 7541 does not mention a need for this AFAICT. I couldn't find any reported vulnerabilities after a quick search. It seems like staticTable could be implemented as a map rather than an array. I looked at the source code for two other HTTP2 implementations. Neither appears to use constant-time string comparisons:

/cc @tatsuhiro-t who originally wrote the code, thoughts?

@fraenkel
Copy link
Contributor

There was a statement regarding prevention of timing attacks, but it was removed.
See httpwg/http2-spec@f4ec4e3

@tombergan
Copy link
Contributor

Thanks for digging that up. In that case, I think it's safe to remove the constant-time string comparison entirely.

@bradfitz
Copy link
Contributor Author

SGTM. Sent you a CL.

@tatsuhiro-t
Copy link

I think it was removed because Never Indexed has been introduced for the sensitive header fields.

@gopherbot
Copy link

CL https://golang.org/cl/37394 mentions this issue.

@golang golang locked and limited conversation to collaborators Feb 23, 2018
c3mb0 pushed a commit to c3mb0/net that referenced this issue Apr 2, 2018
Delete the constant time string comparison. It's slow and shows up in
profiles, nobody else does it, and the spec text no longer recommends
doing it. See bug for discussion and details.

Also clean up some naked returns while I'm here (noted during review).

Fixes golang/go#19238

Change-Id: I344c5766c5d97bbcf01eab0624097941591ce00f
Reviewed-on: https://go-review.googlesource.com/37394
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tom Bergan <tombergan@google.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants