Live data from Hacker News

Rust Cryptography Should Be Written in Rust

briansmith.org

91–100 of 110 posts

Re: Rust Cryptography Should Be Written in Rust

#91
post #74

Earlier quoted context omitted.

People keep finding serious architectural leaks in CPUs like Spectre/Meltdown, which makes me question whether any constant-time implementation can really be without observable side effects.

Some CPUs do have non-constant-time multiplies.

And one protection against that is to map the key into another space using a random (or close enough) key for that transformation, perform the calculation homomorphically, then transform back.

This is often too expensive, but it does come up as a possibility in some zero knowledge protocols.

Re: Rust Cryptography Should Be Written in Rust

#92
post #87

Earlier quoted context omitted.

Whenever I'm wearing my tinfoil hat, I wonder if all the advice to never implement your own crypto is a conspiracy to reduce independent implementations of cryptography algorithms. I know constant time operation is important for these algorithms, but couldn't I do this with a timer? Call the algorithm, store the result, return the result exactly one second (an eternity in CPU time) after it was called. Basically put…

No. Timing attacks look at statistical distributions given a set of inputs. Adding a flat 1 to all the times does not flatten the distributions. Likewise, adding a random jitter has the same problem, where it increases the variance but doesn't remove it - you need more samples to get the same confidence interval, which is very different from preventing timing attacks entirely.

They’re not talking (I don’t think) about adding a flat 1, they’re talking about something like this pseudocode I believe:

   timer = SomeScaffoldThatTimesAFunctionAccurately()
   result = timer(Do Crypto Thing())
   wait(1-timer.elapsed)
   return result
   
So the idea in this scenario is that every operation would take 1 second.

The first obvious drawback of this from a practical point of view is speed. You need crypto operations to be extremely fast so although you could reduce the constant time somewhat it would still be very difficult to calibrate the timing in such a way as not to totally nerf performance. The delay you’re introducing here is required (as I understand it) on every branch and possibly other places so there are thousands of these required in order to do each user-visible crypto operation.

Secondly if you think about the way the attack works, the jitter the attackers are observing to obtain the leaked information is very small so you would need an extremely accurate timer in order to be precise enough not to still leak the jitter.

As I understand it the actual defense against timing attacks is not that different from the above, just that the timing is precomputed and then the delays introduced to be exactly correct. My understanding is it’s generally something like

    If some_conditional:
        Do some operation that takes 2 cycles
        Delay for precisely 1 cycle
    Else:
        Do some operation that takes 3 cycles

    …
    Continue
For example, say you are testing a password. You could do

    Def brokenPasswordChecker(password, attempt)
       For i in len(attempt):
          If attempt[i] != password[i]
             Return false
       Return(true)
But if you do it that way, then attackers could observe that you return immediately after an incorrect character and use that timing to gradually deduce the prefix of the password until they have the whole thing. So instead you do:

    Def maybeLessBadPasswordChecker(password, attempt)
       Bool result = True
       For i in len(attempt):
          If attempt[i] != password[i]
             result =  False
       Return(result)
…which does the exact same number of comparisons every time so this same attack doesn’t work.

This is why you need help from the language/compiler or to break into inline assembly - lots of compiler optimisations will “helpfully” elide the delays you are introducing specifically to make the branches take the same time so they are once again vulnerable to timing attacks. So you need something so you can force that not to happen.

Re: Rust Cryptography Should Be Written in Rust

#94
post #43

I'd love this to be the case, but ring, which the author of the post created, is unfortunately not really maintained. It doesn't build on Windows ARM, which in turn inhibits rustls. It's a shame because I'd prefer to not depend on OpenSSL. Not that it's the author's fault. We shouldn't be reliant on a single person's contributions to have a working Rust cryptography toolchain.

That's Brian's point. rustls/webpki/ring do not have funding in line with projects like Go's crypto or BoringSSL: > ... ARM, Amazon Web Services, Google, and Microsoft [...] should support the Rust community by letting their experts help the Rust community create FIPS-validated cryptography libraries written entirely in safe Rust that expose safe and idiomatic Rust APIs. Rust's large corporate sponsors need to step u…

Those corporate sponsors are currently still using C and C++ for this kind of stuff and there is no change in sight.

Alone how much Azure Sphere gets sold as high security device, and the SDK is C only. There is a new preview support for Rust, yet nothing announced for the stable product, only C on that one.

