5 ms·
Rustls use ring for crypto, and it seems most of the crypto algorithm code of ring is written in C/assembly. Kind of destroy the purpose?
by nialv7 10y ago
Rustls use ring for crypto, and it seems most of the crypto algorithm code of ring is written in C/assembly. Kind of destroy the purpose?
- zmanian 10y agoRust is not a good language for low level crypto implementation because it offers no facilities for side channel resistant algorithims. Ring uses the extensively reviewed implementation from BoringSSL and considerable expertise from the author. Ring has a goal of moving as much code that does not need side channel resistant to Rust. By moving the protocol logic to Rust, the amount of code that needs to be reviewed for memory safety in a TLS library is drastically reduced.
- colemickens 10y agoWhat does Rust the language have to provide in order to achieve side channel resistant algorithms? That doesn't sound right to me. There are primitives in other languages that are needed? Or Rust doesn't abstract at the right level? edit: thanks for the explanations!
- mcpherrinm 10y agoUltimately, it's an optimizing compiler, and it's difficult/impossible to tell the compiler "make this code fast, but not too fast for these specific cases". The same problem affects basically every language that isn't assembly.
- thristian 10y agoIt might even affect assembly, if your CPU's microcode optimizations are sufficiently aggressive.
- briansmith 10y agoMost 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.
- Bromskloss 10y ago> Most high-level languages don't provide guaranteed-constant-time behavior at all. Does even C provide such guarantees? Isn't the compiler free to rewrite the code it's compiling in whatever way it wishes as long as the output is the same?
- DasIch 10y agoC doesn't and even Assembler doesn't entirely. DJB has pushed and is still pushing(?) Intel to publish more information about these things.
- briansmith 10y agoHi, 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 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.