Blog banner
Resources

TestBot Blog: Embedded Test Automation Insights

Engineering notes, testing practices, and platform updates from the TestBot team.

Jothi Kumar G|Embedded QA Engineer|16, June 2026

Automating UDS SecurityAccess: How to Handle Seed/Key Algorithms in TestBot

UDS SecurityAccess seed key algorithm automation in TestBot

Every automotive ECU test engineer eventually hits the same wall: you have automated 20 UDS services without trouble, and then you get to SecurityAccess (0x27). The seed arrives. You need to compute the key. And suddenly your drag-and-drop test sequence needs to call an algorithm that is different for every OEM, every ECU family, and sometimes every firmware version.

This is the most common reason UDS test suites stay partially manual. It should not be.

What SecurityAccess Actually Does

ISO 14229 SecurityAccess (Service ID 0x27) is a two-step challenge-response sequence that gates access to restricted diagnostic functions - DID writes, flash programming, communication control, and sometimes even extended session data. The sequence is:

  1. RequestSeed (sub-function 0x01, 0x03, 0x05…) - tester sends request, ECU responds with a seed value (typically 2–8 bytes, sometimes 16).
  2. SendKey (sub-function 0x02, 0x04, 0x06…) - tester computes the key from the seed using a secret algorithm, sends it back. ECU validates. If correct, it responds positively and grants access. If wrong, it increments a failed attempt counter and eventually locks the security access for a delay period (typically 10–60 seconds).

The algorithm is proprietary. There is no standard. A seed XOR 0xDEADBEEF is as valid as a 256-bit AES-CBC operation - it depends entirely on the ECU manufacturer's implementation.

Three Approaches in TestBot

TestBot's UDS Client Agent supports three ways to provide the seed-to-key computation. Use whichever matches your ECU supplier's delivery format.

Approach 1: Fixed XOR (for simple algorithms)

Many automotive ECUs at development stage use trivial seed/key algorithms - XOR with a fixed mask, shift and add, or a lookup table. The UDS Client Agent accepts a Python expression inline in the SecurityAccess block configuration. For a simple XOR:

key = seed ^ 0x3C5A9F12

The seed bytes are available as a Python bytes object. The expression must return a bytes object of the correct length. This handles the majority of development-phase ECU algorithms without any external code.

Approach 2: Python callback function

For more complex algorithms - Fibonacci transformations, CRC-based keys, multi-step byte manipulation - define a Python function in the test sequence's script section and reference it from the SecurityAccess block:

def compute_key(seed: bytes) -> bytes:
    # your algorithm here
    result = bytearray(len(seed))
    for i, b in enumerate(seed):
        result[i] = (b + 0x53 + i) & 0xFF ^ 0xA7
    return bytes(result)

The function receives the raw seed bytes and must return the key bytes. TestBot calls it automatically during the SecurityAccess sequence, with no manual intervention required.

Approach 3: External DLL / shared library

OEM Tier-1 suppliers commonly receive the seed/key algorithm as a compiled DLL (Windows) or .so (Linux) - precisely to avoid distributing the algorithm in readable source. TestBot's Utility Agent External Command API block can invoke any external executable or load a DLL via Python's ctypes:

import ctypes
lib = ctypes.CDLL("./seed_key_algo.dll")
lib.ComputeKey.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_int]
lib.ComputeKey.restype = ctypes.c_int

key_buf = ctypes.create_string_buffer(4)
lib.ComputeKey(seed_bytes, len(seed_bytes), key_buf, 4)
key = bytes(key_buf.raw)

This approach means the algorithm stays compiled and opaque - exactly as the OEM intends - while the test automation runs fully unattended.

Testing the Algorithm Itself, Not Just the Happy Path

Most SecurityAccess test implementations only test the successful case. A complete test suite should cover four scenarios:

  • Correct key → ECU responds 0x67 (positive response), access granted. Verify the subsequent service call succeeds.
  • Incorrect key (single attempt) → ECU responds 0x7F 0x27 0x35 (requestOutOfRange or invalidKey). Attempt counter increments. Verify the counter is tracked correctly.
  • Exceeded attempt limit → After N failed attempts (check ECU spec - typically 3), ECU returns 0x7F 0x27 0x36 (exceededNumberOfAttempts) and imposes a delay. Verify the delay is approximately correct.
  • Delay timer bypass attempt → Sending a RequestSeed before the delay expires should return 0x7F 0x27 0x37 (requiredTimeDelayNotExpired). Verify this rejection.

The last two are the ones that catch ECU implementation errors in production. An ECU that does not correctly implement the attempt counter or delay can be exploited in the field. These are also the test cases engineers skip when they are running manually - because sitting through a 60-second lockout is frustrating. Automated tests do not get frustrated.

Session Context Matters

SecurityAccess only works in the correct session. Sending a RequestSeed in Default Session should return 0x7F 0x27 0x22 (conditionsNotCorrect). The UDS Client Agent handles session management automatically - transition to Extended or Programming session before invoking SecurityAccess - but verify the sequence explicitly in your test case:

  1. DiagnosticSessionControl (0x10) → Extended Session (0x03)
  2. SecurityAccess RequestSeed (0x27 0x01) → receive seed
  3. SecurityAccess SendKey (0x27 0x02) → compute and send key
  4. Verify access-gated service works (e.g. WriteDataByIdentifier 0x2E)
  5. ECUReset (0x11) → verify access is revoked on reset

The reset verification at step 5 catches ECUs that persist security access across resets - a real implementation defect seen in production ECUs.

Read the Full Guide + See the Agent

UDS Testing Guide - All 22 ISO 14229 Services

The complete UDS reference: all 22 services including SecurityAccess, DID read/write, fault memory, and flash programming - with test scenarios and agent pricing.