<s> from . bindings import _FFI , _C <EOL> import pytest <EOL> def _check ( return_val ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( return_val , int ) and return_val == <NUM_LIT:1> : <EOL> return <EOL> if isinstance ( return_val , bool ) and return_val == True : <EOL> return <EOL> raise Exception ( "<STR_LIT>" % ( str ( type ( return_val ) ) , str ( return_val ) ) ) <EOL> class Cipher ( object ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ "<STR_LIT>" , "<STR_LIT>" ] <EOL> def __init__ ( self , name , _alg = None ) : <EOL> """<STR_LIT>""" <EOL> if _alg : <EOL> self . alg = _alg <EOL> self . gcm = True <EOL> return <EOL> else : <EOL> self . alg = _C . EVP_get_cipherbyname ( name . encode ( "<STR_LIT:utf8>" ) ) <EOL> self . gcm = False <EOL> if self . alg == _FFI . NULL : <EOL> raise Exception ( "<STR_LIT>" % name ) <EOL> if "<STR_LIT>" in name . lower ( ) : <EOL> self . gcm = True <EOL> if "<STR_LIT>" in name . lower ( ) : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> def len_IV ( self ) : <EOL> """<STR_LIT>""" <EOL> return int ( self . alg . iv_len ) <EOL> def len_key ( self ) : <EOL> """<STR_LIT>""" <EOL> return int ( self . alg . key_len ) <EOL> def len_block ( self ) : <EOL> """<STR_LIT>""" <EOL> return int ( self . alg . block_size ) <EOL> def get_nid ( self ) : <EOL> """<STR_LIT>""" <EOL> return int ( self . alg . nid ) <EOL> def op ( self , key , iv , enc = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> c_op = CipherOperation ( enc ) <EOL> _check ( len ( key ) == self . len_key ( ) ) <EOL> _check ( enc in [ <NUM_LIT:0> , <NUM_LIT:1> ] ) <EOL> if not self . gcm : <EOL> _check ( len ( iv ) == self . len_IV ( ) ) <EOL> _check ( _C . EVP_CipherInit_ex ( c_op . ctx , <EOL> self . alg , _FFI . NULL , key , iv , enc ) ) <EOL> else : <EOL> _check ( _C . EVP_CipherInit_ex ( c_op . ctx , <EOL> self . alg , _FFI . NULL , _FFI . NULL , _FFI . NULL , enc ) ) <EOL> _check ( _C . EVP_CIPHER_CTX_ctrl ( c_op . ctx , <EOL> _C . EVP_CTRL_GCM_SET_IVLEN , len ( iv ) , _FFI . NULL ) ) <EOL> _C . EVP_CIPHER_CTX_ctrl ( c_op . ctx , _C . EVP_CTRL_GCM_SET_IV_FIXED , - <NUM_LIT:1> , iv ) ; <EOL> _C . EVP_CIPHER_CTX_ctrl ( c_op . ctx , _C . EVP_CTRL_GCM_IV_GEN , <NUM_LIT:0> , iv ) <EOL> _check ( _C . EVP_CipherInit_ex ( c_op . ctx , <EOL> _FFI . NULL , _FFI . NULL , key , iv , enc ) ) <EOL> c_op . cipher = self <EOL> return c_op <EOL> def enc ( self , key , iv ) : <EOL> """<STR_LIT>""" <EOL> return self . op ( key , iv , enc = <NUM_LIT:1> ) <EOL> def dec ( self , key , iv ) : <EOL> """<STR_LIT>""" <EOL> return self . op ( key , iv , enc = <NUM_LIT:0> ) <EOL> def __del__ ( self ) : <EOL> pass <EOL> @ staticmethod <EOL> def aes_128_gcm ( ) : <EOL> """<STR_LIT>""" <EOL> return Cipher ( None , _C . EVP_aes_128_gcm ( ) ) <EOL> @ staticmethod <EOL> def aes_192_gcm ( ) : <EOL> """<STR_LIT>""" <EOL> return Cipher ( None , _C . EVP_aes_192_gcm ( ) ) <EOL> @ staticmethod <EOL> def aes_256_gcm ( ) : <EOL> """<STR_LIT>""" <EOL> return Cipher ( None , _C . EVP_aes_256_gcm ( ) ) <EOL> def quick_gcm_enc ( self , key , iv , msg , assoc = None , tagl = <NUM_LIT:16> ) : <EOL> """<STR_LIT>""" <EOL> enc = self . enc ( key , iv ) <EOL> if assoc : <EOL> enc . update_associated ( assoc ) <EOL> ciphertext = enc . update ( msg ) <EOL> ciphertext += enc . finalize ( ) <EOL> tag = enc . get_tag ( tagl ) <EOL> return ( ciphertext , tag ) <EOL> def quick_gcm_dec ( self , key , iv , cip , tag , assoc = None ) : <EOL> """<STR_LIT>""" <EOL> dec = self . dec ( key , iv ) <EOL> if assoc : <EOL> dec . update_associated ( assoc ) <EOL> dec . set_tag ( tag ) <EOL> plain = dec . update ( cip ) <EOL> try : <EOL> plain += dec . finalize ( ) <EOL> except : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> return plain <EOL> class CipherOperation ( object ) : <EOL> __slots__ = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> def __init__ ( self , xenc ) : <EOL> self . ctx = _C . EVP_CIPHER_CTX_new ( ) <EOL> _C . EVP_CIPHER_CTX_init ( self . ctx ) <EOL> self . cipher = None <EOL> self . xenc = xenc <EOL> def update ( self , data ) : <EOL> """<STR_LIT>""" <EOL> block_len = self . cipher . len_block ( ) <EOL> alloc_len = len ( data ) + block_len + <NUM_LIT:1> <EOL> outl = _FFI . new ( "<STR_LIT>" ) <EOL> outl [ <NUM_LIT:0> ] = alloc_len <EOL> out = _FFI . new ( "<STR_LIT>" , alloc_len ) <EOL> _check ( _C . EVP_CipherUpdate ( self . ctx , out , outl , data , len ( data ) ) ) <EOL> ret = bytes ( _FFI . buffer ( out ) [ : int ( outl [ <NUM_LIT:0> ] ) ] ) <EOL> return ret <EOL> def finalize ( self ) : <EOL> """<STR_LIT>""" <EOL> block_len = self . cipher . len_block ( ) <EOL> alloc_len = block_len <EOL> outl = _FFI . new ( "<STR_LIT>" ) <EOL> outl [ <NUM_LIT:0> ] = alloc_len <EOL> out = _FFI . new ( "<STR_LIT>" , alloc_len ) <EOL> try : <EOL> _check ( _C . EVP_CipherFinal_ex ( self . ctx , out , outl ) ) <EOL> if outl [ <NUM_LIT:0> ] == <NUM_LIT:0> : <EOL> return b'<STR_LIT>' <EOL> ret = bytes ( _FFI . buffer ( out ) [ : int ( outl [ <NUM_LIT:0> ] ) ] ) <EOL> return ret <EOL> except : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> def update_associated ( self , data ) : <EOL> """<STR_LIT>""" <EOL> if self . xenc == <NUM_LIT:0> : <EOL> self . set_tag ( b"<STR_LIT>" * <NUM_LIT:16> ) <EOL> outl = _FFI . new ( "<STR_LIT>" ) <EOL> _check ( _C . EVP_CipherUpdate ( self . ctx , _FFI . NULL , outl , data , len ( data ) ) ) <EOL> _check ( outl [ <NUM_LIT:0> ] == len ( data ) ) <EOL> def get_tag ( self , tag_len = <NUM_LIT:16> ) : <EOL> """<STR_LIT>""" <EOL> tag = _FFI . new ( "<STR_LIT>" , tag_len ) <EOL> ret = _C . EVP_CIPHER_CTX_ctrl ( self . ctx , _C . EVP_CTRL_GCM_GET_TAG , tag_len , tag ) <EOL> _check ( ret ) <EOL> s = bytes ( _FFI . buffer ( tag ) [ : ] ) <EOL> return s <EOL> def set_tag ( self , tag ) : <EOL> """<STR_LIT>""" <EOL> _check ( _C . EVP_CIPHER_CTX_ctrl ( self . ctx , _C . EVP_CTRL_GCM_SET_TAG , len ( tag ) , tag ) ) <EOL> def __del__ ( self ) : <EOL> _check ( _C . EVP_CIPHER_CTX_cleanup ( self . ctx ) ) <EOL> _C . EVP_CIPHER_CTX_free ( self . ctx ) <EOL> def test_aes_init ( ) : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> assert aes . alg != _FFI . NULL <EOL> assert aes . len_IV ( ) == <NUM_LIT:16> <EOL> assert aes . len_block ( ) == <NUM_LIT:16> <EOL> assert aes . len_key ( ) == <NUM_LIT:16> <EOL> assert aes . get_nid ( ) == <NUM_LIT> <EOL> del aes <EOL> def test_errors ( ) : <EOL> with pytest . raises ( Exception ) as excinfo : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> assert '<STR_LIT>' in str ( excinfo . value ) <EOL> def test_aes_enc ( ) : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> ref = b"<STR_LIT>" * <NUM_LIT> <EOL> ciphertext = enc . update ( ref ) <EOL> ciphertext += enc . finalize ( ) <EOL> dec = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> , enc = <NUM_LIT:0> ) <EOL> plaintext = dec . update ( ciphertext ) <EOL> plaintext += dec . finalize ( ) <EOL> assert plaintext == ref <EOL> def test_aes_ctr ( ) : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> ref = b"<STR_LIT>" * <NUM_LIT> <EOL> ciphertext = enc . update ( ref ) <EOL> ciphertext += enc . finalize ( ) <EOL> dec = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> , enc = <NUM_LIT:0> ) <EOL> plaintext = dec . update ( ciphertext ) <EOL> plaintext += dec . finalize ( ) <EOL> assert plaintext == ref <EOL> def test_aes_ops ( ) : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> enc = aes . enc ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> ref = b"<STR_LIT>" * <NUM_LIT> <EOL> ciphertext = enc . update ( ref ) <EOL> ciphertext += enc . finalize ( ) <EOL> dec = aes . dec ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> plaintext = dec . update ( ciphertext ) <EOL> plaintext += dec . finalize ( ) <EOL> assert plaintext == ref <EOL> def test_aes_gcm_encrypt ( ) : <EOL> aes = Cipher . aes_128_gcm ( ) <EOL> assert aes . gcm <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> enc . update_associated ( b"<STR_LIT>" ) <EOL> ciphertext = enc . update ( b"<STR_LIT>" ) <EOL> c2 = enc . finalize ( ) <EOL> assert c2 == b'<STR_LIT>' <EOL> tag = enc . get_tag ( <NUM_LIT:16> ) <EOL> assert len ( tag ) == <NUM_LIT:16> <EOL> def test_aes_gcm_encrypt_192 ( ) : <EOL> aes = Cipher . aes_192_gcm ( ) <EOL> assert aes . gcm <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> enc . update_associated ( b"<STR_LIT>" ) <EOL> ciphertext = enc . update ( b"<STR_LIT>" ) <EOL> c2 = enc . finalize ( ) <EOL> assert c2 == b'<STR_LIT>' <EOL> tag = enc . get_tag ( <NUM_LIT:16> ) <EOL> assert len ( tag ) == <NUM_LIT:16> <EOL> def test_aes_gcm_encrypt_256 ( ) : <EOL> aes = Cipher . aes_256_gcm ( ) <EOL> assert aes . gcm <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:32> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> enc . update_associated ( b"<STR_LIT>" ) <EOL> ciphertext = enc . update ( b"<STR_LIT>" ) <EOL> c2 = enc . finalize ( ) <EOL> assert c2 == b'<STR_LIT>' <EOL> tag = enc . get_tag ( <NUM_LIT:16> ) <EOL> assert len ( tag ) == <NUM_LIT:16> <EOL> @ pytest . fixture <EOL> def aesenc ( ) : <EOL> aes = Cipher . aes_128_gcm ( ) <EOL> assert aes . gcm <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> enc . update_associated ( b"<STR_LIT>" ) <EOL> ciphertext = enc . update ( b"<STR_LIT>" ) <EOL> c2 = enc . finalize ( ) <EOL> assert c2 == b'<STR_LIT>' <EOL> tag = enc . get_tag ( <NUM_LIT:16> ) <EOL> assert len ( tag ) == <NUM_LIT:16> <EOL> return ( aes , enc , ciphertext , tag ) <EOL> def test_gcm_dec ( aesenc ) : <EOL> aes , enc , ciphertext , tag = aesenc <EOL> dec = aes . dec ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> dec . update_associated ( b"<STR_LIT>" ) <EOL> plaintext = dec . update ( ciphertext ) <EOL> dec . set_tag ( tag ) <EOL> dec . finalize ( ) <EOL> assert plaintext == b"<STR_LIT>" <EOL> def test_gcm_dec_badassoc ( aesenc ) : <EOL> aes , enc , ciphertext , tag = aesenc <EOL> dec = aes . dec ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> dec . update_associated ( b"<STR_LIT>" ) <EOL> plaintext = dec . update ( ciphertext ) <EOL> dec . set_tag ( tag ) <EOL> with pytest . raises ( Exception ) as excinfo : <EOL> dec . finalize ( ) <EOL> assert "<STR_LIT>" in str ( excinfo . value ) <EOL> def test_gcm_dec_badkey ( aesenc ) : <EOL> aes , enc , ciphertext , tag = aesenc <EOL> dec = aes . dec ( key = b"<STR_LIT:B>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> dec . update_associated ( b"<STR_LIT>" ) <EOL> plaintext = dec . update ( ciphertext ) <EOL> dec . set_tag ( tag ) <EOL> with pytest . raises ( Exception ) as excinfo : <EOL> dec . finalize ( ) <EOL> assert "<STR_LIT>" in str ( excinfo . value ) <EOL> def test_gcm_dec_badiv ( aesenc ) : <EOL> aes , enc , ciphertext , tag = aesenc <EOL> dec = aes . dec ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:B>" * <NUM_LIT:16> ) <EOL> dec . update_associated ( b"<STR_LIT>" ) <EOL> plaintext = dec . update ( ciphertext ) <EOL> dec . set_tag ( tag ) <EOL> with pytest . raises ( Exception ) as excinfo : <EOL> dec . finalize ( ) <EOL> assert "<STR_LIT>" in str ( excinfo . value ) <EOL> def test_aes_gcm_byname ( ) : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> assert aes . gcm <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> enc . update_associated ( b"<STR_LIT>" ) <EOL> ciphertext = enc . update ( b"<STR_LIT>" ) <EOL> c2 = enc . finalize ( ) <EOL> assert c2 == b'<STR_LIT>' <EOL> tag = enc . get_tag ( <NUM_LIT:16> ) <EOL> assert len ( tag ) == <NUM_LIT:16> <EOL> dec = aes . dec ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> dec . update_associated ( b"<STR_LIT>" ) <EOL> plaintext = dec . update ( ciphertext ) <EOL> dec . set_tag ( tag ) <EOL> dec . finalize ( ) <EOL> assert plaintext == b"<STR_LIT>" <EOL> def test_aes_gcm_different_IV ( ) : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> enc . update_associated ( b"<STR_LIT>" ) <EOL> ciphertext = enc . update ( b"<STR_LIT>" ) <EOL> c2 = enc . finalize ( ) <EOL> tag = enc . get_tag ( <NUM_LIT:16> ) <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:A>" * <NUM_LIT:16> ) <EOL> enc . update_associated ( b"<STR_LIT>" ) <EOL> ciphertext2 = enc . update ( b"<STR_LIT>" ) <EOL> c2 = enc . finalize ( ) <EOL> tag2 = enc . get_tag ( <NUM_LIT:16> ) <EOL> enc = aes . op ( key = b"<STR_LIT:A>" * <NUM_LIT:16> , iv = b"<STR_LIT:B>" * <NUM_LIT:16> ) <EOL> enc . update_associated ( b"<STR_LIT>" ) <EOL> ciphertext3 = enc . update ( b"<STR_LIT>" ) <EOL> c2 = enc . finalize ( ) <EOL> tag3 = enc . get_tag ( <NUM_LIT:16> ) <EOL> assert ciphertext == ciphertext2 <EOL> assert ciphertext != ciphertext3 <EOL> def test_quick ( ) : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> c , t = aes . quick_gcm_enc ( b"<STR_LIT:A>" * <NUM_LIT:16> , b"<STR_LIT:A>" * <NUM_LIT:16> , b"<STR_LIT>" ) <EOL> p = aes . quick_gcm_dec ( b"<STR_LIT:A>" * <NUM_LIT:16> , b"<STR_LIT:A>" * <NUM_LIT:16> , c , t ) <EOL> assert p == b"<STR_LIT>" <EOL> def test_quick_assoc ( ) : <EOL> aes = Cipher ( "<STR_LIT>" ) <EOL> c , t = aes . quick_gcm_enc ( b"<STR_LIT:A>" * <NUM_LIT:16> , b"<STR_LIT:A>" * <NUM_LIT:16> , b"<STR_LIT>" , assoc = b"<STR_LIT>" ) <EOL> p = aes . quick_gcm_dec ( b"<STR_LIT:A>" * <NUM_LIT:16> , b"<STR_LIT:A>" * <NUM_LIT:16> , c , t , assoc = b"<STR_LIT>" ) <EOL> assert p == b"<STR_LIT>" </s>
