summaryrefslogtreecommitdiffstats
path: root/module/lib/beaker/crypto/pbkdf2.py
diff options
context:
space:
mode:
Diffstat (limited to 'module/lib/beaker/crypto/pbkdf2.py')
-rw-r--r--module/lib/beaker/crypto/pbkdf2.py42
1 files changed, 21 insertions, 21 deletions
diff --git a/module/lib/beaker/crypto/pbkdf2.py b/module/lib/beaker/crypto/pbkdf2.py
index 5f40a5c78..96dc5fbb2 100644
--- a/module/lib/beaker/crypto/pbkdf2.py
+++ b/module/lib/beaker/crypto/pbkdf2.py
@@ -78,8 +78,8 @@ def strxor(a, b):
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b)])
class PBKDF2(object):
- """PBKDF2.py: PKCS#5 v2.0 Password-Based Key Derivation
-
+ """PBKDF2.py : PKCS#5 v2.0 Password-Based Key Derivation
+
This implementation takes a passphrase and a salt (and optionally an
iteration count, a digest module, and a MAC module) and provides a
file-like object from which an arbitrarily-sized key can be read.
@@ -89,10 +89,10 @@ class PBKDF2(object):
The idea behind PBKDF2 is to derive a cryptographic key from a
passphrase and a salt.
-
+
PBKDF2 may also be used as a strong salted password hash. The
'crypt' function is provided for that purpose.
-
+
Remember: Keys generated using PBKDF2 are only as strong as the
passphrases they are derived from.
"""
@@ -109,7 +109,7 @@ class PBKDF2(object):
"""Pseudorandom function. e.g. HMAC-SHA1"""
return self.__macmodule(key=key, msg=msg,
digestmod=self.__digestmodule).digest()
-
+
def read(self, bytes):
"""Read the specified number of key bytes."""
if self.closed:
@@ -131,7 +131,7 @@ class PBKDF2(object):
self.__buf = buf[bytes:]
self.__blockNum = i
return retval
-
+
def __f(self, i):
# i must fit within 32 bits
assert (1 <= i <= 0xffffffff)
@@ -141,7 +141,7 @@ class PBKDF2(object):
U = self.__prf(self.__passphrase, U)
result = strxor(result, U)
return result
-
+
def hexread(self, octets):
"""Read the specified number of octets. Return them as hexadecimal.
@@ -151,7 +151,7 @@ class PBKDF2(object):
def _setup(self, passphrase, salt, iterations, prf):
# Sanity checks:
-
+
# passphrase and salt must be str or unicode (in the latter
# case, we convert to UTF-8)
if isinstance(passphrase, unicode):
@@ -168,7 +168,7 @@ class PBKDF2(object):
raise TypeError("iterations must be an integer")
if iterations < 1:
raise ValueError("iterations must be at least 1")
-
+
# prf must be callable
if not callable(prf):
raise TypeError("prf must be callable")
@@ -180,7 +180,7 @@ class PBKDF2(object):
self.__blockNum = 0
self.__buf = ""
self.closed = False
-
+
def close(self):
"""Close the stream."""
if not self.closed:
@@ -194,13 +194,13 @@ class PBKDF2(object):
def crypt(word, salt=None, iterations=None):
"""PBKDF2-based unix crypt(3) replacement.
-
+
The number of iterations specified in the salt overrides the 'iterations'
parameter.
The effective hash length is 192 bits.
"""
-
+
# Generate a (pseudo-)random salt if the user hasn't provided one.
if salt is None:
salt = _makesalt()
@@ -229,7 +229,7 @@ def crypt(word, salt=None, iterations=None):
iterations = converted
if not (iterations >= 1):
raise ValueError("Invalid salt")
-
+
# Make sure the salt matches the allowed character set
allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"
for ch in salt:
@@ -251,7 +251,7 @@ PBKDF2.crypt = staticmethod(crypt)
def _makesalt():
"""Return a 48-bit pseudorandom salt for crypt().
-
+
This function is not suitable for generating cryptographic secrets.
"""
binarysalt = "".join([pack("@H", randint(0, 0xffff)) for i in range(3)])
@@ -260,7 +260,7 @@ def _makesalt():
def test_pbkdf2():
"""Module self-test"""
from binascii import a2b_hex
-
+
#
# Test vectors from RFC 3962
#
@@ -284,18 +284,18 @@ def test_pbkdf2():
"c5ec59f1a452f5cc9ad940fea0598ed1")
if result != expected:
raise RuntimeError("self-test failed")
-
+
# Test 4
result = PBKDF2("X"*65, "pass phrase exceeds block size", 1200).hexread(32)
expected = ("9ccad6d468770cd51b10e6a68721be61"
"1a8b4d282601db3b36be9246915ec82a")
if result != expected:
raise RuntimeError("self-test failed")
-
+
#
# Other test vectors
#
-
+
# Chunked read
f = PBKDF2("kickstart", "workbench", 256)
result = f.read(17)
@@ -306,7 +306,7 @@ def test_pbkdf2():
expected = PBKDF2("kickstart", "workbench", 256).read(40)
if result != expected:
raise RuntimeError("self-test failed")
-
+
#
# crypt() test vectors
#
@@ -316,7 +316,7 @@ def test_pbkdf2():
expected = '$p5k2$$exec$r1EWMCMk7Rlv3L/RNcFXviDefYa0hlql'
if result != expected:
raise RuntimeError("self-test failed")
-
+
# crypt 2
result = crypt("gnu", '$p5k2$c$u9HvcT4d$.....')
expected = '$p5k2$c$u9HvcT4d$Sd1gwSVCLZYAuqZ25piRnbBEoAesaa/g'
@@ -328,7 +328,7 @@ def test_pbkdf2():
expected = "$p5k2$d$tUsch7fU$nqDkaxMDOFBeJsTSfABsyn.PYUXilHwL"
if result != expected:
raise RuntimeError("self-test failed")
-
+
# crypt 4 (unicode)
result = crypt(u'\u0399\u03c9\u03b1\u03bd\u03bd\u03b7\u03c2',
'$p5k2$$KosHgqNo$9mjN8gqjt02hDoP0c2J0ABtLIwtot8cQ')