U
    ;g[                     @   s   d dl mZmZmZmZ d dlZddlmZ ddlm	Z	m
Z
mZmZmZmZ ddlmZmZmZmZ ddlmZ dd	lmZmZ d
dddddddddddgZdd Zdd
 Zdd Zdd Zdd Zdd Zdd Z dd Z!dd Z"d d Z#d!d Z$d"d Z%d#d Z&d$d% Z'd&d' Z(d(d) Z)dS )*    )unicode_literalsdivisionabsolute_importprint_functionN   )pretty_message)newnullis_nullbuffer_from_bytesbytes_from_bufferderef   )	libcryptolibcrypto_legacy_supportLibcryptoConsthandle_openssl_error)
rand_bytes)	type_namebyte_clsaes_cbc_no_padding_decryptaes_cbc_no_padding_encryptaes_cbc_pkcs7_decryptaes_cbc_pkcs7_encryptdes_cbc_pkcs5_decryptdes_cbc_pkcs5_encryptrc2_cbc_pkcs5_decryptrc2_cbc_pkcs5_encryptrc4_decryptrc4_encrypttripledes_cbc_pkcs5_decrypttripledes_cbc_pkcs5_encryptc                 C   sj   t | }|std}nt|dkr4ttdt|t|d dkrVttdt||t|| ||dfS )a  
    Encrypts plaintext using AES in CBC mode with a 128, 192 or 256 bit key and
    no padding. This means the ciphertext must be an exact multiple of 16 bytes
    long.

    :param key:
        The encryption key - a byte string either 16, 24 or 32 bytes long

    :param data:
        The plaintext - a byte string

    :param iv:
        The initialization vector - either a byte string 16-bytes long or None
        to generate an IV

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A tuple of two byte strings (iv, ciphertext)
       :
            iv must be 16 bytes long - is %s
            r   zJ
            data must be a multiple of 16 bytes long - is %s
            F_calculate_aes_cipherr   len
ValueErrorr   _encryptkeydataivcipher r.   ?/tmp/pip-unpacked-wheel-x1gypflw/oscrypto/_openssl/symmetric.pyr      s    
c                 C   s6   t | }t|dkr&ttdt|t|| ||dS )aM  
    Decrypts AES ciphertext in CBC mode using a 128, 192 or 256 bit key and no
    padding.

    :param key:
        The encryption key - a byte string either 16, 24 or 32 bytes long

    :param data:
        The ciphertext - a byte string

    :param iv:
        The initialization vector - a byte string 16-bytes long

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the plaintext
    r"   r#   Fr%   r&   r'   r   _decryptr)   r.   r.   r/   r   M   s    c                 C   sH   t | }|std}nt|dkr4ttdt||t|| ||dfS )a  
    Encrypts plaintext using AES in CBC mode with a 128, 192 or 256 bit key and
    PKCS#7 padding.

    :param key:
        The encryption key - a byte string either 16, 24 or 32 bytes long

    :param data:
        The plaintext - a byte string

    :param iv:
        The initialization vector - either a byte string 16-bytes long or None
        to generate an IV

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A tuple of two byte strings (iv, ciphertext)
    r"   r#   Tr$   r)   r.   r.   r/   r   q   s    
c                 C   s6   t | }t|dkr&ttdt|t|| ||dS )a9  
    Decrypts AES ciphertext in CBC mode using a 128, 192 or 256 bit key

    :param key:
        The encryption key - a byte string either 16, 24 or 32 bytes long

    :param data:
        The ciphertext - a byte string

    :param iv:
        The initialization vector - a byte string 16-bytes long

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the plaintext
    r"   r#   Tr0   r)   r.   r.   r/   r      s    c                 C   sV   t | dkrttdt | t | dkr0d}n"t | dkrBd}nt | dkrRd}|S )	a  
    Determines if the key is a valid AES 128, 192 or 256 key

    :param key:
        A byte string of the key to use

    :raises:
        ValueError - when an invalid key is provided

    :return:
        A unicode string of the AES variation - "aes128", "aes192" or "aes256"
    )r"          zo
            key must be either 16, 24 or 32 bytes (128, 192 or 256 bits)
            long - is %s
            r"   aes128r2   aes192r3   aes256)r&   r'   r   )r*   r-   r.   r.   r/   r%      s    r%   c                 C   sF   t stdt| dk s$t| dkr6ttdt| td| |ddS )a  
    Encrypts plaintext using RC4 with a 40-128 bit key

    :param key:
        The encryption key - a byte string 5-16 bytes long

    :param data:
        The plaintext - a byte string

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the ciphertext
    -OpenSSL has been compiled without RC4 support   r"   Q
            key must be 5 to 16 bytes (40 to 128 bits) long - is %s
            rc4N)r   EnvironmentErrorr&   r'   r   r(   r*   r+   r.   r.   r/   r      s    c                 C   sF   t stdt| dk s$t| dkr6ttdt| td| |ddS )a  
    Decrypts RC4 ciphertext using a 40-128 bit key

    :param key:
        The encryption key - a byte string 5-16 bytes long

    :param data:
        The ciphertext - a byte string

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the plaintext
    r7   r8   r"   r9   r:   Nr   r;   r&   r'   r   r1   r<   r.   r.   r/   r      s    c                 C   sv   t stdt| dk s$t| dkr6ttdt| |sDtd}nt|dkrbttdt||td| ||dfS )	ah  
    Encrypts plaintext using RC2 in CBC mode with a 40-128 bit key and PKCS#5
    padding.

    :param key:
        The encryption key - a byte string 8 bytes long

    :param data:
        The plaintext - a byte string

    :param iv:
        The initialization vector - a byte string 8-bytes long or None
        to generate an IV

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A tuple of two byte strings (iv, ciphertext)
    -OpenSSL has been compiled without RC2 supportr8   r"   r9      9
            iv must be 8 bytes long - is %s
            rc2Tr   r;   r&   r'   r   r   r(   r*   r+   r,   r.   r.   r/   r     s    
