• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#.  Copyright (C) 2005-2010   Gregory P. Smith (greg@krypto.org)
2#  Licensed to PSF under a Contributor Agreement.
3#
4
5__doc__ = """hashlib module - A common interface to many hash functions.
6
7new(name, data=b'', **kwargs) - returns a new hash object implementing the
8                                given hash function; initializing the hash
9                                using the given binary data.
10
11Named constructor functions are also available, these are faster
12than using new(name):
13
14md5(), sha1(), sha224(), sha256(), sha384(), sha512(), blake2b(), blake2s(),
15sha3_224, sha3_256, sha3_384, sha3_512, shake_128, and shake_256.
16
17More algorithms may be available on your platform but the above are guaranteed
18to exist.  See the algorithms_guaranteed and algorithms_available attributes
19to find out what algorithm names can be passed to new().
20
21NOTE: If you want the adler32 or crc32 hash functions they are available in
22the zlib module.
23
24Choose your hash function wisely.  Some have known collision weaknesses.
25sha384 and sha512 will be slow on 32 bit platforms.
26
27Hash objects have these methods:
28 - update(data): Update the hash object with the bytes in data. Repeated calls
29                 are equivalent to a single call with the concatenation of all
30                 the arguments.
31 - digest():     Return the digest of the bytes passed to the update() method
32                 so far as a bytes object.
33 - hexdigest():  Like digest() except the digest is returned as a string
34                 of double length, containing only hexadecimal digits.
35 - copy():       Return a copy (clone) of the hash object. This can be used to
36                 efficiently compute the digests of datas that share a common
37                 initial substring.
38
39For example, to obtain the digest of the byte string 'Nobody inspects the
40spammish repetition':
41
42    >>> import hashlib
43    >>> m = hashlib.md5()
44    >>> m.update(b"Nobody inspects")
45    >>> m.update(b" the spammish repetition")
46    >>> m.digest()
47    b'\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9'
48
49More condensed:
50
51    >>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
52    'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
53
54"""
55
56# This tuple and __get_builtin_constructor() must be modified if a new
57# always available algorithm is added.
58__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
59                      'blake2b', 'blake2s',
60                      'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
61                      'shake_128', 'shake_256')
62
63
64algorithms_guaranteed = set(__always_supported)
65algorithms_available = set(__always_supported)
66
67__all__ = __always_supported + ('new', 'algorithms_guaranteed',
68                                'algorithms_available', 'pbkdf2_hmac')
69
70
71__builtin_constructor_cache = {}
72
73__block_openssl_constructor = {
74    'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
75    'shake_128', 'shake_256',
76    'blake2b', 'blake2s',
77}
78
79def __get_builtin_constructor(name):
80    cache = __builtin_constructor_cache
81    constructor = cache.get(name)
82    if constructor is not None:
83        return constructor
84    try:
85        if name in {'SHA1', 'sha1'}:
86            import _sha1
87            cache['SHA1'] = cache['sha1'] = _sha1.sha1
88        elif name in {'MD5', 'md5'}:
89            import _md5
90            cache['MD5'] = cache['md5'] = _md5.md5
91        elif name in {'SHA256', 'sha256', 'SHA224', 'sha224'}:
92            import _sha256
93            cache['SHA224'] = cache['sha224'] = _sha256.sha224
94            cache['SHA256'] = cache['sha256'] = _sha256.sha256
95        elif name in {'SHA512', 'sha512', 'SHA384', 'sha384'}:
96            import _sha512
97            cache['SHA384'] = cache['sha384'] = _sha512.sha384
98            cache['SHA512'] = cache['sha512'] = _sha512.sha512
99        elif name in {'blake2b', 'blake2s'}:
100            import _blake2
101            cache['blake2b'] = _blake2.blake2b
102            cache['blake2s'] = _blake2.blake2s
103        elif name in {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512'}:
104            import _sha3
105            cache['sha3_224'] = _sha3.sha3_224
106            cache['sha3_256'] = _sha3.sha3_256
107            cache['sha3_384'] = _sha3.sha3_384
108            cache['sha3_512'] = _sha3.sha3_512
109        elif name in {'shake_128', 'shake_256'}:
110            import _sha3
111            cache['shake_128'] = _sha3.shake_128
112            cache['shake_256'] = _sha3.shake_256
113    except ImportError:
114        pass  # no extension module, this hash is unsupported.
115
116    constructor = cache.get(name)
117    if constructor is not None:
118        return constructor
119
120    raise ValueError('unsupported hash type ' + name)
121
122
123def __get_openssl_constructor(name):
124    if name in __block_openssl_constructor:
125        # Prefer our blake2 and sha3 implementation.
126        return __get_builtin_constructor(name)
127    try:
128        f = getattr(_hashlib, 'openssl_' + name)
129        # Allow the C module to raise ValueError.  The function will be
130        # defined but the hash not actually available thanks to OpenSSL.
131        f()
132        # Use the C function directly (very fast)
133        return f
134    except (AttributeError, ValueError):
135        return __get_builtin_constructor(name)
136
137
138def __py_new(name, data=b'', **kwargs):
139    """new(name, data=b'', **kwargs) - Return a new hashing object using the
140    named algorithm; optionally initialized with data (which must be
141    a bytes-like object).
142    """
143    return __get_builtin_constructor(name)(data, **kwargs)
144
145
146def __hash_new(name, data=b'', **kwargs):
147    """new(name, data=b'') - Return a new hashing object using the named algorithm;
148    optionally initialized with data (which must be a bytes-like object).
149    """
150    if name in __block_openssl_constructor:
151        # Prefer our blake2 and sha3 implementation
152        # OpenSSL 1.1.0 comes with a limited implementation of blake2b/s.
153        # It does neither support keyed blake2 nor advanced features like
154        # salt, personal, tree hashing or SSE.
155        return __get_builtin_constructor(name)(data, **kwargs)
156    try:
157        return _hashlib.new(name, data)
158    except ValueError:
159        # If the _hashlib module (OpenSSL) doesn't support the named
160        # hash, try using our builtin implementations.
161        # This allows for SHA224/256 and SHA384/512 support even though
162        # the OpenSSL library prior to 0.9.8 doesn't provide them.
163        return __get_builtin_constructor(name)(data)
164
165
166try:
167    import _hashlib
168    new = __hash_new
169    __get_hash = __get_openssl_constructor
170    algorithms_available = algorithms_available.union(
171            _hashlib.openssl_md_meth_names)
172except ImportError:
173    new = __py_new
174    __get_hash = __get_builtin_constructor
175
176try:
177    # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA
178    from _hashlib import pbkdf2_hmac
179except ImportError:
180    _trans_5C = bytes((x ^ 0x5C) for x in range(256))
181    _trans_36 = bytes((x ^ 0x36) for x in range(256))
182
183    def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None):
184        """Password based key derivation function 2 (PKCS #5 v2.0)
185
186        This Python implementations based on the hmac module about as fast
187        as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster
188        for long passwords.
189        """
190        if not isinstance(hash_name, str):
191            raise TypeError(hash_name)
192
193        if not isinstance(password, (bytes, bytearray)):
194            password = bytes(memoryview(password))
195        if not isinstance(salt, (bytes, bytearray)):
196            salt = bytes(memoryview(salt))
197
198        # Fast inline HMAC implementation
199        inner = new(hash_name)
200        outer = new(hash_name)
201        blocksize = getattr(inner, 'block_size', 64)
202        if len(password) > blocksize:
203            password = new(hash_name, password).digest()
204        password = password + b'\x00' * (blocksize - len(password))
205        inner.update(password.translate(_trans_36))
206        outer.update(password.translate(_trans_5C))
207
208        def prf(msg, inner=inner, outer=outer):
209            # PBKDF2_HMAC uses the password as key. We can re-use the same
210            # digest objects and just update copies to skip initialization.
211            icpy = inner.copy()
212            ocpy = outer.copy()
213            icpy.update(msg)
214            ocpy.update(icpy.digest())
215            return ocpy.digest()
216
217        if iterations < 1:
218            raise ValueError(iterations)
219        if dklen is None:
220            dklen = outer.digest_size
221        if dklen < 1:
222            raise ValueError(dklen)
223
224        dkey = b''
225        loop = 1
226        from_bytes = int.from_bytes
227        while len(dkey) < dklen:
228            prev = prf(salt + loop.to_bytes(4, 'big'))
229            # endianness doesn't matter here as long to / from use the same
230            rkey = int.from_bytes(prev, 'big')
231            for i in range(iterations - 1):
232                prev = prf(prev)
233                # rkey = rkey ^ prev
234                rkey ^= from_bytes(prev, 'big')
235            loop += 1
236            dkey += rkey.to_bytes(inner.digest_size, 'big')
237
238        return dkey[:dklen]
239
240try:
241    # OpenSSL's scrypt requires OpenSSL 1.1+
242    from _hashlib import scrypt
243except ImportError:
244    pass
245
246
247for __func_name in __always_supported:
248    # try them all, some may not work due to the OpenSSL
249    # version not supporting that algorithm.
250    try:
251        globals()[__func_name] = __get_hash(__func_name)
252    except ValueError:
253        import logging
254        logging.exception('code for hash %s was not found.', __func_name)
255
256
257# Cleanup locals()
258del __always_supported, __func_name, __get_hash
259del __py_new, __hash_new, __get_openssl_constructor
260