Revert 030f292 (use libssl if available)

This commit is contained in:
Lonami Exo 2018-07-25 12:11:58 +02:00
parent 200a4e47b8
commit 7b4cd92066
2 changed files with 93 additions and 5 deletions

View File

@ -1,13 +1,29 @@
"""
AES IGE implementation in Python. This module may use libssl if available.
AES IGE implementation in Python.
If available, cryptg will be used instead, otherwise
if available, libssl will be used instead, otherwise
the Python implementation will be used.
"""
import os
import pyaes
import logging
from . import libssl
__log__ = logging.getLogger(__name__)
try:
import cryptg
__log__.info('cryptg detected, it will be used for encryption')
except ImportError:
cryptg = None
if libssl.encrypt_ige and libssl.decrypt_ige:
__log__.info('libssl detected, it will be used for encryption')
else:
__log__.info('cryptg module not installed and libssl not found, '
'falling back to (slower) Python encryption')
class AES:
@ -23,6 +39,8 @@ class AES:
"""
if cryptg:
return cryptg.decrypt_ige(cipher_text, key, iv)
if libssl.decrypt_ige:
return libssl.decrypt_ige(cipher_text, key, iv)
iv1 = iv[:len(iv) // 2]
iv2 = iv[len(iv) // 2:]
@ -56,13 +74,14 @@ class AES:
Encrypts the given text in 16-bytes blocks by using the
given key and 32-bytes initialization vector.
"""
# Add random padding iff it's not evenly divisible by 16 already
if len(plain_text) % 16 != 0:
padding_count = 16 - len(plain_text) % 16
plain_text += os.urandom(padding_count)
padding = len(plain_text) % 16
if padding:
plain_text += os.urandom(16 - padding)
if cryptg:
return cryptg.encrypt_ige(plain_text, key, iv)
if libssl.encrypt_ige:
return libssl.encrypt_ige(plain_text, key, iv)
iv1 = iv[:len(iv) // 2]
iv2 = iv[len(iv) // 2:]

69
telethon/crypto/libssl.py Normal file
View File

@ -0,0 +1,69 @@
"""
Helper module around the system's libssl library if available for IGE mode.
"""
import ctypes
import ctypes.util
lib = ctypes.util.find_library('ssl')
if not lib:
decrypt_ige = None
encrypt_ige = None
else:
_libssl = ctypes.cdll.LoadLibrary(lib)
# https://github.com/openssl/openssl/blob/master/include/openssl/aes.h
AES_ENCRYPT = ctypes.c_int(1)
AES_DECRYPT = ctypes.c_int(0)
AES_MAXNR = 14
class AES_KEY(ctypes.Structure):
"""Helper class representing an AES key"""
_fields_ = [
('rd_key', ctypes.c_uint32 * (4 * (AES_MAXNR + 1))),
('rounds', ctypes.c_uint),
]
def decrypt_ige(cipher_text, key, iv):
aes_key = AES_KEY()
key_len = ctypes.c_int(8 * len(key))
key = (ctypes.c_ubyte * len(key))(*key)
iv = (ctypes.c_ubyte * len(iv))(*iv)
in_len = ctypes.c_size_t(len(cipher_text))
in_ptr = (ctypes.c_ubyte * len(cipher_text))(*cipher_text)
out_ptr = (ctypes.c_ubyte * len(cipher_text))()
_libssl.AES_set_decrypt_key(key, key_len, ctypes.byref(aes_key))
_libssl.AES_ige_encrypt(
ctypes.byref(in_ptr),
ctypes.byref(out_ptr),
in_len,
ctypes.byref(aes_key),
ctypes.byref(iv),
AES_DECRYPT
)
return bytes(out_ptr)
def encrypt_ige(plain_text, key, iv):
aes_key = AES_KEY()
key_len = ctypes.c_int(8 * len(key))
key = (ctypes.c_ubyte * len(key))(*key)
iv = (ctypes.c_ubyte * len(iv))(*iv)
in_len = ctypes.c_size_t(len(plain_text))
in_ptr = (ctypes.c_ubyte * len(plain_text))(*plain_text)
out_ptr = (ctypes.c_ubyte * len(plain_text))()
_libssl.AES_set_encrypt_key(key, key_len, ctypes.byref(aes_key))
_libssl.AES_ige_encrypt(
ctypes.byref(in_ptr),
ctypes.byref(out_ptr),
in_len,
ctypes.byref(aes_key),
ctypes.byref(iv),
AES_ENCRYPT
)
return bytes(out_ptr)