GithubHelp home page GithubHelp logo

Comments (11)

thaidn avatar thaidn commented on August 20, 2024 2

Unless there's a cleverer attack that I'm unaware of, the timing side channel attack allows recovering the secret HMAC value byte-by-byte. This attack is thwarted if Bytes.equal(s1, s2) compares SHA256(s1) with SHA256(s2). Yes, the adversary knows what bytes being compared, but that's not enough because they need to find a pre-image that hashes to those bytes.

More concretely, they know SHA256(s1) and they can use the timing side channel to figure out the first byte of SHA256(s2). Now what? They need to find s1' such that its first byte matches the first byte of SHA256(s1) and its second byte matches the second byte of SHA256(s2). Before long, the adversary has to reverse SHA256.

from tink.

thaidn avatar thaidn commented on August 20, 2024

Bytes.equal is mostly used to validate MAC, thus we're already doing what you're suggesting, right?

from tink.

SalusaSecondus avatar SalusaSecondus commented on August 20, 2024

No. The problem is that one of the MACs is attacker controlled. So, if one value is unknown (the correct MAC calculated under a secret key) and the other is attacker controlled, then if Bytes.equal() has a timing signal, an attacker can use this to guess the secret MAC. (This is why you are using this standard constant-time algorithm.)

Unfortunately, the JVM and JIT does terrible things to constant time algorithms and can break them horribly. By calculating a MAC under a random key of the values and then comparing those MACs, even if the algorithm isn't constant time, the attacker has no way of knowing what bytes are being compared to what bytes and cannot execute the attack.

NCC Group wrote about an extremely similar defense they call Double HMAC Verification. I prefer my proposed modification because it doesn't require knowledge of the HMAC key (and may be applied to things other than HMACs) and because it is even more randomized than reusing a key multiple times dor the comparison.

from tink.

thaidn avatar thaidn commented on August 20, 2024

Ah I now see what you meant.

Did NCC Group even publish their paper? I want to understand why Bytes.equal doesn't work as they claimed.

Also not sure we need to use double HMAC. Why isn't applying a round of SHA256 enough?

@bleichen @przydatek

from tink.

katrielalex avatar katrielalex commented on August 20, 2024

I have no idea about JVM and constant time algorithms but I don't think a round of SHA256 would be enough, because the attacker could also compute it and would thus know what bytes are being compared. Computing a MAC under a (secret) random key does not reveal that to the attacker.

from tink.

bleichen avatar bleichen commented on August 20, 2024

from tink.

bleichen avatar bleichen commented on August 20, 2024

Looks like overkill to me.

I've been trying to find compilers that would convert functions like Bytes.equal() into
something that is non-constant time. So far without success. Are there examples?

Typically, compilers rather try to remove branches rather than to add new ones to
avoid the cost of branch mispredictions.

from tink.

hillbrad avatar hillbrad commented on August 20, 2024

How I feel about that blog being cited to @thaidn and @bleichen : https://www.theonion.com/bush-finds-error-in-fermilab-calculations-1819566086

(Is is overkill, was intended as advice for naive developers, and it does weaken the HMAC verification against brute force guessing to the collision probability of the hash function.)

from tink.

SalusaSecondus avatar SalusaSecondus commented on August 20, 2024

@hillbrad Thank you. I'm also going to try to track down (and then make public) the other data I found. However until I can find something more solid, we should probably consider this issue closed.

from tink.

thaidn avatar thaidn commented on August 20, 2024

Thanks folks. Closing this bug, but please feel free to reopen once you've gathered more data.

from tink.

tarcieri avatar tarcieri commented on August 20, 2024

It should be possible to use the PrintAssembly command line option for the JVM to have HotSpot emit the generated assembly, which can then be verified for constant-time operation on an architecture-by-architecture basis.

from tink.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.