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

[question] What is the impact of leaking the memory contents to swap? #331

Closed
cipriancraciun opened this issue Nov 14, 2021 · 4 comments
Closed

Comments

@cipriancraciun
Copy link

(This question applies both to scrypt enc / scrypt dec utility, but also to the scrypt algorithm.)

I've made a small experiment with strace and I've seen that scrypt enc does not use mlock to lock its memory into RAM and not risk spilling it to swap.

Therefore I wanted to ask:

  • is scrypt enc using another protection to prevent swap leakage, especially for the password and derived key?
  • (this applies mostly to scrypt algorithm) what is the impact (in terms of password guessing) if the "temporary derivation memory" (i.e. the one governed by the N parameter) is leaked to (unencrypted) swap and then recovered by an attacker, can he use that to deduce the password?
@cperciva
Copy link
Member

Locking memory regions is never going to be guaranteed to help you, just like how zeroing buffers isn't guaranteed to do anything useful -- the compiler (and system libraries, and kernel...) are allowed to make additional copies of data, so even if a copy is locked in RAM it doesn't guarantee that the only copy is locked in RAM. On systems which support it, scrypt uses MAP_NOCORE (which prevents data from spilling into core dumps) but that's not for security purposes -- it's just a matter of convenience to avoid writing out useless data.

If values from scrypt's buffer get leaked, an attacker can use them to break scrypt with the same amount of effort as PBKDF2-salsa20 with an iteration count depending on which part of the buffer is leaked.

@cipriancraciun
Copy link
Author

Locking memory regions is never going to be guaranteed to help you, just like how zeroing buffers isn't guaranteed to do anything useful -- the compiler (and system libraries, and kernel...) are allowed to make additional copies of data, so even if a copy is locked in RAM it doesn't guarantee that the only copy is locked in RAM.

Indeed there aren't any "guarantees", however I doubt that at least C makes copies of large buffers (especially malloc-ed ones).

However, at least on Linux, there is mlockall that at least according to the documentation, by using MCL_CURRENT | MCL_FUTURE (and perhaps even an | MCL_FUTURE) will keep the entire process off the swap, thus it doesn't matter what the compiler does.

Although granted, the current ulimit for locked memory is by default 64 KiB, way less than one would require for scrypt (or any other executable nowdays).

But, at least when running scrypt as root, it might be useful to have an extra argument (say --memlock) that tries to increase that limit, call mlockall (and exit verbosely if any of them fails); this would be useful when using scrypt with important "secrets" (like for example full-disk-encryption keys). Although again granted, the kernel might leak the pipe memory to swap, but that is less likely.


If values from scrypt's buffer get leaked, an attacker can use them to break scrypt with the same amount of effort as PBKDF2-salsa20 with an iteration count depending on which part of the buffer is leaked.

I am not quite that versed in cryptography (at least the theory behind it) to grasp what the statement above implies.

So assume that I use scrypt with such parameters (say N) that requires 1 GiB, and say the OS leaks 25% of that to swap (contiguous or not, assume the worst case scenario) just before (or after) the last iteration (I assume this is the worst case), and the attacker gets its hands on it (say it knows exactly what parts of that buffer it obtained).

Now assuming that I've asked scrypt to generate a 256 bit key, what would be the effort for the attacker to obtain that key (knowing the leaked buffer in swap) as compared to a brute force.

Or, put otherwise, how "serious" in laymen terms is swap leakage of a scrypt's execution memory?

@cperciva
Copy link
Member

Any leak of 32 bytes of data (or more generally, more data than there is entropy in the passphrase used) from scrypt's buffer will dramatically reduce the cost of cracking the passphrase.

"Dramatically" in this case (and my earlier comment about PBKDF2-salsa20) means roughly "you need approximately the same amount of CPU time but you only need a small amount of memory", or alternatively "you can crack it efficiently using GPUs or ASICs" (which have lots of CPU but relatively little RAM).

@cipriancraciun
Copy link
Author

cipriancraciun commented Mar 13, 2022

Thanks for the answer! I'm closing this issue, because the question was answered.


I'll try to summarize your previous reply for those non-cryptographically inclined (please correct me if I'm wrong).

Assuming that "normal" passwords don't even have 128 bits of entropy, basically if one leaks even 16 bytes of the temporary memory used by scrypt, then, at least theoretically, the attacker can use traditional methods to brute force the original password.

As such, password complexity is still important, even when using scrypt.


To put things into perspective, if such a memory leak happens, I normally use 16 character passwords of the form "consonant-vowel consonant-vowel ...", which yields a almost 54 bits of entropy, and assuming one can try around 25 billion passwords per second (an article from 2012, https://securityledger.com/2012/12/new-25-gpu-monster-devours-passwords-in-seconds/, claims ~20 billion SHA1, so I assume things have improved since then), then a password such as mine could, at least theoretically, be brute forced in under 5 days even with a "modest" hardware.

Again, in this paragraph I'm not speaking about brute forcing scrypt, but about how important is password complexity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants