blob: 121029aa670b7b785a3089d8a6011813dc9ee622 [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 Heimes634919a2013-11-20 17:23:06 +01008import hashlib as _hashlib
Guido van Rossuma19f80c2007-11-06 20:51:31 +00009
Guido van Rossum3f429082007-07-10 13:35:52 +000010trans_5C = bytes((x ^ 0x5C) for x in range(256))
11trans_36 = bytes((x ^ 0x36) for x in range(256))
Tim Petersb64bec32001-09-18 02:26:39 +000012
Andrew M. Kuchling1ccdff92001-11-02 21:49:20 +000013# The size of the digests returned by HMAC depends on the underlying
Thomas Wouters902d6eb2007-01-09 23:18:33 +000014# hashing module used. Use digest_size from the instance of HMAC instead.
Andrew M. Kuchling1ccdff92001-11-02 21:49:20 +000015digest_size = None
16
Tim Peters934d31b2004-03-20 20:11:29 +000017
Charles-François Natali7feb9f42012-05-13 19:53:07 +020018
Guido van Rossum8ceef412001-09-11 15:54:00 +000019class HMAC:
Guido van Rossuma19f80c2007-11-06 20:51:31 +000020 """RFC 2104 HMAC class. Also complies with RFC 4231.
Guido van Rossum8ceef412001-09-11 15:54:00 +000021
Andrew M. Kuchling1ccdff92001-11-02 21:49:20 +000022 This supports the API for Cryptographic Hash Functions (PEP 247).
Tim Petersb64bec32001-09-18 02:26:39 +000023 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +000024 blocksize = 64 # 512-bit HMAC; can be changed in subclasses.
Guido van Rossum8ceef412001-09-11 15:54:00 +000025
26 def __init__(self, key, msg = None, digestmod = None):
27 """Create a new HMAC object.
28
29 key: key for the keyed hash object.
30 msg: Initial input for the hash, if provided.
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000031 digestmod: A module supporting PEP 247. *OR*
Christian Heimes634919a2013-11-20 17:23:06 +010032 A hashlib constructor returning a new hash object. *OR*
33 A hash name suitable for hashlib.new().
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000034 Defaults to hashlib.md5.
Christian Heimes634919a2013-11-20 17:23:06 +010035 Implicit default to hashlib.md5 is deprecated and will be
36 removed in Python 3.6.
Guido van Rossum3f429082007-07-10 13:35:52 +000037
Christian Heimes04926ae2013-07-01 13:08:42 +020038 Note: key and msg must be a bytes or bytearray objects.
Guido van Rossum8ceef412001-09-11 15:54:00 +000039 """
Tim Peters934d31b2004-03-20 20:11:29 +000040
Christian Heimes04926ae2013-07-01 13:08:42 +020041 if not isinstance(key, (bytes, bytearray)):
42 raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
Guido van Rossum3f429082007-07-10 13:35:52 +000043
Raymond Hettinger7fdfc2d2002-05-31 17:49:10 +000044 if digestmod is None:
Christian Heimes634919a2013-11-20 17:23:06 +010045 _warnings.warn("HMAC() without an explicit digestmod argument "
46 "is deprecated.", PendingDeprecationWarning, 2)
47 digestmod = _hashlib.md5
Guido van Rossum8ceef412001-09-11 15:54:00 +000048
Florent Xicluna5d1155c2011-10-28 14:45:05 +020049 if callable(digestmod):
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000050 self.digest_cons = digestmod
Christian Heimes634919a2013-11-20 17:23:06 +010051 elif isinstance(digestmod, str):
52 self.digest_cons = lambda d=b'': _hashlib.new(digestmod, d)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000053 else:
Guido van Rossum3f429082007-07-10 13:35:52 +000054 self.digest_cons = lambda d=b'': digestmod.new(d)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000055
56 self.outer = self.digest_cons()
57 self.inner = self.digest_cons()
58 self.digest_size = self.inner.digest_size
Tim Peters88768482001-11-13 21:51:26 +000059
Guido van Rossuma19f80c2007-11-06 20:51:31 +000060 if hasattr(self.inner, 'block_size'):
61 blocksize = self.inner.block_size
62 if blocksize < 16:
Guido van Rossuma19f80c2007-11-06 20:51:31 +000063 _warnings.warn('block_size of %d seems too small; using our '
64 'default of %d.' % (blocksize, self.blocksize),
65 RuntimeWarning, 2)
66 blocksize = self.blocksize
67 else:
68 _warnings.warn('No block_size attribute on given digest object; '
69 'Assuming %d.' % (self.blocksize),
70 RuntimeWarning, 2)
71 blocksize = self.blocksize
72
Christian Heimesc4ab1102013-11-20 17:35:06 +010073 # self.blocksize is the default blocksize. self.block_size is
74 # effective block size as well as the public API attribute.
75 self.block_size = blocksize
76
Guido van Rossum8ceef412001-09-11 15:54:00 +000077 if len(key) > blocksize:
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000078 key = self.digest_cons(key).digest()
Guido van Rossum8ceef412001-09-11 15:54:00 +000079
Serhiy Storchaka5f1a5182016-09-11 14:41:02 +030080 key = key.ljust(blocksize, b'\0')
Thomas Wouters902d6eb2007-01-09 23:18:33 +000081 self.outer.update(key.translate(trans_5C))
82 self.inner.update(key.translate(trans_36))
Raymond Hettinger094662a2002-06-01 01:29:16 +000083 if msg is not None:
Guido van Rossum8ceef412001-09-11 15:54:00 +000084 self.update(msg)
85
Christian Heimesc4ab1102013-11-20 17:35:06 +010086 @property
87 def name(self):
88 return "hmac-" + self.inner.name
89
Guido van Rossum8ceef412001-09-11 15:54:00 +000090 def update(self, msg):
91 """Update this hashing object with the string msg.
92 """
93 self.inner.update(msg)
94
95 def copy(self):
96 """Return a separate copy of this hashing object.
97
98 An update to this copy won't affect the original object.
99 """
Benjamin Peterson0cc74442010-08-21 02:45:15 +0000100 # Call __new__ directly to avoid the expensive __init__.
101 other = self.__class__.__new__(self.__class__)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000102 other.digest_cons = self.digest_cons
Tim Peters934d31b2004-03-20 20:11:29 +0000103 other.digest_size = self.digest_size
Andrew M. Kuchling1ccdff92001-11-02 21:49:20 +0000104 other.inner = self.inner.copy()
105 other.outer = self.outer.copy()
106 return other
Guido van Rossum8ceef412001-09-11 15:54:00 +0000107
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000108 def _current(self):
109 """Return a hash object for the current state.
110
111 To be used only internally with digest() and hexdigest().
112 """
113 h = self.outer.copy()
114 h.update(self.inner.digest())
115 return h
116
Guido van Rossum8ceef412001-09-11 15:54:00 +0000117 def digest(self):
118 """Return the hash value of this hashing object.
119
120 This returns a string containing 8-bit data. The object is
121 not altered in any way by this function; you can continue
122 updating the object after calling this function.
123 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000124 h = self._current()
Guido van Rossum8ceef412001-09-11 15:54:00 +0000125 return h.digest()
126
127 def hexdigest(self):
128 """Like digest(), but returns a string of hexadecimal digits instead.
129 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000130 h = self._current()
131 return h.hexdigest()
Guido van Rossum8ceef412001-09-11 15:54:00 +0000132
133def new(key, msg = None, digestmod = None):
134 """Create a new hashing object and return it.
135
136 key: The starting key for the hash.
137 msg: if available, will immediately be hashed into the object's starting
Tim Petersb64bec32001-09-18 02:26:39 +0000138 state.
Guido van Rossum8ceef412001-09-11 15:54:00 +0000139
140 You can now feed arbitrary strings into the object using its update()
141 method, and can ask for the hash value at any time by calling its digest()
142 method.
143 """
144 return HMAC(key, msg, digestmod)