c                 C   sd   t stdt| dk s$t| dkr6ttdt| t|dkrTttdt|td| ||dS )	a5  
    Decrypts RC2 ciphertext ib CBC mode using a 40-128 bit key and PKCS#5
    padding.

    :param key:
        The encryption key - a byte string 8 bytes long

    :param data:
        The ciphertext - a byte string

    :param iv:
        The initialization vector - a byte string 8 bytes long

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the plaintext
    r>   r8   r"   r9   r?   r@   rA   Tr=   rC   r.   r.   r/   r   N  s    c                 C   s   t | dkr*t | dkr*ttdt | |s8td}nt |dkrVttdt |d}t | dkrz| | dd  } d}|t|| ||d	fS )
a  
    Encrypts plaintext using 3DES in CBC mode using either the 2 or 3 key
    variant (16 or 24 byte long key) and PKCS#5 padding.

    :param key:
        The encryption key - a byte string 16 or 24 bytes long (2 or 3 key mode)

    :param data:
        The plaintext - a byte string

    :param iv:
        The initialization vector - a byte string 8-bytes long or None
        to generate an IV

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A tuple of two byte strings (iv, ciphertext)
    r"   r2   zT
            key must be 16 bytes (2 key) or 24 bytes (3 key) long - %s
            r?   z6
            iv must be 8 bytes long - %s
            tripledes_3keyr   tripledes_2keyT)r&   r'   r   r   r(   r)   r.   r.   r/   r!   {  s"    
c                 C   s|   t | dkr*t | dkr*ttdt | t |dkrHttdt |d}t | dkrl| | dd  } d}t|| ||d	S )
au  
    Decrypts 3DES ciphertext in CBC mode using either the 2 or 3 key variant
    (16 or 24 byte long key) and PKCS#5 padding.

    :param key:
        The encryption key - a byte string 16 or 24 bytes long (2 or 3 key mode)

    :param data:
        The ciphertext - a byte string

    :param iv:
        The initialization vector - a byte string 8-bytes long

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the plaintext
    r"   r2   zW
            key must be 16 bytes (2 key) or 24 bytes (3 key) long - is %s
            r?   r@   rD   r   rE   T)r&   r'   r   r1   r)   r.   r.   r/   r      s    c                 C   sj   t stdt| dkr*ttdt| |s8td}nt|dkrVttdt||td| ||dfS )a  
    Encrypts plaintext using DES in CBC mode with a 56 bit key and PKCS#5
    padding.

    :param key:
        The encryption key - a byte string 8 bytes long (includes error correction bits)

    :param data:
        The plaintext - a byte string

    :param iv:
        The initialization vector - a byte string 8-bytes long or None
        to generate an IV

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A tuple of two byte strings (iv, ciphertext)
    -OpenSSL has been compiled without DES supportr?   T
            key must be 8 bytes (56 bits + 8 parity bits) long - is %s
            r@   desTrB   rC   r.   r.   r/   r     s    
c                 C   sX   t stdt| dkr*ttdt| t|dkrHttdt|td| ||dS )aN  
    Decrypts DES ciphertext in CBC mode using a 56 bit key and PKCS#5 padding.

    :param key:
        The encryption key - a byte string 8 bytes long (includes error correction bits)

    :param data:
        The ciphertext - a byte string

    :param iv:
        The initialization vector - a byte string 8-bytes long

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the plaintext
    rF   r?   rG   r@   rH   Tr=   rC   r.   r.   r/   r     s    c              	   C   s  t |tsttdt|t |ts8ttdt|| dkr\t |ts\ttdt|| dkr|s| tdddgk}|r|rt|d d	krtd
d}z^t
 }t|rtd	 t| |\}}|dkrt }| tddgkrTt||t t t }	t|	 t|t|}	t|	 | dkrNt|tjt|d t }	t|	 t }t||t ||}	t|	 |dk	rt|t|}	t|	 t|}
