Login Register

Vida CEM swapping

A mid-size luxury crossover SUV, the Volvo XC90 made its debut in 2002 at the Detroit Motor Show. Recognized for its safety, practicality, and comfort, the XC90 is a popular vehicle around the world. The XC90 proved to be very popular, and very good for Volvo's sales numbers, since its introduction in model year 2003 (North America). P2 platform.
Post Reply
vtl
Posts: 4727
Joined: 16 August 2012
Year and Model: 2005 XC70
Location: Boston
Has thanked: 114 times
Been thanked: 606 times

Re: Vida CEM swapping

Post by vtl »

sirloins wrote: 13 Feb 2022, 09:29 Originally I was using a 8690719. I think when I last tried the code (over a year ago I think) I was using the 8690720 CEM.

I will be getting both of those CEMs wired up again to test with.
Ok, so it's probably a regression then.

What you did differently is a sub-microsecond histogram basket, plus latency results filtering to reduce noise?

Also your comment in the commit 75f76c546fb0caebcb35b8eac33afb31b8bf63d1

Code: Select all

+/* P1 processes the key in order
+   The order in flash is still shuffled though
+   Order in flash: 5, 2, 1, 4, 0, 3
+*/
does not stay true for all P1 CEMs, as we've seen shuffled compare routine, like for 720 (scroll back a few pages, I've posted a disassembly).

Ah, also MCP2515 support was dropped :)

User avatar
RickHaleParker
Posts: 7129
Joined: 25 May 2015
Year and Model: See Signature below.
Location: Kansas
Has thanked: 8 times
Been thanked: 958 times

Post by RickHaleParker »

P1 8690720 shuffle has been independently confirmed as #2. By trying a known PIN shuffled and un-shuffled in a terminal.
Unbenannt.PNG
Unbenannt.PNG (196.73 KiB) Viewed 743 times
⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙
1998 C70, B5234T3, 16T, AW50-42, Bosch Motronic 4.4, Special Edition package.
2003 S40, B4204T3, 14T twin scroll AW55-50/51SN, Siemens EMS 2000.
2004 S60R, B8444S TF80 AWD. Yamaha V8 conversion
2005 XC90 T6 Executive, B6294T, 4T65 AWD, Bosch Motronic 7.0.

sirloins
Posts: 43
Joined: 5 November 2020
Year and Model: 2010 V50 T5 AWD M66
Location: Ottawa, Canada
Been thanked: 3 times

Post by sirloins »

Sorry, I am catching up with all the progress you guys have made over the year(s).

I have not tried the new code yet at all, so I am not saying there is any regression. When I made the commit for the first P1 shuffle order etc it was using a 8690719 CEM. Shortly after I did that, I changed my bench CEM to the 8690720 because I had the SCL and a Key for it that I was looking to further understand. I did try code from a year ago on it at the time and was having problems (either hardware or as others mentioned the 720 not seeming to work the same).

