a
    kÄ#dC²  ã                   @   sÚ  d Z ddlmZ zddlmZ W n ey>   ddlmZ Y n0 ddlZddlZddl	Z	ddl
Z
ddlmZmZ ddlmZmZ ddlmZ ddlmZ dd	lmZmZmZmZmZmZmZmZmZ dd
lm Z m!Z!m"Z" ddl#m$Z$m%Z% ddl&m'  m(Z( ddl)m*Z*m+Z+m,Z,m-Z- G dd„ de ƒZ.e!e$e.ej/d� e!e*e.ej/d� e!e.e$ej0d� e!e.e*ej1d� G dd„ de ƒZ2e!e$e2ej3d� e!e*e2ej3d� e!e%e2dd� e!e%e2dd� G dd„ de ƒZ4ej5�røddl6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z> ne ?d¡ dZ9e@Z7d Z< Z=Z>dd„ ZAG dd„ deBƒZCd eCd dddd!�iZDe=�r¤eCd"e=jEe>jFd#�eDd"< d$d%„ ZGeCd&e=jEe>jHd'd(d)eGd*�eDd&< d+d%„ ZIeCd,e;jJd-dd)d'd(d.eId/�	eDd,< eCd0e;jKdd-d'd(d1d.eId2�	eDd0< eCd3e;jLdd4d'd(d)d.eId2�	eDd3< eCd5e=jMe>jFd6d7�eDd5< eCd8e=jMe>jFd#�eDd8< ztdd9lNmOZO e
 P¡ �J e
jQd:eOd;� eCd<e=jRe>jFd#�eDd<< eCd=e=jSe>jFd#�eDd=< W d  ƒ n1 �s‚0    Y  W n eT�y¢   Y n0 ej5�rÒdd>lUmVZV dd?lWmXZX dd@lYmZZZ nd ZV ZXZZG dAdB„ dBe@ƒZ[G dCdD„ dDeBƒZ\d e\d ddddE�iZ]eV�rŒeZ�rŒe\dFeVeZj^dGdE�e]dF< e\dHeVeZj_d.dE�e]dH< e\dIeVeZj`dJdE�e]dI< e\dKeVeZjad4dE�e]dK< e\dLeVeZjbdGdE�e]dL< eX�r°e=�r°e\dMeXe=jEdGdNdO�e]dM< dPdQ„ ZcdRZddXdTdU„ZeG dVdW„ dWeBƒZfdS )Yaç  
IPsec layer
===========

Example of use:

>>> sa = SecurityAssociation(ESP, spi=0xdeadbeef, crypt_algo='AES-CBC',
...                          crypt_key=b'sixteenbytes key')
>>> p = IP(src='1.1.1.1', dst='2.2.2.2')
>>> p /= TCP(sport=45012, dport=80)
>>> p /= Raw('testdata')
>>> p = IP(raw(p))
>>> p
<IP  version=4L ihl=5L tos=0x0 len=48 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0x74c2 src=1.1.1.1 dst=2.2.2.2 options=[] |<TCP  sport=45012 dport=http seq=0 ack=0 dataofs=5L reserved=0L flags=S window=8192 chksum=0x1914 urgptr=0 options=[] |<Raw  load='testdata' |>>>  # noqa: E501
>>>
>>> e = sa.encrypt(p)
>>> e
<IP  version=4L ihl=5L tos=0x0 len=76 id=1 flags= frag=0L ttl=64 proto=esp chksum=0x747a src=1.1.1.1 dst=2.2.2.2 |<ESP  spi=0xdeadbeef seq=1 data=b'\xf8\xdb\x1e\x83[T\xab\\\xd2\x1b\xed\xd1\xe5\xc8Y\xc2\xa5d\x92\xc1\x05\x17\xa6\x92\x831\xe6\xc1]\x9a\xd6K}W\x8bFfd\xa5B*+\xde\xc8\x89\xbf{\xa9' |>>  # noqa: E501
>>>
>>> d = sa.decrypt(e)
>>> d
<IP  version=4L ihl=5L tos=0x0 len=48 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0x74c2 src=1.1.1.1 dst=2.2.2.2 |<TCP  sport=45012 dport=http seq=0 ack=0 dataofs=5L reserved=0L flags=S window=8192 chksum=0x1914 urgptr=0 options=[] |<Raw  load='testdata' |>>>  # noqa: E501
>>>
>>> d == p
True
é    )Úabsolute_import)ÚgcdN)ÚconfÚcrypto_validator)ÚorbÚraw)Ú	IP_PROTOS)Úlog_loading)	ÚByteEnumFieldÚ	ByteFieldÚIntFieldÚPacketFieldÚ
ShortFieldÚStrFieldÚ	XIntFieldÚ	XStrFieldÚXStrLenField)ÚPacketÚbind_layersÚRaw)ÚIPÚUDP)ÚIPv6ÚIPv6ExtHdrHopByHopÚIPv6ExtHdrDestOptÚIPv6ExtHdrRoutingc                   @   sœ   e Zd ZdZd Zdd„ Zeddeƒeddƒe	ddƒe
dd	ƒed
dƒedded�edddd„ d�gZedejiedejiedejiedejiedejiiZdS )ÚAHzO
    Authentication Header

    See https://tools.ietf.org/rfc/rfc4302.txt
    c                 C   s   | j d d S )zã
        Compute the size of the ICV based on the payloadlen field.
        Padding size is included as it can only be known from the authentication  # noqa: E501
        algorithm provided by the Security Association.
        é   é   )Ú
payloadlen©Úself© r"   úI/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/layers/ipsec.pyZ__get_icv_lenB   s    	zAH.__get_icv_lenÚnhNr   ÚreservedÚspir   Úseqr   Úicv)Zlength_fromÚpaddingc                 C   s   dS )Nr   r"   )Úxr"   r"   r#   Ú<lambda>U   ó    zAH.<lambda>Úproto)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚnameZ_AH__get_icv_lenr
   r   r   r   r   r   r   Úfields_descr   ÚsocketÚ
IPPROTO_AHr   r   r   r   Úoverload_fieldsr"   r"   r"   r#   r   9   s"   
ø




ûr   )r-   )r$   c                   @   sf   e Zd ZdZd ZeddƒeddƒeddƒgZe	de
jied	e
jied	e
jied	e
jied	e
jiiZdS )
ÚESPzW
    Encapsulated Security Payload

    See https://tools.ietf.org/rfc/rfc4303.txt
    r&   r   r'   r   ÚdataNr-   r$   )r.   r/   r0   r1   r2   r   r   r   r3   r   r4   ÚIPPROTO_ESPr   r   r   r   r6   r"   r"   r"   r#   r7   i   s   ý




ûr7   i”  )Údport)Zsportc                
   @   sd   e Zd ZdZdZeddƒeddƒeddƒedde	ƒed	dƒe
d
dƒeddeƒeddƒgZdd„ ZdS )Ú	_ESPPlainz>
    Internal class to represent unencrypted ESP packets.
    r7   r&   r   r'   ÚivÚ r8   r)   Úpadlenr$   r(   c                 C   s"   t | jƒ| j t d| j| j¡ S )NÚBB)r   r8   r)   ÚstructÚpackr>   r$   r    r"   r"   r#   Údata_for_encryption›   s    z_ESPPlain.data_for_encryptionN)r.   r/   r0   r1   r2   r   r   r   r   r   r   r
   r   r3   rB   r"   r"   r"   r#   r;   ˆ   s   

ör;   )Ú
InvalidTag)Údefault_backend)ÚaeadÚCipherÚ
algorithmsÚmodeszQCan't import python-cryptography v1.7+. Disabled IPsec encryption/authentication.c                 C   s.   | dks|dkrdS t | | ƒt| |ƒ S dS )z3
    Least Common Multiple between 2 integers.
    r   N)Úabsr   )ÚaÚbr"   r"   r#   Ú_lcm³   s    rL   c                   @   sT   e Zd ZdZddd„Zdd„ Zdd„ Zedd	d
„ƒZdd„ Z	ddd„Z
ddd„ZdS )Ú	CryptAlgoz$
    IPsec encryption algorithm
    Nc
           
      C   s  || _ || _|| _|| _d| _d| _trf| jdurDt| jtjƒ| _n"| jt	j
t	jt	jfv rfd| _d| _|durv|| _n|durŒ|jd | _nd| _|du r¤| j| _n|| _|durº|| _n&|durÚtdd„ |jD ƒƒ| _nd| _|du rðd| _n|| _|	du �rd	d
„ | _n|	| _dS )a‰  
        :param name: the name of this encryption algorithm
        :param cipher: a Cipher module
        :param mode: the mode used with the cipher module
        :param block_size: the length a block for this algo. Defaults to the
                           `block_size` of the cipher.
        :param iv_size: the length of the initialization vector of this algo.
                        Defaults to the `block_size` of the cipher.
        :param key_size: an integer or list/tuple of integers. If specified,
                         force the secret keys length to one of the values.
                         Defaults to the `key_size` of the cipher.
        :param icv_size: the length of the Integrity Check Value of this algo.
                         Used by Combined Mode Algorithms e.g. GCM
        :param salt_size: the length of the salt to use as the IV prefix.
                          Usually used by Counter modes e.g. CTR
        :param format_mode_iv: function to format the Initialization Vector
                               e.g. handle the salt value
                               Default is the random buffer from `generate_iv`
        FNTé   r   c                 s   s   | ]}|d  V  qdS )rN   Nr"   )Ú.0Úir"   r"   r#   Ú	<genexpr>ø   r,   z%CryptAlgo.__init__.<locals>.<genexpr>r   c                 [   s   | S ©Nr"   )r<   Úkwr"   r"   r#   r+     r,   z$CryptAlgo.__init__.<locals>.<lambda>)r2   ÚcipherÚmodeÚicv_sizeÚis_aeadÚciphers_aead_apirH   Ú
issubclassZModeWithAuthenticationTagrE   ÚAESGCMÚAESCCMÚChaCha20Poly1305Ú
block_sizeÚiv_sizeÚkey_sizeÚtupleZ	key_sizesÚ	salt_sizeÚ_format_mode_iv)
r!   r2   rT   rU   r]   r^   r_   rV   ra   Úformat_mode_ivr"   r"   r#   Ú__init__Â   sF    
ÿÿ

zCryptAlgo.__init__c                 C   s<   | j r8t|ƒ| j ks8t|ƒ| j v s8tdt|ƒ| j f ƒ‚dS )ú[
        Check that the key length is valid.

        :param key:    a byte string
        zinvalid key size %s, must be %sN©r_   ÚlenÚ	TypeError©r!   Úkeyr"   r"   r#   Ú	check_key  s    "ÿzCryptAlgo.check_keyc                 C   s   t  | j¡S )z:
        Generate a random initialization vector.
        )ÚosÚurandomr^   r    r"   r"   r#   Úgenerate_iv  s    zCryptAlgo.generate_ivc                 C   sN   | j r0|dur0t|  |¡|  ||t|ƒ¡tƒ ƒS t|  |¡|  |¡tƒ ƒS dS )aÀ  
        :param key:     the secret key, a byte string
        :param mode_iv: the initialization vector or nonce, a byte string.
                        Formatted by `format_mode_iv`.
        :param digest:  also known as tag or icv. A byte string containing the
                        digest of the encrypted data. Only use this during
                        decryption!

        :returns:    an initialized cipher object for this algo
        N)rW   rF   rT   rU   rg   rD   )r!   rj   Úmode_ivÚdigestr"   r"   r#   Ú
new_cipher  s    ýýzCryptAlgo.new_cipherc                 C   s†   t |jƒd }t| jdƒ}| | |_tjd|j gtd|jd ƒ¢R Ž |_t |j	ƒt |jƒ t |jƒ d }|d dkr‚t
dƒ‚|S )ai  
        Add the correct amount of padding so that the data to encrypt is
        exactly a multiple of the algorithm's block size.

        Also, make sure that the total ESP packet length is a multiple of 4
        bytes.

        :param esp:    an unencrypted _ESPPlain packet

        :returns:    an unencrypted _ESPPlain packet with valid padding
        é   r   ÚBr   r   zAThe size of the ESP data is not aligned to 32 bits after padding.)rg   r8   rL   r]   r>   r@   rA   Úranger)   r<   Ú
ValueError)r!   ÚespÚdata_lenÚalignZpayload_lenr"   r"   r#   Úpad2  s    &"zCryptAlgo.padFr   c                 C   s   |du r| j r| jnd}| ¡ }| j�r| j| ||jd�}d}	| j rp|r^t d|j||j	¡}	nt d|j|j	¡}	| j
r¬| jtjkr’| j||d�}
n
|  |¡}
|
 |||	¡}n\|  ||¡}
|
 ¡ }| j rö| |	¡ | |¡| ¡  }||jd|… 7 }n| |¡| ¡  }t|j|j	|j| d�S )ar  
        Encrypt an ESP packet

        :param sa:   the SecurityAssociation associated with the ESP packet.
        :param esp:  an unencrypted _ESPPlain packet with valid padding
        :param key:  the secret key used for encryption
        :param icv_size: the length of the icv used for integrity check
        :esn_en:     extended sequence number enable which allows to use 64-bit
                     sequence number instead of 32-bit when using an AEAD
                     algorithm
        :esn:        extended sequence number (32 MSB)
        :return:    a valid ESP packet encrypted with this algorithm
        Nr   )ÚalgoÚsar<   ú!LLLú!LL©Z
tag_length)r&   r'   r8   )rW   rV   rB   rT   rb   r<   r@   rA   r&   r'   rX   rE   r[   Úencryptrq   Ú	encryptorÚauthenticate_additional_dataÚupdateÚfinalizeÚtagr7   )r!   r{   rv   rj   rV   Úesn_enÚesnr8   ro   ÚaadrT   r€   r"   r"   r#   r   U  s.    

zCryptAlgo.encryptc              
   C   sö  |du r| j r| jnd}|jd| j… }|j| jt|jƒ| … }|jt|jƒ| d… }	| j�rŠ| j||d�}
d}| j r¦|r”t d|j	||j
¡}nt d|j	|j
¡}| j�r| jtjkrÊ| j||d�}n
|  |¡}z| |
||	 |¡}W n. t�y } zt|ƒ‚W Y d}~n
d}~0 0 nn|  ||
|	¡}| ¡ }| j �rD| |¡ z| |¡| ¡  }W n. t�yˆ } zt|ƒ‚W Y d}~n
d}~0 0 t|d ƒ}t|d ƒ}|dt|ƒ| d	 … }|t|ƒ| d	 t|ƒd	 … }t|j	|j
||||||	d
�S )aÍ  
        Decrypt an ESP packet

        :param sa: the SecurityAssociation associated with the ESP packet.
        :param esp: an encrypted ESP packet
        :param key: the secret key used for encryption
        :param icv_size: the length of the icv used for integrity check
        :param esn_en: extended sequence number enable which allows to use
                       64-bit sequence number instead of 32-bit when using an
                       AEAD algorithm
        :param esn: extended sequence number (32 MSB)
        :returns: a valid ESP packet encrypted with this algorithm
        :raise scapy.layers.ipsec.IPSecIntegrityError: if the integrity check
            fails with an AEAD algorithm
        Nr   )r{   r<   r|   r}   r~   éþÿÿÿéÿÿÿÿrr   )r&   r'   r<   r8   r)   r>   r$   r(   )rW   rV   r8   r^   rg   rT   rb   r@   rA   r&   r'   rX   rE   r[   ÚdecryptrC   ÚIPSecIntegrityErrorrq   Ú	decryptorr�   r‚   rƒ   r   r;   )r!   r{   rv   rj   rV   r…   r†   r<   r8   r(   ro   r‡   rT   ÚerrrŒ   r>   r$   r)   r"   r"   r#   rŠ   ƒ  sR    
 
 ùzCryptAlgo.decrypt)NNNNNN)N)NFr   )NFr   )r.   r/   r0   r1   rd   rk   rn   r   rq   ry   r   rŠ   r"   r"   r"   r#   rM   ½   s     ÿ
D
#
.rM   ÚNULL)rT   rU   r^   zAES-CBC)rT   rU   c                 K   s   | j | d S )Ns      ©Ú
crypt_salt©r{   r<   rS   r"   r"   r#   r+   Ö  r,   r+   zAES-CTRr   rN   r   )rT   rU   r]   r^   ra   rc   c                 K   s
   | j | S rR   r�   r‘   r"   r"   r#   r+   Þ  r,   zAES-GCM)é   é   é    r’   )rT   r_   rU   ra   r]   r^   rV   rc   zAES-CCMé   )rT   rU   r_   r]   r^   ra   rV   rc   zCHACHA20-POLY1305r”   ZDES)rN   )rT   rU   r_   Z3DES)ÚCryptographyDeprecationWarningÚignore)ÚcategoryZCASTÚBlowfish)ÚHMAC)ÚCMAC)Úhashesc                   @   s   e Zd ZdZdS )r‹   z5
    Error risen when the integrity check fails.
    N)r.   r/   r0   r1   r"   r"   r"   r#   r‹   %  s   r‹   c                   @   sB   e Zd ZdZddd„Zdd„ Zedd„ ƒZddd„Zddd„Z	dS )ÚAuthAlgoz#
    IPsec integrity algorithm
    Nc                 C   s"   || _ || _|| _|| _|| _dS )aØ  
        :param name: the name of this integrity algorithm
        :param mac: a Message Authentication Code module
        :param digestmod: a Hash or Cipher module
        :param icv_size: the length of the integrity check value of this algo
        :param key_size: an integer or list/tuple of integers. If specified,
                         force the secret keys length to one of the values.
                         Defaults to the `key_size` of the cipher.
        N)r2   ÚmacÚ	digestmodrV   r_   )r!   r2   rž   rŸ   rV   r_   r"   r"   r#   rd   1  s
    
