Return-Path: <ovmsdev-bounces@lists.openvehicles.com>
Received: from network-box.com ([unix socket])
	 by nbmailhq5.network-box.com with LMTPA;
	 Sun, 05 Jul 2020 22:24:08 +0800
X-Sieve: CMU Sieve 2.4
Received: from nbmailscanhq5.network-box.com (unknown [10.12.18.182])
	by network-box.com (Postfix) with ESMTP id ADB3B406BD7A
	for <mark.johnson@network-box.com>; Sun,  5 Jul 2020 22:24:08 +0800 (HKT)
Received: from nbmailhk1.network-box.com (localhost [127.0.0.1])
	by nbmailscanhq5.network-box.com (Postfix) with ESMTP id B704FA1EF5
	for <mark.johnson@network-box.com>; Sun,  5 Jul 2020 22:24:05 +0800 (HKT)
Received: from unknown (EHLO nbmailhk1.network-box.com) (10.8.12.9)
  by 127.0.0.1 (Network Box) with SMTP id
 '2e667aac-becb-11ea-9049-7e2b5a688fa9'; 05 Jul 2020 14:24:08 -0000
X-Scanned-By-nbmailscanhq5: eMail scan performed by network-box
X-Scanned-By-nbmailscanhq5: Network Box scan job
 2e9d2746-becb-11ea-9049-7e2b5a688fa9
X-Scanned-By-nbmailscanhq5: Network Box message id
 2e667aac-becb-11ea-9049-7e2b5a688fa9
Received: from nbmailscanhq5.network-box.com (unknown [10.12.18.182])
	by nbmailhk1.network-box.com (Postfix) with ESMTP id 5012F9004B
	for <mark@webb-johnson.net>; Sun,  5 Jul 2020 22:24:05 +0800 (HKT)
Received: from charged.hk (localhost [127.0.0.1])
	by nbmailscanhq5.network-box.com (Postfix) with ESMTP id 34CA7A1EF1
	for <mark@webb-johnson.net>; Sun,  5 Jul 2020 22:24:01 +0800 (HKT)
Received: from unknown (EHLO charged.hk) (10.12.12.188)
  by 127.0.0.1 (Network Box) with SMTP id
 '2a3217a2-becb-11ea-9bb9-7e2b5a688fa9'; 05 Jul 2020 14:24:05 -0000
X-Scanned-By-nbmailscanhq5: eMail scan performed by network-box
X-Scanned-By-nbmailscanhq5: Network Box scan job
 2beab05e-becb-11ea-9bb9-7e2b5a688fa9
X-Scanned-By-nbmailscanhq5: Network Box message id
 2a3217a2-becb-11ea-9bb9-7e2b5a688fa9
Received: from [10.12.12.188] (localhost [IPv6:::1])
	by charged.hk (Postfix) with ESMTP id 472CD80818C0;
	Sun,  5 Jul 2020 22:23:58 +0800 (HKT)
X-Original-To: ovmsdev@lists.openvehicles.com
Delivered-To: ovmsdev@lists.openvehicles.com
Received: from nbmailscanhq5.network-box.com (unknown [10.12.18.182])
 by charged.hk (Postfix) with ESMTP id 0CEB184F12A1
 for <ovmsdev@lists.openvehicles.com>; Sun,  5 Jul 2020 22:23:56 +0800 (HKT)
Received: from [10.12.10.6] (localhost [127.0.0.1])
 by nbmailscanhq5.network-box.com (Postfix) with ESMTPA id 8D230A1EE3
 for <ovmsdev@lists.openvehicles.com>; Sun,  5 Jul 2020 22:23:50 +0800 (HKT)
Received: from unknown (EHLO [10.12.10.6]) (91.132.136.52)
 by 127.0.0.1 (Network Box) with SMTP id
 '2288ac0d-becb-11ea-9049-7e2b5a688fa9';
 05 Jul 2020 14:23:55 -0000
X-NetworkBox-Signature-Group-NBHQ: 0501; GROUP; NBHQ; nbmailscanhq5;
 5f807f87e3ee1abc656824757c2e72b78c10b3a3d4e7fe436f9d8a276ab99468
X-Scanned-By-nbmailscanhq5: eMail scan performed by network-box
X-Scanned-By-nbmailscanhq5: Network Box scan job
 26e7e5d6-becb-11ea-9049-7e2b5a688fa9
X-Scanned-By-nbmailscanhq5: Network Box message id
 2288ac0d-becb-11ea-9049-7e2b5a688fa9
From: Mark Webb-Johnson <mark@webb-johnson.net>
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\))
Message-Id: <AAAA7DA7-98BE-4376-BBC0-348A23798F9D@webb-johnson.net>
Date: Sun, 5 Jul 2020 22:23:44 +0800
To: OVMS Developers <ovmsdev@lists.openvehicles.com>
X-Mailer: Apple Mail (2.3445.104.11)
Subject: [Ovmsdev] TPMS subsystem, Roadster, Model S, Baolong,
 and some UDS hacking/cracking
X-BeenThere: ovmsdev@lists.openvehicles.com
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: OVMS Developers <ovmsdev.lists.openvehicles.com>
List-Unsubscribe: <http://lists.openvehicles.com/mailman/options/ovmsdev>,
 <mailto:ovmsdev-request@lists.openvehicles.com?subject=unsubscribe>
List-Archive: <http://lists.openvehicles.com/pipermail/ovmsdev/>
List-Post: <mailto:ovmsdev@lists.openvehicles.com>
List-Help: <mailto:ovmsdev-request@lists.openvehicles.com?subject=help>
List-Subscribe: <http://lists.openvehicles.com/mailman/listinfo/ovmsdev>,
 <mailto:ovmsdev-request@lists.openvehicles.com?subject=subscribe>
Reply-To: OVMS Developers <ovmsdev@lists.openvehicles.com>
Content-Type: multipart/mixed; boundary="===============2776426517074828385=="
Errors-To: ovmsdev-bounces@lists.openvehicles.com
Sender: "OvmsDev" <ovmsdev-bounces@lists.openvehicles.com>


