Skip to content

Commit 52660b0

Browse files
committed
gh-155428: align hmac.digest and hmac.HMAC.digest outputs when using
small block sizes
1 parent 998b890 commit 52660b0

2 files changed

Lines changed: 26 additions & 16 deletions

File tree

Lib/hmac.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,27 @@ def digest_wrapper(d=b''):
4949
return digest_wrapper
5050

5151

52+
def _select_blocksize(obj, default, stacklevel=3):
53+
if hasattr(obj, 'block_size'):
54+
blocksize = obj.block_size
55+
if blocksize < 16:
56+
import warnings
57+
58+
warnings.warn(f"block_size of {blocksize} seems too small; "
59+
f"using our default of {default}.",
60+
RuntimeWarning, stacklevel=stacklevel)
61+
blocksize = default
62+
else:
63+
import warnings
64+
65+
warnings.warn("No block_size attribute on given digest object; "
66+
f"Assuming {default}.",
67+
RuntimeWarning, stacklevel=stacklevel)
68+
blocksize = default
69+
return blocksize
70+
71+
72+
5273
class HMAC:
5374
"""RFC 2104 HMAC class. Also complies with RFC 4231.
5475
@@ -116,8 +137,6 @@ def _init_builtin_hmac(self, key, msg, digestmod):
116137
self.block_size = self._hmac.block_size
117138

118139
def _init_old(self, key, msg, digestmod):
119-
import warnings
120-
121140
digest_cons = _get_digest_constructor(digestmod)
122141
if _is_shake_constructor(digest_cons):
123142
raise ValueError(f"unsupported hash algorithm {digestmod}")
@@ -127,19 +146,7 @@ def _init_old(self, key, msg, digestmod):
127146
self._inner = digest_cons()
128147
self.digest_size = self._inner.digest_size
129148

130-
if hasattr(self._inner, 'block_size'):
131-
blocksize = self._inner.block_size
132-
if blocksize < 16:
133-
warnings.warn(f"block_size of {blocksize} seems too small; "
134-
f"using our default of {self.blocksize}.",
135-
RuntimeWarning, 2)
136-
blocksize = self.blocksize # pragma: no cover
137-
else:
138-
warnings.warn("No block_size attribute on given digest object; "
139-
f"Assuming {self.blocksize}.",
140-
RuntimeWarning, 2)
141-
blocksize = self.blocksize # pragma: no cover
142-
149+
blocksize = _select_blocksize(self._inner, self.blocksize)
143150
if len(key) > blocksize:
144151
key = digest_cons(key).digest()
145152

@@ -272,7 +279,7 @@ def _compute_digest_fallback(key, msg, digest):
272279
raise ValueError(f"unsupported hash algorithm {digest}")
273280
inner = digest_cons()
274281
outer = digest_cons()
275-
blocksize = getattr(inner, 'block_size', 64)
282+
blocksize = _select_blocksize(inner, HMAC.blocksize)
276283
if len(key) > blocksize:
277284
key = digest_cons(key).digest()
278285
key = key.ljust(blocksize, b'\0')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Ensure that :func:`hmac.digest` and :meth:`hmac.HMAC.digest` output
2+
identical values when using a digest's block size smaller than 16. Patch by
3+
Bénédikt Tran.

0 commit comments

Comments
 (0)