zAuthAlgo.__init__c                 C   s.   | j r*t|ƒ| j vr*tdt|ƒ| j f ƒ‚dS )re   z&invalid key size %s, must be one of %sNrf   ri   r"   r"   r#   rk   A  s    ÿzAuthAlgo.check_keyc                 C   s6   | j tu r|   |  |¡tƒ ¡S |   ||  ¡ tƒ ¡S dS )zn
        :param key:    a byte string
        :returns:       an initialized mac object for this algo
        N)rž   r›   rŸ   rD   ri   r"   r"   r#   Únew_macK  s    
zAuthAlgo.new_macFr   c                 C   s´   | j s
|S |  |¡}| t¡rR| t|t ƒ¡ |t  j| ¡ d| j… 7  _n^| t	¡r°t
| ¡ dd�}|r†t|ƒt d|¡ }nt|ƒ}| |¡ | ¡ d| j… |t	 _|S )a¶  
        Sign an IPsec (ESP or AH) packet with this algo.

        :param pkt:    a packet that contains a valid encrypted ESP or AH layer
        :param key:    the authentication key, a byte string
        :param esn_en: extended sequence number enable which allows to use
                       64-bit sequence number instead of 32-bit
        :param esn: extended sequence number (32 MSB)

        :returns: the signed packet
        NT©Úsendingú!L)rž   r    Úhaslayerr7   r‚   r   r8   rƒ   rV   r   Úzero_mutable_fieldsÚcopyr@   rA   r(   )r!   Úpktrj   r…   r†   rž   ÚcloneÚtempr"   r"   r#   ÚsignV  s    

"

zAuthAlgo.signc           
      C   s>  | j r| jdkrdS |  |¡}d}t|tƒrt|jt|jƒ| j d… }| ¡ }|jdt|jƒ| j … |_t|ƒ}n�| 	t
¡�rt|t
 jƒ| jkrÈ|t
 j| jd… |t
 _|t
 jd| j… |t
 _|t
 j}t| ¡ dd�}|rüt|ƒt d|¡ }nt|ƒ}| |¡ | ¡ d| j… }	||	k�r:td||	f ƒ‚dS )a  
        Check that the integrity check value (icv) of a packet is valid.

        :param pkt:    a packet that contains a valid encrypted ESP or AH layer
        :param key:    the authentication key, a byte string
        :param esn_en: extended sequence number enable which allows to use
                       64-bit sequence number instead of 32-bit
        :param esn: extended sequence number (32 MSB)

        :raise scapy.layers.ipsec.IPSecIntegrityError: if the integrity check
            fails
        r   Nz	not foundFr¡   r£   zpkt_icv=%r, computed_icv=%r)rž   rV   r    Ú
isinstancer7   r8   rg   r¦   r   r¤   r   r(   r)   r¥   r@   rA   r‚   rƒ   r‹   )
r!   r§   rj   r…   r†   rž   Zpkt_icvr¨   r©   Zcomputed_icvr"   r"   r#   Úverifyv  s0    





ÿzAuthAlgo.verify)N)Fr   )Fr   )
r.   r/   r0   r1   rd   rk   r   r    rª   r¬   r"   r"   r"   r#   r�   ,  s   




 r�   )rž   rŸ   rV   zHMAC-SHA1-96é   zSHA2-256-128zSHA2-384-192r“   zSHA2-512-256zHMAC-MD5-96zAES-CMAC-96)r’   )rž   rŸ   rV   r_   c                 C   s¼   |   t| ƒ¡}|j}d}|jdkrH|j}||_| ¡  |`|`|||fS d}|}t|t	t
