1919/* EVP is the preferred interface to hashing in OpenSSL */
2020#include <openssl/evp.h>
2121
22+ #define MUNCH_SIZE INT_MAX
23+
2224
2325#ifndef HASH_OBJ_CONSTRUCTOR
2426#define HASH_OBJ_CONSTRUCTOR 0
@@ -182,10 +184,17 @@ EVP_update(EVPobject *self, PyObject *args)
182184 return NULL ;
183185
184186 MY_GET_BUFFER_VIEW_OR_ERROUT (obj , & view );
185-
186- EVP_DigestUpdate (& self -> ctx , (unsigned char * )view .buf ,
187- Py_SAFE_DOWNCAST (view .len , Py_ssize_t , unsigned int ));
188-
187+ if (view .len > 0 && view .len <= MUNCH_SIZE ) {
188+ EVP_DigestUpdate (& self -> ctx , view .buf , view .len );
189+ } else {
190+ Py_ssize_t offset = 0 , len = view .len ;
191+ while (len ) {
192+ unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len ;
193+ EVP_DigestUpdate (& self -> ctx , (unsigned char * )view .buf + offset , process );
194+ len -= process ;
195+ offset += process ;
196+ }
197+ }
189198 PyBuffer_Release (& view );
190199
191200 Py_INCREF (Py_None );
@@ -284,11 +293,21 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
284293 Py_INCREF (self -> name );
285294
286295 if (data_obj ) {
287- EVP_DigestUpdate (& self -> ctx , (unsigned char * )view .buf ,
288- Py_SAFE_DOWNCAST (view .len , Py_ssize_t , unsigned int ));
296+ if (len > 0 && len <= MUNCH_SIZE ) {
297+ EVP_DigestUpdate (& self -> ctx , cp , Py_SAFE_DOWNCAST (len , Py_ssize_t ,
298+ unsigned int ));
299+ } else {
300+ Py_ssize_t offset = 0 , len = view .len ;
301+ while (len ) {
302+ unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len ;
303+ EVP_DigestUpdate (& self -> ctx , (unsigned char * )view .buf + offset , process );
304+ len -= process ;
305+ offset += process ;
306+ }
307+ }
289308 PyBuffer_Release (& view );
290309 }
291-
310+
292311 return 0 ;
293312}
294313#endif
@@ -357,7 +376,7 @@ static PyTypeObject EVPtype = {
357376static PyObject *
358377EVPnew (PyObject * name_obj ,
359378 const EVP_MD * digest , const EVP_MD_CTX * initial_ctx ,
360- const unsigned char * cp , unsigned int len )
379+ const unsigned char * cp , Py_ssize_t len )
361380{
362381 EVPobject * self ;
363382
@@ -375,8 +394,20 @@ EVPnew(PyObject *name_obj,
375394 EVP_DigestInit (& self -> ctx , digest );
376395 }
377396
378- if (cp && len )
379- EVP_DigestUpdate (& self -> ctx , cp , len );
397+ if (cp && len ) {
398+ if (len > 0 && len <= MUNCH_SIZE ) {
399+ EVP_DigestUpdate (& self -> ctx , cp , Py_SAFE_DOWNCAST (len , Py_ssize_t ,
400+ unsigned int ));
401+ } else {
402+ Py_ssize_t offset = 0 ;
403+ while (len ) {
404+ unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len ;
405+ EVP_DigestUpdate (& self -> ctx , cp + offset , process );
406+ len -= process ;
407+ offset += process ;
408+ }
409+ }
410+ }
380411
381412 return (PyObject * )self ;
382413}
@@ -417,8 +448,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
417448
418449 digest = EVP_get_digestbyname (name );
419450
420- ret_obj = EVPnew (name_obj , digest , NULL , (unsigned char * )view .buf ,
421- Py_SAFE_DOWNCAST (view .len , Py_ssize_t , unsigned int ));
451+ ret_obj = EVPnew (name_obj , digest , NULL , (unsigned char * )view .buf , view .len );
422452
423453 if (data_obj )
424454 PyBuffer_Release (& view );
@@ -452,7 +482,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
452482 NULL, \
453483 CONST_new_ ## NAME ## _ctx_p, \
454484 (unsigned char*)view.buf, \
455- Py_SAFE_DOWNCAST( view.len, Py_ssize_t, unsigned int) ); \
485+ view.len); \
456486 \
457487 if (data_obj) \
458488 PyBuffer_Release(&view); \
0 commit comments