--===============2776426517074828385==
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_B52BF126-997D-4430-921D-64F7D244296E"


--Apple-Mail=_B52BF126-997D-4430-921D-64F7D244296E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8


A long post, but contains some interesting information, and discussion =
of UDS hacking/cracking approaches.

A few weeks ago, I published my work on the Baolong TPMS in the Tesla =
Roadster. This resulted in a new TPMS subsystem in OVMS, as well as =
support for reading and writing tyre ID sets from/to the TPMS ECU in the =
car. For the Tesla Roadster, this requires the new K-line option board =
that should be generally available next week.

I then moved on to look at the Model S. My car (a 2014 Model S) uses a =
Baolong ECU, and can=E2=80=99t display the tyre pressures or =
temperatures. It is a simpler system than the roadster (same =
manufacturer), with just one ECU, one CAN bus connection, no k-line, no =
Lin bus, and no external antennas. Also about US$40 on eBay :-)

Decoding the message data was pretty trivial. Same format as the =
Roadster (same manufacturer, after all), just on a different CAN ID. The =
status messages are different, but the Tesla Model S ECU in developer =
mode shows a nice decode of those. A few minutes in the OVMS firmware =
and we can display tyre pressures and temperatures in the OVMS Apps =
(which strangely, Tesla still can=E2=80=99t do with that Baolong system =
in the car).

A colleague provided some CAN bus dumps of the engineering TPMS tool =
reading and writing tyre ID sets, and they looked pretty simple.

First the read commands:

34.296622 2T11 64F 03 22 f0 90 55 55 55 55
34.310594 2R11 65F 10 13 62 f0 90 11 12 13
34.396020 2T11 64F 30 03 0a 00 00 00 00 00
34.396663 2R11 65F 21 14 21 22 23 24 31 32
34.415594 2R11 65F 22 33 34 41 42 43 44 55

Looks pretty similar to the stuff we=E2=80=99ve seen before with OBDII =
active polling. ID 64F for the command and 65F for the response from the =
ECU. An extended OBDII multi-frame read of PID 0xf090. Easy enough, and =
implemented in the vehicle_teslamodels in less than an hour.

So, on to the write commands:

114.506522 2T11 64F 02 10 03 00 00 00 00 00
114.552387 2R11 65F 06 50 03 00 96 17 70 55

120.956904 2T11 64F 02 27 01 00 00 00 00 00
120.957400 2R11 65F 04 67 01 b5 0a 55 55 55

144.106603 2T11 64F 04 27 02 f7 02 00 00 00
144.107136 2R11 65F 02 67 02 55 55 55 55 55

157.657510 2T11 64F 10 13 2e f0 90 11 12 13
157.657932 2R11 65F 30 03 14 55 55 55 55 55
157.756158 2T11 64F 21 14 21 22 23 24 31 32
157.856138 2T11 64F 22 33 34 41 42 43 44 00
158.148199 2R11 65F 03 6e f0 90 55 55 55 55

At first glance, I skipped over the first three commands (assuming they =
were checking firmware version, or something like that), and looked at =
the last group. Seems similar to the OBDII extended read we saw to read =
the IDs. But when I try it on my bench ECU I don=E2=80=99t get the happy =
=E2=80=9865F 03 6e f0 90=E2=80=99 acknowledging the write, but instead a =
'65F 03 7f 2e 31=E2=80=99 indicating an error.

So, I went back and looked at those first three requests. In OBDII =
speak, these decode as:

64F 02 10 03 00 00 00 00 00
  0x02 =3D 2 data bytes in the request
  0x10 =3D UDS Diagnostic Session Control
  0x03 =3D UDS session type 0x03

65F 06 50 03 00 96 17 70 55
  0x06 =3D 6 data bytes in the response
  0x50 =3D 0x10 + 0x40 =3D successful response to our 0x10 command
  0x03 =3D UDS session type 0x03
  0x00961770 =3D Session data

64F 02 27 01 00 00 00 00 00
  0x02 =3D 2 data bytes in the request
  0x27 =3D UDS Security Access
  0x01 =3D Type 1 (seed request)

65F 04 67 01 b5 0a 55 55 55
  0x04 =3D 4 data bytes in the response
  0x67 =3D 0x27 + 0x40 =3D successful response to our 0x27 command
  0x01 =3D Type 1 (seed)
  0xb50a =3D UDS security access seed data

64F 04 27 02 f7 02 00 00 00
  0x04 =3D 4 data bytes in the request
  0x27 =3D UDS Security Access
  0x02 =3D type 2 (login)
  0xf702 =3D UDS security access login data

65F 02 67 02 55 55 55 55 55
  0x02 =3D 2 data bytes in the response
  0x67 =3D 0x27 + 0x40 =3D successful response to our 0x27 command
  0x02 =3D type 2 (login success)

* See here for an explanation: =
https://en.wikipedia.org/wiki/Unified_Diagnostic_Services =
<https://en.wikipedia.org/wiki/Unified_Diagnostic_Services>

At the point, I had an =E2=80=98oh shit=E2=80=99 moment. Why they hell =
would they use UDS security to protect writing TPMS tyre IDs? Good =
grief.

The way this works is that the diagnostic tool first establishes a =
diagnostic session with the ECU. It then requests a seed, and the ECU =
responds with a random number. The tool and ECU both then independently =
do a secret calculation (based on a secret algorithm and a secret =
number), the tool provides the result to the ECU, and the ECU verifies =
it. The seed provides protection against relay attack, and the password =
or algorithm are never sent over the wire so if done properly this can =
be strong against eavesdropping.

Despite the initial =E2=80=98oh shit=E2=80=99, there were two bits of =
good news. Firstly, the seed was only 2 bytes; that is 65,536 =
combinations and very susceptible to brute force. Secondly, we had a =
number of writes logged from the original tool so knew some good seed =
and login combinations:

843b -> d632
8338 -> d330
8932 -> db32
4738 -> 5730
ff00 -> ff00