tfƒr–t|t	ƒrjt|t
ƒrzd}nt|tƒrŠ|rŠq–|}|j}qP|j}||_| ¡  |`|||fS dS )a‡  
    Split an IP(v6) packet in the correct location to insert an ESP or AH
    header.

    :param orig_pkt: the packet to split. Must be an IP or IPv6 packet
    :param transport_proto: the IPsec protocol number that will be inserted
                            at the split position.
    :returns: a tuple (header, nh, payload) where nh is the protocol number of
             payload.
    Nr   FT)Ú	__class__r   ÚpayloadÚversionr-   Úremove_payloadÚchksumrg   r«   r   r   r   r$   Úplen)Zorig_pktZtransport_protoÚheaderÚnext_hdrr$   Zfound_rt_hdrÚprevr"   r"   r#   Úsplit_for_transportÎ  s2    



r·   )r   r   rr   é   é   é   é   Fc                 C   s@  |   t¡r$dt| t jƒ | t _ntdƒ‚| jdkr’d| _d| _d| _d| _	g }| j
D ]0}|jtv rr| |¡ qX| tdt|ƒ ƒ¡ qX|| _
nªd| _d| _d| _| j}t|tttfƒ�r<t|ttfƒrî|j
D ]}|jd@ rÐd|j |_qÐnFt|tƒ�r<|�r<d|_|j�r4|j ¡ }|j d| j¡ || _n�q<|j}qª| S )aJ  
    When using AH, all "mutable" fields must be "zeroed" before calculating
    the ICV. See RFC 4302, Section 3.3.3.1. Handling Mutable Fields.

    :param pkt: an IP(v6) packet containing an AH layer.
                NOTE: The packet will be modified
    :param sending: if true, ipv6 routing headers will not be reordered
    ó    zno AH layer foundr   r   r”   )r¤   r   rg   r(   rh   r°   ZtosÚflagsÚttlr²   ÚoptionsÚoptionÚIMMUTABLE_IPV4_OPTIONSÚappendr   ZtcÚflZhlimr¯   r«   r   r   r   ZotypeZoptlenZoptdataZsegleftÚ	addressesÚpopÚinsertÚdst)r§   r¢   Zimmutable_optsÚoptrµ   Úfinalr"   r"   r#   r¥     s@    







r¥   c                
   @   sf   e Zd ZdZeefZddd„Zdd	„ Zdd
d„Z	ddd„Z
ddd„Zddd„Zddd„Zddd„ZdS )ÚSecurityAssociationzd
    This class is responsible of "encryption" and "decryption" of IPsec packets.  # noqa: E501
    r   NFr   c                 C   s’  |t tt jtjfvrtdƒ‚t|tjƒr4t|ƒ| _n|| _|| _	|| _
|| _|| _|rÄ|tvrrtd|ttƒf ƒ‚t| | _|r¶| jj}|dt|ƒ| … | _|t|ƒ| d… | _qÚd| _d| _ntd | _d| _d| _|| _|�r|tv�rtd|ttƒf ƒ‚t| | _|| _ntd | _d| _|	�rPt|	ttfƒ�sPtdtjtjf ƒ‚|	| _|
�rˆ|t u�rntdƒ‚t|
tƒ�sˆtdtj ƒ‚|
| _dS )	a`  
        :param proto: the IPsec proto to use (ESP or AH)
        :param spi: the Security Parameters Index of this SA
        :param seq_num: the initial value for the sequence number on encrypted
                        packets
        :param crypt_algo: the encryption algorithm name (only used with ESP)
        :param crypt_key: the encryption key (only used with ESP)
        :param crypt_icv_size: change the default size of the crypt_algo
                               (only used with ESP)
        :param auth_algo: the integrity algorithm name
        :param auth_key: the integrity key
        :param tunnel_header: an instance of a IP(v6) header that will be used
                              to encapsulate the encrypted packets.
        :param nat_t_header: an instance of a UDP header that will be used
                             for NAT-Traversal.
        :param esn_en: extended sequence number enable which allows to use
                       64-bit sequence number instead of 32-bit when using an
                       AEAD algorithm
        :param esn: extended sequence number (32 MSB)
        zproto must be either ESP or AHz&unsupported encryption algo %r, try %rNrŽ   z%unsupported integrity algo %r, try %rztunnel_header must be %s or %sz%nat_t_header is only allowed with ESPznat_t_header must be %s)r7   r   r2   ru   r«   ÚsixÚstring_typesÚevalr-   r&   Úseq_numr…   r†   ÚCRYPT_ALGOSrh   ÚlistÚ
