def get_key_pkt(seed, keyfunction, level=1): # type: (Packet, Callable[[int], int], int) -> Optional[Packet] try: s = seed.securitySeed except AttributeError: return None return cast(Packet, GMLAN() / GMLAN_SA(subfunction=level + 1, securityKey=keyfunction(s)))
def get_seed_pkt(sock, level=1): # type: (_SocketUnion, int) -> Optional[Packet] req = GMLAN() / GMLAN_SA(subfunction=level) for _ in range(10): seed = sock.sr1(req, timeout=5, verbose=False) if seed is None: return None elif seed.service == 0x7f and \ GMLAN_Enumerator._get_negative_response_code(seed) != 0x37: log_interactive.info("Security access no seed! NR: %s", repr(seed)) return None elif seed.service == 0x7f and \ GMLAN_Enumerator._get_negative_response_code(seed) == 0x37: log_interactive.info("Security access retry to get seed") time.sleep(10) continue else: return seed return None
def GMLAN_GetSecurityAccess( sock, # type: SuperSocket key_function, # type: Callable[[int], int] level=1, # type: int timeout=None, # type: Optional[int] verbose=None, # type: Optional[bool] retry=0 # type: int ): # type: (...) -> bool """ Authenticate on ECU. Implements Seey-Key procedure. :param sock: socket to send the message on. :param key_function: function implementing the key algorithm. :param level: level of access :param timeout: timeout for sending, receiving or sniffing packages. :param verbose: set verbosity level :param retry: number of retries in case of failure. :return: True on success. """ if verbose is None: verbose = conf.verb > 0 retry = abs(retry) if key_function is None: return False if level % 2 == 0: warning("Parameter Error: Level must be an odd number.") return False while retry >= 0: retry -= 1 request = GMLAN() / GMLAN_SA(subfunction=level) if verbose: print("Requesting seed..") resp = sock.sr1(request, timeout=timeout, verbose=0) if not _check_response(resp, verbose): if resp is not None and resp.returnCode == 0x37 and retry: if verbose: print("RequiredTimeDelayNotExpired. Wait 10s.") time.sleep(10) if verbose: print("Negative Response.") continue seed = cast(Packet, resp).securitySeed if seed == 0: if verbose: print("ECU security already unlocked. (seed is 0x0000)") return True keypkt = GMLAN() / GMLAN_SA(subfunction=level + 1, securityKey=key_function(seed)) if verbose: print("Responding with key..") resp = sock.sr1(keypkt, timeout=timeout, verbose=0) if resp is None: if verbose: print("Timeout.") continue if verbose: resp.show() if resp.service == 0x67: if verbose: print("SecurityAccess granted.") return True # Invalid Key elif resp.service == 0x7f and resp.returnCode == 0x35: if verbose: print("Key invalid") continue return False
def _get_initial_requests(self, **kwargs): # type: (Any) -> Iterable[Packet] scan_range = kwargs.pop("scan_range", range(1, 10, 2)) return (GMLAN() / GMLAN_SA(subfunction=x) for x in scan_range)
def GMLAN_GetSecurityAccess(sock, key_function, level=1, timeout=None, verbose=None, retry=0): # noqa: E501 # type: (ISOTPSocket, Callable[[int], int], int, Optional[int], Optional[bool], int) -> bool # noqa: E501 """ Authenticate on ECU. Implements Seey-Key procedure. :param sock: socket to send the message on. :param key_function: function implementing the key algorithm. :param level: level of access :param timeout: timeout for sending, receiving or sniffing packages. :param verbose: set verbosity level :param retry: number of retries in case of failure. :return: True on success. """ if verbose is None: verbose = conf.verb > 0 retry = abs(retry) if key_function is None: return False if level % 2 == 0: warning("Parameter Error: Level must be an odd number.") return False while retry >= 0: retry -= 1 request = GMLAN() / GMLAN_SA(subfunction=level) if verbose: print("Requesting seed..") resp = sock.sr1(request, timeout=timeout, verbose=0) if not _check_response(resp, verbose): if verbose: print("Negative Response.") continue seed = resp.securitySeed if seed == 0: if verbose: print("ECU security already unlocked. (seed is 0x0000)") return True keypkt = GMLAN() / GMLAN_SA(subfunction=level + 1, securityKey=key_function(seed)) if verbose: print("Responding with key..") resp = sock.sr1(keypkt, timeout=timeout, verbose=0) if resp is None: if verbose: print("Timeout.") continue if verbose: resp.show() if resp.sprintf("%GMLAN.service%") == "SecurityAccessPositiveResponse": # noqa: E501 if verbose: print("SecurityAccess granted.") return True # Invalid Key elif resp.sprintf("%GMLAN.service%") == "NegativeResponse" and \ resp.sprintf("%GMLAN.returnCode%") == "InvalidKey": if verbose: print("Key invalid") continue return False
def _get_initial_requests(self, **kwargs): # type: (Any) -> Iterable[Packet] return (GMLAN() / GMLAN_SA(subfunction=x) for x in range(1, 10, 2))