That, and in particular the last one, doesn=E2=80=99t seem to show much =
entropy. The seed->password is just not random enough.

I started with some blind guesses:

Here are our known samples:
843b -> d632
8338 -> d330
8932 -> db32
4738 -> 5730
ff00 -> ff00
In binary:
843b 1000 0100 0011 1011
d632 1101 0110 0011 0010=20
8338 1000 0011 0011 1000
d330 1101 0011 0011 0000
8932 1000 1001 0011 0010
db32 1101 1011 0011 0010
4738 0100 0111 0011 1000
5730 0101 0111 0011 0000
ff00 1111 1111 0000 0000
ff00 1111 1111 0000 0000
It seems that the first byte can have 0=E2=80=99s become a 1, but never =
a 1 become a 0. So let=E2=80=99s assume that is a boolean OR operator.
=20
The second byte doesn=E2=80=99t have such good data, but it seems a 1 =
can become a 0. So let=E2=80=99s assume that it is a boolean AND =
operator.=20
     ----or--- ---and---
     0101 0010 ??11 0?10
In ascii, 0101 0010 is =E2=80=9CR=E2=80=9D. The second byte is harder, =
as we don=E2=80=99t have enough data and only know the result for 5 out =
of the 8 bits. But, if it is a letter, we can guess it is 0111 0?10. In =
ascii, 0111 0010 is the lower case =E2=80=9Cr=E2=80=9D.
=20
So, OR the first byte with =E2=80=9CR=E2=80=9D, then AND the second byte =
with =E2=80=9Cr=E2=80=9D. Can it be that simple? Can my first blind =
guess be correct?
=20
A little perl code:
=20
#!/usr/bin/perl
=20
while (<>)
  {
  chop;
  my $val =3D hex($_);
=20
  my $first =3D $val >> 8;
  my $second =3D $val & 0xff;
=20
  printf "Response for %04x is %02x %02x\n",$val,($first | =
0b01010010),($second & 0b01110010)
  }
=20
# Running it=E2=80=A6
843b
Response for 843b is d6 32
8338
Response for 8338 is d3 30
8932
Response for 8932 is db 32
4738
Response for 4738 is 57 30
ff00
Response for ff00 is ff 00

