a
    kÄ#dž>  ã                   @   sö  d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
 ddlmZ ddlm  mZ ejr�ddlmZmZmZ dd	lmZ dd
lmZ ejr¨ddlmZmZ nG dd„ dƒZi ZG dd„ deƒZG dd„ de ƒZ!G dd„ de "ee#¡ƒZ$ej�rG dd„ de$ƒZ%G dd„ de%ƒZ&ej�rbG dd„ de$ƒZ'G dd„ de'ƒZ(G dd„ de'ƒZ)G dd„ de)ƒZ*G d d!„ d!e "ee#¡ƒZ+ej�r¢G d"d#„ d#e+ƒZ,G d$d%„ d%e,ƒZ-ej�rÊG d&d'„ d'e+ƒZ.G d(d)„ d)e.ƒZ/ej�ròG d*d+„ d+e+ƒZ0G d,d-„ d-e0ƒZ1dS ).a]  
Authenticated Encryption with Associated Data ciphers.

RFC 5288 introduces new ciphersuites for TLS 1.2 which are based on AES in
Galois/Counter Mode (GCM). RFC 6655 in turn introduces AES_CCM ciphersuites.
The related AEAD algorithms are defined in RFC 5116. Later on, RFC 7905
introduced cipher suites based on a ChaCha20-Poly1305 construction.
é    )Úabsolute_importN)Úconf)Ú
pkcs_i2ospÚ
pkcs_os2ip)ÚCipherError)Ústrxor)ÚCipherÚ
algorithmsÚmodes)Údefault_backend)Ú
InvalidTag)ÚAESCCMÚChaCha20Poly1305c                   @   s   e Zd ZdS )r   N)Ú__name__Ú
__module__Ú__qualname__© r   r   úZ/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/layers/tls/crypto/cipher_aead.pyr   !   s   r   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )Ú_AEADCipherMetaclassz—
    Cipher classes are automatically registered through this metaclass.
    Furthermore, their name attribute is extracted from their class name.
    c                    sN   |  d¡s|dd … |d< tt| ƒ | |||¡}|  d¡sJ|t|dd … < |S )NÚ_AEADCipheré   Úname)Ú
startswithÚsuperr   Ú__new__Ú_tls_aead_cipher_algs)ÚclsZ	ciph_nameÚbasesÚdctZ	the_class©Ú	__class__r   r   r   ,   s    
ÿ
z_AEADCipherMetaclass.__new__)r   r   r   Ú__doc__r   Ú__classcell__r   r   r   r   r   '   s   r   c                   @   s   e Zd ZdZdS )ÚAEADTagErrorz-
    Raised when MAC verification fails.
    N©r   r   r   r!   r   r   r   r   r#   6   s   r#   c                       sf   e Zd ZdZdZdZdZd‡ fdd„	Z‡ fdd	„Zd
d„ Z	dd„ Z
ddd„Zddd„Zdd„ Z‡  ZS )r   zþ
    The hasattr(self, "pc_cls") tests correspond to the legacy API of the
    crypto library. With cryptography v2.0, both CCM and GCM should follow
    the else case.

    Note that the "fixed_iv" in TLS RFCs is called "salt" in the AEAD RFC 5116.
    Úaeadé   é   Nc                    s  ddddœ| _ |du r*d| j d< d| j }|du rFd| j d< d| j }|du r\d| j d< d	}t|tƒrnt|ƒ}tt| ƒ d|¡ tt| ƒ d|¡ tt| ƒ d|¡ t	| d
ƒ�rt| j
tƒrät|  
|¡|  |  ¡ ¡tƒ | jd�| _n"t|  
|¡|  |  ¡ ¡tƒ d�| _n|  |¡| _dS )zò
        'key' and 'fixed_iv' are to be provided as strings, whereas the internal  # noqa: E501
        'nonce_explicit' is an integer (it is simpler for incrementation).
        !! The whole 'nonce' may be called IV in certain RFCs.
        T)ÚkeyÚfixed_ivÚnonce_explicitNFr(   ó    r)   r*   r   Úpc_cls©ÚbackendÚ
