HNHacker News
TopNewBestAskShowJobs

briansmith

2,968 karma · joined October 5, 2007

https://briansmith.org/
submissionscomments
briansmith··on Mundane: Rust cryptography library that is difficult to misuse
> This problem is compounded by it only being possible to link one version of Ring in to the same program.

I am planning to fix this in ring early in 2021 (January)...

> Even if you don't depend on Ring directly, Ring could appear as a dependency of many of your dependencies. This forces you into upgrading all of your Ring-depending dependencies in lockstep. You cannot upgrade any until all of these dependencies support the same latest version of Ring.

Then you won't need to upgrade everything in lockstep.

That said, I still do recommend everybody only use the latest version.

briansmith··on Third-Party Audit of Rustls
I commented on this at https://github.com/briansmith/webpki/issues/130. This is nothing to be concerned about, for quite a few reasons. I don't expect any compatibility issues with being stricter since Google Chrome's new X.509 processing does enforce the stricter syntax.
briansmith··on Third-Party Audit of Rustls
I spent significant effort writing the name constraint implementation in mozilla::pkix (used by Firefox) and by webpki (used by Rustls) to fix this situation. The result is summarized by Netflix:

> The result was that every browser (except for Firefox, which showed a 100% pass rate) and every HTTPS client (such as Java, Node.JS, and Python) allowed some sort of Name Constraint bypass.

- https://netflixtechblog.com/bettertls-c9915cd255c0

Since then, Google Chrome has implemented and deployed a new certificate processing library on some (most?) platforms it supports, and I bet they have similar or better name constraint support. I believe Apple has also improved their implementation.

> I wish that NameConstraints were better supported, to make it easier to support intermediate CAs; for instance, prove you own example.com and you could then have a CA restricted to *.example.com. But right now, that just doesn't seem feasible.

Since the aforementioned improvements have shipped in production browsers, it is much more practical, from a technical standpoint, to do that. The real problem now is browsers' CA policies. As I understand it, they do not want you to be able to get your own name-constrained intermediate CA certificate. The CA that issues you the intermediate CA certificate would be on the hook, with the consequence of being removed from the root CA programs, if you issued a malformed certificate. And there are other issues with the policy. I hope there are improvements to the browsers' CA policies to make this practical, but I wouldn't hold my breath.

briansmith··on Teen Becomes First Hacker to Earn $1M Through Bug Bounties
I received a bug bounty from Mozilla after leaving, in a browser component I previously worked on. I didn't write the vulnerable code though.

On the other hand, Google refused to pay me a bug bounty for a bug I found in the same component, in part because I used to work on it when I was at Mozilla, even though I didn't write the vulnerable code.

briansmith··on Mundane: Rust cryptography library backed by BoringSSL
We are continuing the project of replacing C code with Rust code in ring. The pace of that effort is mostly a function of how much work time I have available to spend on ring.

Day-to-day ring development happens on Windows and it was designed to "just work" on Windows (as well as Linux, macOS, Android, iOS, and other supported target operating systems). We did a huge amount of work to make the build system fully automatic to enable this, and we have a pretty extensive CI mechanism to make sure everything "just works" as much as we can.

As for WebAssembly, I'm looking forward to something like https://pdfs.semanticscholar.org/3887/6d86e5e7851181efc9ed3b....

However, you should probably use the WebCrypto API in a web app if at all possible, instead of a wasm crypto library. Unfortunately the WebCrypto API is 100% asynchronous whereas almost every other crypto API is 100% synchronous so that's easier said than done. Really browsers should add a synchronous WebCrypto API; then crypto libraries can transparently delegate to it when targetting wasm.

briansmith··on Building on Rock, Not Sand
https://github.com/bluejekyll/trust-dns
briansmith··on Maybe we shouldn't skip SHA-3
NIST did specify a SHA-512/256 that has its own IV, like SHA-384.
briansmith··on Maybe Skip SHA-3
I guess 32-bit x86 performance is maybe not the best benchmark. I think people aren't optimizing for that ISA to the same extent as they are optimizing for x86-64, 64-bit ARMv8, or 32-bit ARM.

If you care about performance and you don't have dedicated SHA-256 instructions then on a 64-bit platform you should evaluate SHA-512 as it is much faster. If you only have 256 bits of storage available then truncate its output to 256 bits. IIRC, it's about 1GB/sec on my Haswell laptop.

briansmith··on New vulnerabilities found in ARM mbed TLS
You can probably find the same or similar bugs in lots of crypto libraries. I occasionally fix similar issues in ring and BoringSSL so that the BoringSSL/LibreSSL/OpenSSL/ring community can discover and fix the issues.