OK. But that is easy. Let=E2=80=99s try it for some new data=E2=80=A6
OVMS# can can2 tx standard 64F 02 10 03 00 00 00 00 00
V (11781198) canlog-monitor: 1593874849.354117 2T11 64F 02 10 03 00 00 =
00 00 00
V (11781248) canlog-monitor: 1593874849.400007 2R11 65F 06 50 03 00 96 =
17 70 55
=20
OVMS# can can2 tx standard 64F 02 27 01 00 00 00 00 00
V (11786098) canlog-monitor: 1593874854.254102 2T11 64F 02 27 01 00 00 =
00 00 00
V (11786098) canlog-monitor: 1593874854.254637 2R11 65F 04 67 01 be 01 =
55 55 55
=20
(My program gives "Response for be01 is fe 00=E2=80=9D)
=20
OVMS# can can2 tx standard 64F 04 27 02 fe 00 00 00 00
V (11805208) canlog-monitor: 1593874873.364121 2T11 64F 04 27 02 fe 00 =
00 00 00
V (11805208) canlog-monitor: 1593874873.364639 2R11 65F 02 67 02 55 55 =
55 55 55
Of course, that is a guess. But after trying a few dozen times I get =
success 100% of the time.

It does make me wonder what is the point of even attempting to add a =
security layer so trivially easy to crack.

I implemented the write in the OVMS firmware for Tesla Model S, and we =
have:

OVMS# tpms read
TPMS read as 11121314,21222324,31323334,41424344
V (34357) canlog-monitor: 34.296622 2T11 64F 03 22 f0 90 55 55 55 55
V (34377) canlog-monitor: 34.310594 2R11 65F 10 13 62 f0 90 11 12 13
V (34457) canlog-monitor: 34.396020 2T11 64F 30 03 0a 00 00 00 00 00
V (34457) canlog-monitor: 34.396663 2R11 65F 21 14 21 22 23 24 31 32
V (34477) canlog-monitor: 34.415594 2R11 65F 22 33 34 41 42 43 44 55

OVMS# tpms write models
Tyre set 'models' written to vehicle TPMS successfully
V (39687) canlog-monitor: 39.627553 2T11 64F 02 10 03 00 00 00 00 00
V (39737) canlog-monitor: 39.673421 2R11 65F 06 50 03 00 96 17 70 55
V (39787) canlog-monitor: 39.726138 2T11 64F 02 27 01 00 00 00 00 00
V (39787) canlog-monitor: 39.726907 2R11 65F 04 67 01 80 3b 55 55 55
V (39887) canlog-monitor: 39.826021 2T11 64F 04 27 02 d2 32 00 00 00
V (39887) canlog-monitor: 39.826744 2R11 65F 02 67 02 55 55 55 55 55
V (39987) canlog-monitor: 39.926014 2T11 64F 10 13 2e f0 90 08 02 ee
V (39987) canlog-monitor: 39.926747 2R11 65F 30 03 14 55 55 55 55 55
V (40087) canlog-monitor: 40.026051 2T11 64F 21 37 08 02 e9 63 08 02
V (40187) canlog-monitor: 40.126015 2T11 64F 22 ed fb 08 02 db 3a 00
V (40187) canlog-monitor: 40.126692 2R11 65F 03 7f 2e 78 55 55 55 55
V (40477) canlog-monitor: 40.418525 2R11 65F 03 6e f0 90 55 55 55 55

OVMS# tpms read
TPMS read as 0802ee37,0802e963,0802edfb,0802db3a
V (62107) canlog-monitor: 62.046624 2T11 64F 03 22 f0 90 55 55 55 55
V (62127) canlog-monitor: 62.060579 2R11 65F 10 13 62 f0 90 08 02 ee
V (62207) canlog-monitor: 62.146023 2T11 64F 30 03 0a 00 00 00 00 00
V (62207) canlog-monitor: 62.146658 2R11 65F 21 37 08 02 e9 63 08 02
V (62227) canlog-monitor: 62.165585 2R11 65F 22 ed fb 08 02 db 3a 55

Code committed, and working in my car.

Regards, Mark


--Apple-Mail=_B52BF126-997D-4430-921D-64F7D244296E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=utf-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dutf-8"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; line-break: after-white-space;" class=3D""><div =
class=3D""><br class=3D""></div><div class=3D"">A long post, but =
contains some interesting information, and discussion of UDS =
hacking/cracking approaches.</div><div class=3D""><br =
class=3D""></div><div class=3D"">A few weeks ago, I published my work on =
the Baolong TPMS in the Tesla Roadster. This resulted in a new TPMS =
subsystem in OVMS, as well as support for reading and writing tyre ID =
sets from/to the TPMS ECU in the car. For the Tesla Roadster, this =
requires the new K-line option board that should be generally available =
next week.</div><div class=3D""><br class=3D""></div><div class=3D"">I =
then moved on to look at the Model S. My car (a 2014 Model S) uses a =
Baolong ECU, and can=E2=80=99t display the tyre pressures or =
temperatures. It is a simpler system than the roadster (same =
manufacturer), with just one ECU, one CAN bus connection, no k-line, no =
Lin bus, and no external antennas. Also about US$40 on eBay =
:-)</div><div class=3D""><br class=3D""></div><div class=3D"">Decoding =
the message data was pretty trivial. Same format as the Roadster (same =
manufacturer, after all), just on a different CAN ID. The status =
messages are different, but the Tesla Model S ECU in developer mode =
shows a nice decode of those. A few minutes in the OVMS firmware and we =
can display tyre pressures and temperatures in the OVMS Apps (which =
strangely, Tesla still can=E2=80=99t do with that Baolong system in the =
car).</div><div class=3D""><br class=3D""></div><div class=3D"">A =
colleague provided some CAN bus dumps of the engineering TPMS tool =
reading and writing tyre ID sets, and they looked pretty =
simple.</div><div class=3D""><br class=3D""></div><div class=3D"">First =
the read commands:</div><div class=3D""><br class=3D""></div><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><div =
class=3D""><div class=3D""><font face=3D"Andale Mono" class=3D""><span =
style=3D"font-style: normal; font-size: 14px;" class=3D"">34.296622 2T11 =
64F 03 22 f0 90 55 55 55 55</span></font></div><div class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">34.310594 2R11 65F 10 13 62 f0 90 11 12 =
13</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">34.396020 2T11 64F 30 03 0a 00 00 00 00 =
00</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">34.396663 2R11 65F 21 14 21 22 23 24 31 =
32</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">34.415594 2R11 65F 22 33 34 41 42 43 44 =
55</span></font></div></div></blockquote><div class=3D""><br =
class=3D""></div><div class=3D"">Looks pretty similar to the stuff =
we=E2=80=99ve seen before with OBDII active polling. ID 64F for the =
command and 65F for the response from the ECU. An extended OBDII =
multi-frame read of PID 0xf090. Easy enough, and implemented in the =
vehicle_teslamodels in less than an hour.</div><div class=3D""><br =
class=3D""></div><div class=3D"">So, on to the write commands:</div><div =
class=3D""><br class=3D""></div><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D"">114.506522 2T11 =
64F 02 10 03 00 00 00 00 00<br class=3D"">114.552387 2R11 65F 06 50 03 =
00 96 17 70 55</span></font></blockquote><blockquote style=3D"margin: 0 =
0 0 40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-size: 14px;" class=3D""><br =
class=3D"">120.956904 2T11 64F 02 27 01 00 00 00 00 00<br =
class=3D"">120.957400 2R11 65F 04 67 01 b5 0a 55 55 =
55</span></font></blockquote><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D""><br =
class=3D"">144.106603 2T11 64F 04 27 02 f7 02 00 00 00<br =
class=3D""></span></font><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D"">144.107136 2R11 =
65F 02 67 02 55 55 55 55 55</span></font></div><div class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-size: 14px;" =
class=3D""><br class=3D""></span></font></div><div class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">157.657510 2T11 64F 10 13 2e f0 90 11 12 =
13</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">157.657932 2R11 65F 30 03 14 55 55 55 55 =
55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">157.756158 2T11 64F 21 14 21 22 23 24 31 =
32</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">157.856138 2T11 64F 22 33 34 41 42 43 44 =
00</span></font></div><div class=3D""><span style=3D"font-size: 14px; =
font-family: &quot;Andale Mono&quot;;" class=3D"">158.148199 2R11 65F 03 =
6e f0 90 55 55 55 55</span></div></blockquote><div class=3D""><br =
class=3D""></div><div class=3D"">At first glance, I skipped over the =
first three commands (assuming they were checking firmware version, or =
something like that), and looked at the last group. Seems similar to the =
OBDII extended read we saw to read the IDs. But when I try it on my =
bench ECU I don=E2=80=99t get the happy =E2=80=9865F 03 6e f0 90=E2=80=99 =
acknowledging the write, but instead a '65F 03 7f 2e 31=E2=80=99 =
indicating an error.</div><div class=3D""><br class=3D""></div><div =
class=3D"">So, I went back and looked at those first three requests. In =
OBDII speak, these decode as:</div><div class=3D""><br =
class=3D""></div><blockquote style=3D"margin: 0 0 0 40px; border: none; =
padding: 0px;" class=3D""><blockquote style=3D"margin: 0px 0px 0px 40px; =
border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D"">64F 02 10 03 00 =
00 00 00 00</span></font></blockquote><blockquote style=3D"margin: 0px =
0px 0px 40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale=
 Mono" class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; =
0x02 =3D 2 data bytes in the =
request</span></font></blockquote><blockquote style=3D"margin: 0px 0px =
0px 40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x10 =
=3D UDS Diagnostic Session Control</span></font></blockquote><blockquote =
style=3D"margin: 0px 0px 0px 40px; border: none; padding: 0px;" =
class=3D""><font face=3D"Andale Mono" class=3D""><span style=3D"font-size:=
 14px;" class=3D"">&nbsp; 0x03 =3D UDS session type =
