
    hϽ                     	   d Z 	 ddlmZ n# e$ r	 ddlmZ Y nw xY w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mZ dd	lmZm Z m!Z!m"Z"m#Z# dd
l$m%Z%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+  G d de          Z, e"e%e,ej-                    e"e(e,ej-                    e"e,e%ej.                    e"e,e(ej/                    G d de          Z0 G d de          Z1 G d de          Z2 e"e%e0ej3                    e"e(e0ej3                    e!e&e0d            e!e&e0d            e#e&e0dd            e#e&e1dd            e#e&e2dd            G d de          Z4e
j5        r-ddl6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z> 	 ddl?m=Z@ n'# e$ r e=Z@Y nw xY w ejA        d            dZ9eBZ7dxZ<xZ=Z>d! ZC G d" d#eD          ZEd$ eEd$ddd%          iZFe=r eEd&e=jG        e>jH        '          eFd&<   d( ZI eEd)e=jG        e>jJ        d*d+d,eI-          eFd)<   d. ZK eEd/e;jL        d0dd,d*d+d1eK2	  	        eFd/<    eEd3e;jL        d0dd,d*d+d1eK2	  	        eFd3<    eEd4e;jM        dd0d*d+d5d1eK6	  	        eFd4<    eEd7e;jN        dd8d*d+d,d1eK6	  	        eFd7<    eEd9e@jO        e>jH        d:;          eFd9<    eEd<e@jO        e>jH        '          eFd<<   e@e=u rvdd=lPmQZQ  ejR                    5   ejS        d>eQ?            eEd@e@jT        e>jH        '          eFd@<    eEdAe@jU        e>jH        '          eFdA<   ddd           n# 1 swxY w Y   n6 eEd@e@jT        e>jH        '          eFd@<    eEdAe@jU        e>jH        '          eFdA<   e
j5        rddBlVmWZW ddClXmYZY ddDlZm[Z[ ndxZWxZYZ[ G dE dFeB          Z\ G dG dHeD          Z]d$ e]d$dddI          iZ^eWrue[rs e]dJeWe[j_        dKI          e^dJ<    e]dLeWe[j`        d1I          e^dL<    e]dMeWe[ja        dNI          e^dM<    e]dOeWe[jb        d8I          e^dO<    e]dPeWe[jc        dKI          e^dP<   eYre=r e]dQeYe=jG        dKdRS          e^dQ<   dT ZddUZedZdWZf G dX dYeD          ZgdS )[a  
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
    )gcdN)confcrypto_validator)orbraw)	IP_PROTOS)log_loading)
ByteEnumField	ByteFieldIntFieldPacketField
ShortFieldStrField
XByteField	XIntField	XStrFieldXStrLenField)PacketRawbind_bottom_upbind_layersbind_top_down)IPUDP)IPv6IPv6ExtHdrHopByHopIPv6ExtHdrDestOptIPv6ExtHdrRoutingc                   $   e Zd ZdZd Zd Z edde           edd           e	dd           e
dd           ed	d
           edde           e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                     | j         dz
  dz  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selfs    V/mounts/lovelace/software/anaconda3/lib/python3.11/site-packages/scapy/layers/ipsec.py__get_icv_lenzAH.__get_icv_lenP   s     !#q((    nhNr$   reservedspir"   seqr   icv)length_frompaddingc                     dS )Nr    )xs    r'   <lambda>zAH.<lambda>c   s    A r)   proto)__name__
__module____qualname____doc__name_AH__get_icv_lenr
   r   r   r   r   r   r   fields_descr   socket
IPPROTO_AHr   r   r   r   overload_fieldsr2   r)   r'   r    r    G   s          D	) 	) 	) 	dD),,	,%%
:t$$	%$$UDm<<<Y++>>>	K 	Wf'(tV&'T6#45D&"34D&"34OOOr)   r    )r5   )r*   c                       e Zd ZdZd Z edd           edd           edd          gZe	dd            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   dataNc                    |rt          |          dk    r.t          j        d|dd                   d         dk    rt          S t          |          dk    r&t          j        d|          d         dk    rt          S t
          S | S )Nr#   z!Ir   r"   z!B   )lenstructunpackNON_ESPNAT_KEEPALIVErA   )cls_pktargskargss       r'   dispatch_hookzESP.dispatch_hook   s{     	4yyA~~&-d1Q3i"@"@"Ct"K"KTaFM$$=$=a$@D$H$H$$

r)   r5   r*   N)r6   r7   r8   r9   r:   r   r   r   r<   classmethodrN   r   r=   IPPROTO_ESPr   r   r   r   r?   r2   r)   r'   rA   rA   w   s         
 D 		%$$	&$K    [ 	Wf()tV'(T6#56D&"45D&"45OOOr)   rA   c                   (    e Zd Z edd          gZdS )rH   non_espr   N)r6   r7   r8   r   r<   r2   r)   r'   rH   rH      s$        	)S!!KKKr)   rH   c                   (    e Zd Z edd          gZdS )rI   nat_keepaliverD   N)r6   r7   r8   r   r<   r2   r)   r'   rI   rI      s$        
?D))KKKr)   rI   i  )dport)sport)rV   rW   c                       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 ZdS )	_ESPPlainz>
    Internal class to represent unencrypted ESP packets.
    rA   r,   r   r-   iv rB   r0   padlenr*   r.   c                 |    t          | j                  | j        z   t          j        d| j        | j                  z   S )NBB)r   rB   r0   rF   packr\   r*   r%   s    r'   data_for_encryptionz_ESPPlain.data_for_encryption   s.    49~~,v{4dg/V/VVVr)   N)r6   r7   r8   r9   r:   r   r   r   r   r   r   r
   r   r<   r`   r2   r)   r'   rY   rY      s          D 		%rFB$$B	(AdAy))KW W W W Wr)   rY   )
InvalidTag)default_backend)aeadCipher
algorithmsmodes)re   zQCan't import python-cryptography v1.7+. Disabled IPsec encryption/authentication.c                 d    | dk    s|dk    rdS t          | |z            t          | |          z  S )z3
    Least Common Multiple between 2 integers.
    r   )absr   )abs     r'   _lcmrk      s7     	Avvaq1q5zzSAYY&&r)   c                   X    e Zd ZdZ	 	 ddZd Zd Zedd            Zd Z	dd
