On Fri, Nov 17, 2017 at 05:08:02PM +0000, Devrandom wrote:
> I'm going to try to compile with older versions, will let you know how it
> goes.  Ideally we could get to versions before zcash was announced.
> 
> This will be fun, have not done Rust before.  But here are some thoughts
> about the Rust compiler after trying to compile it from source:
> 
> - the Rust compiler can only be built with itself, which means that you
> have to start from a binary, so you might as well trust the binary

Nope! There's an alternate Rust compiler written in C++ called mrustc:

    https://github.com/thepowersgang/mrustc

It's not suitable for general use as it lacks a borrow checker, but Rust only
needs the borrow checker to catch mistakes; if your code is perfect alredy you
don't need it. Thus mrustc is suitable for compiling the Rust compiler itself,
something I hear it is able to do. Assuming you can in fact get that to work,
that's sufficient to do diverse double-compilation.

Secondly, if you're feeling adventerous, you could try re-bootstrapping it from
the original OCaml implementation. :)

FWIW I have a timestamp on mrustc from a few days ago:

    
https://github.com/petertodd/mrustc/commit/6b30d486dc3b653302fd4bc4887b92e5feb1044c

> - if we start with a really old one, the chances of a targeted attack are
> pretty slim

Agreed, but note that a targeted attack isn't our *only* threat.

When you think about it, compiler backdoors are basically a class of exploit
where the attack causes source code to be miscompiled into machine code that
the auditors looking at the source code didn't expect. This means that a
compiler backdoor can be generic, and can be prepared in advance.

Basically, in this scenario the Rust compiler would have a subtle compilation
flaw that could be maliciously triggered by the powersoftau authors to produce
machine code that did something other than what you'd expect it to do, e.g.
causing a PRNG to zero out part of it's entropy pool. Starting with a really
old Rust compiler doesn't necessarily protect us from this attack; this type of
attack may also be done with an *accidental* compiler bug too (although it'd be
harder to find a suitable one).


A cheap way to defeat this intentional miscompilation attack is to simply
modify the powersoftau codebase as much as possible so that any hypothetical
miscompilations are no longer triggered. For example, even if you didn't have
the skillset to understand the code, you could mechanically go through the
codebase (and dependencies) and replace all integers with a hexadecimal string
type, and reimplement the necessary operator traits for that new type.

Sure, that'd be slow as heck, but it doesn't have to be fast: by using a
deterministic secret you can compare your ridiculous hex string implementation
with the reference implementation offline. If both implementations match,
you've just ruled out a whole class of intentional miscompilation attacks.

> - a general trojan that detects access to /dev/random and reduces entropy
> could still be lurking
> - the mixing of entropy from the user should mitigate, unless the compiler
> can be smart enough to detect even that

A trojan that can detect access to /dev/random would be in a position to do
whatever it wanted to the powersoftau binary; this is basically the same
problem as getting a clean Rust compiler.

> BTW, what does the timestamp on crates.io buy us? Looking at the repo, it
> looks like they just commit version numbers, but not git hashes of the
> source code.

They do. For example, powersoftau depends on the blake2 crate, v0.6.1

The relevant crates.io-index entry is at 
https://github.com/rust-lang/crates.io-index/blob/master/bl/ak/blake2,
specifically:

    
{"name":"blake2","vers":"0.6.1","deps":[{"name":"digest","req":"^0.6","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal"},{"name":"crypto-mac","req":"^0.4","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal"},{"name":"generic-array","req":"^0.8","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal"},{"name":"byte-tools","req":"^0.2","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal"},{"name":"crypto-tests","req":"^0.5","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"}],"cksum":"53bf612c0f2839b7e764ebac65d6cb985f7c6812de399d0728038f4b1da141bc","features":{"simd_asm":["simd_opt"],"simd_opt":["simd"],"simd":[]},"yanked":false}

The "chsum" field is actually the SHA256 hash of the crate file for that
specific version, and the crate file is simply a tarball of the sourcecode.

You'll also note how the Cargo.lock file in the powersoftau repo specifies the
exact hash digest in the [metadata] section at the end:

    "checksum blake2 0.6.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"53bf612c0f2839b7e764ebac65d6cb985f7c6812de399d0728038f4b1da141bc"

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org

Attachment: signature.asc
Description: Digital signature

Reply via email to