0x03</span></font></blockquote><blockquote style=3D"margin: 0px 0px 0px =
40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D""><br class=3D"">65F =
06 50 03 00 96 17 70 55</span></font></blockquote><blockquote =
style=3D"margin: 0px 0px 0px 40px; border: none; padding: 0px;" =
class=3D""><font face=3D"Andale Mono" class=3D""><span style=3D"font-size:=
 14px;" class=3D"">&nbsp; 0x06 =3D 6 data bytes in the =
response</span></font></blockquote><blockquote style=3D"margin: 0px 0px =
0px 40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x50 =
=3D 0x10 + 0x40 =3D successful response to our =
0x10&nbsp;command</span></font></blockquote><blockquote style=3D"margin: =
0px 0px 0px 40px; border: none; padding: 0px;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-size: 14px;" =
class=3D"">&nbsp; 0x03 =3D UDS session type =
0x03</span></font></blockquote><blockquote style=3D"margin: 0px 0px 0px =
40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x00961770 =
=3D Session data</span></font></blockquote><blockquote style=3D"margin: =
0px 0px 0px 40px; border: none; padding: 0px;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-size: 14px;" =
class=3D""><br class=3D"">64F 02 27 01 00 00 00 00 =
00</span></font></blockquote><blockquote style=3D"margin: 0px 0px 0px =
40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x02 =3D 2 =
data bytes in the request</span></font></blockquote><blockquote =
style=3D"margin: 0px 0px 0px 40px; border: none; padding: 0px;" =
class=3D""><font face=3D"Andale Mono" class=3D""><span style=3D"font-size:=
 14px;" class=3D"">&nbsp; 0x27 =3D UDS Security =
Access</span></font></blockquote><blockquote style=3D"margin: 0px 0px =
0px 40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x01 =
=3D Type 1 (seed request)</span></font></blockquote><blockquote =
style=3D"margin: 0px 0px 0px 40px; border: none; padding: 0px;" =
class=3D""><font face=3D"Andale Mono" class=3D""><span style=3D"font-size:=
 14px;" class=3D""><br class=3D"">65F 04 67 01 b5 0a 55 55 =
55</span></font></blockquote><blockquote style=3D"margin: 0px 0px 0px =
40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x04 =3D 4 =
data bytes in the response</span></font></blockquote><blockquote =
style=3D"margin: 0px 0px 0px 40px; border: none; padding: 0px;" =
class=3D""><font face=3D"Andale Mono" class=3D""><span style=3D"font-size:=
 14px;" class=3D"">&nbsp; 0x67 =3D 0x27 + 0x40 =3D successful response =
to our 0x27 command</span></font></blockquote><blockquote style=3D"margin:=
 0px 0px 0px 40px; border: none; padding: 0px;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-size: 14px;" =
class=3D"">&nbsp; 0x01 =3D Type 1 =
(seed)</span></font></blockquote><blockquote style=3D"margin: 0px 0px =
0px 40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; =
0xb50a =3D UDS&nbsp;security access seed =
data</span></font></blockquote><blockquote style=3D"margin: 0px 0px 0px =
40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D""><br class=3D"">64F =
04 27 02 f7 02 00 00 00</span></font></blockquote><blockquote =
style=3D"margin: 0px 0px 0px 40px; border: none; padding: 0px;" =
class=3D""><font face=3D"Andale Mono" class=3D""><span style=3D"font-size:=
 14px;" class=3D"">&nbsp; 0x04 =3D 4 data bytes in the =