Z
ddZdS )	CryptAlgoz$
    IPsec encryption algorithm
    Nc
                 X   || _         || _        || _        || _        d| _        d| _        t          rd| j        %t          | j        t          j                  | _        n8| j        t          j
        t          j        t          j        fv rd| _        d| _        ||| _        n||j        dz  | _        nd| _        || j        | _        n|| _        ||| _        n-|$t!          d |j        D                       | _        nd| _        |d| _        n|| _        |	
d | _        dS |	| _        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              3       K   | ]	}|d z  V  
dS )ro   Nr2   ).0is     r'   	<genexpr>z%CryptAlgo.__init__.<locals>.<genexpr>)  s&      !C!CQ!q&!C!C!C!C!C!Cr)   r   c                     | S rO   r2   )rZ   kws     r'   r4   z$CryptAlgo.__init__.<locals>.<lambda>3  s    B r)   )r:   ciphermodeicv_sizeis_aeadciphers_aead_apirf   
issubclassModeWithAuthenticationTagrc   AESGCMAESCCMChaCha20Poly1305
block_sizeiv_sizekey_sizetuple	key_sizes	salt_size_format_mode_iv)
r&   r:   rv   rw   r   r   r   rx   r   format_mode_ivs
             r'   __init__zCryptAlgo.__init__   sM   * 		  % 	-y$)$)*/*I K  Kdk!%!6!8 8 8#(,%!(DOO$/14DOODO??DLL"DL$DMM!!C!C&2B!C!C!CCCDMM DMDNN&DN!#6#6D   #1D   r)   c                     | j         rUt          |          | j         k    s?t          |          | j         v s+t          dt          |          d| j                   dS dS dS )[
        Check that the key length is valid.

        :param key:    a byte string
        invalid key size z
