[HN Gopher] Preparing Rustls for Wider Adoption
       ___________________________________________________________________
        
       Preparing Rustls for Wider Adoption
        
       Author : jaas
       Score  : 180 points
       Date   : 2021-04-20 14:56 UTC (8 hours ago)
        
 (HTM) web link (www.abetterinternet.org)
 (TXT) w3m dump (www.abetterinternet.org)
        
       | zelly wrote:
       | Rustls is still not formally verified. It may not have memory
       | errors, but there are a lot of other security errors besides just
       | that (and there may be more of them since it hasn't been used as
       | much as open|boringssl has been used). It's a slight improvement
       | at best.
       | 
       | Ideally you want a formally verified SPARK or CompCert C
       | implementation of TLS, but those are not open sores compilers so
       | they won't fly.
        
       | dochtman wrote:
       | Happy to answer any questions that come up!
        
         | erdii wrote:
         | Hey @dochtmann :)
         | 
         | Isn't rustls [1] also built on very unsafe groundwork? Namely
         | ring [2], which, according to github, contains 47.3% Assembly
         | and some C as well.
         | 
         | I'm not trolling here - we were discussing this a lot in my
         | peer group lately.
         | 
         | [1] https://github.com/ctz/rustls [2]
         | https://github.com/briansmith/ring
        
           | baby wrote:
           | Had the same thought the other day:
           | https://cryptologie.net/article/520/cryptography-and-
           | assembl...
           | 
           | Not a fan of assembly for cryptographic code.
        
           | briansmith wrote:
           | The goal of the _ring_ project is to be much safer than
           | OpenSSL without any notable decrease in performance. That is,
           | my goal is to give you memory safety  "for free" if you
           | switch from OpenSSL/BoringSSL to _ring_. In some cases it is
           | better than free because we end up being faster.
           | 
           | The assembly code in _ring_ is some of the most heavily-
           | tested code in the world. It 's fuzzed pretty much
           | continuously in various projects that use it, and a bunch of
           | testing has been done on it. It is from BoringSSL, and much
           | of it is shared with OpenSSL and/or Linux kernel. As we are
           | able to replace the assembly code with safer code, we'll
           | continue to do so, just like we've replaced most of the C
           | code with which we started.
        
           | volta83 wrote:
           | Also, ring enforces everyone to use the latest version by
           | pruning older versions from crates.io, which means your
           | builds will fail every time they update.
           | 
           | Main reason I stopped using it.
        
             | CodesInChaos wrote:
             | I thought crates.io doesn't allow removal?
             | 
             | You can yank crate versions, but that doesn't affect builds
             | which lock a version via cargo.lock so failing builds
             | shouldn't be an issue.
        
               | steveklabnik wrote:
               | They meant yanking.
        
             | tialaramex wrote:
             | Of course, if our claim is that we want to avoid security
             | bugs, and we accept the principle that (without some more
             | specific definition) all bugs are security bugs, then any
             | time ring fixes a bug we want to avoid using the old
             | version...
             | 
             | Now for all I know, ring has never fixed any bugs and it
             | just loves adding new API features so that this pruning has
             | no desirable security properties at all, but in principle I
             | can see that this is the equivalent of the standard
             | boilerplate Linux release text which tells you that you
             | should update to the latest kernel because they fixed bugs.
             | 
             |  _If_ you have a complete threat model and _if_ you are
             | capable of the insight needed to examine all changes and
             | determine how they impact that model, you could
             | successfully choose whether to upgrade based on whether a
             | new version fixes a bug you care about. But chances are you
             | _don 't_ have such a model and even if you did you _aren
             | 't_ capable of the inhuman levels of insight needed, even
             | in a language like Rust (and forgetting that we're talking
             | about this because large parts of ring aren't even in
             | Rust).
        
               | volta83 wrote:
               | crates.io and the Rust community adheres to semantic
               | versioning.
               | 
               | If ring wants to notify me that I should update, they
               | should send an email to a security mailing list, open a
               | CVE, register the cve in any of the rust services to
               | notify users with those dependencies (there are some,
               | like crev), etc.
               | 
               | Pruning your releases from crates.io just means that I am
               | going to be annoyed the first time it happens, will start
               | looking for a solution the second time it happens, and it
               | won't happen a third time (and it didn't). If you want to
               | wake me up a Saturday at 4 am, the world better be on
               | fire.
               | 
               | This is probably the only dependency I can remember as
               | being... more than annoying, toxic. I still prevent any
               | of my dependencies from ending up with ring as a
               | dependency. If that shows up in our dependency tree, CI
               | fails, and that change cannot be committed.
               | Unfortunately, this pruning of old releases was only one
               | of the issues with ring (there were others, like cross-
               | compiling it wasn't easy, etc.). All in all it was a no
               | brainer to drop it as a dependency.
               | 
               | I don't think I've ever met a rust dev with something
               | nice to say about `ring`. In a meetup a couple of years
               | ago another rustacean said: "`ring` is so secure that it
               | protects you from using it in your projects". Sums it
               | pretty well.
               | 
               | The library has couple of thousands of daily downloads so
               | for the latest version, and like 25k daily downloads for
               | other versions, so maybe things changed now.
        
               | tialaramex wrote:
               | > If you want to wake me up a Saturday at 4 am, the world
               | better be on fire.
               | 
               | In a previous role I actually have had things set so that
               | I might be woken at 4am on a Saturday, IIRC specifically
               | under certain conditions it'd play "Straight out of
               | Compton" at full volume on my Hi Fi to ensure my
               | attention, which gave me about 10 seconds before it gets
               | real loud.
               | 
               | I was leak hunting, specifically looking for a huge leak
               | in a production system that we couldn't reproduce on
               | smaller test systems - so I needed to wake up, attempt to
               | diagnose the leak and then (regardless of whether
               | successful or not) mitigate it (kill the bloated process,
               | one transaction fails but everything else will auto-
               | repair) and go back to bed.
               | 
               | But what I don't understand here is, why are you
               | constantly rebuilding and alerting on failure? A CI flag
               | can wait until Monday stand-up, are you _auto-deploying_
               | any change of state even when there aren 't any humans
               | around to cause that? Why? That strikes me as up there
               | with Apache's "But your Good OCSP response expires in 18
               | hours, so I stapled this newer Bad one instead" in terms
               | of terrible mistakes.
               | 
               | If instead your _new builds_ fail after pruning, the
               | human who is causing a new build can decide what to do
               | about that when it happens, no need for anybody to be
               | woken at 4am.
        
               | briansmith wrote:
               | When I merged security fixes from BoringSSL/OpenSSL, I
               | yanked the old versions of _ring_ that didn 't have the
               | security fixes. I thought that was a pretty reasonable
               | policy, however people who like to comment in these
               | forums disagreed very loudly, so I stopped doing that.
               | Not sure that's better, but there's less complaining.
               | 
               | In general, my initial thinking was based too much on the
               | assumption that people would help maintain the things
               | that depend on _ring_ to update them to the latest
               | release. It turns out there 's less cooperative
               | maintenance like that than I expected.
        
               | volta83 wrote:
               | > In general, my initial thinking was based too much on
               | the assumption that people would help maintain the things
               | that depend on ring to update them to the latest release.
               | It turns out there's less cooperative maintenance like
               | that than I expected.
               | 
               | I think that's a reasonable assumption.
               | 
               | What isn't reasonable is to expect people to "upgrade
               | right now". Not everybody lives in your time zone, so
               | when you yank a dependency, you might be breaking a
               | workflow in the other part of the world at 3 am, and if
               | some webserver doesn't deploy or whatever, somebody will
               | get a call.
               | 
               | I'm not suggesting this is an easy problem to solve, but
               | there is a wide range of options before "never upgrading"
               | and "force an upgrade right now". Some of these are
               | supported by Cargo via Cargo.lock, etc. so the
               | responsibility for how this is handled doesn't fall on
               | one library or person.
               | 
               | Building a secure system is also not the exclusive
               | responsibility of `ring`. If I'm building a secure
               | system, I have to assume that `ring` will have a bug
               | that's exploitable at some point, and that someone will
               | use it in a zero-day, and my system needs to be secure
               | even if that happens.
               | 
               | So "updating right now" doesn't buy me much. Its
               | something that can wait until after a meeting, or after
               | my vacation, or until monday. Its not a "the world is on
               | fire" situation, even though it would still be pretty
               | severe.
               | 
               | I'd still like to get "notified" ASAP and asynchronously
               | somehow. While updating ring is low effort, the update
               | still needs to "internal QA,..." etc. at companies, and
               | that takes people's time that must be planned on.
        
               | viraptor wrote:
               | With software which needs security considerations it's
               | also common to want to test the vulnerable versions,
               | write tests internally and verify the broken/fixed
               | behaviour. Yanking old versions makes this annoying. (Yes
               | you can rebuild from the repo tag, but that's annoying,
               | especially in indirect dependencies)
        
               | jzoch wrote:
               | I loved your policy and appreciated how principled it
               | was. People here are too harsh and most of them don't
               | write code in Rust where regular updates are much more
               | the norm than other communities.
        
               | richardwhiuk wrote:
               | Yanking releases which have bugs / vulnerabilities in
               | them is very much not the norm in the Rust community.
               | 
               | This is why projects like https://github.com/RustSec
               | exist.
        
               | steveklabnik wrote:
               | I don't know about that, crates that RustSec has
               | advisories for are often yanked, in my experience.
               | 
               | Bugs? No. Security bugs? Yes.
        
               | richardwhiuk wrote:
               | Hyper 0.11.26 - https://crates.io/crates/hyper/0.11.26
               | 
               | Not yanked.
               | 
               | Vulnerable to https://github.com/RustSec/advisory-
               | db/blob/main/crates/hype...
        
               | steveklabnik wrote:
               | Sure, it's quite possible that not every single one ever
               | is. One single version of one single library not being
               | yanked doesn't mean that nobody ever does it.
        
               | [deleted]
        
             | Arnavion wrote:
             | Your builds will only fail if you don't check in your
             | lockfile.
        
             | briansmith wrote:
             | That hasn't been the case for a long time, a year or more.
        
             | dochtman wrote:
             | That issue should be fixed in the next release. It is
             | definitely a nuisance, but fixing it is not easy due to the
             | assembly code involved.
        
           | oconnor663 wrote:
           | One thing to keep in mind is that the low level building
           | blocks of crypto algorithms can be relatively easy to test,
           | compared to higher level protocol and application code. For
           | example, a block cipher takes simple inputs, usually a couple
           | of fixed-length arrays and maybe some integer flags. There
           | might be a ton of assembly under the covers, but that
           | assembly isn't responsible for reasoning about pointer
           | lifetimes or parsing data formats or any of the usual things
           | that tend to trip up unsafe code. (Like a TLS
           | implementation!) Instead, the block cipher is a pure
           | mathematical function of those inputs, and that makes it
           | relatively easy to come up with a set of test vectors that
           | cover the function. This also means that the C code and Rust
           | code for the same block cipher tend to look very similar.
           | 
           | Now there definitely are some tricky requirements in crypto
           | code that application code doesn't need to deal with, like
           | constant-time requirements. But auditing for those isn't
           | really any harder in assembly or C than it is in Rust. In the
           | end, porting these sorts of core crypto algorithms from C to
           | Rust tends to be more interesting from a build systems and
           | tooling perspective than from a correctness perspective.
        
           | dochtman wrote:
           | It uses ring for cryptographic operations, yes. However, note
           | that all the ASM in ring is meticulously kept up to date with
           | BoringSSL upstream, which ring was derived from. Plus, there
           | was pretty successful third-party security audit last year.
           | 
           | Also, the goal is definitely to bring all of that code into
           | Rust, unfortunately Rust lacked the features to do that
           | safely (things like const generics).
        
             | birktj wrote:
             | Could I ask why const generics would be a blocker? I see
             | how it would help facilitate more elegant APIs as well as
             | better stack allocated structures. However is it not
             | possible to live without this, possibly with a slightly
             | more clumsy design?
        
             | CameronNemo wrote:
             | >Plus, there was pretty successful third-party security
             | audit last year.
             | 
             | The security audit referenced by the post suggests offering
             | EverCrypt as an optional alternative to ring. Are you going
             | to act on the audit's recommendation, or continue to only
             | offer ring?
        
           | steveklabnik wrote:
           | > Isn't rustls [1] also built on very unsafe groundwork?
           | 
           | Depending on what you mean by "groundwork" literally
           | everything is. Hardware doesn't obey Rust's rules, and you
           | need to interface with hardware to get input, and do output,
           | so literally every program will have unsafe code at the base.
           | 
           | The key difference is that Rust gives you the tools to
           | explicitly demarcate what is safe, and what is not, and build
           | safe abstractions on top of (hopefully validated) unsafe
           | foundations.
        
         | e12e wrote:
         | This looks great. As I understand it, the major reason openssl
         | is still in use (at all, really) -is a very unhealthy
         | dependency on it's demented and complex Api... Has anything
         | changed that makes it easier to switch from broken ssl lib to a
         | new "perfect" one?
         | 
         | Are we likely to see stdlib changes in python, ruby etc?
         | 
         | The site mentions:
         | 
         | > Enforce a no-panic policy to eliminate the potential for
         | undefined behavior when Rustls is used across the C language
         | boundary.
         | 
         | Is this a thing? Does panic open up for undefined behavior when
         | using a rust library via C?
         | 
         | I can't recall seeing it mentioned before/in other rust
         | threads/projects?
         | 
         | I whish you the best of luck- libopenssl is terrifying :)
        
           | dochtman wrote:
           | On the Python angle, I recently spent some time building
           | Python bindings for another Rust project with PyO3 and was
           | quite happy with the result. Since then, I've been toying
           | with the idea about building a somewhat compatible
           | replacement for Python's ssl module based on rustls. I'd be
           | happy to work on that, but I'd need to find some way to fund
           | it (Patreon or GitHub Sponsors might work, but so far I
           | haven't had a lot of luck gaining sponsors there).
        
           | orra wrote:
           | Panicking (unwinding) across an FFI boundary is very much
           | undefined behaviour. You'd get analogous cross language
           | issues with C++ exceptions. Or mixing GCC ABI unwinding with
           | MSVC ABI unwinding.
           | 
           | Nonetheless, there is a working group, proposing to make it
           | defined under certain circumstances. https://blog.rust-
           | lang.org/inside-rust/2020/02/27/ffi-unwind...
        
             | e12e wrote:
             | But is this undefined behavior in the typical c sense (lol,
             | I see you call function possibly_undefined() I'll just make
             | you a sandwich and clobber all registers instead) - or
             | undefined behavior in the sense that it should crash - but
             | might return?
        
               | nicoburns wrote:
               | > is this undefined behavior in the typical c sense (lol,
               | I see you call function possibly_undefined() I'll just
               | make you a sandwich and clobber all registers instead)
               | 
               | Yes.
        
               | orra wrote:
               | I'm not sure I'd draw a distinction. People used to say
               | you should initialise your variables in C89 to NULL, so
               | you'd get a crash if you forget to properly set the
               | variable. But enough security bugs have been caused by
               | null pointer dereferences.
               | 
               | In the Rust case, IIRC, Rust annotates functions with the
               | LLVM attribute no_unwind. I'd expect bad things, thanks
               | to optimisation passes, if an unwind were to start.
               | Doubly so if mixing GCC with MSVC ABI.
        
             | e12e wrote:
             | Thank you for that link, I thought (production build) rust
             | panic was simply a core dump. I didn't realize there was
             | stack unwinding going on.
        
               | Tobu wrote:
               | There are two options at the moment [1]:
               | - panic=abort (uncatchable)       - panic=unwind.
               | 
               | With the latter, you would need a catch_unwind at the FFI
               | boundary.
               | 
               | [1] https://doc.rust-
               | lang.org/cargo/reference/profiles.html#pani...
        
               | e12e wrote:
               | I see. I would think that for a library, in production,
               | all you'd want for panic was a crash. (I guess this is
               | the abort case).
               | 
               | AAre the panics being discussed for removal in rust tls
               | "soft" errors that should _not_ crash?
        
         | tialaramex wrote:
         | What does this mean?
         | 
         | > Make it possible to configure server-side connections based
         | on client input.
         | 
         | The other three bullet points I can immediately understand what
         | they're achieving (the "No-panic policy" is trickiest but since
         | I'm learning Rust I knew what that means, and it also links a
         | ticket describing more)
         | 
         | But for this one I haven't a clue, maybe it should be obvious,
         | and somebody else will explain.
        
           | sleevi wrote:
           | Using (defined) properties of the TLS ClientHello to
           | determine how the server will respond.
           | 
           | For example, changing the certificate used based on the ALPN
           | identity, the SNI server host, and the advertised client
           | ciphersuites.
        
         | orra wrote:
         | Rustls depends upon Ring. Ring itself has a lot of code from
         | BoringSSL, an OpenSSL fork.
         | 
         | Long term, is this OK? How do we ensure the assembly and C code
         | in Ring is as safe as Rustls itself?
        
           | dochtman wrote:
           | See my other answer.
        
         | teddyh wrote:
         | RFC 7250 support (Raw Public Keys) is not in the list1 of
         | "Current features", but neither is it listed under "Possible
         | future features" or even "Non-features". GnuTLS supports this
         | feature, so GnuTLS is what I use. What is the status of this
         | feature in Rustls?
         | 
         | EDIT: I found issue #4232, but the reporter is not making a
         | compelling case, since the use case presented is for a
         | prospective new application, yet to be written.
         | 
         | 1. https://github.com/ctz/rustls#current-features
         | 
         | 2. https://github.com/ctz/rustls/issues/423
        
           | dochtman wrote:
           | I don't think the list of possible future features has been
           | kept especially up-to-date -- we should probably fix that (or
           | get rid of the list). If you want to weigh in on that issue
           | to discuss why you think it's a valuable feature to add, that
           | would be great!
        
             | teddyh wrote:
             | I don't have a Github account, so I won't, sorry.
        
               | dochtman wrote:
               | If you reply here, I'm happy to relay your comments to
               | that issue.
        
               | teddyh wrote:
               | My comment is basically "I have a project with components
               | written in C which might benefit from Rust, and would
               | probably also benefit from Rustls. But the project
               | requires RFC 7250 support, which only GnuTLS currently
               | has."
        
         | est31 wrote:
         | Congrats for securing the contract! Looking forward to the IP
         | address stuff especially.
        
       | weinzierl wrote:
       | Rustls is really cool. I came to it because one of my projects
       | used a library that in turn (by default) used OpenSSL. After much
       | tinkering and not getting OpenSSL play well on that particular
       | system I switched to Rustls and it worked out of the box and like
       | a charm.
       | 
       | That being said and from what I understand Rustls is not a drop
       | in replacement and it is not that easy for all Rust libraries
       | which use TLS.
       | 
       | Which brings me to the point that I think a big leap forward for
       | wider Rustls adoption in the Rust world itself would be to make
       | it easily usable with all popular and widely used Rust libraries
       | that depend on a TLS implementation.
       | 
       | What I would like to see is sort of a global (not per dependency)
       | features = ["rustls-tls"]
       | 
       | so that all libraries and their dependencies use Rustls
       | automatically and OpenSSL is completely out of the picture. I
       | know that this is not on Rustls alone but on the library writers
       | too, but still it would be really cool to switch the TLS
       | implementation like that.
       | 
       | Then we could even dream to make Rustls the default and use
       | OpenSSL (or one of its relatives) only if need be.
        
         | swsieber wrote:
         | Many crates do this type of thing. I don't know how hard it
         | would be to isolate this type of thing into its own crate.
        
         | hctaw wrote:
         | I'm really not a fan of having a global TLS knob to turn in all
         | Rust crates... that strikes me as heavy handed and inelegant.
         | Why give a global configuration variable for something used by
         | a tiny portion of crates? And what if a crate is incompatible
         | with rustls? How do you express that with such a global knob in
         | a sane way?
         | 
         | It's the wrong abstraction too - this is handled better by
         | dynamic linkage. Rust just doesn't have a great dynamic library
         | story (a C API/ABI is not exactly what I'm talking about here).
         | 
         | What you'd really want is a                  trait TLS {
         | // ...         }
         | 
         | in some base tls crate and leave the implementation up to other
         | crates. And any upstream dependency would require something
         | like:                  pub fn initialize <T: TLS> (tls:T) { ...
         | }
        
           | richardwhiuk wrote:
           | https://crates.io/crates/native-tls/0.2.7 provides this for
           | native TLS implementations (which is what hyper-tls uses).
           | 
           | It's pretty bare bones though, because to expose things
           | through that, all of the underlying implementations need to
           | support it.
        
         | querez wrote:
         | isn't what you're arguing for essentially to make Rustls (or at
         | least its API) part of a Rust standard library, so that
         | everyone's forced (or very highly encouraged) to use it instead
         | of alternatives?
        
           | e12e wrote:
           | I think that if tcp[1] is in the stdlib, tls probably should
           | be too. Maybe even ssh. I get there was a time when "listen
           | to the network" meant plain text networking - but today, for
           | a large subset of applications and libraries, not supporting
           | tls is a bug.
           | 
           | [1] https://doc.rust-lang.org/std/net/struct.TcpListener.html
        
             | ChrisSD wrote:
             | Implementing crypto is much much harder than simply
             | providing abstractions over the OS' TCP/UDP APIs.
             | 
             | Far better to let the experts do it.
        
               | e12e wrote:
               | That's not really an argument _against_ having it in
               | stdlib, though?
        
               | ChrisSD wrote:
               | It's much simpler to develop complex libraries outside of
               | the stdlib. And given Rust's strong stability guarantees,
               | it can't stabilize any APIs until they're finalized
               | anyway. So development of new APIs often happens outside
               | the stdlib and then if a third party library proves
               | itself and can commit to a completely stable API then it
               | might be uplifted into the stdlib, so long as there's a
               | very strong case to do so.
               | 
               | I should also add that most applications won't even be
               | using the TCP/UDP primitives directly. They'll likely be
               | using a third party library. Rust's stdlib is
               | intentionally minimal and lacking a lot of higher level
               | features that are practically necessary for many
               | applications.
        
             | baby wrote:
             | Tls is part of Golang's stdlib
        
           | est31 wrote:
           | Not suggesting it should be done, but note that Go does right
           | this _exactly this_. They also have world class crypto people
           | on the language team.
        
             | hctaw wrote:
             | Go has to do this because they include https in the
             | standard library. Rust defers that task to the ecosystem,
             | so it doesn't have the same requirements.
        
             | richardwhiuk wrote:
             | In what sense does Go do this right?
        
               | est31 wrote:
               | It does _right this_ not, _this right_. It 's accessible
               | to every go program: https://golang.org/pkg/crypto/tls/
        
               | pitaj wrote:
               | I've never heard someone use _right this_ , is that
               | similar to _exactly this_ or _just this_?
        
               | richardwhiuk wrote:
               | Yeah, I'd expect that to be phrased as "does this" - the
               | right seems utterly superfluous at best, and very
               | misleading.
               | 
               | "Right this minute" is a common phrase, but "does right
               | this" isn't (at least in UK English).
        
               | est31 wrote:
               | Hmm seems you are right. I guess it's a german-ism that
               | slipped into my english. The english analog to "macht
               | genau das" is either "does exactly that" or "does just
               | that". The literal translation I used "does right this"
               | seems to have no use. So my bad, I'm sorry.
        
               | richardwhiuk wrote:
               | No problem :)
        
             | [deleted]
        
       | est31 wrote:
       | Back when rustls was initially announced, people criticized how
       | few ciphersuites it supported, like only TLS1.3 and parts of TLS
       | 1.2. Not sure, I might have been among them. And it still doesn't
       | support TLS 1.1 or TLS 1.0. But since then, browsers have dropped
       | support for many of those ciphersuites, so it's far less
       | interesting to implement support for them at this point.
        
         | maeln wrote:
         | It can be useful if you need to work with legacy system that
         | only support old cipher and protocol. But then I guess there is
         | always openssl and co who still do the job.
        
           | Animats wrote:
           | I had to struggle with this recently. I have to deal with
           | something that uses a root cert generated in 2005, valid to
           | 2025, and signed with 1024-bit RSA. Rustls silently ignores
           | this root cert. I can add it to the root cert store with no
           | complaints, but it will not be used.
           | 
           | One problem with Rustls is that the error messages are not
           | very informative. The situation described above just
           | generated an "Invalid certificate" message. More use of
           | anyhow::Context would be helpful. I don't disagree with
           | Rustls disallowing decade-obsolete crypto. It's the "silently
           | ignores" part that's a problem.
        
       | senkora wrote:
       | How does this compare to the verified TLS implementation from
       | Project Everest?
       | 
       | https://project-everest.github.io/
       | 
       | https://mitls.org/
        
         | CameronNemo wrote:
         | From a layman's perspective:
         | 
         | 1. The EverCrypt primitives are formally proven, whereas ring
         | has no such formal proofs. Also it seems that all the EverCrypt
         | primitives have portable (non-assembly) fallbacks, while ring
         | has several primitives that are assembly only and have no
         | portable fallback.
         | 
         | 2. MiTLS is written in F#, which is harder to integrate with
         | other languages than Rust.
        
           | JoshTriplett wrote:
           | > Also it seems that all the EverCrypt primitives have
           | portable (non-assembly) fallbacks, while ring has several
           | primitives that are assembly only and have no portable
           | fallback.
           | 
           | Ring uses assembly to make sure it can do constant-time
           | operations, to avoid leaking information through computation
           | time. What does EverCrypt use for constant-time operations?
        
             | SAI_Peregrinus wrote:
             | This is an important point. The C standard does not define
             | the time it takes for an operation to complete as
             | "observable behavior", so compilers are *always* free to
             | change timings, even with optimization disabled. It is
             | fundamentally impossible to guarantee constant-time
             | execution in Standard portable C. It's possible to use non-
             | standard intrinsics and compiler directives to get such a
             | guarantee, but that's not portable.
             | 
             | AFAIK Rust also doesn't guarantee timing. That's part of
             | why Ring uses assembly for the constant-time bits (really
             | Ring uses code from BoringSSL for that, and BoringSSL uses
             | assembly for that reason and for performance.)
        
               | CodesInChaos wrote:
               | I don't think Intel/AMD make any guarantees about
               | instructions being constant time either.
        
               | SAI_Peregrinus wrote:
               | Correct, and don't provide any guarantees about
               | electromagnetic side channel emissions or power side
               | channels or...
               | 
               | The lack of a guarantee in assembly is less of a concern
               | than the lack of a guarantee in C, since the CPU behavior
               | is less likely to change unexpectedly than a C compiler.
               | 
               | Though Intel at least does provide a list of instruction
               | latencies and throughputs, in their "Intel 64 and IA-32
               | Architectures Optimization Reference Manual"[1].
               | 
               | [1] https://www.intel.com/content/dam/www/public/us/en/do
               | cuments...
        
               | steveklabnik wrote:
               | It doesn't seem to stop people from trying though:
               | https://www.bearssl.org/constanttime.html
               | 
               | (This sort of thing is _not_ my area of expertise, but
               | has always made me uneasy...)
        
               | SAI_Peregrinus wrote:
               | Yeah. That sort of thing works, right up until some
               | compiler gets released that optimizes it out. It's
               | "portable C", but the behavior it's trying to produce is
               | non-portable.
               | 
               | Especially note his guideline to look at the assembly
               | output. The best guarantee is to simply check that the
               | compiler did what you wanted.
               | 
               | There are also some aspects that a compiler is unlikely
               | to alter. EG if you write code with no secret-dependent
               | branches, no normal compiler will insert any secret-
               | dependent branches during optimization. It's generally
               | safe to rely on the compiler not being actively malicious
               | or de-optimizing code.
        
               | nwmcsween wrote:
               | This is only possible with resource aware types, it would
               | be nice to import a function with resource constraints
               | such as constant time, etc.
        
               | JoshTriplett wrote:
               | Rust doesn't guarantee timing, but there are crates that
               | carefully construct constant-time primitives that should
               | work with current Rust, such as
               | https://crates.io/crates/subtle-ng .
               | 
               | Personally, I would love to see enhancements to Rust and
               | LLVM that would make it possible to provide such
               | guarantees in pure Rust.
        
             | baby wrote:
             | And assembly makes the code harder to audit:
             | https://cryptologie.net/article/520/cryptography-and-
             | assembl...
        
               | dathinab wrote:
               | But assembly is unavoidable.
               | 
               | for the guaranteeing const execution time aspects. More
               | or less any language compiled by LLVM, GCC or similar
               | optimizing compilers can't do so. (And even wrt. assembly
               | the cpus could do optimizations which also brake this but
               | it's less likely).
               | 
               | Same is true for any language using a JIT with
               | optimizations like e.g. Java, JavaScript, C#, etc.
               | 
               | Practically the degree of how much compilers could mess
               | up const execution time guarantes is language dependent
               | but for many languages especially including such using
               | compilers created for C/C++ basically you have no useful
               | guarantees.
               | 
               | At best you can create some code which just with the
               | current version happen to not be optimized in a bad way.
               | But this means you will have to review the produced
               | assemply code and do it again and again every time the
               | compiler (or just surrounding code) changes... To make it
               | worse the high level code is force to use all kind of
               | tricks to prevent the compiler from doing certain
               | optimizations, which often obfuscate the intent of the
               | code.
               | 
               | So all in all having a small very well reviewed set of
               | assembly snippets for the core primitives the the easier
               | to review and more reliable way in many cases. (Note that
               | "a small set" means that just a few primitives are
               | assembly only, not all the crypto, which normally is good
               | enough).
               | 
               | Through best would be to have some language which focuses
               | on both making it reasonable to implement such primitives
               | in a more high level language and has tooling for proving
               | code correctness and also code-to-assembly transformation
               | correctness (e.g. see what SeL4 did wrt. proving
               | assembly).
        
           | [deleted]
        
           | fulafel wrote:
           | Doesn't .net have pretty good C FFI support, what would make
           | it harder than a Rust lib?
        
           | briansmith wrote:
           | > The EverCrypt primitives are formally proven, whereas ring
           | has no such formal proofs.
           | 
           | We do use some of the Fiat Crypto stuff for elliptic curve
           | computations. I am not opposed to switching some stuff to use
           | EverCrypt or other things that might be better, as long as
           | the performance is the same or better, and as long as there's
           | a clear path towards that code being in Rust.
           | 
           | > ring has several primitives that are assembly only and have
           | no portable fallback.
           | 
           | Either in the latest release (0.16.20) or the upcoming
           | release, there is a portable non-assembly implementation of
           | everything in _ring_.
        
             | CameronNemo wrote:
             | Thanks for the correction!
        
       | Vogtinator wrote:
       | Does it allow building as a completely shared library? If not,
       | everything using it will have to be rebuilt from scratch on each
       | update, which is highly annoying and a security issue on its own
       | IMO. Apparently it has a Rust API, so it's probably unlikely.
        
         | baby wrote:
         | It's rust
        
       | orra wrote:
       | It took me a minute to work out who 'a better internet' aka ISRG
       | are. It's the folk behind Let's Encrypt. That's cool.
       | 
       | Anyway, this sounds great to me. I'm not a huge fan of memory
       | unsafe languages, especially for critical code.
        
       ___________________________________________________________________
       (page generated 2021-04-20 23:00 UTC)