tag_length©r.   )ÚreadyÚkey_lenÚfixed_iv_lenÚ
isinstanceÚstrr   r   r   Ú__setattr__Úhasattrr,   r   r   Úpc_cls_modeÚ
_get_noncer   Útag_lenÚ_cipherÚ
cipher_cls©Úselfr(   r)   r*   r   r   r   Ú__init__I   s6    






ý

þ
z_AEADCipher.__init__c                    sŠ   |dkr<| j d ur0t| dƒr(|| j j_n|| j _d| jd< n8|dkrPd| jd< n$|dkrtt|tƒrjt|ƒ}d| jd< t	t
| ƒ ||¡ d S )Nr(   r,   Tr)   r*   )r;   r7   Ú	algorithmr(   Ú_keyr1   r4   r5   r   r   r   r6   ©r>   r   Úvalr   r   r   r6   o   s    



z_AEADCipher.__setattr__c                 C   s   | j t| j| jƒ S ©N)r)   r   r*   Únonce_explicit_len)r>   r   r   r   r9      s    ÿz_AEADCipher._get_noncec                 C   s"   | j d }|d| jd   | _ dS )zK
        Increment the explicit nonce while avoiding any overflow.
        é   é   r'   N)r*   rE   )r>   Úner   r   r   Ú_update_nonce_explicitƒ   s    
z"_AEADCipher._update_nonce_explicitc                 C   s    dt  | j¡v rt||ƒ‚t| dƒrn|  ¡ | jj_d| jj_	| j 
¡ }| |¡ | |¡| ¡  }||j7 }n| j |  ¡ ||¡}t| j| jƒ}|  ¡  || S )aÑ  
        Encrypt the data then prepend the explicit part of the nonce. The
        authentication tag is directly appended with the most recent crypto
        API. Additional data may be authenticated without encryption (as A).

        The 'seq_num' should never be used here, it is only a safeguard needed
        because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py
        actually is a _AEADCipher_TLS13 (even though others are not).
        Fr,   N)ÚsixÚ
itervaluesr1   r   r7   r9   r;   ÚmodeÚ_initialization_vectorÚ_tagÚ	encryptorÚauthenticate_additional_dataÚupdateÚfinalizeÚtagÚencryptr   r*   rE   rI   )r>   ÚPÚAÚseq_numrO   Úresr*   r   r   r   Úauth_encryptŠ   s    





ÿz_AEADCipher.auth_encryptTc           	      C   s(  |d| j … || j | j … || j d…   }}}dt | j¡v rPt|||ƒ‚t|ƒ| _|rr|t 	dt
|ƒ¡7 }t| dƒrà|  ¡ | jj_|| jj_| j ¡ }| |¡ | |¡}z| ¡  W n tyÜ   t|||ƒ‚Y n0 n>z| j |  ¡ || |¡}W n  t�y   t|d|ƒ‚Y n0 |||fS )ae  
        Decrypt the data and authenticate the associated data (i.e. A).
        If the verification fails, an AEADTagError is raised. It is the user's
        responsibility to catch it if deemed useful. If we lack the key, we
        raise a CipherError which contains the encrypted input.

        Note that we add the TLSCiphertext length to A although we're supposed
        to add the TLSCompressed length. Fortunately, they are the same,
        but the specifications actually messed up here. :'(

        The 'add_length' switch should always be True for TLS, but we provide
        it anyway (mostly for test cases, hum).

        The 'seq_num' should never be used here, it is only a safeguard needed
        because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py
        actually is a _AEADCipher_TLS13 (even though others are not).
        NFú!Hr,   ú<unauthenticated data>)rE   r:   rJ   rK   r1   r   r   r*   ÚstructÚpackÚlenr7   r9   r;   rL   rM   rN   Ú	decryptorrP   rQ   rR   r   r#   Údecrypt)	r>   rV   ÚCrW   Z
add_lengthZnonce_explicit_strÚmacr_   rU   r   r   r   Úauth_decrypt¦   s6    þ