, must be Nr   rE   	TypeErrorr&   keys     r'   	check_keyzCryptAlgo.check_key7  st     = 	7#c((dm";";s3xx4=?X?X) XXXXt}}6 7 7 7	7 	7";";?X?Xr)   c                 4    t          j        | j                  S )z:
        Generate a random initialization vector.
        )osurandomr   r%   s    r'   generate_ivzCryptAlgo.generate_ivA  s     z$,'''r)   c           
      >   | j         rT|Rt          |                     |          |                     ||t	          |                    t                                S t          |                     |          |                     |          t                                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
        )ry   rd   rv   rw   rE   rb   )r&   r   mode_ivdigests       r'   
new_cipherzCryptAlgo.new_cipherI  s     < 	F.C  		'63v;;77!!   C  		'""!!  r)   c                    t          |j                  dz   }t          | j        d          }| |z  |_        t          j        d|j        z  gt          d|j        dz             R  |_        t          |j	                  t          |j                  z   t          |j                  z   dz   }|dz  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.)rE   rB   rk   r   r\   rF   r_   ranger0   rZ   
ValueError)r&   espdata_lenalignpayload_lens        r'   padzCryptAlgo.padc  s     sx==1$ T_a(( Y&

 k#
"2NU1cj1n5M5MNNN #&kkCMM1C4D4DDqH?a`aaa
r)   Fr   c                    || j         r| j        nd}|                                }| j        r|                     | ||j                  }d}	| j         rD|r"t          j        d|j        ||j	                  }	n t          j        d|j        |j	                  }	| j
        r| j        t          j        k    r|                     ||          }
n|                     |          }
| j        dk    r&||
                    |d|	|j        z   |z             z   }n|
                    |||	          }n|                     ||          }
|
                                }| j         rR|                    |	           |                    |          |                                z   }||j        d|         z  }n*|                    |          |                                z   }t+          |j        |j	        |j        |z   	          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sarZ   !LLL!LL