Arguably, the real bug is that these crypto libraries even try to represent negative numbers at all in the first place. In ring I'm close to removing all support for negative numbers.

briansmith··on Visual Studio '15 preview 4
Did you file a bug on the rustc issue? I'd like to get that fixed and/or even help get it fixed, by fixing the Rust toolchain.
briansmith··on Rustls: new, modern TLS library written in Rust
Rustls doesn't really have to deal with the timing attack issue, because those issues are handled by the underlying crypto library, ring. And, ring wasn't built from scratch. It builds upon all the constant-time crypto code in BoringSSL and OpenSSL. And, we've improved the constant-timedness of the code in several ways and contributed most of those improvements back to BoringSSL.
briansmith··on Rustls: new, modern TLS library written in Rust
Most high-level languages don't provide guaranteed-constant-time behavior at all. That's a big reason why ring uses lots of BoringSSL's/OpenSSL's assembly language code.

Also, one of my goals with the ring project is to identify exactly what constant-time utilities are needed for a crypto library, so that I can draft a proposal for improving the Rust language and libraries to provide such features.

briansmith··on Rustls: new, modern TLS library written in Rust
Hi, I'm the person who started the ring project. There is a lot of assembly language code in ring, and there's still some C code too. The thing to keep in mind is that we started from 100% C and assembly language code. Since August 2015, ring has supported a 100% Rust certificate validation library (webpki, it's open source on GitHub), and a 100% Rust TLS implementation (not Rustls, but one that wasn't open source). As we've improved upon the code we started with, we do generally replace it with Rust code, while keeping everything on top of it working. But, we don't replace C code with Rust code just for the sake of doing so. There's always some concrete benefit to each change we make, beyond language advocacy.

The assembly language code we inherited from BoringSSL (and OpenSSL) is really important for performance and for safety from side-channel attacks, like timing attacks. I believe that rewriting most of the assembly language code in Rust would be a net loss for security. I have very long-term ideas for how to avoid needing so much hand-coded assembly, but we have higher-priority things to do now. And, the assembly language code is really good. Really.

The C code is increasingly getting replaced (not rewritten or just transliterated) with Rust code, wherever it makes sense to do so. You can see some of the planned work of this type at https://github.com/briansmith/ring/labels/oxidation. To see the past work, review the commit log of ring.

However, we've done tons of work to make the C code safer too. For example, I've written dozens of patches to eliminate cases of undefined behavior and other unsafe coding patterns in the C code. Many of these changes have been integrated into BoringSSL.

Also, we've greatly reduced the usage of the heap. Already, you can use most of ring's functionality without a heap. Importantly, this means that we have solid evidence that, for almost every ring feature, there is zero chance of use-after-frees, double-frees, or memory leaks. It also means that the memory usage is very predictable, which makes it easier to use in constrained environments.

In addition, I've tried to design the ring API very carefully to limit the potential for things built on top of it to misuse the crypto. For example, the API enforces--statically, at compile time--that an ECDHE key can be used only once. Similarly, it enforces--statically, at compile time--that an AES/ChaCha20 encryption key is never used for decryption, and vice versa. Similarly, it ensures that encryption is always properly authenticated--there's no way to accidentally do "MAC before encrypt" and similar things. We even make sure that you don't use less-safe AES-GCM nonces that aren't exactly 96 bits.

Finally, anything that uses ring get all the advantages that come with Rust automatically, such as Rust's use-after-free protection and data race protection. (ring replaced all the C threading/synchronization stuff using the safer Rust constructs already.)

So, even though there is some C code, and even though there's a lot of assembly language code, things that use ring are still getting lots of Rust's advantages.

There are other alternatives that are "pure" or close to "pure" Rust, such as rust-crypto. But, those libraries are missing important things like RSA and ECDH and ECDSA over the NIST P-256 and P-384 curves. That's all needed for a practical TLS implementation.

briansmith··on Rustls: new, modern TLS library written in Rust
Out of curiousity, what sort of evidence of safety is the Servo team using to evaluate crypto libraries? I'd love to see the criteria.
briansmith··on Rustls: new, modern TLS library written in Rust
> Attacks like downgrade attacks, for example, are not memory unsafety issues.

First, this library only implements TLS 1.2 with AEAD cipher suites (AES-128-GCM, AES-256-GCM, and ChaCha20-Poly1305) and perfect forward secrecy (using ECDHE with the X25519, P-256, and P-384 curves, and RSA and ECDSA signatures). Thus, downgrade to something worse than what NSS or OpenSSL or BoringSSL consider to be the very best crypto is avoided at a very fundamental level.

