"""Original implementation of the TP-Link Smart Home protocol.""" import struct from typing import Generator class OriginalTPLinkSmartHomeProtocol: """Original implementation of the TP-Link Smart Home protocol.""" INITIALIZATION_VECTOR = 171 @staticmethod def _xor_payload(unencrypted: bytes) -> Generator[int, None, None]: key = OriginalTPLinkSmartHomeProtocol.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 """ plainbytes = request.encode() return struct.pack(">I", len(plainbytes)) + bytes( OriginalTPLinkSmartHomeProtocol._xor_payload(plainbytes) ) @staticmethod def _xor_encrypted_payload(ciphertext: bytes) -> Generator[int, None, None]: key = OriginalTPLinkSmartHomeProtocol.INITIALIZATION_VECTOR for cipherbyte in ciphertext: plainbyte = key ^ cipherbyte key = cipherbyte yield plainbyte @staticmethod def decrypt(ciphertext: bytes) -> str: """Decrypt a response of a TP-Link Smart Home Device. :param ciphertext: encrypted response data :return: plaintext response """ return bytes( OriginalTPLinkSmartHomeProtocol._xor_encrypted_payload(ciphertext) ).decode()