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