Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keeping Secrets in Rust #2533

Open
arielb1 opened this issue Aug 27, 2018 · 14 comments
Open

Keeping Secrets in Rust #2533

arielb1 opened this issue Aug 27, 2018 · 14 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC.

Comments

@arielb1
Copy link
Contributor

arielb1 commented Aug 27, 2018

Keeping secrets in Rust

In cryptographic code, it is important to keep some values secret and prevent attackers from knowing them.

Rust, as most programming languages, makes no guarantees about this - it only specifies the behavior of programs, not what an attacker can figure out about them. Because of that, compilers are allowed to optimize code in ways that leak secrets.

There are basically 2 kinds of secrecy we care about:

Side-Channel Security

Side-Channel Security is about preventing attackers from observing secret data through side-channels (for example, timing, cache effects, etc.).

Compilation to a concrete machine can introduce side-channels. For example, most common CPUs don't treat control flow as a secret, and leak it into the timing of operations, and the timing of other operations executing on the machine, in a fairly complex and hard-to-control but possible-to-observe way. (If this was a paper, I would cite 4 separate attacks here).

Because of that, a compiler that introduces a branch on a secret value would leak that secret into control-flow, and therefore, potentially to an attacker.

As any leak of secret data can lead to an attack, it is important to have a way of writing code that will not leak secrets through such channels.

XXX: come up with good examples of miscompilations here.

Forward Secrecy

Machines (and VMs, and processes, etc.) are sometimes completely compromised by attackers. While it would seem that after a machine is compromised, everything that machine ever touched is necessarily lost, that is in fact only necessarily true for things the machine currently touches.

Many impportant sessions are short-lived. For example, in TLS, the session key that is actually used to encrypt traffic only lives as long as a socket. Therefore, if we erase the session key after the socket is closed, an attacker who had compromised our machine can't use the key to decrypt yesterday's traffic. If the compromise is detected and rectified quickly, the attacker can only decrypt a small amount of data.

However, if we want to erase something, we need to erase it in a way that prevents an attacker who had compromised the machine from recovering it. For example, if temporary copies of the erased data are presesnt somewhere in memory, an attacker can use them.

Therefore, we need a scheme to erase everything derived from secret data.

Links to older discussions

@arielb1 arielb1 changed the title Keeping secrets in Rust Keeping Secrets in Rust Aug 27, 2018
@arielb1
Copy link
Contributor Author

arielb1 commented Aug 27, 2018

Because LLVM does not have any model of data secrecy, much of the work here would have to be done in LLVM. That's not a reason not to have a vision of the way it integrates with Rust before we commit to something.

@arielb1
Copy link
Contributor Author

arielb1 commented Aug 27, 2018

cc @gnzlbg @hdevalence

@burdges
Copy link

burdges commented Aug 28, 2018

I closed the zero stack thread because we want to be able to zero the stack space we actually use in sensitive code.

@est31
Copy link
Member

est31 commented Aug 28, 2018

I've heard someone state that it's also possible to ask the OS to allocate memory as non-swappable. If secrets get swapped to disk, you might be able to read them later on.

This is entirely doable outside of LLVM, you just need the right syscalls.

@arielb1
Copy link
Contributor Author

arielb1 commented Aug 29, 2018

@est31

I think that today swap is fairly uncommon, but if you want to avoid it there's flockmlock.

@burdges

That thread claims that

If all functions zero their own data, then we zero needlessly anytime a loop repeatedly calls the same functions, as always happens in cryptography.

Is there any analysis of that claim with a concrete slowdown? There's a link to a pdf in the issue, but it's dead.

@est31
Copy link
Member

est31 commented Aug 29, 2018

@arielb1 some people still recommend swap in order to free memory for caching files.

@cdown
Copy link

cdown commented Aug 29, 2018

I think that today swap is fairly uncommon

This isn't generally true at most reasonably sized companies where resource efficiency is needed. See https://chrisdown.name/2018/01/02/in-defence-of-swap.html as an example of why we still use it, for example.

@burdges
Copy link

burdges commented Aug 30, 2018

I think the high level points should be mentioned in this talk: https://www.youtube.com/watch?v=cQ9wTyYCdNU

I'm not sure in what journal articles he makes those claims though.

@arielb1
Copy link
Contributor Author

arielb1 commented Aug 31, 2018

This isn't generally true at most reasonably sized companies where resource efficiency is needed.

Reading your github, are you talking about a linux server context, where a significant amount of memory is bound in pages that are not used except for initialization?

@cdown
Copy link

cdown commented Aug 31, 2018

Reading your github, are you talking about a linux server context, where a significant amount of memory is bound in pages that are not used except for initialization?

I'll avoid getting into a swap-based side discussion on this task, but that's one of many benefits of swap rather than being the only one. This applies both in a server and desktop context.

@arielb1
Copy link
Contributor Author

arielb1 commented Aug 31, 2018

I'll avoid getting into a swap-based side discussion on this task, but that's one of many benefits of swap rather than being the only one. This applies both in a server and desktop context.

Sure. It's just that on many uses of Linux, having no swap and asserting that there is no swap is a non-terrible, and operationally easy, way of handling the swap+secret problem.

@Centril Centril added T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC. labels Oct 14, 2018
@joshtriplett
Copy link
Member

@arielb1 Agreed. I'd love to see this, but we'd need some hope of a code-generation backend, too.

@hdevalence
Copy link

I'm not sure that the properties desired are possible for Rust to achieve, as they are not properties of the source or generated code, but of the combined software-hardware system executing the software.

@gnzlbg
Copy link
Contributor

gnzlbg commented Aug 1, 2019

@hdevalence Whether they are possible to achieve is definitely target dependent, e.g., if the hardware makes them impossible to achieve, then there is nothing we can do about that from Rust. But if some hardware could support them, and we are able to formulate them as properties of the Rust abstract machine and make sure that all optimizations and code generation respects them, then a Rust program running on that hardware could have those properties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

8 participants