Re: Rust Cryptography Should Be Written in Rust

#95
post #2

So far the only solid use case for Rust that I have seen in applications where security is extremely important. Not wonder it is becoming the de-facto language for building applications in the blockchain space. Does anyone else use Rust outside the blockchain/cryptography space? What are you working on?

Only hobby coding, leetcode stuff and such.

Work is all about Java, .NET, Web and mobile OSes, Rust hardly brings anything to the table there, other than less capable tooling, higher attrition with existing ecosystem and complexity in designing borrow checker friendly algorithms versus automatic memory management.

Re: Rust Cryptography Should Be Written in Rust

#96

Earlier quoted context omitted.

FWIW, RustCrypto is neither written in safe rust or only rust. It uses inline assembly, unsafe byte manipulation, and unsafe intrinsics

> unsafe intrinsics You mean like AESENC which you should always be using if available? The rust fanclub obsession with calling things like that unsafe simply because it has the same keyword in front of it is fairly ridiculous. > inline assembly Sometimes it's the only way to get some sort of constant time guarantees.

> You mean like AESENC which you should always be using if available?

Yes. And make it not unsafe

> Sometimes it's the only way to get some sort of constant time guarantees

I don't think you understood the article then. Brian wants the constant time guarantees as an intrinsic in the std library, guaranteed by the compiler, and exposed as safe rust.

> The rust fanclub obsession with calling things like that unsafe simply because it has the same keyword in front of it is fairly ridiculous.

If you have to use the unsafe keyword, you're creating the possibility of memory safety vulnerability. It would be amazing if you could immediately see that all code in a library does not use unsafe and know an entire class of vulnerabilities does not exist

Re: Rust Cryptography Should Be Written in Rust

#98

Earlier quoted context omitted.

Whenever I'm wearing my tinfoil hat, I wonder if all the advice to never implement your own crypto is a conspiracy to reduce independent implementations of cryptography algorithms. I know constant time operation is important for these algorithms, but couldn't I do this with a timer? Call the algorithm, store the result, return the result exactly one second (an eternity in CPU time) after it was called. Basically put…

It depends. If your threat model involved an attacker being able to monitor your power supply (as in some kind of embedded system), they’d be able to see the real work done and separate that from the fake delay.

Except if your 'wait' operation is doing the same computation (add, multiply...) but won't use the result. I often do that in some real-time/low-latency things where you want things constant-time (or can't easily define the worst-case execution time, just make all paths the worst). Then you still need to blind the speculative execution mechanisms so that they don't 'see' you're not using the result.

Re: Rust Cryptography Should Be Written in Rust

#99

Earlier quoted context omitted.

What if there are branches but both paths result in the same number of cycles being required to execute the instructions? Is it correct to say: "all branchless code runs in constant time, but not all constant time code is branchless"?

The subtlety is that eliminating branching isn't sufficient to have constant time code. A simple example is using trigonometric and transcendental opcodes. They don't branch (at the assembly level), but on x86 take variable amounts of time depending on the input operand. Very few algorithms actually use these opcodes though, so a more relevant concern is memory access due to variable latency. Even if you have that na…

Add cache misses, bus interference, SMT woes and it quickly becomes harder and harder to write (and check) constant-time (or WCET) properties. Even modern micro-benchmarks are a huge labyrinth of architectural traps.

Re: Rust Cryptography Should Be Written in Rust

#100
post #40

Earlier quoted context omitted.

Last I tried it also had issues with building on platforms like MIPS or PPC. If hardware acceleration is not available it should fall back to software not fail to build.

> If hardware acceleration is not available it should fall back to software not fail to build. It's not always possible to make the same security guarantees for these implementations. Software implementations of AES are frequently vulnerable to cache timing attacks, for example (e.g. [1]); even simple operations integer multiplication may not be constant-time on some architectures. [1]: https://cr.yp.to/antiforgery/c…

Bit sliced AES is about as good as you can do. ARX ciphers like ChaCha are theoretically better but it’s also not possible to be 100% certain of constant time on every conceivable architecture. And what if the architecture is being emulated? All bets are off then.

At some point this gets pedantic. Just not supporting anything but x64 and ARM64 means any project using ring or a dependency that uses ring can’t build elsewhere which turns ring into a land mine dependency.

Post reply on HN