tag_lengthAES-NULL-GMACr)   )r,   r-   rB   )ry   rx   r`   rv   r   rZ   rF   r_   r,   r-   rz   rc   r~   r:   encryptr   	encryptorauthenticate_additional_dataupdatefinalizetagrA   )r&   r   r   r   rx   esn_enesnrB   r   aadrv   r   s               r'   r   zCryptAlgo.encrypt  s    (,;t}}!H&&((; 	I***GGGC| ? ? +fcgsCGDDCC +eSWcg>>C$ I;$+--![[[BBFF![[--F9//&..#sSV|d?R"S"SSDD!>>'4==DDg66",,..	< I::3???$++D11I4F4F4H4HHDIM)8)44DD$++D11I4F4F4H4HHDswCG#&4-@@@@r)   c           
      v   || j         r| j        nd}|j        d| j                 }|j        | j        t	          |j                  |z
           }|j        t	          |j                  |z
  d         }	| j        r|                     ||          }
d}| j         rD|r"t          j        d|j	        ||j
                  }n t          j        d|j	        |j
                  }| j        r| j        t          j        k    r|                     ||          }n|                     |          }	 | j        dk    r!||                    |
|	||z   |z             z   }n|                    |
||	z   |          }n# t           $ r}t#          |          d}~ww xY w|                     ||
|	          }|                                }| j         r|                    |           	 |                    |          |                                z   }n!# t           $ r}t#          |          d}~ww xY wt/          |d                   }t/          |d	                   }|t	          |          |z
  d
z
  t	          |          d
z
           }|dt	          |          |z
  d
z
           }t1          |j	        |j
        ||||||	          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   rZ   r   r   r   r   r   )r,   r-   rZ   rB   r0   r\   r*   r.   )ry   rx   rB   r   rE   rv   r   rF   r_   r,   r-   rz   rc   r~   r:   decryptra   IPSecIntegrityErrorr   	decryptorr   r   r   r   rY   )r&   r   r   r   rx   r   r   rZ   rB   r.   r   r   rv   errr   r\   r*   r0   s                     r'   r   zCryptAlgo.decrypt  s     (,;t}}!HXmt|m$xS]]X%==>hs38}}x/001;  	3**bR*88GC| ? ? +fcgsCGDDCC +eSWcg>>C$ 3;$+--![[[BBFF![[--F3yO33#fnnWc38d?&S&SS%~~gtcz3GG! 3 3 3-c2223 gs;;",,..	< @::3???3$++D11I4F4F4H4HHDD! 3 3 3-c2223 T"Xb]] s4yy6)A-s4yy1}<=+SYY'!++,SW W"!( & " " " 	"s1   *AE1 1
F;F

F*H 
H#HH#)NNNNNNrO   NFr   )r6   r7   r8   r9   r   r   r   r   r   r   r   r   r2   r)   r'   rm   rm      s          EINRB2 B2 B2 B2H7 7 7( ( (    2! ! !F0A 0A 0A 0AdH" H" H" H" H" H"r)   rm   NULL)rv   rw   r   zAES-CBC)rv   rw   c                     | j         |z   dz   S )Ns      
crypt_saltr   rZ   ru   s      r'   r4   r4     s    2=23EH[3[ r)   zAES-CTRr"   ro   r#   )rv   rw   r   r   r   r   c                     | j         |z   S rO   r   r   s      r'   r4   r4     s    0B r)   zAES-GCM)          r   )rv   r   rw   r   r   r   rx   r   r   zAES-CCM   )rv   rw   r   r   r   r   rx   r   zCHACHA20-POLY1305r   DES)ro   )rv   rw   r   3DES)CryptographyDeprecationWarningignore)categoryCASTBlowfish)HMAC)CMAC)hashesc                       e Zd ZdZdS )r   z5
    Error risen when the integrity check fails.
    N)r6   r7   r8   r9   r2   r)   r'   r   r   j  s          	Dr)   r   c                   F    e Zd ZdZd
dZd Zed             ZddZdd	Z	dS )AuthAlgoz#
    IPsec integrity algorithm
    Nc                 L    || _         || _        || _        || _        || _        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)r:   mac	digestmodrx   r   )r&   r:   r   r   rx   r   s         r'   r   zAuthAlgo.__init__v  s+     	"  r)   c                     | j         r=t          |          | j         vr)t          dt          |          d| j                   dS dS )r   r   z, must be one of Nr   r   s     r'   r   zAuthAlgo.check_key  s\     = 	7SXXT]::) XXXXt}}6 7 7 7	7 	7::r)   c                     | j         t          u r5|                      |                     |          t                                S |                      ||                                 t                                S )zn
        :param key:    a byte string
        :returns:       an initialized mac object for this algo
        )r   r   r   rb   r   s     r'   new_maczAuthAlgo.new_mac  s]     8t88DNN3//1B1BCCC88C!1!1?3D3DEEEr)   Fr   c                 
   | j         s|S |                     |          }|                    t                    r|                    t          |t                                        |r(|                    t          j        d|                     |t                   xj        |	                                d| j
                 z  c_        n|                    t                    r|                    t          t          |                                d                               |r(|                    t          j        d|                     |	                                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
        !LNTsending)r   r   haslayerrA   r   bytesrF   r_   rB   r   rx   r    zero_mutable_fieldscopyr.   )r&   pktr   r   r   r   s         r'   signzAuthAlgo.sign  s0    x 	Jll3<< 	9JJuSX''' 3

6;tS11222HMMS\\^^NT]N;;MMM\\" 	9JJu0TJJJKKLLL 3

6;tS11222,,..$-8CGK
r)   c                    | j         r| j        dk    rdS |                     |          }d}t          |t                    r|j        t          |j                  | j        z
  d         }|                                }|j        dt          |j                  | j        z
           |_        |                    t          |                     |r(|                    t          j        d|                     n"|                    t                    rt          |t                   j                  | j        k    r^|t                   j        | j        d         |t                   _        |t                   j        d| j                 |t                   _        |t                   j        }t!          |                                d          }|                    t          |                     |r(|                    t          j        d|                     |                                d| j                 }||k    rt%          d|d|          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 foundr   Fr   zpkt_icv=z, computed_icv=)r   rx   r   
isinstancerA   rB   rE   r   r   r   rF   r_   r   r    r.   r0   r   r   r   )	r&   r   r   r   r   r   pkt_icvclonecomputed_icvs	            r'   verifyzAuthAlgo.verify  s    x 	4=A--Fll3c3 	3hs38}}t}<==>GHHJJE$DS__t}%D$DEEJJJuU||$$$ 3

6;tS11222\\" 
	33r7;4=00"%b'+dmnn"=B!"gk.4=.9B"gkG'

EBBBEJJuU||$$$ 3

6;tS11222||~~nt}n5 l""%%'.ww'> ? ? ? #"r)   rO   )Fr   )
r6   r7   r8   r9   r   r   r   r   r   r   r2   r)   r'   r   r   q  s         ! ! ! ! 7 7 7 F F F   B.? .? .? .? .? .?r)   r   )r   r   rx   zHMAC-SHA1-96   zSHA2-256-128zSHA2-384-192r   zSHA2-512-256zHMAC-MD5-96zAES-CMAC-96)r   )r   r   rx   r   c                 D   |                      t          |                     }|j        }d}|j        dk    r+|j        }||_        |                                 |`|`|||fS d}|}t          |t          t          t          f          rqt          |t                    r	 t          |t                    rd}nt          |t                    r|rn+|}|j        }t          |t          t          t          f          q|j        }||_        |                                 |`|||f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versionr5   remove_payloadchksumrE   r   r   r   r   r*   plen)orig_pkttransport_protoheadernext_hdrr*   found_rt_hdrprevs          r'   split_for_transportr     sA    H..F~H	B~\&MJr8## $68IK\#]^^ 		(($677 ($566 #H&788 \ D'H $68IK\#]^^ 		( W!Kr8##r)   )r   r"   r               Fc           	         |                      t                    r3dt          | t                   j                  z  | t                   _        nt	          d          | j        dk    rd| _        d| _        d| _        d| _	        g }| j
        D ]X}|j        t          v r|                    |           &|                    t          dt          |          z                       Y|| _
        nd| _        d| _        d| _        | j        }t'          |t(          t*          t,          f          rt'          |t(          t,          f          r$|j
        D ]}|j        dz  rd|j        z  |_        ngt'          |t*                    rQ|rOd|_        |j        r@|j                                        }|j                            d| j                   || _        nn)|j        }t'          |t(          t*          t,          f          | 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    rE   r.   r   r   tosflagsttlr   optionsoptionIMMUTABLE_IPV4_OPTIONSappendr   tcflhlimr   r   r   r   r   otypeoptlenoptdatasegleft	addressespopinsertdst)r   r   immutable_optsoptr   finals         r'   r   r   T  s    ||B -CGK 0 00B+,,,
{a  	
; 	? 	?Cz333%%c****%%c'CHH*<&=&=>>>>$  ;$68IK\#]^^ 	((%79J$KLL #+ ; ;Cy4' ;&-
&:; H&788 	W 	 $% % $$.2244E&--a999#CG'H# $68IK\#]^^ 	(& Jr)   c                   `    e Zd ZdZeefZ	 	 	 	 ddZd ZddZ	dd	Z
dd
ZddZddZddZdS )SecurityAssociationzd
    This class is responsible of "encryption" and "decryption" of IPsec packets.  # noqa: E501
    r"   NFr   c                    |t           t          t           j        t          j        hvrt          d          t	          |t
                    r0t           j        t           t          j        t          i|         | _        n|| _        || _        || _        || _	        || _
        |r|t          vr't          d|dt          t                              t          |         | _        |rK| j        j        }|dt!          |          |z
           | _        |t!          |          |z
  d         | _        n/d| _        d| _        n t          d         | _        d| _        d| _        || _        |rJ|t(          vr't          d|dt          t(                              t(          |         | _        || _        nt(          d         | _        d| _        |	rEt	          |	t.          t0          f          s)t          dt.          j        dt0          j                  |	| _        |
rI|t           urt          d	          t	          |
t4                    st          d
t4          j        z            |
| _        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 z, try Nr   zunsupported integrity algo ztunnel_header must be z or z%nat_t_header is only allowed with ESPznat_t_header must be %s)rA   r    r:   r   r   strr5   r,   seq_numr   r   CRYPT_ALGOSr   list
crypt_algor   rE   	crypt_keyr   crypt_icv_size
AUTH_ALGOS	auth_algoauth_keyr   r   tunnel_headerr   nat_t_header)r&   r5   r,   r  r  r  r  r  r  r   r!  r   r   r   s                 r'   r   zSecurityAssociation.__init__  sU   2 b#(BG444=>>>eS!! 	(C"5e<DJJDJ 	#,,i!+T+->->->!@ A A A)*5DO ' O5	!*+FC	NNY,F+F!G"+C	NNY,F,G,G"H!%"& *&1DO!DN"DO, 	!
**i!*D,<,<,<!> ? ? ?'	2DN$DMM'/DN DM 	UMB:!F!F 	U)STTT* 	FC GHHHlC00 F 9CH DEEE(r)   c                 b    |j         | j         k    rt          d|j         | j         fz            d S )Nz.packet spi=0x%x does not match the SA spi=0x%x)r,   r   )r&   r   s     r'   	check_spizSecurityAssociation.check_spi  s?    7dhL Wdh/0 1 1 1 r)   c                 
   || j                                         }n9t          |          | j         j        k    rt	          d| j         j        z            t          | j        |p| j        |          }| j        rT| j        	                                }|j
        dk    r|`|`|`n|`|`|                    t!          ||z                      }t#          |t$          j                  \  }}	}
|
|_        |	|_        | j                             |          }| j                             | || j        | j        |p| j        |p| j                  }| j                            || j        |p| j        |p| j                   | j        r7| j        	                                }d|_        |`|j
        dk    r|`n|`||z  }|j
        dk    r|`|`n|`|| xj        dz  c_        |                    t!          ||z                      S )Nziv length must be %s)r,   r-   rZ   r#   r   r   r   r"   )r  r   rE   r   r   rY   r,   r  r   r   r   r5   r   r*   r   r   r   r   r=   rQ   rB   r   r   r  r  r   r   r  r   r  r!  )r&   r   r  rZ   r   r   r   tunnel	ip_headerr*   r   r!  s               r'   _encrypt_espz SecurityAssociation._encrypt_esp  s-   :,,..BB2ww$/111 69P PQQQDH'*AT\bIII 	6',,..F~""LJMMIK""3v|#4#455C!4S&:L!M!M	2wo!!#&&o%%dC&*&9-3-Bt{*-/ & ; ;
 	C M#)#8T[ #tx 	 	1 	1 	1
  	&,1133L"#L  A%%OOL%I!!   ?LLALL""3y3#7#7888r)   c                 8   t          | j        |p| j        d| j        j        z            }| j        rT| j                                        }|j        dk    r|`|`	|`
