blob: 93c084e4ae8088f9c2638aa8341105822d5dec22 [file] [log] [blame]
Guido van Rossum8ceef412001-09-11 15:54:00 +00001"""HMAC (Keyed-Hashing for Message Authentication) Python module.
2
3Implements the HMAC algorithm as described by RFC 2104.
4"""
5
Guido van Rossuma19f80c2007-11-06 20:51:31 +00006import warnings as _warnings
Antoine Pitroua85017f2013-04-20 19:21:44 +02007from _operator import _compare_digest as compare_digest
Christian Heimes2f050c72018-01-27 09:53:43 +01008try:
9 import _hashlib as _hashopenssl
10except ImportError:
11 _hashopenssl = None
12 _openssl_md_meths = None
13else:
14 _openssl_md_meths = frozenset(_hashopenssl.openssl_md_meth_names)
Christian Heimes634919a2013-11-20 17:23:06 +010015import hashlib as _hashlib
Guido van Rossuma19f80c2007-11-06 20:51:31 +000016
Guido van Rossum3f429082007-07-10 13:35:52 +000017trans_5C = bytes((x ^ 0x5C) for x in range(256))
18trans_36 = bytes((x ^ 0x36) for x in range(256))
Tim Petersb64bec32001-09-18 02:26:39 +000019
Andrew M. Kuchling1ccdff92001-11-02 21:49:20 +000020# The size of the digests returned by HMAC depends on the underlying
Thomas Wouters902d6eb2007-01-09 23:18:33 +000021# hashing module used. Use digest_size from the instance of HMAC instead.
Andrew M. Kuchling1ccdff92001-11-02 21:49:20 +000022digest_size = None
23
Tim Peters934d31b2004-03-20 20:11:29 +000024
Charles-François Natali7feb9f42012-05-13 19:53:07 +020025
Guido van Rossum8ceef412001-09-11 15:54:00 +000026class HMAC:
Guido van Rossuma19f80c2007-11-06 20:51:31 +000027 """RFC 2104 HMAC class. Also complies with RFC 4231.
Guido van Rossum8ceef412001-09-11 15:54:00 +000028
Andrew M. Kuchling1ccdff92001-11-02 21:49:20 +000029 This supports the API for Cryptographic Hash Functions (PEP 247).
Tim Petersb64bec32001-09-18 02:26:39 +000030 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +000031 blocksize = 64 # 512-bit HMAC; can be changed in subclasses.
Guido van Rossum8ceef412001-09-11 15:54:00 +000032
33 def __init__(self, key, msg = None, digestmod = None):
34 """Create a new HMAC object.
35
36 key: key for the keyed hash object.
37 msg: Initial input for the hash, if provided.
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000038 digestmod: A module supporting PEP 247. *OR*
Christian Heimes634919a2013-11-20 17:23:06 +010039 A hashlib constructor returning a new hash object. *OR*
40 A hash name suitable for hashlib.new().
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000041 Defaults to hashlib.md5.
Christian Heimes634919a2013-11-20 17:23:06 +010042 Implicit default to hashlib.md5 is deprecated and will be
43 removed in Python 3.6.
Guido van Rossum3f429082007-07-10 13:35:52 +000044
Christian Heimes04926ae2013-07-01 13:08:42 +020045 Note: key and msg must be a bytes or bytearray objects.
Guido van Rossum8ceef412001-09-11 15:54:00 +000046 """
Tim Peters934d31b2004-03-20 20:11:29 +000047
Christian Heimes04926ae2013-07-01 13:08:42 +020048 if not isinstance(key, (bytes, bytearray)):
49 raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
Guido van Rossum3f429082007-07-10 13:35:52 +000050
Raymond Hettinger7fdfc2d2002-05-31 17:49:10 +000051 if digestmod is None:
Christian Heimes634919a2013-11-20 17:23:06 +010052 _warnings.warn("HMAC() without an explicit digestmod argument "
53 "is deprecated.", PendingDeprecationWarning, 2)
54 digestmod = _hashlib.md5
Guido van Rossum8ceef412001-09-11 15:54:00 +000055
Florent Xicluna5d1155c2011-10-28 14:45:05 +020056 if callable(digestmod):
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000057 self.digest_cons = digestmod
Christian Heimes634919a2013-11-20 17:23:06 +010058 elif isinstance(digestmod, str):
59 self.digest_cons = lambda d=b'': _hashlib.new(digestmod, d)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000060 else:
Guido van Rossum3f429082007-07-10 13:35:52 +000061 self.digest_cons = lambda d=b'': digestmod.new(d)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000062
63 self.outer = self.digest_cons()
64 self.inner = self.digest_cons()
65 self.digest_size = self.inner.digest_size
Tim Peters88768482001-11-13 21:51:26 +000066
Guido van Rossuma19f80c2007-11-06 20:51:31 +000067 if hasattr(self.inner, 'block_size'):
68 blocksize = self.inner.block_size
69 if blocksize < 16:
Guido van Rossuma19f80c2007-11-06 20:51:31 +000070 _warnings.warn('block_size of %d seems too small; using our '
71 'default of %d.' % (blocksize, self.blocksize),
72 RuntimeWarning, 2)
73 blocksize = self.blocksize
74 else:
75 _warnings.warn('No block_size attribute on given digest object; '
76 'Assuming %d.' % (self.blocksize),
77 RuntimeWarning, 2)
78 blocksize = self.blocksize
79
Christian Heimesc4ab1102013-11-20 17:35:06 +010080 # self.blocksize is the default blocksize. self.block_size is
81 # effective block size as well as the public API attribute.
82 self.block_size = blocksize
83
Guido van Rossum8ceef412001-09-11 15:54:00 +000084 if len(key) > blocksize:
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000085 key = self.digest_cons(key).digest()
Guido van Rossum8ceef412001-09-11 15:54:00 +000086
Serhiy Storchaka5f1a5182016-09-11 14:41:02 +030087 key = key.ljust(blocksize, b'\0')
Thomas Wouters902d6eb2007-01-09 23:18:33 +000088 self.outer.update(key.translate(trans_5C))
89 self.inner.update(key.translate(trans_36))
Raymond Hettinger094662a2002-06-01 01:29:16 +000090 if msg is not None:
Guido van Rossum8ceef412001-09-11 15:54:00 +000091 self.update(msg)
92
Christian Heimesc4ab1102013-11-20 17:35:06 +010093 @property
94 def name(self):
95 return "hmac-" + self.inner.name
96
Guido van Rossum8ceef412001-09-11 15:54:00 +000097 def update(self, msg):
98 """Update this hashing object with the string msg.
99 """
100 self.inner.update(msg)
101
102 def copy(self):
103 """Return a separate copy of this hashing object.
104
105 An update to this copy won't affect the original object.
106 """
Benjamin Peterson0cc74442010-08-21 02:45:15 +0000107 # Call __new__ directly to avoid the expensive __init__.
108 other = self.__class__.__new__(self.__class__)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000109 other.digest_cons = self.digest_cons
Tim Peters934d31b2004-03-20 20:11:29 +0000110 other.digest_size = self.digest_size
Andrew M. Kuchling1ccdff92001-11-02 21:49:20 +0000111 other.inner = self.inner.copy()
112 other.outer = self.outer.copy()
113 return other
Guido van Rossum8ceef412001-09-11 15:54:00 +0000114
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000115 def _current(self):
116 """Return a hash object for the current state.
117
118 To be used only internally with digest() and hexdigest().
119 """
120 h = self.outer.copy()
121 h.update(self.inner.digest())
122 return h
123
Guido van Rossum8ceef412001-09-11 15:54:00 +0000124 def digest(self):
125 """Return the hash value of this hashing object.
126
127 This returns a string containing 8-bit data. The object is
128 not altered in any way by this function; you can continue
129 updating the object after calling this function.
130 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000131 h = self._current()
Guido van Rossum8ceef412001-09-11 15:54:00 +0000132 return h.digest()
133
134 def hexdigest(self):
135 """Like digest(), but returns a string of hexadecimal digits instead.
136 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000137 h = self._current()
138 return h.hexdigest()
Guido van Rossum8ceef412001-09-11 15:54:00 +0000139
140def new(key, msg = None, digestmod = None):
141 """Create a new hashing object and return it.
142
143 key: The starting key for the hash.
144 msg: if available, will immediately be hashed into the object's starting
Tim Petersb64bec32001-09-18 02:26:39 +0000145 state.
Guido van Rossum8ceef412001-09-11 15:54:00 +0000146
147 You can now feed arbitrary strings into the object using its update()
148 method, and can ask for the hash value at any time by calling its digest()
149 method.
150 """
151 return HMAC(key, msg, digestmod)
Christian Heimes2f050c72018-01-27 09:53:43 +0100152
153
154def digest(key, msg, digest):
155 """Fast inline implementation of HMAC
156
157 key: key for the keyed hash object.
158 msg: input message
159 digest: A hash name suitable for hashlib.new() for best performance. *OR*
160 A hashlib constructor returning a new hash object. *OR*
161 A module supporting PEP 247.
162
163 Note: key and msg must be a bytes or bytearray objects.
164 """
165 if (_hashopenssl is not None and
166 isinstance(digest, str) and digest in _openssl_md_meths):
167 return _hashopenssl.hmac_digest(key, msg, digest)
168
169 if callable(digest):
170 digest_cons = digest
171 elif isinstance(digest, str):
172 digest_cons = lambda d=b'': _hashlib.new(digest, d)
173 else:
174 digest_cons = lambda d=b'': digest.new(d)
175
176 inner = digest_cons()
177 outer = digest_cons()
178 blocksize = getattr(inner, 'block_size', 64)
179 if len(key) > blocksize:
180 key = digest_cons(key).digest()
181 key = key + b'\x00' * (blocksize - len(key))
182 inner.update(key.translate(trans_36))
183 outer.update(key.translate(trans_5C))
184 inner.update(msg)
185 outer.update(inner.digest())
186 return outer.digest()