Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions kasa/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,24 +89,32 @@ async def query(host: str, request: Union[str, Dict], retry_count: int = 3) -> D
# make mypy happy, this should never be reached..
raise SmartDeviceException("Query reached somehow to unreachable")

@staticmethod
def _xor_payload(unencrypted):
key = TPLinkSmartHomeProtocol.INITIALIZATION_VECTOR
for unencryptedbyte in unencrypted:
key = key ^ unencryptedbyte
yield key

@staticmethod
def encrypt(request: str) -> bytes:
"""Encrypt a request for a TP-Link Smart Home Device.

:param request: plaintext request data
:return: ciphertext to be send over wire, in bytes
"""
key = TPLinkSmartHomeProtocol.INITIALIZATION_VECTOR

plainbytes = request.encode()
buffer = bytearray(struct.pack(">I", len(plainbytes)))
return struct.pack(">I", len(plainbytes)) + bytes(
TPLinkSmartHomeProtocol._xor_payload(plainbytes)
)

for plainbyte in plainbytes:
cipherbyte = key ^ plainbyte
@staticmethod
def _xor_encrypted_payload(ciphertext):
key = TPLinkSmartHomeProtocol.INITIALIZATION_VECTOR
for cipherbyte in ciphertext:
plainbyte = key ^ cipherbyte
key = cipherbyte
buffer.append(cipherbyte)

return bytes(buffer)
yield plainbyte

@staticmethod
def decrypt(ciphertext: bytes) -> str:
Expand All @@ -115,14 +123,6 @@ def decrypt(ciphertext: bytes) -> str:
:param ciphertext: encrypted response data
:return: plaintext response
"""
key = TPLinkSmartHomeProtocol.INITIALIZATION_VECTOR
buffer = []

for cipherbyte in ciphertext:
plainbyte = key ^ cipherbyte
key = cipherbyte
buffer.append(plainbyte)

plaintext = bytes(buffer)

return plaintext.decode()
return bytes(
TPLinkSmartHomeProtocol._xor_encrypted_payload(ciphertext)
).decode()