@@ -369,6 +369,7 @@ def final(self, authTag=None):
369369 raise WolfCryptError ("Decryption error (%d)" % ret )
370370
371371
372+
372373if _lib .CHACHA_ENABLED :
373374 class ChaCha (_Cipher ):
374375 """
@@ -424,6 +425,115 @@ def set_iv(self, nonce, counter = 0):
424425 self ._IV_counter = counter
425426 self ._set_key (0 )
426427
428+ if _lib .CHACHA20_POLY1305_ENABLED :
429+ class ChaCha20Poly1305 (object ):
430+ """
431+ ChaCha20 Poly1305
432+ """
433+ block_size = 16
434+ _key_sizes = [16 , 24 , 32 ]
435+ _native_type = "ChaCha *"
436+ _aad = bytes ()
437+ _tag_bytes = 16
438+ _mode = None
439+ generatedCipherText = bytes ()
440+ generatedPlainText = bytes ()
441+
442+ def __init__ (self , key , IV , isEncrypt ):
443+ """
444+ tag_bytes is the number of bytes to use for the authentication tag during encryption
445+ """
446+ key = t2b (key )
447+ IV = t2b (IV )
448+ isEncrypt = True
449+ if len (key ) not in self ._key_sizes :
450+ raise ValueError ("key must be %s in length, not %d" %
451+ (self ._key_sizes , len (key )))
452+ self ._native_object = _ffi .new (self ._native_type )
453+ _lib .wc_AesInit (self ._native_object , _ffi .NULL , - 2 )
454+ ret = _lib .wc_ChaCha20Poly1305_Init (self ._native_object , self ._aad , len (self ._aad ),
455+ key , len (key ), IV , len (IV ), isEncrypt )
456+ if ret < 0 :
457+ raise WolfCryptError ("Init error (%d)" % ret )
458+
459+ def set_aad (self , data ):
460+ """
461+ Set the additional authentication data for the stream
462+ """
463+ if self ._mode is not None :
464+ raise WolfCryptError ("AAD can only be set before encrypt() or decrypt() is called" )
465+ self ._aad = t2b (data )
466+
467+ def get_aad (self ):
468+ return self ._aad
469+
470+ def encrypt (self , data ):
471+ """
472+ Add more data to the encryption stream
473+ """
474+ data = t2b (data )
475+ aad = bytes ()
476+ if self ._mode is None :
477+ self ._mode = _ENCRYPTION
478+ aad = self ._aad
479+ elif self ._mode == _DECRYPTION :
480+ raise WolfCryptError ("Class instance already in use for decryption" )
481+ self ._buf = _ffi .new ("byte[%d]" % (len (data )))
482+ ret = _lib .wc_ChaCha20Poly1305_UpdateData (self ._native_type , aad , len (aad ))
483+ if ret < 0 :
484+ raise WolfCryptError ("Decryption error (%d)" % ret )
485+ return bytes (self ._buf )
486+
487+ def decrypt (self , data ):
488+ """
489+ Add more data to the decryption stream
490+ """
491+ aad = bytes ()
492+ data = t2b (data )
493+ if self ._mode is None :
494+ self ._mode = _DECRYPTION
495+ aad = self ._aad
496+ elif self ._mode == _ENCRYPTION :
497+ raise WolfCryptError ("Class instance already in use for decryption" )
498+ self ._buf = _ffi .new ("byte[%d]" % (len (data )))
499+ ret = _lib .wc_ChaCha20Poly1305_Decrypt (self ._key , self_IV , aad , len (aad ),
500+ generatedCipherText , len (generatedCipherText ),
501+ authTag , generatedPlainText )
502+ if ret < 0 :
503+ raise WolfCryptError ("Decryption error (%d)" % ret )
504+ return bytes (self ._buf )
505+
506+ def checkTag (self , authTag ):
507+ """
508+ Check the authentication tag for the stream
509+ """
510+ authTag = t2b (authTag )
511+ ret = _lib .wc_ChaCha20Poly1305_CheckTag (authTag , len (authTag ))
512+ if ret < 0 :
513+ raise WolfCryptError ("Decryption error (%d)" % ret )
514+
515+ def final (self , authTag = None ):
516+ """
517+ When encrypting, finalize the stream and return an authentication tag for the stream.
518+ When decrypting, verify the authentication tag for the stream.
519+ The authTag parameter is only used for decrypting.
520+ """
521+ if self ._mode is None :
522+ raise WolfCryptError ("Final called with no encryption or decryption" )
523+ elif self ._mode == _ENCRYPTION :
524+ authTag = _ffi .new ("byte[%d]" % self ._tag_bytes )
525+ ret = _lib .wc_ChaCha20Poly1305_Final (self ._native_type , authTag )
526+ if ret < 0 :
527+ raise WolfCryptError ("Encryption error (%d)" % ret )
528+ return _ffi .buffer (authTag )[:]
529+ else :
530+ if authTag is None :
531+ raise WolfCryptError ("authTag parameter required" )
532+ authTag = t2b (authTag )
533+ ret = _lib .wc_ChaCha20Poly1305_Final (self ._native_type , authTag )
534+ if ret < 0 :
535+ raise WolfCryptError ("Decryption error (%d)" % ret )
536+
427537if _lib .DES3_ENABLED :
428538 class Des3 (_Cipher ):
429539 """
0 commit comments