Yes, when I posted the disassembly for my P1 it was an 8690719 and shuffle order 2. I did disassemble the 8690720 as well and found the shuffle order the same (#2, as you posted).

So all I want to do is help you guys figure out why that is not working on the 8690720.

I will get my bench setup up and running again and try to help in any way I can.

User avatar
RickHaleParker
Posts: 7129
Joined: 25 May 2015
Year and Model: See Signature below.
Location: Kansas
Has thanked: 8 times
Been thanked: 958 times

Post by RickHaleParker »

Does the shuffle order for 8690719 & 8690720 need to be updated?
Careful ... the P1 has fooled us before. My "P1 parameters Update" which we ended up reverting.

unsigned char shuffle_orders[4][PIN_LEN] = { { 0, 1, 2, 3, 4, 5 }, { 3, 1, 5, 0, 2, 4 }, {5, 2, 1, 4, 0, 3} { 2, 4, 5, 0, 3, 1} };

~~~

} cem_params[] = {
// P1
{ 8690719, CAN_500KBPS, 0 },
{ 8690720, CAN_500KBPS, 0 },
⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙
1998 C70, B5234T3, 16T, AW50-42, Bosch Motronic 4.4, Special Edition package.
2003 S40, B4204T3, 14T twin scroll AW55-50/51SN, Siemens EMS 2000.
2004 S60R, B8444S TF80 AWD. Yamaha V8 conversion
2005 XC90 T6 Executive, B6294T, 4T65 AWD, Bosch Motronic 7.0.

vtl
Posts: 4727
Joined: 16 August 2012
Year and Model: 2005 XC70
Location: Boston
Has thanked: 114 times
Been thanked: 606 times

Post by vtl »

RickHaleParker wrote: 14 Feb 2022, 07:42 Does the shuffle order for 8690719 & 8690720 need to be updated?
Careful ... the P1 has fooled us before. My "P1 parameters Update" which we ended up reverting.

unsigned char shuffle_orders[4][PIN_LEN] = { { 0, 1, 2, 3, 4, 5 }, { 3, 1, 5, 0, 2, 4 }, {5, 2, 1, 4, 0, 3} { 2, 4, 5, 0, 3, 1} };

~~~

} cem_params[] = {
// P1
{ 8690719, CAN_500KBPS, 0 },
{ 8690720, CAN_500KBPS, 0 },
720 is 5, 2, 1, 4, 0 as seen here: viewtopic.php?p=592875#p592875 But it still does not crack.

User avatar
RickHaleParker
Posts: 7129
Joined: 25 May 2015
Year and Model: See Signature below.
Location: Kansas
Has thanked: 8 times
Been thanked: 958 times

Post by RickHaleParker »

vtl wrote: 14 Feb 2022, 08:40 720 is 5, 2, 1, 4, 0, 3 as seen here:
The post above ( with the ODIN GUI ) is a 720 . The last try is the PIN from flash shuffled with 5, 2, 1, 4, 0, 3, It unlocked.
The 720 CEM was tried with the other shuffles, 5, 2, 1, 4, 0, 3 is the only one that produced different latencies.
⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙⸙
1998 C70, B5234T3, 16T, AW50-42, Bosch Motronic 4.4, Special Edition package.
2003 S40, B4204T3, 14T twin scroll AW55-50/51SN, Siemens EMS 2000.
2004 S60R, B8444S TF80 AWD. Yamaha V8 conversion
2005 XC90 T6 Executive, B6294T, 4T65 AWD, Bosch Motronic 7.0.

sirloins
Posts: 43
Joined: 5 November 2020
Year and Model: 2010 V50 T5 AWD M66
Location: Ottawa, Canada
Been thanked: 3 times

Post by sirloins »

I think I confused myself as it has been a long time regarding shuffle orders on P1.

The can message to unlock the CEM is not shuffled. It is processed in order 0, 1, 2, 3, 4, 5. When it checks the PIN, it compares to the Flash memory in a shuffled order.

So yes, if you read the Flash 0xFBEF8 and see: 66 49 55 54 05 19
You need to shuffle it before sending the unlock command like so: 19 55 49 05 66 54

This is the 5, 2, 1, 4, 0, 3 order.

Now, as seen by the disassembly, the 6 bytes the CEM receives via CAN is checked in order, just the flash locations are shuffled.

This means when brute-forcing, or cracking. You want to start with position 0, then 1, 2, 3, 4, 5. This is shuffle order 0 in the volvo-cem-cracker.


00 00 00 00 00 00
01 00 00 00 00 00
02 00 00 00 00 00
etc. etc.

I did submit a pull-request with the code changes I made to the latest branch to make it work on my 719 and 720 CEMs here on my bench. If anyone has one to try it out on, please do. Note there is a constant called LATENCY_RESOLUTION, for my P1s I set this to 4.

vtl
Posts: 4727
Joined: 16 August 2012
Year and Model: 2005 XC70
Location: Boston
Has thanked: 114 times
Been thanked: 606 times

Post by vtl »

sirloins wrote: 16 Feb 2022, 20:23 I think I confused myself as it has been a long time regarding shuffle orders on P1.

The can message to unlock the CEM is not shuffled. It is processed in order 0, 1, 2, 3, 4, 5. When it checks the PIN, it compares to the Flash memory in a shuffled order.

So yes, if you read the Flash 0xFBEF8 and see: 66 49 55 54 05 19
You need to shuffle it before sending the unlock command like so: 19 55 49 05 66 54

This is the 5, 2, 1, 4, 0, 3 order.

Now, as seen by the disassembly, the 6 bytes the CEM receives via CAN is checked in order, just the flash locations are shuffled.

This means when brute-forcing, or cracking. You want to start with position 0, then 1, 2, 3, 4, 5. This is shuffle order 0 in the volvo-cem-cracker.
Shuffle order is the order in pin compare routine in CEM. The cracker code needs to iterate on the byte that is compared first in the CEM route, right? It makes no sense iterating on the byte that is not even checked, because the whole routine aborts earlier.

720 compares bytes in CAN message linearly to flash bytes stored in this order:

Code: Select all

.data:0003fe41 a1 05                            cmpa 0x5,X
.data:0003fe47 a1 02                            cmpa 0x2,X
.data:0003fe4d a1 01                            cmpa 0x1,X
.data:0003fe53 a1 04                            cmpa 0x4,X
.data:0003fe59 a1 00                            cmpa 0x0,X
.data:0003fe5f a1 03                            cmpa 0x3,X
sirloins wrote: 16 Feb 2022, 20:23 I did submit a pull-request with the code changes I made to the latest branch to make it work on my 719 and 720 CEMs here on my bench. If anyone has one to try it out on, please do. Note there is a constant called LATENCY_RESOLUTION, for my P1s I set this to 4.
Good one! In fact, because STD is not used anymore, and no further signal analysis has been evolved past our trivial total latency accumulation, there's no point in calculating the total latency via histogram, which is quite coarse. Can you try this patch on your 719/720?
Last edited by vtl on 17 Feb 2022, 10:21, edited 1 time in total.

sirloins
Posts: 43
Joined: 5 November 2020
Year and Model: 2010 V50 T5 AWD M66
Location: Ottawa, Canada
Been thanked: 3 times

Post by sirloins »

Shuffle order is the order in pin compare routine in CEM. The cracker code need to iterate on the byte that is compared first in the CEM route, right? It makes no sense iterating on the byte that is not even checked, because the whole routine aborts earlier.

720 compares bytes in CAN message linearly to flash bytes stored in this order:...
Yes, 719 and 720 take the CAN message and compare it:

CAN Byte 0 -> Flash Byte 5
CAN Byte 1 -> Flash Byte 2
CAN Byte 2 -> Flash Byte 1
CAN Byte 3 -> Flash Byte 4
CAN Byte 4 -> Flash Byte 0
CAN Byte 5 -> Flash Byte 3

So the shuffle order 0 is indeed correct (as it is in GIT right now).
Can you try this patch on your 719/720?
Just using this patch without my change does not work ( I tried against my 2 CEMs). If I add in my change then it works (with your patch), although without that patch it seems to isolate the right number better and is always in the first position for the candidate short list.
I believe it is due to the fact that the latency units are in microseconds. Looking at the PIN check routing, I think there are only a few extra instructions when the PIN fails:

Code that executes on first CAN byte:

Code: Select all

ROM:FE38                 pshx
ROM:FE39                 pshy
ROM:FE3A                 tfr     d, y
ROM:FE3C                 ldx     #$FEF8
ROM:FE3F                 ldaa    1,y+
ROM:FE41                 cmpa    5,x
ROM:FE43                 bne     loc_FE63

ROM:FE63 loc_FE63:                               ; CODE XREF: ROM:FE43↑j
ROM:FE63                                         ; ROM:FE49↑j ...
ROM:FE63                 ldab    #0
ROM:FE65                 bra     loc_FE69

ROM:FE69 loc_FE69:                               ; CODE XREF: ROM:FE65↑j
ROM:FE69                 puly
ROM:FE6A                 pulx
ROM:FE6B                 rts
The code that executes when the second byte fails (and first is correct):

Code: Select all

ROM:FE38                 pshx
ROM:FE39                 pshy
ROM:FE3A                 tfr     d, y
ROM:FE3C                 ldx     #$FEF8
ROM:FE3F                 ldaa    1,y+
ROM:FE41                 cmpa    5,x
ROM:FE43                 bne     loc_FE63
ROM:FE45                 ldaa    1,y+
ROM:FE47                 cmpa    2,x
ROM:FE49                 bne     loc_FE63

ROM:FE63 loc_FE63:                               ; CODE XREF: ROM:FE43↑j
ROM:FE63                                         ; ROM:FE49↑j ...
ROM:FE63                 ldab    #0
ROM:FE65                 bra     loc_FE69

ROM:FE69 loc_FE69:                               ; CODE XREF: ROM:FE65↑j
ROM:FE69                 puly
ROM:FE6A                 pulx
ROM:FE6B                 rts
So the difference is only:

Code: Select all

ldaa    1,y+
cmpa    2,x
bne     loc_FE63
I have not checked out how many CPU cycles this is, but if it is less than 8 then it means the latency will be under 1us difference between the fail and pass of the first-byte check.

vtl
Posts: 4727
Joined: 16 August 2012
Year and Model: 2005 XC70
Location: Boston
Has thanked: 114 times
Been thanked: 606 times

Post by vtl »

sirloins wrote: 17 Feb 2022, 10:19 So the shuffle order 0 is indeed correct (as it is in GIT right now).
Ok, you're right :)
sirloins wrote: 17 Feb 2022, 10:19 Just using this patch without my change does not work ( I tried against my 2 CEMs). If I add in my change then it works (with your patch), although without that patch it seems to isolate the right number better and is always in the first position for the candidate short list.
I believe it is due to the fact that the latency units are in microseconds. Looking at the PIN check routing, I think there are only a few extra instructions when the PIN fails:
...
I have not checked out how many CPU cycles this is, but if it is less than 8 then it means the latency will be under 1us difference between the fail and pass of the first-byte check.
The cracker iterates over 3 bytes/positions at a time (that's why CALC_BYTES can't be more than 4). This accumulates more latency for the right subsequence.

Didn't work... Interesting. And yet rounding the result up to a quarter of microsecond, or, in other words spoiling the precision in a terrible way, makes it work?

Post Reply
  • Similar Topics
    Replies
    Views
    Last post