1818from dataclasses import dataclass
1919
2020from Crypto .Cipher import AES
21- from Crypto .Util .Padding import pad , unpad
2221from google .protobuf .message import DecodeError , Message
2322from PIL import Image
2423from vacuum_map_parser_base .config .image_config import ImageConfig
2524from vacuum_map_parser_base .map_data import ImageData , MapData
2625
2726from roborock .exceptions import RoborockException
2827from roborock .map .proto .b01_scmap_pb2 import RobotMap # type: ignore[attr-defined]
28+ from roborock .protocol import Utils
2929
3030from .map_parser import ParsedMapData
3131
@@ -83,7 +83,7 @@ def _derive_map_key(serial: str, model: str) -> bytes:
8383 model_suffix = model .split ("." )[- 1 ]
8484 model_key = (model_suffix + "0" * 16 )[:16 ].encode ()
8585 material = f"{ serial } +{ model_suffix } +{ serial } " .encode ()
86- encrypted = AES . new ( model_key , AES . MODE_ECB ). encrypt ( pad ( material , AES . block_size ) )
86+ encrypted = Utils . encrypt_ecb ( material , model_key )
8787 md5 = hashlib .md5 (base64 .b64encode (encrypted ), usedforsecurity = False ).hexdigest ()
8888 return md5 [8 :24 ].encode ()
8989
@@ -99,15 +99,16 @@ def _decode_base64_payload(raw_payload: bytes) -> bytes:
9999
100100def _decode_b01_map_payload (raw_payload : bytes , * , serial : str , model : str ) -> bytes :
101101 """Decode raw B01 `MAP_RESPONSE` payload into inflated SCMap bytes."""
102+ # TODO: Move this lower-level B01 transport decode under `roborock.protocols`
103+ # so this module only handles SCMap parsing/rendering.
102104 encrypted_payload = _decode_base64_payload (raw_payload )
103105 if len (encrypted_payload ) % AES .block_size != 0 :
104106 raise RoborockException ("Unexpected encrypted B01 map payload length" )
105107
106108 map_key = _derive_map_key (serial , model )
107- decrypted_hex = AES .new (map_key , AES .MODE_ECB ).decrypt (encrypted_payload )
108109
109110 try :
110- compressed_hex = unpad ( decrypted_hex , AES . block_size ).decode ("ascii" )
111+ compressed_hex = Utils . decrypt_ecb ( encrypted_payload , map_key ).decode ("ascii" )
111112 compressed_payload = bytes .fromhex (compressed_hex )
112113 return zlib .decompress (compressed_payload )
113114 except (ValueError , UnicodeDecodeError , zlib .error ) as err :
0 commit comments