@@ -1939,20 +1939,30 @@ locked_HMAC_CTX_copy(HMAC_CTX *new_ctx_p, HMACobject *self)
19391939 return 0 ;
19401940}
19411941
1942- /* returning 0 means that an error occurred and an exception is set */
1942+ #define BAD_DIGEST_SIZE 0
1943+
1944+ /*
1945+ * Return the digest size in bytes.
1946+ *
1947+ * On error, set an exception and return BAD_DIGEST_SIZE.
1948+ */
19431949static unsigned int
19441950_hashlib_hmac_digest_size (HMACobject * self )
19451951{
19461952 const EVP_MD * md = _hashlib_hmac_get_md (self );
19471953 if (md == NULL ) {
1948- return 0 ;
1954+ return BAD_DIGEST_SIZE ;
19491955 }
1950- unsigned int digest_size = EVP_MD_size (md );
1951- assert (digest_size <= EVP_MAX_MD_SIZE );
1956+ int digest_size = EVP_MD_size (md );
1957+ /* digest_size < 0 iff EVP_MD context is NULL (which is impossible here) */
1958+ assert (digest_size >= 0 );
1959+ assert (digest_size <= (int )EVP_MAX_MD_SIZE );
1960+ /* digest_size == 0 means that the context is not entirely initialized */
19521961 if (digest_size == 0 ) {
1953- notify_ssl_error_occurred ("invalid digest size" );
1962+ raise_ssl_error (PyExc_ValueError , "missing digest size" );
1963+ return BAD_DIGEST_SIZE ;
19541964 }
1955- return digest_size ;
1965+ return ( unsigned int ) digest_size ;
19561966}
19571967
19581968static int
@@ -2053,24 +2063,38 @@ _hashlib_HMAC_update_impl(HMACobject *self, PyObject *msg)
20532063 Py_RETURN_NONE ;
20542064}
20552065
2056- static int
2057- _hmac_digest (HMACobject * self , unsigned char * buf , unsigned int len )
2066+ /*
2067+ * Extract the MAC value to 'buf' and return the digest size.
2068+ *
2069+ * The buffer 'buf' must have at least hashlib_openssl_HMAC_digest_size(self)
2070+ * bytes. Smaller buffers lead to undefined behaviors.
2071+ *
2072+ * On error, set an exception and return -1.
2073+ */
2074+ static Py_ssize_t
2075+ _hmac_digest (HMACobject * self , unsigned char * buf )
20582076{
2077+ unsigned int digest_size = _hashlib_hmac_digest_size (self );
2078+ assert (digest_size <= EVP_MAX_MD_SIZE );
2079+ if (digest_size == BAD_DIGEST_SIZE ) {
2080+ assert (PyErr_Occurred ());
2081+ return -1 ;
2082+ }
20592083 HMAC_CTX * temp_ctx = py_openssl_wrapper_HMAC_CTX_new ();
20602084 if (temp_ctx == NULL ) {
2061- return 0 ;
2085+ return -1 ;
20622086 }
20632087 if (locked_HMAC_CTX_copy (temp_ctx , self ) < 0 ) {
20642088 HMAC_CTX_free (temp_ctx );
2065- return 0 ;
2089+ return -1 ;
20662090 }
2067- int r = HMAC_Final (temp_ctx , buf , & len );
2091+ int r = HMAC_Final (temp_ctx , buf , NULL );
20682092 HMAC_CTX_free (temp_ctx );
20692093 if (r == 0 ) {
20702094 notify_ssl_error_occurred_in (Py_STRINGIFY (HMAC_Final ));
2071- return 0 ;
2095+ return -1 ;
20722096 }
2073- return 1 ;
2097+ return digest_size ;
20742098}
20752099
20762100/*[clinic input]
@@ -2082,16 +2106,9 @@ static PyObject *
20822106_hashlib_HMAC_digest_impl (HMACobject * self )
20832107/*[clinic end generated code: output=1b1424355af7a41e input=bff07f74da318fb4]*/
20842108{
2085- unsigned char digest [EVP_MAX_MD_SIZE ];
2086- unsigned int digest_size = _hashlib_hmac_digest_size (self );
2087- if (digest_size == 0 ) {
2088- return NULL ;
2089- }
2090- int r = _hmac_digest (self , digest , digest_size );
2091- if (r == 0 ) {
2092- return NULL ;
2093- }
2094- return PyBytes_FromStringAndSize ((const char * )digest , digest_size );
2109+ unsigned char buf [EVP_MAX_MD_SIZE ];
2110+ Py_ssize_t n = _hmac_digest (self , buf );
2111+ return n < 0 ? NULL : PyBytes_FromStringAndSize ((const char * )buf , n );
20952112}
20962113
20972114/*[clinic input]
@@ -2109,24 +2126,17 @@ static PyObject *
21092126_hashlib_HMAC_hexdigest_impl (HMACobject * self )
21102127/*[clinic end generated code: output=80d825be1eaae6a7 input=5e48db83ab1a4d19]*/
21112128{
2112- unsigned char digest [EVP_MAX_MD_SIZE ];
2113- unsigned int digest_size = _hashlib_hmac_digest_size (self );
2114- if (digest_size == 0 ) {
2115- return NULL ;
2116- }
2117- int r = _hmac_digest (self , digest , digest_size );
2118- if (r == 0 ) {
2119- return NULL ;
2120- }
2121- return _Py_strhex ((const char * )digest , digest_size );
2129+ unsigned char buf [EVP_MAX_MD_SIZE ];
2130+ Py_ssize_t n = _hmac_digest (self , buf );
2131+ return n < 0 ? NULL : _Py_strhex ((const char * )buf , n );
21222132}
21232133
21242134static PyObject *
21252135_hashlib_hmac_get_digest_size (PyObject * op , void * Py_UNUSED (closure ))
21262136{
21272137 HMACobject * self = HMACobject_CAST (op );
2128- unsigned int digest_size = _hashlib_hmac_digest_size (self );
2129- return digest_size == 0 ? NULL : PyLong_FromLong (digest_size );
2138+ unsigned int size = _hashlib_hmac_digest_size (self );
2139+ return size == BAD_DIGEST_SIZE ? NULL : PyLong_FromLong (size );
21302140}
21312141
21322142static PyObject *
0 commit comments