@@ -396,32 +396,36 @@ class AesGcmStream(object):
396396 block_size = 16
397397 _key_sizes = [16 , 24 , 32 ]
398398 _native_type = "Aes *"
399- _aad = bytes ()
400- _tag_bytes = 16
401- _mode = None
402399
403400 def __init__ (self , key , IV , tag_bytes = 16 ):
404401 """
405402 tag_bytes is the number of bytes to use for the authentication tag during encryption
406403 """
407404 key = t2b (key )
408405 IV = t2b (IV )
409- if tag_bytes < 4 or tag_bytes > 16 :
410- raise ValueError ("tag_bytes must be between 4 and 16" )
406+ # NIST SP 800-38D valid GCM tag lengths: 16, 15, 14, 13, 12, 8, 4 bytes.
407+ if tag_bytes not in (4 , 8 , 12 , 13 , 14 , 15 , 16 ):
408+ raise ValueError (
409+ "tag_bytes must be one of 4, 8, 12, 13, 14, 15, or 16" )
410+ # Per-instance state: AAD, tag length, and current mode (enc/dec).
411+ self ._aad = bytes ()
411412 self ._tag_bytes = tag_bytes
413+ self ._mode = None
412414 if len (key ) not in self ._key_sizes :
413415 raise ValueError ("key must be %s in length, not %d" %
414416 (self ._key_sizes , len (key )))
417+ self ._init_done = False
415418 self ._native_object = _ffi .new (self ._native_type )
416419 ret = _lib .wc_AesInit (self ._native_object , _ffi .NULL , - 2 )
417420 if ret < 0 :
418421 raise WolfCryptError ("AES init error (%d)" % ret )
422+ self ._init_done = True
419423 ret = _lib .wc_AesGcmInit (self ._native_object , key , len (key ), IV , len (IV ))
420424 if ret < 0 :
421425 raise WolfCryptError ("Init error (%d)" % ret )
422426
423427 def __del__ (self ):
424- if hasattr (self , '_native_object' ):
428+ if getattr (self , '_init_done' , False ):
425429 _lib .wc_AesFree (self ._native_object )
426430
427431 def set_aad (self , data ):
@@ -446,11 +450,11 @@ def encrypt(self, data):
446450 aad = self ._aad
447451 elif self ._mode == _DECRYPTION :
448452 raise WolfCryptError ("Class instance already in use for decryption" )
449- self . _buf = _ffi .new ("byte[%d]" % (len (data )))
450- ret = _lib .wc_AesGcmEncryptUpdate (self ._native_object , self . _buf , data , len (data ), aad , len (aad ))
453+ buf = _ffi .new ("byte[%d]" % (len (data )))
454+ ret = _lib .wc_AesGcmEncryptUpdate (self ._native_object , buf , data , len (data ), aad , len (aad ))
451455 if ret < 0 :
452456 raise WolfCryptError ("Encryption error (%d)" % ret )
453- return bytes (self . _buf )
457+ return bytes (buf )
454458
455459 def decrypt (self , data ):
456460 """
@@ -463,11 +467,11 @@ def decrypt(self, data):
463467 aad = self ._aad
464468 elif self ._mode == _ENCRYPTION :
465469 raise WolfCryptError ("Class instance already in use for encryption" )
466- self . _buf = _ffi .new ("byte[%d]" % (len (data )))
467- ret = _lib .wc_AesGcmDecryptUpdate (self ._native_object , self . _buf , data , len (data ), aad , len (aad ))
470+ buf = _ffi .new ("byte[%d]" % (len (data )))
471+ ret = _lib .wc_AesGcmDecryptUpdate (self ._native_object , buf , data , len (data ), aad , len (aad ))
468472 if ret < 0 :
469473 raise WolfCryptError ("Decryption error (%d)" % ret )
470- return bytes (self . _buf )
474+ return bytes (buf )
471475
472476 def final (self , authTag = None ):
473477 """
@@ -505,7 +509,9 @@ class ChaCha(_Cipher):
505509 _IV_nonce = b""
506510 _IV_counter = 0
507511
508- def __init__ (self , key = "" , size = 32 ):
512+ def __init__ (self , key = "" , size = 32 ): # pylint: disable=unused-argument
513+ # size is kept for backwards compatibility; key length is now
514+ # derived from the actual key and validated against _key_sizes.
509515 self ._native_object = _ffi .new (self ._native_type )
510516 self ._enc = None
511517 self ._dec = None
@@ -1231,7 +1237,11 @@ def make_key(cls, size, rng=None):
12311237 ret = _lib .wc_ecc_set_rng (ecc .native_object , rng .native_object )
12321238 if ret < 0 :
12331239 raise WolfCryptError ("Error setting ECC RNG (%d)" % ret )
1234- ecc ._rng = rng
1240+
1241+ # Retain the RNG so it outlives the ECC key. Even outside the
1242+ # timing-resistance path, wolfSSL internals may retain a pointer
1243+ # to the RNG; keeping the reference avoids any UAF risk.
1244+ ecc ._rng = rng
12351245
12361246 return ecc
12371247
0 commit comments