@@ -58,9 +58,15 @@ def copy(self):
5858 """
5959 copy = self .new ("" )
6060
61- _ffi .memmove (copy ._native_object , # pylint: disable=protected-access
62- self ._native_object ,
63- self ._native_size )
61+ if hasattr (self , '_copy' ):
62+ ret = self ._copy (self ._native_object ,
63+ copy ._native_object ) # pylint: disable=protected-access
64+ if ret < 0 : # pragma: no cover
65+ raise WolfCryptError ("Hash copy error (%d)" % ret )
66+ else :
67+ _ffi .memmove (copy ._native_object , # pylint: disable=protected-access
68+ self ._native_object ,
69+ self ._native_size )
6470
6571 return copy
6672
@@ -88,11 +94,21 @@ def digest(self):
8894 if self ._native_object :
8995 obj = _ffi .new (self ._native_type )
9096
91- _ffi .memmove (obj , self ._native_object , self ._native_size )
92-
93- ret = self ._final (obj , result )
94- if ret < 0 : # pragma: no cover
95- raise WolfCryptError ("Hash finalize error (%d)" % ret )
97+ if hasattr (self , '_copy' ):
98+ ret = self ._copy (self ._native_object , obj )
99+ if ret < 0 : # pragma: no cover
100+ raise WolfCryptError ("Hash copy error (%d)" % ret )
101+ else :
102+ _ffi .memmove (obj , self ._native_object , self ._native_size )
103+
104+ try :
105+ ret = self ._final (obj , result )
106+ if ret < 0 : # pragma: no cover
107+ raise WolfCryptError ("Hash finalize error (%d)" % ret )
108+ finally :
109+ delete = getattr (self , '_delete' , None )
110+ if delete :
111+ delete (obj )
96112
97113 return _ffi .buffer (result , self .digest_size )[:]
98114
@@ -117,6 +133,7 @@ class Sha(_Hash):
117133 _native_type = "wc_Sha *"
118134 _native_size = _ffi .sizeof ("wc_Sha" )
119135 _delete = _lib .wc_ShaFree
136+ _copy = _lib .wc_ShaCopy
120137
121138 def __del__ (self ):
122139 self ._delete (self ._native_object )
@@ -143,6 +160,7 @@ class Sha256(_Hash):
143160 _native_type = "wc_Sha256 *"
144161 _native_size = _ffi .sizeof ("wc_Sha256" )
145162 _delete = _lib .wc_Sha256Free
163+ _copy = _lib .wc_Sha256Copy
146164
147165 def __del__ (self ):
148166 self ._delete (self ._native_object )
@@ -169,6 +187,7 @@ class Sha384(_Hash):
169187 _native_type = "wc_Sha384 *"
170188 _native_size = _ffi .sizeof ("wc_Sha384" )
171189 _delete = _lib .wc_Sha384Free
190+ _copy = _lib .wc_Sha384Copy
172191
173192 def __del__ (self ):
174193 self ._delete (self ._native_object )
@@ -195,6 +214,7 @@ class Sha512(_Hash):
195214 _native_type = "wc_Sha512 *"
196215 _native_size = _ffi .sizeof ("wc_Sha512" )
197216 _delete = _lib .wc_Sha512Free
217+ _copy = _lib .wc_Sha512Copy
198218
199219 def __del__ (self ):
200220 self ._delete (self ._native_object )
@@ -232,14 +252,22 @@ class Sha3(_Hash):
232252 64 : _lib .wc_Sha3_512_Free ,
233253 }
234254
255+ _SHA3_COPY = {
256+ 28 : _lib .wc_Sha3_224_Copy ,
257+ 32 : _lib .wc_Sha3_256_Copy ,
258+ 48 : _lib .wc_Sha3_384_Copy ,
259+ 64 : _lib .wc_Sha3_512_Copy ,
260+ }
261+
235262 def __del__ (self ):
236- if hasattr (self , '_delete' ):
263+ if getattr (self , '_delete' , None ):
237264 self ._delete (self ._native_object )
238265
239266 def __init__ (self , string = None , size = SHA3_384_DIGEST_SIZE ): # pylint: disable=W0231
240267 self ._native_object = _ffi .new (self ._native_type )
241268 self .digest_size = size
242269 self ._delete = self ._SHA3_FREE .get (size )
270+ self ._copy = self ._SHA3_COPY .get (size )
243271 ret = self ._init ()
244272 if ret < 0 : # pragma: no cover
245273 raise WolfCryptError ("Sha3 init error (%d)" % ret )
@@ -252,7 +280,12 @@ def new(cls, string=None, size=SHA3_384_DIGEST_SIZE):
252280
253281 def copy (self ):
254282 c = Sha3 (size = self .digest_size )
255- _ffi .memmove (c ._native_object , self ._native_object , self ._native_size )
283+ if self ._copy :
284+ ret = self ._copy (self ._native_object , c ._native_object )
285+ if ret < 0 : # pragma: no cover
286+ raise WolfCryptError ("Hash copy error (%d)" % ret )
287+ else :
288+ _ffi .memmove (c ._native_object , self ._native_object , self ._native_size )
256289 return c
257290
258291 def _init (self ):
0 commit comments