n|`|`|                    t          ||z                      }t          |t           j                  \  }}}	||_        |j        dk    r2t          |          dz  dk    rdt          |           dz  z  |_        n1t          |          dz  dk    rdt          |           dz  z  |_        t          |          dz  dz
  |_        |j        dk    rYt          |          t          |          z   t          |	          z   |_	        |`
|                    t          |                    }n9t          |j                  t          |          z   t          |	          z   |_        | j                            ||z  |	z  | j        |p| j        |p| j                  }
|| xj        d	z  c_        |
S )
Nr   )r,   r-   r.   r#   r   ro   r   r   r%  r"   )r    r,   r  r  rx   r   r   r   r5   rE   r   r*   r   r   r   r   r=   r>   r0   r$   r   r   r  r   r   )r&   r   r  r   r   ahr&  r'  r*   r   
signed_pkts              r'   _encrypt_ahzSecurityAssociation._encrypt_ah2  s   DH'"9T\dn557 7 7  	6',,..F~""LJMMIK""3v|#4#455C!4S&:K!L!L	2w!!c"ggkQ&6&6 !SWWHqL1BJJWWq[A !SWWHqL1BJ
 B1q(!!	NNSWW4s7||CIM !++C	NN;;II !233c"gg=GLIN^((R')A)-060E$+-0_DH ) > >
 ?LLALLr)   c                     t          || j                  st          d|j        d| j                  | j        t
          u r|                     |||||          S |                     ||||          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 , supported protos are )r  rZ   r   r   )r  r   r   )r   SUPPORTED_PROTOSr   r   r5   rA   r(  r,  )r&   r   r  rZ   r   r   s         r'   r   zSecurityAssociation.encryptg  s    " #t455 	F)"}}}d.C.CE F F F:$$S'(*6), % . . . ##C+1s $ < < <r)   Tc                 n   |t                    }|rF|                     |           | j                            || j        |p| j        |p| j                   | j                            | || j	        | j
        p| j        j        p| j        j        |p| j        |p| j                  }| j        rb|                                 |j        dk    r|j        |_        n|j        |_        |                    |j                  } ||j                  S |}|j        dk    rn|j        |_        |`|                                 t)          |          t)          |j                  z   |_        |                    t-          |                    }n| j        r!|j        |_        |                                 n*|j        |j        _        |j                                         t)          |j                  t)          |j                  z   |_        |                    |j                  }| ||j                  z  S Nr%  r#   )rA   r#  r  r   r  r   r   r  r   r  r  rx   r   r   r   r*   r5   guess_payload_classrB   r   rE   r   r   r!  
