diff options
| -rw-r--r-- | Doc/library/hmac.rst | 27 | ||||
| -rw-r--r-- | Modules/operator.c | 13 |
2 files changed, 28 insertions, 12 deletions
diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst index a8ca3afe44..ce93cbc777 100644 --- a/Doc/library/hmac.rst +++ b/Doc/library/hmac.rst @@ -70,19 +70,36 @@ This module also provides the following helper function: .. function:: compare_digest(a, b) - Return ``a == b``. This function uses an approach designed to prevent - timing analysis, making it appropriate for cryptography. *a* and *b* + Return ``a == b``. This function uses an approach designed to prevent timing + analysis by avoiding content based short circuiting behaviour, making it + appropriate for cryptography. *a* and *b* must both be of the same type: either :class:`str` (ASCII only, as e.g. returned by :meth:`HMAC.hexdigest`), or any type that supports the buffer protocol (e.g. :class:`bytes`). + Using a short circuiting comparison (that is, one that terminates as soon as + it finds any difference between the values) to check digests for correctness + can be problematic, as it introduces a potential vulnerability when an + attacker can control both the message to be checked *and* the purported + signature value. By keeping the plaintext consistent and supplying different + signature values, an attacker may be able to use timing variations to search + the signature space for the expected value in O(n) time rather than the + desired O(2**n). + .. note:: - If *a* and *b* are different lengths, or if an error occurs, - a timing attack may be able to infer information about the types - and lengths of *a* and *b*, but not their values. + + While this function reduces the likelihood of leaking the contents of the + expected digest via a timing attack, it still may leak some timing + information when the input values differ in lengths as well as in error + cases like unsupported types or non ASCII strings. When the inputs have + different length the timing depends solely on the length of ``b``. It is + assumed that the expected length of the digest is not a secret, as it is + typically published as part of a file format, network protocol or API + definition. .. versionadded:: 3.3 + .. seealso:: Module :mod:`hashlib` diff --git a/Modules/operator.c b/Modules/operator.c index 7c7ef8fcbe..8ad54063d9 100644 --- a/Modules/operator.c +++ b/Modules/operator.c @@ -211,15 +211,14 @@ _tscmp(const unsigned char *a, const unsigned char *b, PyDoc_STRVAR(compare_digest__doc__, "compare_digest(a, b) -> bool\n" "\n" -"Return ``a == b``. This function uses an approach designed to prevent\n" -"timing analysis, making it appropriate for cryptography. *a* and *b*\n" -"must both be of the same type: either `str` (ASCII only, as e.g.\n" -"returned by HMAC.hexdigest()), or any type that supports the buffer\n" -"protocol, (e.g. `bytes`).\n" +"Return 'a == b'. This function uses an approach designed to prevent\n" +"timing analysis, making it appropriate for cryptography.\n" +"a and b must both be of the same type: either str (ASCII only),\n" +"or any type that supports the buffer protocol (e.g. bytes).\n" "\n" -"Note: If *a* and *b* are different lengths, or if an error occurs,\n" +"Note: If a and b are of different lengths, or if an error occurs,\n" "a timing attack may be able to infer information about the types\n" -"and lengths of *a* and *b*, but not their values.\n"); +"and lengths of a and b, but not their values.\n"); static PyObject* compare_digest(PyObject *self, PyObject *args) |
