-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Scrypt Implementation #3117
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
Scrypt Implementation #3117
Conversation
def derive_scrypt(self, key_material, salt, length, N, r, p): | ||
for b in self._filtered_backends(ScryptBackend): | ||
return b.derive_scrypt(key_material, salt, length, N, r, p) | ||
Raise UnsupportedAlgorithm("This backend does not support scrypt.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've got yourself a SyntaxError here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. :)
I think you can skip the |
@alex Hmm, fair idea. I'll give that a shot. |
@reaperhulk, @alex I need some API advice on this. So, What do you think we should pass in to |
It looks like if SCRYPT_MAX_MEM is set to zero during compile then it defines it to |
@reaperhulk What I don't like about that is that it breaks expectations if the user compiles OpenSSL with that particular option enabled. After some hours of deliberation, my thoughts will be to handle that error gracefully (which we'd need to do anyway), and have our CI compile OpenSSL with |
|
||
# If the backend has support for Scrypt, dynamically register the backend and | ||
# implement the interface. | ||
def _derive_scrypt(self, key_material, salt, length, n, r, p): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should just be on the class normally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this break if the user uses the OpenSSL backend directly instead of going through default_backend()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because https://github.com/pyca/cryptography/pull/3117/files#diff-2b076058f22fe576413155fbf8ebafbdR19 will catch it if ScryptBackend
is not registered so even though the method is present it won't be called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
D'oh. Right. :)
Users are going to use whatever the default of their distro is in 99.9% of cases. If that number is low enough to cause failures when setting scrypt variables that's problematic...and 32MB is not a particularly huge number. We definitely should handle the error gracefully, but I'm 👎 on anything that requires a custom compile flag to make our tests pass. |
On the contrary I'd say that in practice almost no one is going to be using such high memory settings in production because that is 32MB every time you derive a key with Scrypt and very little systems can support that with any kind of practical load. |
On a system with 64GB of RAM that's 1/2000th of available memory, and 64GB is not hard to come by. That said, maybe you can convince me that "large enough to pass the test vectors" is a good starting point and then we can change it in the future if users complain. |
Ultimately ram usage is controlled by the 3 parameters scrypt takes, so if people want it to use less RAM they should change those. I have no problem setting max memory to |
# implement the interface. | ||
def _derive_scrypt(self, key_material, salt, length, n, r, p): | ||
buf = self._ffi.new("unsigned char[]", length) | ||
self._lib.EVP_PBE_scrypt(key_material, len(key_material), salt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to check the return value here.
(Will also need docs and a changelog entry) |
Looks like there's a small pep8 issue to clear up too :) |
from tests.utils import load_nist_vectors, load_vectors_from_file | ||
|
||
vectors = load_vectors_from_file( | ||
"KDF/scrypt.txt", load_nist_vectors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be os.path.join("KDF", "scrypt.txt")
|
:param int r: Block size parameter. | ||
:param int p: Parallelization parameter. | ||
:param backend: An instance of | ||
:class:`~cryptography.hazmat.backends.interfaces.ScryptBackend`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't documented, that's why the tests are failing.
Working on a better description for N, r and p now. Will push it up when I'm done. |
Alright, I hope that explanation makes sense to people as much as it does in my head. Suggestions welcomed. :) |
Conflicts: CHANGELOG.rst
@alex @reaperhulk ping |
.. _`key stretching`: https://en.wikipedia.org/wiki/Key_stretching | ||
.. _`HKDF`: https://en.wikipedia.org/wiki/HKDF | ||
.. _`HKDF paper`: https://eprint.iacr.org/2010/264 | ||
.. _`RFC 7914`: https://tools.ietf.org/html/rfc7914 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This link is not required now that you're using the :rfc:
setup.
Time for one quick question in ignorance: We have an |
I think it should for consistency sake. Added. |
Anybody remember why we added AlreadyFinalized as an exception? |
Because salt is in the constructor and we don't want to make it easy to On Thu, Sep 1, 2016 at 8:39 AM, Paul Kehrer notifications@github.com
"I disapprove of what you say, but I will defend to the death your right to |
Definitely not ready for reviews yet!