ttd}t||
||t|}	t|	 t|
t|}t||
|}	t|	 |t|
t|7 }|W S |rt	| X dS )a  
    Encrypts plaintext

    :param cipher:
        A unicode string of "aes128", "aes192", "aes256", "des",
        "tripledes_2key", "tripledes_3key", "rc2", "rc4"

    :param key:
        The encryption key - a byte string 5-32 bytes long

    :param data:
        The plaintext - a byte string

    :param iv:
        The initialization vector - a byte string - unused for RC4

    :param padding:
        Boolean, if padding should be used - unused for RC4

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the ciphertext
    ;
            key must be a byte string, not %s
            <
            data must be a byte string, not %s
            r:   :
            iv must be a byte string, not %s
            r4   r5   r6   r"   r   padding must be specifiedNrA   r?   int *)
isinstancer   	TypeErrorr   r   setr&   r'   r   EVP_CIPHER_CTX_freeEVP_CIPHER_CTX_newr
   r   _setup_evp_encrypt_decryptr	   ZEVP_EncryptInit_exEVP_CIPHER_CTX_set_key_lengthEVP_CIPHER_CTX_ctrlr   EVP_CTRL_SET_RC2_KEY_BITSEVP_CIPHER_CTX_set_paddingintr   r   ZEVP_EncryptUpdater   r   ZEVP_EncryptFinal_ex)r-   r*   r+   r,   paddingZis_aesevp_cipher_ctx
evp_cipherbuffer_sizeresbufferoutput_lengthoutputr.   r.   r/   r(   :  sr    





r(   c              	   C   s  t |tsttdt|t |ts8ttdt|| dkr\t |ts\ttdt|| tddddgkr||s|tdd	}z^t	 }t
|rtd
 t| |\}}|d	krt }| tddgkr6t||t t t }t| t|t|}t| | dkr0t|tjt|d t }t| t }t||t ||}t| |d	k	rtt|t|}t| t|}	ttd}
t||	|
|t|}t| t|	t|
}t||	|
}t| |t|	t|
7 }|W S |rt| X d	S )a  
    Decrypts AES/RC4/RC2/3DES/DES ciphertext

    :param cipher:
        A unicode string of "aes128", "aes192", "aes256", "des",
        "tripledes_2key", "tripledes_3key", "rc2", "rc4"

    :param key:
        The encryption key - a byte string 5-32 bytes long

    :param data:
        The ciphertext - a byte string

    :param iv:
        The initialization vector - a byte string - unused for RC4

    :param padding:
        Boolean, if padding should be used - unused for RC4

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by OpenSSL

    :return:
        A byte string of the plaintext
    rI   rJ   r:   rK   r4   r5   r6   rL   Nr   rA   r?   rM   )rN   r   rO   r   r   rP   r'   r   rQ   rR   r
   r   rS   r	   ZEVP_DecryptInit_exrT   r&   rU   r   rV   rW   rX   r   r   ZEVP_DecryptUpdater   r   ZEVP_DecryptFinal_ex)r-   r*   r+   r,   rY   rZ   r[   r\   r]   r^   r_   r`   r.   r.   r/   r1     sn    





r1   c              	   C   sx   t jt jt jt jt jt jt jt jd|   }| dkr>t	|}n2dddddddd|  }|t
tt	||  }||fS )a  
    Creates an EVP_CIPHER pointer object and determines the buffer size
    necessary for the parameter specified.

    :param evp_cipher_ctx:
        An EVP_CIPHER_CTX pointer

    :param cipher:
        A unicode string of "aes128", "aes192", "aes256", "des",
        "tripledes_2key", "tripledes_3key", "rc2", "rc4"

    :param key:
        The key byte string

    :param data:
        The plaintext or ciphertext as a byte string

    :param padding:
        If padding is to be used

    :return:
        A 2-element tuple with the first element being an EVP_CIPHER pointer
        and the second being an integer that is the required buffer size
    )r4   r5   r6   rA   r:   rH   rE   rD   r:   r"   r?   )r4   r5   r6   rA   rH   rE   rD   )r   ZEVP_aes_128_cbcZEVP_aes_192_cbcZEVP_aes_256_cbcZEVP_rc2_cbcZEVP_rc4ZEVP_des_cbcZEVP_des_ede_cbcZEVP_des_ede3_cbcr&   rX   mathceil)r-   r+   r[   r\   
block_sizer.   r.   r/   rS     s2    	
	rS   )*
__future__r   r   r   r   ra   _errorsr   _ffir   r	   r
   r   r   r   Z
_libcryptor   r   r   r   utilr   _typesr   r   __all__r   r   r   r   r%   r   r   r   r   r!   r    r   r   r(   r1   rS   r.   r.   r.   r/   <module>   sF    0$'#!!!0-300,rn