about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Høyer Iversen <mail@dahoiv.net>2020-03-04T21·24+0100
committerGitHub <noreply@github.com>2020-03-04T21·24+0100
commit8e7446f4108db748e82a68e41b254e80b01bd51b (patch)
treefaf0bddcbccbb025da2c905e3b301a64f91aa43a
parentdfd478922b34b7810743b3bf145bed3026159838 (diff)
Fix CBC mode padding and use adler32 for checksums (#315)
* Fix CBC mode padding and use adler32 for checksums

* Change line order

This change comes to improve the readability of the code.

* Use zero-padding for CBC mode
-rw-r--r--broadlink/__init__.py35
1 files changed, 9 insertions, 26 deletions
diff --git a/broadlink/__init__.py b/broadlink/__init__.py
index 3190a7b7446c..1c622301e31a 100644
--- a/broadlink/__init__.py
+++ b/broadlink/__init__.py
@@ -8,6 +8,7 @@ import struct
 import threading
 import time
 from datetime import datetime
+from zlib import adler32
 
 from cryptography.hazmat.backends import default_backend
 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
@@ -109,11 +110,8 @@ def discover(timeout=None, local_ip_address=None):
     packet[0x1c] = port & 0xff
     packet[0x1d] = port >> 8
     packet[0x26] = 6
-    checksum = 0xbeaf
 
-    for i in range(len(packet)):
-        checksum += packet[i]
-    checksum = checksum & 0xffff
+    checksum = adler32(packet, 0xbeaf) & 0xffff
     packet[0x20] = checksum & 0xff
     packet[0x21] = checksum >> 8
 
@@ -251,26 +249,17 @@ class device:
 
         # pad the payload for AES encryption
         if payload:
-            numpad = (len(payload) // 16 + 1) * 16
-            payload = payload.ljust(numpad, b"\x00")
-
-        checksum = 0xbeaf
-        for i in range(len(payload)):
-            checksum += payload[i]
-            checksum = checksum & 0xffff
-
-        payload = self.encrypt(payload)
-
+            payload += bytearray(((len(payload)-1)//16+1)*16 - len(payload))
+        
+        checksum = adler32(payload, 0xbeaf) & 0xffff
         packet[0x34] = checksum & 0xff
         packet[0x35] = checksum >> 8
 
+        payload = self.encrypt(payload)
         for i in range(len(payload)):
             packet.append(payload[i])
 
-        checksum = 0xbeaf
-        for i in range(len(packet)):
-            checksum += packet[i]
-            checksum = checksum & 0xffff
+        checksum = adler32(packet, 0xbeaf) & 0xffff
         packet[0x20] = checksum & 0xff
         packet[0x21] = checksum >> 8
 
@@ -403,9 +392,7 @@ class bg1(device):
         for i in range(len(js)):
             packet.append(js[i])
 
-        checksum = 0xc0ad
-        for c in packet[0x08:]:
-            checksum = (checksum + c) & 0xffff
+        checksum = adler32(packet[0x08:], 0xc0ad) & 0xffff
         packet[0x06] = checksum & 0xff
         packet[0x07] = checksum >> 8
 
@@ -969,11 +956,7 @@ def setup(ssid, password, security_mode):
     payload[0x85] = pass_length  # Character length of password
     payload[0x86] = security_mode  # Type of encryption (00 - none, 01 = WEP, 02 = WPA1, 03 = WPA2, 04 = WPA1/2)
 
-    checksum = 0xbeaf
-    for i in range(len(payload)):
-        checksum += payload[i]
-        checksum = checksum & 0xffff
-
+    checksum = adler32(payload, 0xbeaf) & 0xffff
     payload[0x20] = checksum & 0xff  # Checksum 1 position
     payload[0x21] = checksum >> 8  # Checksum 2 position