request</span></font></blockquote><blockquote style=3D"margin: 0px 0px =
0px 40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x27 =
=3D&nbsp;</span></font><span style=3D"font-family: &quot;Andale =
Mono&quot;; font-size: 14px;" class=3D"">UDS Security =
Access</span></blockquote><blockquote style=3D"margin: 0px 0px 0px 40px; =
border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x02 =3D =
type 2 (login)</span></font></blockquote><blockquote style=3D"margin: =
0px 0px 0px 40px; border: none; padding: 0px;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-size: 14px;" =
class=3D"">&nbsp; 0xf702 =3D UDS security access login =
data</span></font></blockquote><blockquote style=3D"margin: 0px 0px 0px =
40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D""><br =
class=3D""></span></font><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-size: 14px;" class=3D"">65F 02 67 02 55 =
55 55 55 55</span></font></div><div class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-size: 14px;" class=3D"">&nbsp; 0x02 =
=3D 2 data bytes in the response</span></font></div><div class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-size: 14px;" =
class=3D"">&nbsp; 0x67 =3D&nbsp;</span></font><span style=3D"font-family: =
&quot;Andale Mono&quot;; font-size: 14px;" class=3D"">0x27 + 0x40 =3D =
successful response to our 0x27 =
command</span></div></blockquote><blockquote style=3D"margin: 0px 0px =
0px 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"font-family: &quot;Andale Mono&quot;; font-size: 14px;" =
class=3D"">&nbsp; 0x02 =3D type 2 (login =
success)</span></blockquote></blockquote><div class=3D""><br =
class=3D""></div><blockquote style=3D"margin: 0 0 0 40px; border: none; =
padding: 0px;" class=3D""><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><div class=3D"">* See here for =
an explanation:&nbsp;<a =
href=3D"https://en.wikipedia.org/wiki/Unified_Diagnostic_Services" =
class=3D"">https://en.wikipedia.org/wiki/Unified_Diagnostic_Services</a></=
div></blockquote></blockquote><div class=3D""><br class=3D""></div><div =
class=3D"">At the point, I had an =E2=80=98oh shit=E2=80=99 moment. Why =
they hell would they use UDS security to protect writing TPMS tyre IDs? =
Good grief.</div><div class=3D""><br class=3D""></div><div class=3D"">The =
way this works is that the diagnostic tool first establishes a =
diagnostic session with the ECU. It then requests a seed, and the ECU =
responds with a random number. The tool and ECU both then independently =
do a secret calculation (based on a secret algorithm and a secret =
number), the tool provides the result to the ECU, and the ECU verifies =
it. The seed provides protection against relay attack, and the password =
or algorithm are never sent over the wire so if done properly this can =
be strong against eavesdropping.</div><div class=3D""><br =
class=3D""></div><div class=3D"">Despite the initial =E2=80=98oh =
shit=E2=80=99, there were two bits of good news. Firstly, the seed was =
only 2 bytes; that is 65,536 combinations and very susceptible to brute =
force. Secondly, we had a number of writes logged from the original tool =
so knew some good seed and login combinations:</div><div class=3D""><br =
class=3D""></div><div class=3D""><div class=3D""><ul =
class=3D"MailOutline"><li class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal;" class=3D"">843b -&gt; =
d632</span></font></li><li class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal;" class=3D"">8338 -&gt; =
d330</span></font></li><li class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal;" class=3D"">8932 -&gt; =
db32</span></font></li><li class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal;" class=3D"">4738 -&gt; =
5730</span></font></li><li class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal;" class=3D"">ff00 -&gt; =
ff00</span></font></li></ul></div></div><div class=3D""><br =
class=3D""></div><div class=3D"">That, and in particular the last one, =
doesn=E2=80=99t seem to show much entropy. The seed-&gt;password is just =
not random enough.</div><div class=3D""><br class=3D""></div><div =
class=3D"">I started with some blind guesses:</div><div class=3D""><br =
class=3D""></div><blockquote style=3D"margin: 0 0 0 40px; border: none; =
padding: 0px;" class=3D""><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><div class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">Here are our known =
samples:</font></span></div></blockquote><blockquote style=3D"margin: 0 =
0 0 40px; border: none; padding: 0px;" class=3D""><blockquote =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); margin-left: =
30pt; margin-right: 0in;" class=3D""><div style=3D"margin: 0in 0in =
0.0001pt;" class=3D""><font face=3D"Andale Mono" class=3D""><span =
style=3D"font-style: normal; font-size: 14px;" class=3D"">843b -&gt; =
d632<br class=3D"">8338 -&gt; d330<br class=3D"">8932 -&gt; =
db32</span></font></div><div style=3D"margin: 0in 0in 0.0001pt;" =
class=3D""><font face=3D"Andale Mono" class=3D""><span =
style=3D"font-style: normal; font-size: 14px;" class=3D"">4738 -&gt; =
5730</span></font></div><div style=3D"margin: 0in 0in 0.0001pt;" =
class=3D""><font face=3D"Andale Mono" class=3D""><span =
style=3D"font-style: normal; font-size: 14px;" class=3D"">ff00 -&gt; =
ff00</span></font></div></blockquote></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><span=
 style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">In binary:</font></span></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" =
class=3D""><blockquote style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, =
0, 0); margin-left: 30pt; margin-right: 0in;" class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">843b 1000 0100 0011 1011</span></font></div><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">d632 1101 0110 0011 =
0010&nbsp;</span></font></div></blockquote></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" =
class=3D""><blockquote style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, =
0, 0); margin-left: 30pt; margin-right: 0in;" class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">8338 1000 0011 0011 1000<br class=3D"">d330 1101 0011 0011 =
0000</span></font></div></blockquote></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" =
class=3D""><blockquote style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, =
0, 0); margin-left: 30pt; margin-right: 0in;" class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">8932 1000 1001 0011 0010<br class=3D"">db32 1101 1011 0011 =
0010</span></font></div></blockquote></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" =
class=3D""><blockquote style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, =
0, 0); margin-left: 30pt; margin-right: 0in;" class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">4738 0100 0111 0011 1000<br class=3D"">5730 0101 0111 0011 =
0000</span></font></div></blockquote></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" =
class=3D""><blockquote style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, =
0, 0); margin-left: 30pt; margin-right: 0in;" class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">ff00 1111 1111 0000 0000<br class=3D"">ff00 1111 1111 0000 =
0000</span></font></div></blockquote></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><span=
 style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">It seems that the first byte can have 0=E2=80=99s become a 1, =
but never a 1 become a 0. So let=E2=80=99s assume that is a boolean OR =
operator.</font></span></blockquote><blockquote style=3D"margin: 0 0 0 =
40px; border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></span></blockquote><blockquote style=3D"margin: =
0 0 0 40px; border: none; padding: 0px;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D""><span style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, =
0);" class=3D"">The&nbsp;second byte doesn=E2=80=99t have such good =
data, but it seems a 1 can become a 0. So let=E2=80=99s assume that it =
is a boolean AND operator.</span><span style=3D"caret-color: rgb(0, 0, =
0); color: rgb(0, 0, 0);" =
class=3D"">&nbsp;</span></span></font></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" =
class=3D""><blockquote style=3D"margin-left: 30pt; margin-right: 0in;" =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D""><font color=3D"#000000" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0);" class=3D"">&nbsp; &nbsp; =
&nbsp;----or--- ---and---</span></font><br class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" =
class=3D"">&nbsp; &nbsp; &nbsp;0101 0010 ??11 =
0?10</span></span></font></div></blockquote></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">In ascii, 0101 0010 is&nbsp;=E2=80=9CR=E2=80=9D.&nbsp;The&nbsp;=
second byte is harder, as we&nbsp;don=E2=80=99t&nbsp;have enough data =
and only know the result for 5 out of the 8 bits. But, if it is a =
letter, we can guess it is 0111 0?10. In ascii, 0111 0010 is the lower =
case =E2=80=9Cr=E2=80=9D.</span></font></div></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><o:p style=3D"font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></o:p></div></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">So, OR the first byte with&nbsp;=E2=80=9CR=E2=80=9D, then AND =
the second byte with&nbsp;=E2=80=9Cr=E2=80=9D. Can it be that simple? =
Can my first blind guess be =
correct?</span></font></div></blockquote><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D""><span style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, =
0);" class=3D"">&nbsp;<br class=3D""></span><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0);" class=3D"">A little perl code:<br =
class=3D""></span><span style=3D"caret-color: rgb(0, 0, 0); color: =
rgb(0, 0, 0);" class=3D"">&nbsp;</span></span></font><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><span=
 style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">#!/usr/bin/perl</font></span></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><span=
 style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></span></blockquote><blockquote style=3D"margin: =
