Package: python-cryptography / 1.7.1-3~bpo8+1

0001-add-memory-limit-check-for-scrypt.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
From ced38e7dcb84cd11039fe6b7c078593c2a4968ff Mon Sep 17 00:00:00 2001
From: Paul Kehrer <paul.l.kehrer@gmail.com>
Date: Sun, 18 Dec 2016 18:36:05 -0600
Subject: add memory limit check for scrypt

fixes #3323
---
 src/cryptography/hazmat/backends/openssl/backend.py |  8 +++++---
 tests/hazmat/primitives/test_scrypt.py              | 19 +++++++++++++++++++
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 71063c1..9e101a3 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -143,6 +143,7 @@ class Backend(object):
         self._cipher_registry = {}
         self._register_default_ciphers()
         self.activate_osrandom_engine()
+        self._scrypt_mem_limit = sys.maxsize // 2
 
     def openssl_assert(self, ok):
         return binding._openssl_assert(self._lib, ok)
@@ -1894,9 +1895,10 @@ class Backend(object):
 
     def derive_scrypt(self, key_material, salt, length, n, r, p):
         buf = self._ffi.new("unsigned char[]", length)
-        res = self._lib.EVP_PBE_scrypt(key_material, len(key_material), salt,
-                                       len(salt), n, r, p, sys.maxsize // 2,
-                                       buf, length)
+        res = self._lib.EVP_PBE_scrypt(
+            key_material, len(key_material), salt, len(salt), n, r, p,
+            self._scrypt_mem_limit, buf, length
+        )
         self.openssl_assert(res == 1)
         return self._ffi.buffer(buf)[:]
 
diff --git a/tests/hazmat/primitives/test_scrypt.py b/tests/hazmat/primitives/test_scrypt.py
index 49b304e..450eb82 100644
--- a/tests/hazmat/primitives/test_scrypt.py
+++ b/tests/hazmat/primitives/test_scrypt.py
@@ -22,10 +22,28 @@ vectors = load_vectors_from_file(
     os.path.join("KDF", "scrypt.txt"), load_nist_vectors)
 
 
+def _skip_if_memory_limited(memory_limit, params):
+    # Memory calc adapted from OpenSSL (URL split over 2 lines, thanks PEP8)
+    # https://github.com/openssl/openssl/blob/6286757141a8c6e14d647ec733634a
+    # e0c83d9887/crypto/evp/scrypt.c#L189-L221
+    blen = int(params["p"]) * 128 * int(params["r"])
+    vlen = 32 * int(params["r"]) * (int(params["n"]) + 2) * 4
+    memory_required = blen + vlen
+    if memory_limit < memory_required:
+        pytest.skip("Test exceeds Scrypt memory limit. "
+                    "This is likely a 32-bit platform.")
+
+
+def test_memory_limit_skip():
+    with pytest.raises(pytest.skip.Exception):
+        _skip_if_memory_limited(1000, {"p": 16, "r": 64, "n": 1024})
+
+
 @pytest.mark.requires_backend_interface(interface=ScryptBackend)
 class TestScrypt(object):
     @pytest.mark.parametrize("params", vectors)
     def test_derive(self, backend, params):
+        _skip_if_memory_limited(backend._scrypt_mem_limit, params)
         password = params["password"]
         work_factor = int(params["n"])
         block_size = int(params["r"])
@@ -77,6 +95,7 @@ class TestScrypt(object):
 
     @pytest.mark.parametrize("params", vectors)
     def test_verify(self, backend, params):
+        _skip_if_memory_limited(backend._scrypt_mem_limit, params)
         password = params["password"]
         work_factor = int(params["n"])
         block_size = int(params["r"])