þ
z_AEADCipher.auth_decryptc                 C   s$   |   | j| j| j¡}| j ¡ |_|S rD   )r    r(   r)   r*   r1   Úcopy©r>   Úcr   r   r   ÚsnapshotÖ   s    z_AEADCipher.snapshot)NNN)N)NT)r   r   r   r!   Útyper3   rE   r?   r6   r9   rI   rY   rc   rg   r"   r   r   r   r   r   =   s   &

0r   c                   @   s    e Zd ZejZejZdZ	dZ
dS )ÚCipher_AES_128_GCMé   N)r   r   r   r	   ÚAESr,   r
   ÚGCMr8   r2   r:   r   r   r   r   ri   Ý   s   ri   c                   @   s   e Zd ZdZdS )ÚCipher_AES_256_GCMé    N©r   r   r   r2   r   r   r   r   rm   ç   s   rm   c                   @   s   e Zd ZeZdZdZdS )ÚCipher_AES_128_CCMrj   N)r   r   r   r   r<   r2   r:   r   r   r   r   rp   ì   s   rp   c                   @   s   e Zd ZdZdS )ÚCipher_AES_256_CCMrn   Nro   r   r   r   r   rq   ñ   s   rq   c                   @   s   e Zd ZdZdS )ÚCipher_AES_128_CCM_8r'   N©r   r   r   r:   r   r   r   r   rr   ô   s   rr   c                   @   s   e Zd ZdZdS )ÚCipher_AES_256_CCM_8rn   Nro   r   r   r   r   rt   ÷   s   rt   c                       sR   e Zd ZdZdZd‡ fdd„	Z‡ fdd„Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
‡  ZS )Ú_AEADCipher_TLS13zÔ
    The hasattr(self, "pc_cls") enable support for the legacy implementation
    of GCM in the cryptography library. They should not be used, and might
    eventually be removed, with cryptography v2.0. XXX
    r%   Nc                    sð   dddœ| _ |du r(d| j d< d| j }|du rDd| j d< d| j }tt| ƒ d|¡ tt| ƒ d|¡ t| dƒrÂt| jt	ƒr¢t
|  |¡|  |¡tƒ | jd	�| _qìt
|  |¡|  |¡tƒ d
�| _n*| jtkrÚ|  |¡| _n| j|| jd�| _dS )a9  
        'key' and 'fixed_iv' are to be provided as strings. This IV never
        changes: it is either the client_write_IV or server_write_IV.

        Note that 'nonce_explicit' is never used. It is only a safeguard for a
        call in session.py to the TLS 1.2/ChaCha20Poly1305 case (see RFC 7905).
        T)r(   r)   NFr(   r+   r)   r,   r-   r0   )r/   )r1   r2   r3   r   ru   r6   r7   r4   r,   r   r   r8   r   r:   r;   r<   r   r=   r   r   r   r?     s.    





ý

þ

z_AEADCipher_TLS13.__init__c                    sd   |dkr<| j d ur0t| dƒr(|| j j_n|| j _d| jd< n|dkrNd| jd< tt| ƒ ||¡ d S )Nr(   r,   Tr)   )	r;   r7   r@   r(   rA   r1   r   ru   r6   rB   r   r   r   r6   (  s    


z_AEADCipher_TLS13.__setattr__c                 C   s&   | j t|ƒ }d| | }t|| jƒS )Nr+   )r3   r^   r   r)   )r>   rW   ÚpadlenZpadded_seq_numr   r   r   r9   4  s    z_AEADCipher_TLS13._get_noncec                 C   s´   dt  | j¡v rt||ƒ‚t| dƒrpd| jj_|  |¡| jj_	| j 
¡ }| |¡ | |¡| ¡  }||j7 }n@tjršt| jtƒrš| j |  |¡||¡}n| j |  |¡||¡}|S )zß
        Encrypt the data, and append the computed authentication code.
        The additional data for TLS 1.3 is the record header.

        Note that the cipher's authentication tag must be None when encrypting.
        Fr,   N)rJ   rK   r1   r   r7   r;   rL   rN   r9   rM   rO   rP   rQ   rR   rS   r   Úcrypto_valid_advancedr4   r   rT   )r>   rU   rV   rW   rO   rX   r   r   r   rY   9  s    