0 0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">while (&lt;&gt;)</font></span></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><span=
 style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp; {</font></span></blockquote><blockquote style=3D"margin:=
 0 0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp; chop;</font></span></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><span=
 style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp; my $val =3D =
hex($_);</font></span></blockquote><blockquote style=3D"margin: 0 0 0 =
40px; border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></span></blockquote><blockquote style=3D"margin: =
0 0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp; my $first =3D $val &gt;&gt; =
8;</font></span></blockquote><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" class=3D"">&nbsp; my $second =3D =
$val &amp; 0xff;</font></span></blockquote><blockquote style=3D"margin: =
0 0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></span></blockquote><blockquote style=3D"margin: =
0 0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp; printf "Response for %04x is %02x %02x\n",$val,($first =
| 0b01010010),($second &amp; =
0b01110010)</font></span></blockquote><blockquote style=3D"margin: 0 0 0 =
40px; border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" class=3D"">&nbsp; =
}</font></span></blockquote><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></span></blockquote><blockquote style=3D"margin: =
0 0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D""># Running it=E2=80=A6</font></span></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><span=
 style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">843b</font></span></blockquote><blockquote style=3D"margin: 0 =
0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">Response for 843b is d6 =
32</font></span></blockquote><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" =
class=3D"">8338</font></span></blockquote><blockquote style=3D"margin: 0 =
0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">Response for 8338 is d3 =
30</font></span></blockquote><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" =
class=3D"">8932</font></span></blockquote><blockquote style=3D"margin: 0 =
0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">Response for 8932 is db =
32</font></span></blockquote><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" =
class=3D"">4738</font></span></blockquote><blockquote style=3D"margin: 0 =
0 0 40px; border: none; padding: 0px;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">Response for 4738 is 57 =
30</font></span></blockquote><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-size: 14px;" =
class=3D""><font face=3D"Andale Mono" =
class=3D"">ff00</font></span></blockquote><blockquote style=3D"margin: 0 =
0 0 40px; border: none; padding: 0px;" class=3D""><div class=3D""><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">Response for ff00 is ff 00<br class=3D""><br =
class=3D""></span></font></div></div></div></blockquote><div =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=3D""><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">OK. But that is easy. Let=E2=80=99s try it =
for some new data=E2=80=A6</span></font></div></div></div><blockquote =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); margin-left: =
30pt; margin-right: 0in;" class=3D""><div class=3D""><div style=3D"margin:=
 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale Mono" class=3D""><span=
 style=3D"font-style: normal; font-size: 14px;" class=3D"">OVMS# can =
can2 tx standard 64F 02 10 03 00 00 00 00 00<o:p =
class=3D""></o:p></span></font></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (11781198) canlog-monitor: 1593874849.354117 2T11 64F 02 10 =
03 00 00 00 00 00<o:p class=3D""></o:p></span></font></div></div><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">V (11781248) canlog-monitor: =
1593874849.400007 2R11 65F 06 50 03 00 96 17 70 55<o:p =
class=3D""></o:p></span></font></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><o:p style=3D"font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></o:p></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">OVMS# can can2 tx standard 64F 02 27 01 00 00 00 00 00<o:p =
class=3D""></o:p></span></font></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (11786098) canlog-monitor: 1593874854.254102 2T11 64F 02 27 =
01 00 00 00 00 00<o:p class=3D""></o:p></span></font></div></div><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">V (11786098) canlog-monitor: =
1593874854.254637 2R11 65F 04 67 01 be 01 55 55 55<o:p =
class=3D""></o:p></span></font></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><o:p style=3D"font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></o:p></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">(My program gives "Response for be01 is fe 00=E2=80=9D)<o:p =
class=3D""></o:p></span></font></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><o:p style=3D"font-style: =
normal; font-size: 14px;" class=3D""><font face=3D"Andale Mono" =
class=3D"">&nbsp;</font></o:p></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">OVMS# can can2 tx standard 64F 04 27 02 fe 00 00 00 00<o:p =
class=3D""></o:p></span></font></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (11805208) canlog-monitor: 1593874873.364121 2T11 64F 04 27 =
02 fe 00 00 00 00<o:p class=3D""></o:p></span></font></div></div><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt;" class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">V (11805208) canlog-monitor: =
1593874873.364639 2R11 65F 02 67 02 55 55 55 55 =
55</span></font></div></div></blockquote></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; =
font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div></div><blockquote style=3D"caret-color: rgb(0, 0, =
0); color: rgb(0, 0, 0); margin-left: 30pt; margin-right: 0in;" =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; =
font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div><div style=3D"margin: 0in 0in 0.0001pt; =
font-size: 11pt; font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div><div style=3D"margin: 0in 0in 0.0001pt; =
font-size: 11pt; font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div><div style=3D"margin: 0in 0in 0.0001pt; =
font-size: 11pt; font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div><div style=3D"margin: 0in 0in 0.0001pt; =
font-size: 11pt; font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div></blockquote><div class=3D""><div style=3D"margin: =
0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div></div><blockquote =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); margin-left: =
30pt; margin-right: 0in;" class=3D""><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div></blockquote><blockquote =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); margin-left: =
30pt; margin-right: 0in;" class=3D""><div class=3D""><div style=3D"margin:=
 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: =
