Add support for pure python AES implementation (#78)
This commit is contained in:
parent
7a852b2084
commit
4f03ffb963
2 changed files with 44 additions and 22 deletions
|
@ -1,10 +1,15 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
try:
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
|
except ImportError, e:
|
||||||
|
import pyaes
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import random
|
import random
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
def gendevice(devtype, host, mac):
|
def gendevice(devtype, host, mac):
|
||||||
|
@ -145,6 +150,29 @@ class device:
|
||||||
self.type = "Unknown"
|
self.type = "Unknown"
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
|
if 'pyaes' in sys.modules:
|
||||||
|
self.encrypt = self.encrypt_pyaes
|
||||||
|
self.decrypt = self.decrypt_pyaes
|
||||||
|
else:
|
||||||
|
self.encrypt = self.encrypt_pycrypto
|
||||||
|
self.decrypt = self.decrypt_pycrypto
|
||||||
|
|
||||||
|
def encrypt_pyaes(self, payload):
|
||||||
|
aes = pyaes.AESModeOfOperationCBC(self.key, iv = bytes(self.iv))
|
||||||
|
return "".join([aes.encrypt(bytes(payload[i:i+16])) for i in range(0, len(payload), 16)])
|
||||||
|
|
||||||
|
def decrypt_pyaes(self, payload):
|
||||||
|
aes = pyaes.AESModeOfOperationCBC(self.key, iv = bytes(self.iv))
|
||||||
|
return "".join([aes.decrypt(bytes(payload[i:i+16])) for i in range(0, len(payload), 16)])
|
||||||
|
|
||||||
|
def encrypt_pycrypto(self, payload):
|
||||||
|
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
||||||
|
return aes.encrypt(bytes(payload))
|
||||||
|
|
||||||
|
def decrypt_pycrypto(self, payload):
|
||||||
|
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
||||||
|
return aes.decrypt(bytes(payload))
|
||||||
|
|
||||||
def auth(self):
|
def auth(self):
|
||||||
payload = bytearray(0x50)
|
payload = bytearray(0x50)
|
||||||
payload[0x04] = 0x31
|
payload[0x04] = 0x31
|
||||||
|
@ -174,10 +202,7 @@ class device:
|
||||||
|
|
||||||
response = self.send_packet(0x65, payload)
|
response = self.send_packet(0x65, payload)
|
||||||
|
|
||||||
enc_payload = response[0x38:]
|
payload = self.decrypt(response[0x38:])
|
||||||
|
|
||||||
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
|
||||||
payload = aes.decrypt(bytes(enc_payload))
|
|
||||||
|
|
||||||
if not payload:
|
if not payload:
|
||||||
return False
|
return False
|
||||||
|
@ -225,8 +250,7 @@ class device:
|
||||||
checksum += payload[i]
|
checksum += payload[i]
|
||||||
checksum = checksum & 0xffff
|
checksum = checksum & 0xffff
|
||||||
|
|
||||||
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
payload = self.encrypt(payload)
|
||||||
payload = aes.encrypt(bytes(payload))
|
|
||||||
|
|
||||||
packet[0x34] = checksum & 0xff
|
packet[0x34] = checksum & 0xff
|
||||||
packet[0x35] = checksum >> 8
|
packet[0x35] = checksum >> 8
|
||||||
|
@ -301,8 +325,7 @@ class mp1(device):
|
||||||
response = self.send_packet(0x6a, packet)
|
response = self.send_packet(0x6a, packet)
|
||||||
err = response[0x22] | (response[0x23] << 8)
|
err = response[0x22] | (response[0x23] << 8)
|
||||||
if err == 0:
|
if err == 0:
|
||||||
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
payload = self.decrypt(bytes(response[0x38:]))
|
||||||
payload = aes.decrypt(bytes(response[0x38:]))
|
|
||||||
if type(payload[0x4]) == int:
|
if type(payload[0x4]) == int:
|
||||||
state = payload[0x0e]
|
state = payload[0x0e]
|
||||||
else:
|
else:
|
||||||
|
@ -350,8 +373,7 @@ class sp2(device):
|
||||||
response = self.send_packet(0x6a, packet)
|
response = self.send_packet(0x6a, packet)
|
||||||
err = response[0x22] | (response[0x23] << 8)
|
err = response[0x22] | (response[0x23] << 8)
|
||||||
if err == 0:
|
if err == 0:
|
||||||
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
payload = self.decrypt(bytes(response[0x38:]))
|
||||||
payload = aes.decrypt(bytes(response[0x38:]))
|
|
||||||
return bool(payload[0x4])
|
return bool(payload[0x4])
|
||||||
|
|
||||||
class a1(device):
|
class a1(device):
|
||||||
|
@ -366,8 +388,7 @@ class a1(device):
|
||||||
err = response[0x22] | (response[0x23] << 8)
|
err = response[0x22] | (response[0x23] << 8)
|
||||||
if err == 0:
|
if err == 0:
|
||||||
data = {}
|
data = {}
|
||||||
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
payload = self.decrypt(bytes(response[0x38:]))
|
||||||
payload = aes.decrypt(bytes(response[0x38:]))
|
|
||||||
if type(payload[0x4]) == int:
|
if type(payload[0x4]) == int:
|
||||||
data['temperature'] = (payload[0x4] * 10 + payload[0x5]) / 10.0
|
data['temperature'] = (payload[0x4] * 10 + payload[0x5]) / 10.0
|
||||||
data['humidity'] = (payload[0x6] * 10 + payload[0x7]) / 10.0
|
data['humidity'] = (payload[0x6] * 10 + payload[0x7]) / 10.0
|
||||||
|
@ -417,8 +438,7 @@ class a1(device):
|
||||||
err = response[0x22] | (response[0x23] << 8)
|
err = response[0x22] | (response[0x23] << 8)
|
||||||
if err == 0:
|
if err == 0:
|
||||||
data = {}
|
data = {}
|
||||||
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
payload = self.decrypt(bytes(response[0x38:]))
|
||||||
payload = aes.decrypt(bytes(response[0x38:]))
|
|
||||||
if type(payload[0x4]) == int:
|
if type(payload[0x4]) == int:
|
||||||
data['temperature'] = (payload[0x4] * 10 + payload[0x5]) / 10.0
|
data['temperature'] = (payload[0x4] * 10 + payload[0x5]) / 10.0
|
||||||
data['humidity'] = (payload[0x6] * 10 + payload[0x7]) / 10.0
|
data['humidity'] = (payload[0x6] * 10 + payload[0x7]) / 10.0
|
||||||
|
@ -445,8 +465,7 @@ class rm(device):
|
||||||
response = self.send_packet(0x6a, packet)
|
response = self.send_packet(0x6a, packet)
|
||||||
err = response[0x22] | (response[0x23] << 8)
|
err = response[0x22] | (response[0x23] << 8)
|
||||||
if err == 0:
|
if err == 0:
|
||||||
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
payload = self.decrypt(bytes(response[0x38:]))
|
||||||
payload = aes.decrypt(bytes(response[0x38:]))
|
|
||||||
return payload[0x04:]
|
return payload[0x04:]
|
||||||
|
|
||||||
def send_data(self, data):
|
def send_data(self, data):
|
||||||
|
@ -465,8 +484,7 @@ class rm(device):
|
||||||
response = self.send_packet(0x6a, packet)
|
response = self.send_packet(0x6a, packet)
|
||||||
err = response[0x22] | (response[0x23] << 8)
|
err = response[0x22] | (response[0x23] << 8)
|
||||||
if err == 0:
|
if err == 0:
|
||||||
aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv))
|
payload = self.decrypt(bytes(response[0x38:]))
|
||||||
payload = aes.decrypt(bytes(response[0x38:]))
|
|
||||||
if type(payload[0x4]) == int:
|
if type(payload[0x4]) == int:
|
||||||
temp = (payload[0x4] * 10 + payload[0x5]) / 10.0
|
temp = (payload[0x4] * 10 + payload[0x5]) / 10.0
|
||||||
else:
|
else:
|
||||||
|
|
10
setup.py
10
setup.py
|
@ -6,19 +6,23 @@ from setuptools import setup, find_packages
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
dynamic_requires = []
|
try:
|
||||||
|
import pyaes
|
||||||
|
dynamic_requires = ["pyaes==1.6.0"]
|
||||||
|
except ImportError, e:
|
||||||
|
dynamic_requires = ['pycrypto==2.6.1']
|
||||||
|
|
||||||
version = 0.3
|
version = 0.3
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='broadlink',
|
name='broadlink',
|
||||||
version=0.3,
|
version=0.4,
|
||||||
author='Matthew Garrett',
|
author='Matthew Garrett',
|
||||||
author_email='mjg59@srcf.ucam.org',
|
author_email='mjg59@srcf.ucam.org',
|
||||||
url='http://github.com/mjg59/python-broadlink',
|
url='http://github.com/mjg59/python-broadlink',
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
scripts=[],
|
scripts=[],
|
||||||
install_requires=['pycrypto==2.6.1'],
|
install_requires=dynamic_requires,
|
||||||
description='Python API for controlling Broadlink IR controllers',
|
description='Python API for controlling Broadlink IR controllers',
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 4 - Beta',
|
'Development Status :: 4 - Beta',
|
||||||
|
|
Loading…
Reference in a new issue