ÿz_AEADCipher_TLS13.auth_encryptc                 C   sF  |d| j  … || j  d…  }}dt | j¡v r<t||ƒ‚t| dƒrª|  |¡| jj_	|| jj_
| j ¡ }| |¡ | |¡}z| ¡  W n ty¦   t||ƒ‚Y n0 n”zttjrÚt| jtƒrÚ| j |  |¡|| |¡}nBtj�rt| tƒ�r|t dt|ƒ¡7 }| j |  |¡|| |¡}W n t�y<   td|ƒ‚Y n0 ||fS )a1  
        Decrypt the data and verify the authentication code (in this order).
        If the verification fails, an AEADTagError is raised. It is the user's
        responsibility to catch it if deemed useful. If we lack the key, we
        raise a CipherError which contains the encrypted input.
        NFr,   rZ   r[   )r:   rJ   rK   r1   r   r7   r9   r;   rL   rM   rN   r_   rP   rQ   rR   r   r#   r   rw   r4   r   r`   ÚCipher_CHACHA20_POLY1305r\   r]   r^   )r>   rV   ra   rW   rb   r_   rU   r   r   r   rc   R  s4    "






ÿÿz_AEADCipher_TLS13.auth_decryptc                 C   s    |   | j| j¡}| j ¡ |_|S rD   )r    r(   r)   r1   rd   re   r   r   r   rg   u  s    z_AEADCipher_TLS13.snapshot)NNN)r   r   r   r!   rh   r?   r6   r9   rY   rc   rg   r"   r   r   r   r   ru   û   s   %#ru   c                   @   s    e Zd ZeZdZdZdZdZdS )ÚCipher_CHACHA20_POLY1305_TLS13rn   rj   é   r   N)	r   r   r   r   r<   r2   r:   r3   rE   r   r   r   r   ry   |  s
   ry   c                   @   s   e Zd ZdZdS )rx   z�
        This TLS 1.2 cipher actually uses TLS 1.3 logic, as per RFC 7905.
        Changes occur at the record layer (in record.py).
        Nr$   r   r   r   r   rx   ƒ  s   rx   c                   @   s$   e Zd ZejZejZdZ	dZ
dZdS )ÚCipher_AES_128_GCM_TLS13rj   rz   N)r   r   r   r	   rk   r,   r
   rl   r8   r2   r3   r:   r   r   r   r   r{   Œ  s
   r{   c                   @   s   e Zd ZdZdS )ÚCipher_AES_256_GCM_TLS13rn   Nro   r   r   r   r   r|   —  s   r|   c                   @   s   e Zd ZeZdZdZdZdS )ÚCipher_AES_128_CCM_TLS13rj   rz   N)r   r   r   r   r<   r2   r:   r3   r   r   r   r   r}   œ  s   r}   c                   @   s   e Zd ZdZdS )ÚCipher_AES_128_CCM_8_TLS13r'   Nrs   r   r   r   r   r~   ¢  s   r~   )2r!   Ú
__future__r   r\   Zscapy.configr   Zscapy.layers.tls.crypto.pkcs1r   r   Zscapy.layers.tls.crypto.commonr   Zscapy.utilsr   Zscapy.libs.sixZlibsrJ   Zcrypto_validZ&cryptography.hazmat.primitives.ciphersr   r	   r
   Zcryptography.hazmat.backendsr   Zcryptography.exceptionsr   rw   Z+cryptography.hazmat.primitives.ciphers.aeadr   r   r   rh   r   Ú	Exceptionr#   Úwith_metaclassÚobjectr   ri   rm   rp   rq   rr   rt   ru   ry   rx   r{   r|   r}   r~   r   r   r   r   Ú<module>   sL   	  
 