Merge pull request #44 from tuxuser/fix/laf_crypto

Using cryptography lib instead of (dead) pycrypto
This commit is contained in:
Peter Wu 2018-03-17 12:36:44 +01:00 committed by GitHub
commit 7eeac45d22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 17 deletions

View file

@ -20,10 +20,12 @@ LGLAF.py depends on:
- Python 2.7 or 3: https://www.python.org/ - Python 2.7 or 3: https://www.python.org/
- (Windows) LG driver, - (Windows) LG driver,
[LGMobileDriver\_WHQL\_Ver\_4.0.3.exe](http://18d5a.wpc.azureedge.net/8018D5A/tool/dn/downloader.dev?fileKey=UW00120120425) [LGMobileDriver\_WHQL\_Ver\_4.2.0.exe](http://oceanhost.eu/wylc5rg7a8ou/LGMobileDriver_WHQL_Ver_4.2.0.exe.htm)
(12986920 bytes, (16691672 bytes,
sha256sum: 86e893b7f5da7f7d2656d9ce2563f082271983bb63903d0ed5cb279c560db459) sha256sum: d78ae6dfe7d34b9cabb8c4de5c6e734b6fed20b513d0da0183871bd77abba56c),
**WARNING**: This file was found via google search, it's not downloaded directly from LG servers
- (Linux) PyUSB: https://walac.github.io/pyusb/ - (Linux) PyUSB: https://walac.github.io/pyusb/
- Cryptography library: https://cryptography.io/en/latest/
On Linux, you must also install On Linux, you must also install
[rules.d/42-usb-lglaf.rules](rules.d/42-usb-lglaf.rules) to `/etc/udev/rules.d/` [rules.d/42-usb-lglaf.rules](rules.d/42-usb-lglaf.rules) to `/etc/udev/rules.d/`

View file

@ -1,11 +1,15 @@
from Crypto.Cipher import AES import struct
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from lglaf import int_as_byte from lglaf import int_as_byte
def key_transform(old_key): def key_transform(old_key):
new_key = b'' new_key = b''
old_key = bytearray(old_key)
for x in range(32, 0, -1): for x in range(32, 0, -1):
new_key += int_as_byte(old_key[x-1] - (x % 0x0C)) c = old_key[x-1]
new_key += int_as_byte(c - (x % 0x0C))
return new_key return new_key
@ -13,11 +17,10 @@ def xor_key(key, kilo_challenge):
# Reserve key # Reserve key
key_xor = b'' key_xor = b''
pos = 0 pos = 0
challenge = struct.unpack('>I', kilo_challenge)[0]
for i in range(8): for i in range(8):
key_xor += int_as_byte(key[pos] ^ kilo_challenge[3]) k = struct.unpack('<I', key[pos:pos + 4])[0]
key_xor += int_as_byte(key[pos + 1] ^ kilo_challenge[2]) key_xor += struct.pack('<I', k ^ challenge)
key_xor += int_as_byte(key[pos + 2] ^ kilo_challenge[1])
key_xor += int_as_byte(key[pos + 3] ^ kilo_challenge[0])
pos += 4 pos += 4
return key_xor return key_xor
@ -29,5 +32,6 @@ def encrypt_kilo_challenge(encryption_key, kilo_challenge):
plaintext += int_as_byte(k) plaintext += int_as_byte(k)
encryption_key = key_transform(encryption_key) encryption_key = key_transform(encryption_key)
xored_key = xor_key(encryption_key, kilo_challenge) xored_key = xor_key(encryption_key, kilo_challenge)
obj = AES.new(xored_key, AES.MODE_ECB) obj = Cipher(algorithms.AES(xored_key), modes.ECB(),
return obj.encrypt(plaintext) backend=default_backend()).encryptor()
return obj.update(plaintext) + obj.finalize()

View file

@ -24,16 +24,21 @@ except ImportError:
_logger = logging.getLogger("LGLAF.py") _logger = logging.getLogger("LGLAF.py")
# Python 2/3 compat # Python 2/3 compat
try: input = raw_input try:
except: pass input = raw_input
if '\0' == b'\0': int_as_byte = chr except:
else: int_as_byte = lambda x: bytes([x]) pass
if '\0' == b'\0':
int_as_byte = chr
else:
int_as_byte = lambda x: bytes([x])
# laf crypto for KILO challenge/response # laf crypto for KILO challenge/response
try: try:
import laf_crypto import laf_crypto
except ImportError: except ImportError as e:
_logger.warning("LAF Crypto failed to import!") _logger.warning("LAF Crypto failed to import! Error: %s" % e)
pass pass
# Use Manufacturer key for KILO challenge/response # Use Manufacturer key for KILO challenge/response

5
tests/conftest.py Normal file
View file

@ -0,0 +1,5 @@
import pytest
@pytest.fixture(scope='session')
def laf_key():
return b'qndiakxxuiemdklseqid~a~niq,zjuxl'

17
tests/test_crypto.py Normal file
View file

@ -0,0 +1,17 @@
from binascii import unhexlify
import laf_crypto
def test_transform(laf_key):
transformed = laf_crypto.key_transform(laf_key)
assert transformed == b'dqoev)ohnsWu\\bk`oiicmZ_lpqe\\ealp'
def test_xor_key(laf_key):
transformed_key = b'dqoev)ohnsWu\\bk`oiicmZ_lpqe\\ealp'
challenge = unhexlify(b'f29ae130')
xored_key = laf_crypto.xor_key(transformed_key, challenge)
assert xored_key == b'T\x90\xf5\x97F\xc8\xf5\x9a^\x92\xcd\x87l\x83\xf1\x92_\x88\xf3\x91]\xbb\xc5\x9e@\x90\xff\xaeU\x80\xf6\x82'
def test_challenge(laf_key):
resp = laf_crypto.encrypt_kilo_challenge(laf_key, unhexlify(b'f29ae130'))
assert resp == unhexlify(b'2f47ca81ebeee6f414263c0542c8d132')