Calibri, sans-serif;" class=3D""><o:p class=3D""></o:p></div></div><div =
style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: =
Calibri, sans-serif;" class=3D""><o:p class=3D""></o:p></div><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; =
font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div></div><div style=3D"margin: 0in 0in 0.0001pt; =
font-size: 11pt; font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div><div style=3D"margin: 0in 0in 0.0001pt; =
font-size: 11pt; font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div></blockquote><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div><div style=3D"margin: 0in 0in =
0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div></blockquote><blockquote =
style=3D"margin: 0 0 0 40px; border: none; padding: 0px;" class=3D""><div =
style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=3D""><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; =
font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div></div></div><div class=3D""><div style=3D"margin: =
0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: =
Calibri, sans-serif;" class=3D""><o:p class=3D""></o:p></div></div><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; =
font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div></div><div class=3D""><div style=3D"margin: 0in =
0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: =
Calibri, sans-serif;" class=3D""><o:p class=3D""></o:p></div></div><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; =
font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div></div><div class=3D""><div style=3D"margin: 0in =
0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div></div><div class=3D""><div =
style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: =
Calibri, sans-serif;" class=3D""><o:p class=3D""></o:p></div></div><div =
class=3D""><div style=3D"margin: 0in 0in 0.0001pt; font-size: 11pt; =
font-family: Calibri, sans-serif;" class=3D""><o:p =
class=3D""></o:p></div></div><div class=3D""><div style=3D"margin: 0in =
0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" =
class=3D""><o:p class=3D""></o:p></div></div></blockquote><div =
class=3D"">Of course, that is a guess. But after trying a few dozen =
times I get success 100% of the time.</div><div class=3D""><br =
class=3D""></div>It does make me wonder what is the point of even =
attempting to add a security layer so trivially easy to crack.<div =
class=3D""><br class=3D""></div><div class=3D"">I implemented the write =
in the OVMS firmware for Tesla Model S, and we have:</div><div =
class=3D""><br class=3D""></div><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;" class=3D""><div class=3D""><div =
class=3D""><font face=3D"Andale Mono" class=3D""><span =
style=3D"font-style: normal; font-size: 14px;" class=3D"">OVMS# tpms =
read</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">TPMS read as =
11121314,21222324,31323334,41424344</span></font></div><div =
class=3D""><font face=3D"Andale Mono" class=3D""><span =
style=3D"font-style: normal; font-size: 14px;" class=3D"">V (34357) =
canlog-monitor: 34.296622 2T11 64F 03 22 f0 90 55 55 55 =
55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (34377) canlog-monitor: 34.310594 2R11 65F 10 13 62 f0 90 =
11 12 13</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (34457) canlog-monitor: 34.396020 2T11 64F 30 03 0a 00 00 =
00 00 00</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (34457) canlog-monitor: 34.396663 2R11 65F 21 14 21 22 23 =
24 31 32</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (34477) canlog-monitor: 34.415594 2R11 65F 22 33 34 41 42 =
43 44 55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D""><br class=3D""></span></font></div><div class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">OVMS# tpms write =
models</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">Tyre set 'models' written to vehicle TPMS =
successfully</span></font></div><div class=3D""><font face=3D"Andale =
Mono" class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (39687) canlog-monitor: 39.627553 2T11 64F 02 10 03 00 00 =
00 00 00</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (39737) canlog-monitor: 39.673421 2R11 65F 06 50 03 00 96 =
17 70 55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (39787) canlog-monitor: 39.726138 2T11 64F 02 27 01 00 00 =
00 00 00</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (39787) canlog-monitor: 39.726907 2R11 65F 04 67 01 80 3b =
55 55 55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (39887) canlog-monitor: 39.826021 2T11 64F 04 27 02 d2 32 =
00 00 00</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (39887) canlog-monitor: 39.826744 2R11 65F 02 67 02 55 55 =
55 55 55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (39987) canlog-monitor: 39.926014 2T11 64F 10 13 2e f0 90 =
08 02 ee</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (39987) canlog-monitor: 39.926747 2R11 65F 30 03 14 55 55 =
55 55 55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (40087) canlog-monitor: 40.026051 2T11 64F 21 37 08 02 e9 =
63 08 02</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (40187) canlog-monitor: 40.126015 2T11 64F 22 ed fb 08 02 =
db 3a 00</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (40187) canlog-monitor: 40.126692 2R11 65F 03 7f 2e 78 55 =
55 55 55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (40477) canlog-monitor: 40.418525 2R11 65F 03 6e f0 90 55 =
55 55 55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D""><br class=3D""></span></font></div><div class=3D""><font =
face=3D"Andale Mono" class=3D""><span style=3D"font-style: normal; =
font-size: 14px;" class=3D"">OVMS# tpms read</span></font></div><div =
class=3D""><font face=3D"Andale Mono" class=3D""><span =
style=3D"font-style: normal; font-size: 14px;" class=3D"">TPMS read as =
0802ee37,0802e963,0802edfb,0802db3a</span></font></div><div =
class=3D""><font face=3D"Andale Mono" class=3D""><span =
style=3D"font-style: normal; font-size: 14px;" class=3D"">V (62107) =
canlog-monitor: 62.046624 2T11 64F 03 22 f0 90 55 55 55 =
55</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (62127) canlog-monitor: 62.060579 2R11 65F 10 13 62 f0 90 =
08 02 ee</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (62207) canlog-monitor: 62.146023 2T11 64F 30 03 0a 00 00 =
00 00 00</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (62207) canlog-monitor: 62.146658 2R11 65F 21 37 08 02 e9 =
63 08 02</span></font></div><div class=3D""><font face=3D"Andale Mono" =
class=3D""><span style=3D"font-style: normal; font-size: 14px;" =
class=3D"">V (62227) canlog-monitor: 62.165585 2R11 65F 22 ed fb 08 02 =
db 3a 55</span></font></div></div></blockquote><div class=3D""><br =
class=3D""></div><div class=3D"">Code committed, and working in my =
car.</div><div class=3D""><br class=3D""></div><div class=3D"">Regards, =
Mark</div><div class=3D""><br class=3D""></div></body></html>=

--Apple-Mail=_B52BF126-997D-4430-921D-64F7D244296E--

--===============2776426517074828385==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
OvmsDev mailing list
OvmsDev@lists.openvehicles.com
http://lists.openvehicles.com/mailman/listinfo/ovmsdev

--===============2776426517074828385==--
