U
    \ey$                     @   s   d dl mZmZmZ d dlmZ d dlmZmZm	Z	 d dl
mZ d dlmZ eejeejeejeejG dd deZdS )	    )absolute_importdivisionprint_function)utils)
InvalidTagUnsupportedAlgorithm_Reasons)ciphers)modesc                   @   sN   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
edZdS )_CipherContext   r   c                 C   s  || _ || _|| _|| _d | _t| jtjr<| jjd | _	nd| _	| j j
 }| j j|| j j
j}| j j}z|t|t|f }W n4 tk
r   td|j|r|jn|tjY nX || j ||}|| j jjkrd|}	|d k	r|	d|7 }	|	d| j  7 }	t|	tjt|tjr8| j j|j}
njt|tjrX| j j|j}
nJt|tjrx| j j|j }
n*t|tjr| j j|j }
n
| j jj}
| j j
!||| j jj| j jj| j jj|}| j "|dk | j j
#|t$|j%}| j "|dk t|tj&r| j j
'|| j j
j(t$|
| j jj}| j "|dk |j)d k	r| j j
'|| j j
j*t$|j)|j)}| j "|dk |j)| _n.| j| j+kr| j j
j,r| j j
j-st.d| j j
!|| j jj| j jj| j j|j%|
|}| j "|dk | j j
/|d || _0d S )	N   r   z6cipher {} in {} mode is not supported by this backend.zcipher {0.name} zin {0.name} mode z_is not supported by this backend (Your version of OpenSSL may be too old. Current version: {}.)r   z_delayed passing of GCM tag requires OpenSSL >= 1.0.2. To use this feature please update OpenSSL)1_backendZ_cipher_mode
_operation_tag
isinstancer	   ZBlockCipherAlgorithmZ
block_size_block_size_bytes_libZEVP_CIPHER_CTX_new_ffigcZEVP_CIPHER_CTX_freeZ_cipher_registrytypeKeyErrorr   formatnamer   ZUNSUPPORTED_CIPHERNULLZopenssl_version_textr
   ZModeWithInitializationVectorfrom_bufferZinitialization_vectorZModeWithTweakZtweakZModeWithNonceZnonceZEVP_CipherInit_exopenssl_assertZEVP_CIPHER_CTX_set_key_lengthlenkeyGCMEVP_CIPHER_CTX_ctrlZEVP_CTRL_AEAD_SET_IVLENtagEVP_CTRL_AEAD_SET_TAG_DECRYPT"CRYPTOGRAPHY_OPENSSL_LESS_THAN_102CRYPTOGRAPHY_IS_LIBRESSLNotImplementedErrorZEVP_CIPHER_CTX_set_padding_ctx)selfZbackendZciphermodeZ	operationZctxregistryZadapterZ
evp_ciphermsgZiv_nonceres r.   N/usr/lib/python3/dist-packages/cryptography/hazmat/backends/openssl/ciphers.py__init__   s      


     

z_CipherContext.__init__c                 C   s2   t t|| j d }| ||}t|d | S )Nr   )	bytearrayr   r   update_intobytes)r)   databufnr.   r.   r/   updatez   s    z_CipherContext.updatec                 C   s   t |t || j d k r6tdt || j d | jjd| jjj|dd}| jjd}| jj	
| j||| jj|t |}| j|dk |d S )Nr   z1buffer must be at least {} bytes for this payloadzunsigned char *T)Zrequire_writableint *r   )r   r   
ValueErrorr   r   r   castr   newr   EVP_CipherUpdater(   r   )r)   r4   r5   outlenr-   r.   r.   r/   r2      s(        z_CipherContext.update_intoc                 C   s|  t | jtjr| d | j| jkrDt | jtjrD| jd krDt	d| j
jd| j}| j
jd}| j
j| j||}|dkr| j
 }|st | jtjrt| j
|d | j
jj| j
jj t	dt | jtjrB| j| jkrB| j
jd| j}| j
j| j| j
jj| j|}| j
|dk | j
j|d d  | _| j
j| j}| j
|dk | j
j|d |d  S )N    z4Authentication tag must be provided when decrypting.zunsigned char[]r8   r   zFThe length of the provided data is not a multiple of the block length.r   )r   r   r
   r    r7   r   r$   ZModeWithAuthenticationTagr"   r9   r   r   r;   r   r   ZEVP_CipherFinal_exr(   Z_consume_errorsr   r   Z_lib_reason_matchZERR_LIB_EVPZ'EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH_ENCRYPTr!   ZEVP_CTRL_AEAD_GET_TAGbufferr   ZEVP_CIPHER_CTX_cleanup)r)   r5   r=   r-   errorsZtag_bufr.   r.   r/   finalize   sZ    



   z_CipherContext.finalizec                 C   s|   | j jjr| j jjstdt|| jjk r>td	| jj| j j
| j| j jjt||}| j |dk || _|  S )NzUfinalize_with_tag requires OpenSSL >= 1.0.2. To use this method please update OpenSSLz.Authentication tag must be {} bytes or longer.r   )r   r   r%   r&   r'   r   r   Z_min_tag_lengthr9   r   r!   r(   r#   r   r   rB   )r)   r"   r-   r.   r.   r/   finalize_with_tag   s,      z _CipherContext.finalize_with_tagc                 C   sN   | j jd}| j j| j| j jj|| j j|t|}| j 	|dk d S )Nr8   r   )
r   r   r;   r   r<   r(   r   r   r   r   )r)   r4   r=   r-   r.   r.   r/   authenticate_additional_data   s       z+_CipherContext.authenticate_additional_datar   N)__name__
__module____qualname__r?   r$   r0   r7   r2   rB   rC   rD   r   Zread_only_propertyr"   r.   r.   r.   r/   r      s   e6r   N)Z
__future__r   r   r   Zcryptographyr   Zcryptography.exceptionsr   r   r   Zcryptography.hazmat.primitivesr	   Z&cryptography.hazmat.primitives.ciphersr
   Zregister_interfaceZCipherContextZAEADCipherContextZAEADEncryptionContextZAEADDecryptionContextobjectr   r.   r.   r.   r/   <module>   s   