Second, I and other people have been advocating strongly against design decisions that force implementations to add downgrade vectors. In particular, there is a version number field in the TLS ClientHello that we know causes problems. People have proposed solutions to avoid this version number causing compatibility problems for TLS 1.3, but Mozilla's TLS people have not supported making this improvement. Thus, we're likely going to have downgrade issues by design in TLS 1.3 that would be completely avoidable, due in large part to the people making NSS and other C crypto libraries.

briansmith··on Pretty Curved Privacy
Here's the effect that this ultimately has, as far as I can see: The most reasonable people, who we would ultimately like to see build something that people use, get discouraged and go work on something else. The most stubborn, unreasonable people then charge ahead, and eventually a few of them break through via marketing and win millions or billions of users, with whatever they put together. It's a net loss.

I don't understand the value of pointing to something that died 5 years ago and where nobody even wrote a single test as a model to learn from. There's got to be better models to follow, if our goal is to point people at things to learn from. There's no need to turns things ad hominem by shifting the focus to authorship and away from the actual merits of the software: design, code quality, test coverage.

briansmith··on Pretty Curved Privacy
One can't really learn cryptography without writing code. IMO, people should write code and share it and get feedback on it, and experts should donate some time to help them improve, so that we can have more experts. And experts should encourage good programming practices: good testing, good design documentation, etc.

I've worked on code bases written by experts that put billions of people at risks that were avoidable with proper testing. Conversely, I've seen newcomers write very good code--yes, even crypto code--that was clearly correct because of their code clarity, documentation, and tests.

There's a lot of people who are going to interpret your comment--the one at the top of this discussion--as "Newbies shouldn't even try, and definitely shouldn't show their code to anybody." I doubt that's what you intended, but that's unfortunately the message that gets conveyed, judging from the discussions I've had with lots of newcomers. Nobody's going to write perfect crypto code right away. We can't be shooting them down before they even get started.

briansmith··on Pretty Curved Privacy
The appeal to expertise is exactly what I'm objecting to. Let's judge things on their technical merits: tests, clarity of code, correctness, etc.

I've talked to way too many people that want to make contributions to improve security software, including crypto software, but get scared away because of the implied and explicit discouragement due to such appeals. It's holding our industry back and slowing us down.

briansmith··on Pretty Curved Privacy
I'm not sure what you are trying to say.

Are you saying that people should use CPGB? Are you saying that CPGB is better than pcp because you think the author of CPGB is more of an expert than the author of pcp?

Did you notice the pcp author actually tried to write tests, whereas there are no tests in CPGB?

BTW, the last commit to CPGB was on Dec 19, 2011.

I've nothing against CPGB and I'm not familiar with pcp but I think this "expert" thing is ridiculous.

briansmith··on Show HN: MassDNS – A high-performance DNS stub resolver in C
Which statistics are you referring to?
briansmith··on Afl.rs: Fuzzing Rust code with american-fuzzy-lop
If you're parsing untrusted input, you should try to systemically avoid panics. Easier said than done, but I have started a small framework for protocol parsers called untrusted.rs that helps: https://github.com/briansmith/untrusted.

The main idea is that most panics (in parsers) are going to be caused by using the indexing operator on slices containing the untrusted input, so we wrap the input in a type that hides the slicing functionality, giving us only methods that return 'Result's.

nom is a much fancier thing which, IIUC, solves the same problems, and more: https://github.com/Geal/nom.

briansmith··on Baby Steps: Slowly Porting Musl to Rust
> Since the Rust standard library depends on libc, I'm not sure how one would properly allow the Rust symbols to replace the linked-in libc symbols while still depending on the rest of libc. Maybe it's not an issue? Maybe there's some magic which could be done?

Static libraries can have circular dependencies like that. For example, in ring[1] I have C code in one static library, which calls some Rust functions in my Rust code. And, that Rust code calls functions in the C static library. The linker...links them together.

[1] https://github.com/briansmith/ring