underlayerr   r   )	r&   r   r   r   r   	encryptedr   rJ   r'  s	            r'   _decrypt_espz SecurityAssociation._decrypt_esp  s   H	 	7NN3N!!)T])/)>4;&)oTX " 7 7 7 o%%dIt~&*&9 '>&*o&>'>&*n&=-3-Bt{*-/ & ; ;  "	-    {aF		))#(33C3sx== I A%%"%&	$((*** #ISX >	%//I??		$ :#&6IL,,.....1fI(+(77999!$Y%6!7!7#ch--!G	//99C ss38}},,r)   c                    |rF|                      |           | j                            || j        |p| j        |p| j                   |t                   }|j        }|                    d            | j	        r|S |}|j
        dk    ri|j        |_        |`|                                 t          |          t          |          z   |_        |                    t#          |                    }nS|j        |j        _        |j                                         t          |j                  t          |          z   |_        ||z  S r1  )r#  r  r   r  r   r   r    r   remove_underlayerr   r   r*   r5   r   r   rE   r   r   r3  r   )r&   r   r   r   r   r*  r   r'  s           r'   _decrypt_ahzSecurityAssociation._decrypt_ah  s;    	7NN3N!!#t})/)>4;&)oTX " 7 7 7 W*!!$''' 	'NI A%%"$%	$((*** #IW =	%//I??		#%5 ,,...!$Y%6!7!7#g,,!F	 w&&r)   c                    t          || j                  st          d|j        d| j                  | j        t
          u r3|                    t
                    r|                     ||||          S | j        t          u r3|                    t                    r| 	                    ||||          S t          |d| j        j
        d          )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 r.  )r   r   r   z has no z layer)r   r/  r   r   r5   rA   r   r5  r    r8  r:   )r&   r   r   r   r   s        r'   r   zSecurityAssociation.decrypt  s     #t455 	F)"}}}d.C.CE F F F :c!2!2$$S,2 % = = =Z2#,,r"2"2##Cv3#OOOCCCIJJJr)   )
r"   NNNNNNNFr   )NNNNr   )TNN)r6   r7   r8   r9   r   r   r/  r   r#  r(  r,  r   r5  r8  r   r2   r)   r'   r  r    s          DzIM $*.JKL) L) L) L)\1 1 1
:9 :9 :9 :9x3 3 3 3j< < < <83- 3- 3- 3-j' ' ' '@K K K K K Kr)   r  )F)hr9   mathr   ImportError	fractionsr   r=   rF   warningsscapy.configr   r   scapy.compatr   r   
scapy.datar   scapy.errorr	   scapy.fieldsr
   r   r   r   r   r   r   r   r   r   scapy.packetr   r   r   r   r   scapy.layers.inetr   r   scapy.layers.inet6r   r   r   r   r    r>   
IPPROTO_IPIPPROTO_IPV6rA   rH   rI   rQ   rY   crypto_validcryptography.exceptionsra   cryptography.hazmat.backendsrb   &cryptography.hazmat.primitives.ciphersrc   rd   re   rf   $cryptography.hazmat.decrepit.ciphersdecrepit_algorithmsinfo	Exceptionrk   objectrm   r  AESCBC_aes_ctr_format_mode_ivCTR_salt_format_mode_ivr}   r~   r   	TripleDEScryptography.utilsr   catch_warningsfilterwarningsCAST5r   #cryptography.hazmat.primitives.hmacr   #cryptography.hazmat.primitives.cmacr   cryptography.hazmat.primitivesr   r   r   r  SHA1SHA256SHA384SHA512MD5r   r  r   r  r2   r)   r'   <module>rc     s
   6    				    / / / / / / / / ! ! ! ! ! ! ! !             # # # # # #                                     & % % % % % % %           
% % % % % % % %P B&+ , , , , D"* + + + + Bv( ) ) ) ) B, - - - -
    &   D    f       F    B6- . . . . D#&, - - - - sCt $ $ $ $ sCt $ $ $ $ c3d$ / / / / c7$d 3 3 3 3 c=D 9 9 9 9
W W W W W W W W0  '222222<<<<<<           )	
 	
 	
 	
 	
 	
 	
  ) ) )() K A B B BOJ"&&F&Z%
' ' 'R" R" R" R" R" R" R" R"t IIfTa@@@  P<&Yy.8n,1I7 7 7K	 \[&Yy.8n,1I23/0126MO O OK	 CB&Yy.2k0<,01223/0026JL L LK	 $-9_48K6B2678895668<P$R $R $RK  'Yy.2k,00<23/012026JL L LK	 (1y1D8<8M6::<<=9:;<:<@T(V (V (VK#$ #5*=*G(-	,02 2 2K $)F+>+H).4 4 4K j((EEEEEE$X$&& 		@ 		@#H#H-KM M M M"+)F3F3L16#< #< #<K '0i
7J7S5:Y'@ '@ '@K
#		@ 		@ 		@ 		@ 		@ 		@ 		@ 		@ 		@ 		@ 		@ 		@ 		@ 		@ 		@ (i/B/H-2Y8 8 8F #,)J3F3O16#< #< #<J   8888888888885555555  D4&
	 	 	 	 	) 	 	 	y? y? y? y? y?v y? y? y?B HHVBBB
  6F 6!)..24:K35"7 "7 "7J~ "*..24:M35"7 "7 "7J~ "*..24:M35"7 "7 "7J~ "*..24:M35"7 "7 "7J~
 !)-139:24!6 !6 !6J}  9J 9 (-13=>2427	!9 !9 !9J}.$ .$ .$f C C C CPTK TK TK TK TK& TK TK TK TK TKs1    #F* *F43F46A	MMM