crypt_algora   rg   Ú	crypt_keyr�   Úcrypt_icv_sizeÚ
AUTH_ALGOSÚ	auth_algoÚauth_keyr   r   Útunnel_headerr   Únat_t_header)r!   r-   r&   rÎ   rÑ   rÒ   rÓ   rÕ   rÖ   r×   rØ   r…   r†   ra   r"   r"   r#   rd   [  sV    
ÿ



ÿ


zSecurityAssociation.__init__c                 C   s$   |j | j kr td|j | j f ƒ‚d S )Nz.packet spi=0x%x does not match the SA spi=0x%x)r&   rh   )r!   r§   r"   r"   r#   Ú	check_spi©  s    
ÿzSecurityAssociation.check_spic                 C   sŽ  |d u r| j  ¡ }n t|ƒ| j jkr4td| j j ƒ‚t| j|pB| j|d�}| jrŒ| j 	¡ }|j
dkrr|`|`|`n|`|`| t|| ƒ¡}t|tjƒ\}}	}
|
|_|	|_| j  |¡}| j j| || j| j|pÐ| j|pØ| jd�}| j || j¡ | j�r(| j 	¡ }d|_|`|j
dk�r|`n|`|| }|j
dk�rZt|ƒt|ƒ |_|`| t|ƒ¡}nt|jƒt|ƒ |_|d u �r†|  jd7  _|| S )Nziv length must be %s)r&   r'   r<   r   ©r…   r†   r   r   ) rÑ   rn   rg   r^   rh   r;   r&   rÎ   r×   r¦   r°   r-   r²   r$   r³   r®   r   r·   r4   r9   r8   ry   r   rÒ   rÓ   r…   r†   rÕ   rª   rÖ   rØ   r¯   )r!   r§   rÎ   r<   r…   r†   rv   ÚtunnelÚ	ip_headerr$   r¯   rØ   r"   r"   r#   Ú_encrypt_esp®  sP    

ý

z SecurityAssociation._encrypt_espc                 C   s~  t | j|p| jd| jj d�}| jr`| j ¡ }|jdkrF|`|`	|`
n|`|`| t|| ƒ¡}t|tjƒ\}}}	||_|jdkr¨t	|ƒd dkr¨dt	|ƒ d  |_n$t	|ƒd dkrÌdt	|ƒ d  |_t	|ƒd d |_|jdk�rt	|ƒt	|ƒ t	|	ƒ |_	|`
| t|ƒ¡}nt	|jƒt	|ƒ t	|	ƒ |_| jj|| |	 | j|�pR| j|�p\| jd�}
|d u �rz|  jd	7  _|
S )
Nr¼   )r&   r'   r(   r   r¹   rN   r   rr   rÚ   r   )r   r&   rÎ   rÕ   rV   r×   r¦   r°   r-   rg   r²   r$   r³   r®   r   r·   r4   r5   r)   r   r¯   rª   rÖ   r…   r†   )r!   r§   rÎ   r…   r†   ÚahrÛ   rÜ   r$   r¯   Z
signed_pktr"   r"   r#   Ú_encrypt_ahè  s@    
ÿ



ý
zSecurityAssociation._encrypt_ahc                 C   sT   t || jƒs td|j| jf ƒ‚| jtu r>| j|||||d�S | j||||d�S dS )aÓ  
        Encrypt (and encapsulate) an IP(v6) packet with ESP or AH according
        to this SecurityAssociation.

        :param pkt:     the packet to encrypt
        :param seq_num: if specified, use this sequence number instead of the
                        generated one
        :param esn_en:  extended sequence number enable which allows to
                        use 64-bit sequence number instead of 32-bit when
                        using an AEAD algorithm
        :param esn:     extended sequence number (32 MSB)
        :param iv:      if specified, use this initialization vector for
                        encryption instead of a random one.

        :returns: the encrypted/encapsulated packet
        z*cannot encrypt %s, supported protos are %s)rÎ   r<   r…   r†   )rÎ   r…   r†   N)r«   ÚSUPPORTED_PROTOSrh   r®   r-   r7   rÝ   rß   )r!   r§   rÎ   r<   r…   r†   r"   r"   r#   r     s    
