Clock Skew Fingerprinting
Every transmitter runs on its own crystal, and no two crystals agree. Measuring that disagreement from arrival timestamps attributes traffic to a physical device that carries no identity of its own.
Clock skew fingerprinting attributes messages to the physical device that sent them by measuring the tiny, constant frequency error of that device's crystal. It works on any bus where messages are periodic and timestamps are recorded, and it works precisely where addressing does not: a CAN frame carries no source address, but the quartz behind it is as good as one.
What it is
A quartz oscillator is specified to a tolerance in parts per million. Automotive and embedded parts are commonly quoted at plus or minus 30 to 100 ppm once temperature is included, and the actual error of any individual part is a stable number somewhere in that band. A node that publishes a message every 100 ms on a crystal running 40 ppm fast emits every 99.996 ms as measured by the recorder's own clock. Over ninety seconds that is 3.6 ms of accumulated offset, which a microsecond-resolution capture measures easily.
The measurement is normally written as an accumulated offset: for the k-th frame of an identifier with nominal period P,
r(k) = t(k) - k * P
and the slope of r against t is the crystal offset. Every identifier published by the same box gives the same slope; identifiers from different boxes do not. The idea was made concrete for vehicles by Cho and Shin's CIDS work, which used it as a live intrusion detection primitive: a masquerading node cannot fake somebody else's crystal.
Why it matters
It answers a question no payload can. On CAN there is no source address, so nothing in a frame says which box sent it, and a spoofed frame is byte-identical to the real thing. Skew gives you attribution: which identifiers share a transmitter, whether an identifier has acquired a second one, and whether a frame that claims to be from the body controller has the body controller's clock. It also survives the usual evasions, because an attacker can copy a payload, a counter and a checksum but cannot copy an oscillator.
How to work it
- Group the capture by identifier, build r(k) = t(k) - k*P, and look at how it walks. Missing frames must be accounted for, since k is an index and not a count.
- Fit a line. This is where it goes wrong. Transport delay on a shared medium is one sided: a frame waits for the medium and for anything of higher priority, so the noise on t(k) is non-negative and its mean moves with the load. A least-squares fit therefore returns the crystal plus the growth rate of the queue.
- Use the estimator the network clock-skew literature settled on for exactly this reason. Because the error is non-negative, the honest line is the lowest line that still passes under every point, found with a linear program: maximise na + bsum(t) subject to a + b*t(k) <= r(k). With two unknowns the optimum is an edge of the lower convex hull, so it can be found by building the hull and testing its edges.
- Sort the recovered offsets. Devices appear as tight clusters with wide empty gaps between them, and the clusters are the answer.
Pitfalls
- Least squares is the trap, not the tool. On a bus whose load changes across the capture it produces a map that looks tidy and is wrong, splitting real devices and merging different ones.
- Restricting to the quiet part of a capture reduces the bias but rarely removes it, and it throws away the time span the estimate depends on.
- Temperature moves a crystal. Over minutes it is stable enough; over hours it is not, and a warming ECU walks.
- Give every device the same nominal period and enough frames. An estimate over fifty samples has an error comparable to the spacing between devices.
- Recorder-side buffering that delays frames unevenly poisons the whole measurement. Timestamp in hardware if you can.