briansmith··on Baby Steps: Slowly Porting Musl to Rust
IMO, it would be more interesting to see it done top-down, instead of bottom-up. That is, instead of starting with rewriting `strlen`, why not start with rewriting `getaddrinfo`? That would be a very interesting project because you could write `getaddrinfo` with a safe Rust API (i.e. one that doesn't require using `unsafe` to call it), and then wrap it in an `unsafe` function that exports the unsafe C `getaddrinfo` function. This could arguably then be an improvement on the musl code.
briansmith··on Cache-Control: immutable
This Google Chrome document is worth reading: https://docs.google.com/document/d/1vwx8WiUASKyC2I-j2smNhaJa...

In particular, it gets into the heart of the matter: What does the user want to happen when they click the Refresh button?

It does seem worthwhile to try to change the default behavior of the Refresh button to mean "refresh the page" instead of "fix the page" (what it currently does), which would make this "immutable" proposal unnecessary, AFAICT.

briansmith··on A critique of "How to C in 2016"
What do you think Rust needs to do to become viable in the embedded world?
briansmith··on Triple-Triple Redundant 777 Primary Flight Computer (1996) [pdf]
In Firefox 4, there was a need to implement the HKDF crypto algorithm in a variety of code bases: Java, Javascript, C using OpenSSL, C using NSS. One team coded three implementations. Later, another team coded an implementation. But, that last implementation didn't interop with the first three. Of course, the two teams disagreed about which was wrong, each believing that they were right and the other team was wrong.

Surely if three different implementations in three different languages agree, then the problem is with the fourth, disagreeing implementation! However, the second team annoyingly pointed out that they had automated tests that covered the official test vectors. Well, maybe the tests were coded wrongly too! Well, could the first team implement the tests that include the official test vectors? What a waste of time! There are automated tests that check that the first three implementations all calculate the same results for many random inputs!

It turns out that the very first implementation, in Javascript, had a bug, and that bug was transliterated into two other implementations. But since the second team hated reading Javascript code, and because that team consisted 100% of annoying (but good-looking) pedants, they implemented the algorithm by reading the spec. instead of by copying the first implementation, and so they got it right.

Incidentally, the bug was that the key and value in an HMAC calculation were swapped. HKDF uses HMAC in a counterintuitive way, where the key isn't (necessarily) a secret, but the value is.

briansmith··on Ideas for a New Elliptic Curve Library
Right now, I don't see any advantage of embedding the DSL into Rust code, when instead I could have the DSL completely separate from Rust, and just use Rust's FFI to access what the DSL compiler generates. One benefit of the FFI route is that the result wouldn't be Rust-specific.

Remember that one of the goals is to become confident that the implementation is correct without also having to analyze whether rustc is correct or whether the Rust language has meaningful semantics. If we involve rustc in it, then we've greatly expanded the scope of what we have to analyze.

Even if asm! were stable in Rust, I would still prefer to have my assembly language in separate .s/.asm files. rustc gets updated every 6 weeks, which is great, but I'd really kind of like my assembler to be more static than that. Assembly language benefits massively from having macros, but Rust actually is not as good of a macro language for assembly as existing assembler macro languages. I'd rather see rustc improve at compiling Rust code than have it try to also compile ASM code.

briansmith··on Ideas for a New Elliptic Curve Library
> Does he mean doing what Galois did [1][2] with tools like CRYPTOL [3][4]? Or something more like this [5] with EasyCrypt and CompCert? Or something simpler like Altran's SPARK crypto [6]? And maybe with protocol-level verification like miTLS [7]?

Yes.

> I don't think there's a question about whether the goals can be met so much as a lack of uptake of methods and tools that meet them.

I agree. And, that's a big part of the reason I didn't spend a lot of time on formal verification when I wrote what I wrote. The target audience of my writing is people think that the result must be as fast as the fastest implementation, but that only think that formal verification of correctness is nice to have and/or impractical to the point of not being worth trying. That isn't my own personal prioritization, but I think that actually describes the prioritization of almost everybody deploying open source crypto software today.

Anyway, I hope to have more to say about formal verification of ECC implementations later.

briansmith··on Ideas for a New Elliptic Curve Library
Integrating with LLVM is almost definitely more work than just porting the simple compiler to multiple architectures. Plus, LLVM is actually the source of the difficulty of writing constant-time code using Rust's official compiler, because LLVM is too smart.
briansmith··on Ideas for a New Elliptic Curve Library
The idea is that the DSL compiler would be responsible for ensuring constant-timeness. Note that C, C++, and Rust offer no guarantee of constant-timeness. Even processors don't offer constant-timeness guarantees and some instructions (often division) are not constant-time. See also http://blog.erratasec.com/2015/03/x86-is-high-level-language....

I wrote the paper mostly in the context of implementing signature verification, which doesn't require side-channel protection since there are no secrets in verification. But, I think the DSL approach is even more important for ECDH and signing, where side-channel protection is important.

Finally, given that processors don't even promise us that any instruction is constant-time, and given that other types of attacks are possible where constant-timesness doesn't help so much (e.g. power analysis), I think it is worth considering other approaches to side-channel protection (e.g. blinding). For many applications, constant-timeness isn't sufficient and I'd love to learn that it isn't necessary.

← PreviousPage 2 of 27Next →