ÿ
þÿzSecurityAssociation.encryptTc           	      C   s,  |t  }|r&|  |¡ | j || j¡ | jj| || j| jpH| jj	pH| jj	|pP| j
|pX| jd�}| jrž| ¡  |jdkr€|j|_n|j|_| |j¡}||jƒS |}|jdkrä|j|_|`| ¡  t|ƒt|jƒ |_| t|ƒ¡}n*|j|j_|j ¡  t|jƒt|jƒ |_| |j¡}|||jƒ S d S ©NrÚ   r   )r7   rÙ   rÕ   r¬   rÖ   rÑ   rŠ   rÒ   rÓ   rV   r…   r†   r×   r±   r°   r$   r-   Zguess_payload_classr8   r²   rg   r®   r   Ú
underlayerr¯   r³   )	r!   r§   r¬   r…   r†   Z	encryptedrv   ÚclsrÜ   r"   r"   r#   Ú_decrypt_esp9  s>    
ÿû





z SecurityAssociation._decrypt_espc                 C   sÊ   |r0|   |¡ | jj|| j|p"| j|p*| jd� |t }|j}| d ¡ | j	rR|S |}|j
dkr–|j|_|`| ¡  t|ƒt|ƒ |_| t|ƒ¡}n(|j|j_|j ¡  t|jƒt|ƒ |_|| S d S rá   )rÙ   rÕ   r¬   rÖ   r…   r†   r   r¯   Zremove_underlayerr×   r°   r$   r-   r²   r±   rg   r®   r   râ   r³   )r!   r§   r¬   r…   r†   rÞ   r¯   rÜ   r"   r"   r#   Ú_decrypt_ahg  s,    
þ



zSecurityAssociation._decrypt_ahc                 C   s„   t || jƒs td|j| jf ƒ‚| jtu rF| t¡rF| j||||d�S | jtu rl| t¡rl| j	||||d�S td|| jj
f ƒ‚dS )aY  
        Decrypt (and decapsulate) an IP(v6) packet containing ESP or AH.

        :param pkt:     the packet to decrypt
        :param verify:  if False, do not perform the integrity check
        :param esn_en:  extended sequence number enable which allows to use
                        64-bit sequence number instead of 32-bit when using an
                        AEAD algorithm
        :param esn:        extended sequence number (32 MSB)
        :returns: the decrypted/decapsulated packet
        :raise scapy.layers.ipsec.IPSecIntegrityError: if the integrity check
            fails
        z*cannot decrypt %s, supported protos are %s)r¬   r…   r†   z%s has no %s layerN)r«   rà   rh   r®   r-   r7   r¤   rä   r   rå   r2   )r!   r§   r¬   r…   r†   r"   r"   r#   rŠ   ‡  s    
ÿÿzSecurityAssociation.decrypt)
r   NNNNNNNFr   )NNNN)NFr   )NNNN)TNN)TNN)TNN)r.   r/   r0   r1   r   r   rà   rd   rÙ   rÝ   rß   r   rä   rå   rŠ   r"   r"   r"   r#   rÊ   T  s       ý
N
:
5

.
 rÊ   )F)gr1   Ú
__future__r   Úmathr   ÚImportErrorÚ	fractionsrl   r4   r@   ÚwarningsZscapy.configr   r   Zscapy.compatr   r   Z
scapy.datar   Zscapy.errorr	   Zscapy.fieldsr
   r   r   r   r   r   r   r   r   Zscapy.packetr   r   r   Zscapy.layers.inetr   r   Zscapy.libs.sixZlibsrË   Zscapy.layers.inet6r   r   r   r   r   r5   Ú
IPPROTO_IPÚIPPROTO_IPV6r7   r9   r;   Zcrypto_validZcryptography.exceptionsrC   Zcryptography.hazmat.backendsrD   Z&cryptography.hazmat.primitives.ciphersrE   rF   rG   rH   ÚinfoÚ	ExceptionrL   ÚobjectrM   rÏ   ZAESZCBCZ_aes_ctr_format_mode_ivZCTRZ_salt_format_mode_ivrZ   r[   r\   Z	TripleDESZcryptography.utilsr–   Úcatch_warningsÚfilterwarningsZCAST5r™   ÚAttributeErrorZ#cryptography.hazmat.primitives.hmacrš   Z#cryptography.hazmat.primitives.cmacr›   Zcryptography.hazmat.primitivesrœ   r‹   r�   rÔ   ÚSHA1ÚSHA256ÚSHA384ÚSHA512ÚMD5r·   rÁ   r¥   rÊ   r"   r"   r"   r#   Ú<module>   s>  ,(

  ÿþ
ú
ø
	ø
	ø
ý
þ

ÿþ
þ.~ÿý
ý
ý
ý
ý
ü
	3
H