NefMoto

Technical => Flashing and Chipping => Topic started by: Basano on November 12, 2013, 02:09:04 AM



Title: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on November 12, 2013, 02:09:04 AM
Hello everyone,

Would anyone be able to share knowledge on the Seed - Key Algorithm in the Bosch MED9.1 ECU's?

Please excuse the length of my post, I've tried to include as much detail and information as I can.

I'm interested to explore my car and have build a little test rig that handles CAN bus and the Transport Protocol 2.0 :-)

KWP Diagnostics are working nicely and I can read and compute measuring blocks, but I'm being brave and trying for something complex!

After careful reading, I've found a couple of sources of information which I've listed here for reference.


1) Seed - Key via K-Line
http://www.freediag.org/opendiag/4983.html
<attached>

2) Corporate Group Requirement Specification For Programming Control Units with Keyword Protocol 2000 Transport Protocol 2.0.pdf
<attached>


So what I've tried are the steps described in 1). Even though it's KWP over K-Line, I'm hoping it's similar for KWP over CAN bus. I've sent my ECU a request for Vendor ID (KWP 0x1A 0x92) and it's happily responded (KWP 0x5A 0x92 0x30 0x32 0x36 0x31 0x53 0x30 0x32 0x33 0x34 0x32) (ascii 0261S02342).

ms   ID   Len   D0   D1   D2   D3   D4   D5   D6   D7
82343   740   5   18   0   2   1A   92         
82348   300   1   B9                     
82355   300   8   25   0   C   5A   92   30   32   36
82360   300   8   16   31   53   30   32   33   34   32
82363   740   1   B7                     

Now in the K-Line example in the above link, only the first five bytes are used (0x30 0x32 0x36 0x31 0x53), so I've used the same for my calculations.

(0x30 + 0x32 + 0x36 + 0x31 + 0x53) & 0x3F = 0x1C

USing 0x1C as an index to the lookup table (count from the beginning until you reach the 0x1C/28dec value):

0x0A221289,0x144890A1,0x24212491,0x290A0285,0x42145091,0x504822C1,0x0A24C4C1,0x14252229,
0x24250525,0x2510A491,0x28488863,0x29148885,0x422184A5,0x49128521,0x50844A85,0x620CC211,
0x124452A9,0x18932251,0x2424A459,0x29149521,0x42352621,0x4A512289,0x52A48911,0x11891475,
0x22346523,0x4A3118D1,0x64497111,0x0AE34529,0x15398989,0x22324A67,0x2D12B489,0x132A4A75,
0x19B13469,0x25D2C453,0x4949349B,0x524E9259,0x1964CA6B,0x24F5249B,0x28979175,0x352A5959,
0x3A391749,0x51D44EA9,0x564A4F25,0x6AD52649,0x76493925,0x25DE52C9,0x332E9333,0x68D64997,
0x494947FB,0x33749ACF,0x5AD55B5D,0x7F272A4F,0x35BD5B75,0x3F5AD55D,0x5B5B6DAD,0x6B5DAD6B,
0x75B57AD5,0x5DBAD56F,0x6DBF6AAD,0x75775EB5,0x5AEDFED5,0x6B5F7DD5,0x6F757B6B,0x5FBD5DBD

Returns 0x15398989.

Next I send my ECU a seed request (KWP 0x27 0x01) and it responds back with a seed! (KWP 0x67 0x01 0x01 0xAA 0x20 0xC4)

ms   ID   Len   D0   D1   D2   D3   D4   D5   D6   D7
11176   740   5   12   0   2   27   1         
11181   300   1   B3                     
11186   300   8   2A   0   6   67   1   1   AA   20
11192   300   2   1B   C4                  
11198   740   1   BC                     


I use this seed as follows. I shift and add the bytes together and run the result through a loop that shifts and xor's. Same as in the K-Line example.

            SEED = ((RX_STR[4] << 24) + (RX_STR[5] << 16) + (RX_STR[6] << 8) + RX_STR[7]); // (0x01 << 24) + (0xAA << 16) + (0x20 << 8) + 0xC4 = 0x01AA20C4
            for (byte i = 0; i < 5; i++) {
              if ((SEED & 0x80000000) == 0) {
                SEED = 0x15398989 ^ (SEED << 1); // here I'm using the entry I got from the above lookup table
              }
              else {
                SEED = (SEED << 1);
              }             
            }   

After this, I have a value of SEED = 0x1B185F96E

I take this modified seed and decompose it back into bytes

            TX_STR[0] = 0x00;       
            TX_STR[1] = 0x06;         
            TX_STR[2] = 0x27;
            TX_STR[3] = 0x02;
            TX_STR[4] = (SEED >> 24) & 0xFF; //B1
            TX_STR[5] = (SEED >> 16) & 0xFF; //85
            TX_STR[6] = (SEED >> 8) & 0xFF; //F9
            TX_STR[7] = SEED & 0xFF; //6E


Finally, I now transmit this back to my ECU (KWP 0x27 0x02 0xB1 0x85 0xF9 0x6E), which responds back with (KWP 0x7F 0x27 0x35) Invalid Key

ms   ID   Len   D0   D1   D2   D3   D4   D5   D6   D7
11209   740   8   23   0   6   27   2   B1   85   F9
11220   740   2   14   6E                  
11225   300   1   B5                     
11496   300   6   1C   0   3   7F   27   35      
11499   740   1   BD                     


Invalid Key!

What am I missing?

Can anyone share details of the algorithms or starting points for this? Hugely appreciated!

Thanks


My car:
Audi S3 2.0TFSI 265HP 8P Model Year 2008

VCDS scan:
Monday,11,November,2013,13:02:26:53506
VCDS Version: Release 12.12.0 (x64)
                Address 01: Engine
Control Module Part Number: 8P0 907 115 H
  Component and/or Version: 2.0l R4/4V TFSI     0050
           Software Coding: 01030003180F0060
            Work Shop Code: WSC 06314

Advanced Identification
     Serial number: AUX7Z0GNFNQ0NG
     Identification: RB8-658
     Revision: 5BH16---
     Date: 13.11.07
     Test stand number: 1360
     Manufacturer number: 0129
Flash Status
     Programming Attempts: 0
     Successful Attempts: 0
     Programming Status: 00000000
     Required Conditions: 00000000
Software
     A000
     A4.8.6
Misc.
     Hardware number: 8P0 907 115 B
     Immo Challenge: AB 17 95 39

Bosch ECU Hardware ID: 0261S02342










Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: airtite on November 12, 2013, 03:01:44 AM
I cant provide any help but I am sure someone on here will step up....... I do like where this is going though.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: nyet on November 12, 2013, 01:01:02 PM
I don't know anything about seeds, but perhaps your byte order is wrong? have you tried sending the low order seed byte first?


Title: Re: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: n0ble on November 12, 2013, 01:48:39 PM
Impressive first post!!


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on November 13, 2013, 02:56:25 AM
Hi all,

Thanks for the comments  :D

I've got a lot of useful information out of this forum (e.g. KWP1281 formulas for calculating measuring blocks values) so I wanted to try and put something back.

Sometimes the first posts are pretty brief and don't give much to go on, so I tried to give as much information as I could!

I'll try swapping around the MSB/LSB and see what happens.

I've also seen suggestions about looking in the .bin. At a very high level:

1) Get hold of a .bin for this ECU (people have posted them on this forum, so OK)
2) Open the .bin up in a hex editor (also OK)
3) Somewhere in there would be a sequence of assembler, probably with some XOR's ...

If only it was so simple! 1) and 2) are OK, but 3) has taken peoples ages and ages. Where to even start  ;D Still, getting there is half the fun. It's a hobby for me.

Thanks


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on January 15, 2014, 03:48:16 AM
Hello everyone,

Happy New Year to you all  :)

I’ve made some small progress. I got an clone from eBay and put together a sniffer which shows the CANBUS communications between the clone tool and the ECU.

All I’ve done at the moment is an ECU read. I’m not confident enough to try any writes!

So this is what I saw in the ECU read log.

It starts with reading some basic info about the ECU:

1A 86 – Extended ECU-Ident
1A 92 – systemSupplierECUHardwareNumber
1A 94 – systemSupplierECUSoftwareNumber
1A 9B - Item number / ECU-Ident
1A 9C – Flash Status

Then it does the Seed Key handshake:

27 03 (tool -> ECU)
67 03 3E F2 6B 40 (ECU -> tool, seed is 3E F2 6B 40)
27 04 3E F3 7C B0 (tool -> ECU, key is 3E F3 7C B0)
67 04 34 (ECU -> tool, access granted)

Worth pointing out the seed/keys are 3/4 rather than the default 1/2. Perhaps a different level of access?

Then it goes on to start a diagnostic session and read out the data, but I’m just looking at the seed/keys right now. You can see the rest of the communication in the attached log. I normally open the text file in Excel which formats the columns a bit nicer and lets me filter on what I want to see.

I did this a few times and collected the keys/seeds:

3E F2 6B 40 seed
3E F3 7C B0 key

E6 94 31 80 seed
E6 95 42 F0 key

B7 52 04 80 seed
B7 53 15 F0 key

In each case, key = (seed + 0x00011170)

0x00011170 / 70000 dec

Now VCDS also has a security access screen, where you can input a login code for a controller. If I connect to the engine ECU with my VCDS and use this value of 70000dec, security access is successful!!

But this is a very basic algorithm (key = (seed + 0x00011170). I assume this is just for read access. I guess write access would be a more challenging algorithm?

I’m a bit wary of doing a write in case I break my ecu! (I don’t have much experience with this)

I’ve attached the log file of the ecu read, some KWP docs that help explain the protocol and the bin.

 ;D


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: prj on January 15, 2014, 03:58:32 PM
Get yourself a tool that can do BDM.
After that make a full backup of your ECU, this involves opening the ECU and making the backup.

After this, no matter WHAT you do with the ecu bar hardware damage, you will always be able to restore from backup :)


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: terok on January 16, 2014, 08:25:12 AM
Haven't tested, but for write i'm guessing 50000 (0xC350).


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on January 17, 2014, 04:21:13 AM
Get yourself a tool that can do BDM.
After that make a full backup of your ECU, this involves opening the ECU and making the backup.

After this, no matter WHAT you do with the ecu bar hardware damage, you will always be able to restore from backup :)

Yep, seen a cheap one on eBay. Backups are ALWAYS a good idea  :D

Haven't tested, but for write i'm guessing 50000 (0xC350).

Thanks very much!

I will give this a try this evening and let you know the result.

I have feeling that there are two 'access' levels here, for want of a different word.

Seed/Key exchange 27 01/02 xx xx xx xx and Seed/Key exchange 27 03/04  xx xx xx xx

Certainly the clone tool used 27 03/04  xx xx xx xx for the ECU read. I have some ideas about how to trick the clone tool into starting an ECU write dialogue (plugging it into a simulator instead of my ECU) so I don't have to abuse my ECU.

Thanks



Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on January 19, 2014, 02:06:24 PM
Nope, 50000dec (0x0000C350) didn't work  :(

Here's the trace:

R0 91201 740 5 15 0 2 27 3
R0 91203 300 1 B6
R0 91209 300 8 23 0 6 67 3 BB 32 4B
R0 91214 300 2 14 0
R0 91217 740 1 B5
R0 91379 740 8 26 0 6 27 4 BB 33 E
R0 91411 740 2 17 50
R0 91412 300 1 B8
R0 91691 300 6 15 0 3 7F 27 35 <- invalidKey
R0 91695 740 1 B6

For comparison, here's the trace of a succesful login with 70000dec (0x00011170)

R0 57186 740 5 15 0 2 27 3
R0 57188 300 1 B6
R0 57196 300 8 23 0 6 67 3 6D 2C F8
R0 57201 300 2 14 C0
R0 57205 740 1 B5
R0 57364 740 8 26 0 6 27 4 6D 2E A
R0 57404 740 2 17 30
R0 57406 300 1 B8
R0 57412 300 6 15 0 3 67 4 34 <- securityAccessAllowed
R0 57416 740 1 B6


Hmmm.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: nyet on January 19, 2014, 08:57:49 PM
Well, if it's always a multiple of decimal 10000 (what a strange choice), have you tried each one from 10000 to 90000?


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on January 20, 2014, 03:34:41 AM
Thanks,

I can try it. I found out (the hard way) that the timeout between incorrect attempt is 10 minutes and if you switch the ignition off, the timer simply stops and restarts once you switch it back on!

But I have an update that may lead in another direction…  ;D

I finally lashed the ecu-simulator together (at least, something that simulates the ecu role in the dialogue between ecu and clone tool). Fortunately the security access happens right after the ECU ID messages, so I don’t have to simulate very much before the seed/key stuff starts. The simulator is pretty crude but at least I don’t have to keep running out to the car with all the cables and laptop etc. (plus it’s cold!)

Now I can safely plug the clone tool into the sim and push the write button without worrying about my car.

So this is what I’ve found:

Read from ECU
Uses Security Access 27 03 xx xx xx xx
Simple algorithm (key = seed + 0x00011170) dec 70000

Write to ECU
Uses Security Access 27 01 xx xx xx xx
Complex algorithm ???

Hmm. Different Security Accesses for read and write!

I’ve harvested some seeds from my car (just by sending it a few 27 01) and I can feed them to the clone tool using the sim.

Here are the resulting pairs (clone tool requests a seed, I send it a seed and it replies with a key)

Security Access 27 01
0C F4 23 3D Seed
C1 39 3A 1C  Key

0E F5 90 FF Seed
81 0F 42 5C Key

10 66 74 01 Seed
B3 B4 3B 58 Key

03 32 95 2C Seed
66 52 A5 80 Key

01 93 1E CA Seed
32 63 D9 40 Key

All the login codes (70000dec) use Security Access 27 03, hence why I say I think this is going in another direction for writing to the ECU.

I believe Security Access 27 01 (writing) uses the more complex revolving XOR type of algorithm, rather than the very simple addition algorithm used by Security Access 27 03 (reading)


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on January 21, 2014, 03:34:30 AM
Ahha, now we are getting somewhere!

So I decided to feed some seeds to the clone tool that have easy patterns. I’m no cryptographer, but this seemed to make sense 

You can see what happens with the first simple seed below. Everything gets shifted to the left five times:

            Hex                 Binary
Seed     01 01 01 01     0000 0001   0000 0001   0000 0001   0000 0001
Key       20 20 20 20     0010 0000   0010 0000   0010 0000   0010 0000

Then I tried this seed. From the above, I now know it shifts five times. So what I’ve done here is arrange another seed with the bit pattern so the left most bit will be shifted out on the fifth shift:

            Hex                  Binary
Seed     08 01 01 01      0000 1000   0000 0001   0000 0001   0000 0001
Key       5F 9D 7D 9C     0101 1111   1001 1101   0111 1101   1001 1100

Totally transformed, but how? XOR is the operation all the examples talk about, so let’s play a bit. Start with:

Hex                 Binary
08 01 01 01     0000 1000   0000 0001   0000 0001   0000 0001

Shift this five times to the left. NB, this is a rotate. So the bit that get shifted out on the left gets shifted in on the right.

Hex                 Binary
00 20 20 21     0000 0000   0010 0000   0010 0000   0010 0001

Now XOR. We know what the input is (00 20 20 21) and we know what the output is (5F 9D 7D 9C) so we can solve for the value you XOR the input with:

          Hex                        Binary
          00 20 20 21            0000 0000   0010 0000   0010 0000   0010 0001
XOR    5F BD 5D BD          0101 1111   1011 1101   0101 1101   1011 1101
          5F 9D 7D 9C           0101 1111   1001 1101   0111 1101   1001 1100

So, we get a value of 5F BD 5D BD.

Not only does this value of 5F BD 5D BD show up in the .bin from the ECU, but it’s also present in the example algorithm posted at the beginning of the thread. Coincidence, maybe not!

Putting it all together I get this algorithm:

              for (byte i = 0; i < 5; i++) {
                if ((SEED & 0x80000000) == 0x80000000) { // can’t check the bit overflow / carry bit directly, but if the MSB is high then we can infer the next shift will set the carry bit
                  SEED = (0X5FBD5DBD ^ ((SEED << 1) | (SEED >> 31))); // since C doesn’t have a rotate as such, OR the << and >> to make a rotate
                }
                else {
                  SEED = ((SEED << 1) | (SEED >> 31)) ;
                }             
              }         

Very similar to the example algorithm and aligns with the corporate specification I posted at the beginning of the thread as well  ;D

I’ll test it out and let you know.
 


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: nyet on January 21, 2014, 10:00:59 AM
Well done!

Nice to be able to send any seed you want for testing :)


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on January 23, 2014, 03:29:41 AM
OK, so I coded it up and tested it out against my MED9.1 ECU.

It works!  ;D

In summary then:

Security Access 27 01 xx xx xx xx (for writing to the ECU)

for (byte i = 0; i < 5; i++) {
    if ((SEED & 0x80000000) == 0x80000000) { /* Can’t check the bit overflow / carry
                                                                           bit directly, but if the MSB is high
                                                                           then we can infer the next shift will
                                                                           set the carry bit
                                                                     */
        SEED = (0X5FBD5DBD ^ ((SEED << 1) | (SEED >> 31))); /* Since C doesn’t have a rotate as
                                                                                                  such, OR the << and >> to make a
                                                                                                  rotate
                                                                                              */
    }
    else {
        SEED = ((SEED << 1) | (SEED >> 31)) ;
    }            
}
KEY = SEED;

Security Access 27 03 xx xx xx xx (for reading from the ECU)

KEY = (SEED + 0x00011170);

Enjoy!


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: nyet on January 23, 2014, 11:24:12 AM
Do you have a working flashing program now?


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on January 24, 2014, 02:18:06 AM
LOL - still a long way away...

I have reached the next stumbling block! After Security Access comes the transfer of data.

The actual transfer of data between the flash tool and the ECU can be compressed + encrypted   :-\

Looking at the traces of the interaction between the flash tool and my ECU simulator and between the flash tool and my actual ECU, reading from the ECU is in plain text, but writing to the ECU isn't  :(

If you want to know what all the KWP commnds mean, they are described in the attachments posted in this thread. No big secrets there.

KWP Request Upload (read from ECU)

35 aa bb cc de ff gg hh

aa - memory address (high byte)
bb - memory address (middle byte)
cc - memory address (low byte)
d - compression method (high nibble)
e - encrypting method (low nibble)
ff - memory size (high byte)
gg - memory size (middle byte)
hh - memory size (low byte)

Example: 35 00 00 00 00 20 00 00 (from my log of ECU read by flash tool)

Start at address 0x000000 and read 0x200000 (2097152 bytes / 2048kb / 2mb)
Compression  = 0 (no compression)
Encryption = 0 (no encryption)

KWP Request Download (write to ECU)

34 aa bb cc de ff gg hh

aa - memory address (high byte)
bb - memory address (middle byte)
cc - memory address (low byte)
d - compression method (high nibble)
e - encrypting method (low nibble)
ff - memory size (high byte)
gg - memory size (middle byte)
hh - memory size (low byte)

Example: 34 02 00 00 11 06 00 00  (from my log of ECU write by flash tool)

Start at address 0x020000 and write 0x060000 (393216 bytes / 384kb)
Compression  = 1 (compression method #1)
Encryption = 1 (encryption method #1)

Reading from the ECU is OK, both encryption and compression are off and the contents of the .bin match what's transferred out from the ECU.

But writing is a mystery. The flash tool encrypts and compresses the .bin and this encrypted + compressed bit stream is piped down to the ECU. The bytes in the bit stream look nothing like the bytes in the bin :-(

I have no idea what algorithms are used to encrypt and compress the contents of the bin. At least with Security Access I had the example algorithms as a starting point, but here I don't have anything.

Grateful for any hints.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: RaraK on January 24, 2014, 11:25:58 AM
ecuwrite.log would be nice to see ;)


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: nyet on January 24, 2014, 12:01:40 PM
I have no idea what algorithms are used to encrypt and compress the contents of the bin. At least with Security Access I had the example algorithms as a starting point, but here I don't have anything.

Grateful for any hints.

Supposedly RSA PKE.

Going to need to find a RKA privkey, looks like.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on January 26, 2014, 02:24:28 PM
ecuwrite.log would be nice to see ;)

Happy to oblige, here you go ;D

Just remember, the log is between my ECU simulator and the flash tool, not a real ECU. I had to guess some of the ECU responses and also the serial buffer on the sim tool got hammered and dropped a few packets. You'll still get an idea of what's going on with KWP 2000 though.

Supposedly RSA PKE.

Going to need to find a RKA privkey, looks like.

RSA PKE? Aaargh, that’s just not fair!!!

Leaving that aside for a moment, there’s another little check at the end of the data transfer process. It’s described in the Corporate Group Requirement Specification For Programming Control Units with Keyword Protocol 2000 Transport Protocol 2.0 and this check also appears at the end of the write log between the flash tool and my ECU simulator.

After the data is transferred from the flash tool to the ECU, the flash tool instructs the ECU to calculate a checksum for a small part of the flash.

KWP StartRoutineByLocalIdentifier (CalculateFlashChecksum)

31 aa bb cc dd ee ff gg hh ii

aa - routine local identifier
bb - start address (high byte)
cc - start address (middle byte)
dd - start address (low byte)
ee - end address (high byte)
ff - end address (middle byte)
gg - end address (low byte)
hh - checksum of the data (high byte)
ii - checksum of the data (low byte)

Example: 31 C5 1F 00 00 1F FF FF 96 83 (from my log of ECU write by flash tool)

The ECU is instructed by the flash tool to calculate the checksum of a block of data starting at address 0x1F0000 and ending at address  0x1FFFFF (so block is 64k in size and happens to be at the end of the 2mb flash) and compare it to 0x9683. Now 0x9683 is the checksum calculated by the flash tool and sent down to the ECU and should match the checksum as calculated by the ECU, meaning the data transfer was OK (why only a small 64k block? Some processing constraint?)

So how is the checksum calculated? I did the write of the ECU sim by the flash tool several times, each time using a hex editor to change a few bytes within the last 64k of the 2mb flash file. Each time, I ALSO saved the last 64k of the modified 2mb flash file (containing my changed bytes) to a new file 64k in size.

Here were the KWP commands from those writes. Each time the checksum changes, which it should, since each time I changed a few bytes within this last 64k block.

31 C5 1F 00 00 1F FF FF 96 83
31 C5 1F 00 00 1F FF FF A8 05
31 C5 1F 00 00 1F FF FF 7E 4E   

But now remember, I’d also saved those little 64k blocks into a new file every time I changed it. So I took the files and ran them though a freeware checksum utility CHK (http://compressme.net) , referenced by Wikipedia in the article on checksums (http://en.wikipedia.org/wiki/Checksum)

Look at the checksums CHK gave me for the little files when I chose type CRC32:

4A019683
0328A805
DEAB7E4E

In each case, the last four numbers match what the flash tool (and presumably the ECU) use!

To be totally precise, this is CRC32b  after I tried the same test with some other online calculators and did some reading


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Aurélien on February 01, 2014, 01:40:20 PM
I think files are flashed in sgo format that was the standard encryption for non UDS ecu. ( Now it's FRF )

Can't you request a download uncompressed and unencrypted ?


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: prj on February 02, 2014, 03:33:50 PM
I think files are flashed in sgo format that was the standard encryption for non UDS ecu. ( Now it's FRF )

Can't you request a download uncompressed and unencrypted ?

Not unless it's in test mode.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on February 03, 2014, 01:09:27 AM
Hi guys,

So from my logging of the ECU <-> Flash Tool communications, I saw the write to the ECU is encrypted/compressed and the read from the ECU was in clear text.

Write 34 02 00 00 11 06 00 00

Read 35 00 00 00 00 20 00 00

This got me wondering - could you request the read to be compressed/encrypted as well?

I was hoping to read the exact same segment of memory four times over (clear, compressed, encrypted, compressed and encrypted) and see if there are any discernable patterns.

So I tried some ECU reads with these compression/encryption bits set as well

35 00 00 00 01 00 00 40
7F 35 51 fail - improper upload type

35 00 00 00 10 00 00 40
7F 35 51 fail - improper upload type

35 00 00 00 11 00 00 40
7F 35 51 fail - improper upload type

35 00 00 00 00 00 00 40 ok
75 3F ok

Sadly they all failed except for clear text :-(

I think files are flashed in sgo format that was the standard encryption for non UDS ecu. ( Now it's FRF )

Can't you request a download uncompressed and unencrypted ?

Thanks very much, I'll look into that sgo stuff. Have you got any examples perhaps?

I was also thinking about trying a uncompressed and unencrypted write to the ECU, but I'm waiting to get my spare ECU prepared (not keen to experiment with the one in the car since it's my daily drive. OK to do reads though). I did try reading compressed and encrypted from the ECU but they failed as descibed above. Maybe what I can try is different diagnostic modes (10 85 / 10 86) and see if different operations are permitted withing each mode?

Not unless it's in test mode.

That's interesting and partially answers the question posed above. How do you put the ECU into a 'test mode'? Is it another KWP2000 command or something else? I'll have my spare ECU on the bench, so can attempt pretty much whatever is suggested. I'd be keen to here a bit more about this test mode  ;D

Thanks for the comments, it all helps.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Aurélien on February 03, 2014, 06:43:40 AM
I would try a 10 86 session yes. Maybe you can try some read (un)encrypted/compressed in 10 86 mode !


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: prj on February 03, 2014, 04:37:43 PM
That's interesting and partially answers the question posed above. How do you put the ECU into a 'test mode'? Is it another KWP2000 command or something else? I'll have my spare ECU on the bench, so can attempt pretty much whatever is suggested. I'd be keen to here a bit more about this test mode  ;D

Thanks for the comments, it all helps.

On ME7 you must mod the EEPROM, on MED9 no idea.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on February 05, 2014, 02:04:19 AM
Thanks all,

I did a bit of reading about the sgo files. It looks like this is the format that VAG use to deliver the software. There are descriptions of utilities that convert the sgo file to a bin file, then the bin file can be written to the ECU by a flash tool. However, I don’t need to convert from sgo to bin because I already have the bin file (2MB file from read of ECU).

Here’s what I’m seeing - the input to the flash tool is a bin file and the output from the flash tool down to the ECU is an encrypted-compressed version of this bin. I can see this encrypted-compressed data when I sniff the connection between the flash tool and my ECU simulator.

Question – is the entire 2MB bin file written down to the ECU?

I don’t think it is, I think just a portion of that 2MB is sent down. If I look at the KWP write command it’s saying write 0x60000 bytes to memory location 0x20000.

Example: 34 02 00 00 11 06 00 00  (from my log of ECU write by flash tool)

Start at address 0x020000 and write 0x060000 (393216 bytes / 384KB)
Compression  = 1 (compression method #1)
Encryption = 1 (encryption method #1)

That’s not 2Mb!

So what can I do to see how the flash tool encrypts/compresses the bin when it sends it down to the ECU? Assuming that the same encryption/compression is used for both writing and reading I tried asking the ECU for various reads. Any encrypted or compressed read request was unsuccessful (although I only tried in diagnostic mode 86). The only read request that’s accepted is plain text. Scratch that then.

I don’t have any options in the flash tool to control the write request either. It’s a chinese clone of a very popular ODB flash tool and the user interface has three big buttons – ECU ID, Read and Write ;D That’s about it. You can’t tell it about encryption or compression, it must be hardcoded in.

So where does that leave me? I decide to try modifying the contents of the 2MB bin file and see what changes when the flash tool writes it down to the ECU (my ECU simulator). I put in some easy patterns (00 00 00 00, 11 11 11 11, 22 22 22 22 etc) to see what changes. But since I don’t believe the entire 2MB bin is sent down to the ECU, where should I put my changes? Beginning, middle or end? For want of a better starting place, I modified the contents of the 2MB bin starting at 0x20000 since that’s where the KWP write command starts.

2MB bin @ 0x20000 (original file)
5A 5A 5A 5A 38 60 00 00 98 6D 82 C2 38 80 00 FF 98 8D 82 C3 98 6D 82 C0 98 8D 82 C1 4E 80 00 20

2MB bin @ 0x20000 (modified file)
5A 5A 5A 5A 00 00 00 00 00 00 00 00 00 00 00 00 98 8D 82 C3 98 6D 82 C0 98 8D 82 C1 4E 80 00 20

2MB bin @ 0x20000 (modified file)
5A 5A 5A 5A 11 11 11 11 11 11 11 11 11 11 11 11 98 8D 82 C3 98 6D 82 C0 98 8D 82 C1 4E 80 00 20

Then I used the flash tool to write these down to the ECU simulator and snooped the connection between the flash tool and simulator:

orig.bin      5A 5A 5A 5A 38 60 00 00 98 6D 82 C2 38 80 00 FF            
R0   25821   740   8   29      0   F5   36   41   4D   54   20
R0   25823   740   8   2A      20   20   20   20   20   20   20
R0   25825   740   8   2B      20   20   20   1A   1   7C   90
R0   25827   740   8   2C      3E   3F   8   35   5A   5   72
R0   25831   740   8   2D      74   DB   2   E6   A7   6A   EF
R0   25834   740   8   2E      62   9A   EA   F9   C1   AC   FC
R0   25838   740   8   2F      8   D0   AF   FA   E8   F0   B5
                                    
mod0.bin      5A 5A 5A 5A 00 00 00 00 00 00 00 00 00 00 00 00            
R0   90813   740   8   29      0   F5   36   41   4D   54   20
R0   90815   740   8   2A      20   20   20   20   20   20   20
R0   90817   740   8   2B      20   20   20   1A   1   7C   90
R0   90820   740   8   2C      3E   3F   8   35   62   65   72
R0   90823   740   8   2D      74   43   6F   64   65   52   6F
R0   90827   740   8   2E      62   65   EA   F9   C1   AC   FC
R0   90830   740   8   2F      8   D0   AF   FA   E8   F0   B5
                                    
mod1.bin      5A 5A 5A 5A 11 11 11 11 11 11 11 11 11 11 11 11            
R0   18190   740   8   29      0   F5   36   41   4D   54   20
R0   18192   740   8   2A      20   20   20   20   20   20   20
R0   18194   740   8   2B      20   20   20   1A   1   7C   90
R0   18196   740   8   2C      3E   3F   8   35   73   74   63
R0   18198   740   8   2D      65   52   7E   75   74   43   7E
R0   18202   740   8   2E      73   74   EA   F9   C1   AC   FC
R0   18205   740   8   2F      8   D0   AF   FA   E8   F0   B5

Now I can see how the flash tool is changing the bin (encrypting/compressing) as it sends it down to the ECU  :o


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on February 05, 2014, 02:42:09 AM
So what algorithm is being used to encrypt/compress? It looks awfully regular and seems to repeat…

Playing around a bit (a lot) this is what I came up with. Quite proud of this actually :D

XOR with 0x62 65 72 74 43 6F 64 65 52 6F [edit - I know it's these ten bytes, but not sure about the start byte and end byte since it repeats]

This repeats every ten bytes.

Original file: 5A 5A 5A 5A 38 60 00 00 98 6D 82 C2 38 80 00 FF 98 8D 82 C3 98 6D 82 C0 98 8D 82 C1 4E 80 00 20

XOR with: 64 65 52 6F 62 65 72 74 43 6F 64 65 52 6F 62 65 72 74 43 6F 64 65 52 6F 62 65 72 74 43 6F 64 65 (note how it repeats every ten bytes)

Encrypted file: 3E 3F 08 35 5A 05 72 74 DB 02 E6 A7 6A EF 62 9A EA F9 C1 AC FC 08 D0 AF FA E8 F0 B5 0D EF 64 45

Perfect match to the enctypted/compressed data stream!

Gotta love XOR  :-*

This leads to the next observation. I don't think it is compressed, just XOR'd.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Aurélien on February 05, 2014, 03:49:28 AM
Good job. The 00 00 [...] 00 trick was clever.  ;)

I don't see anywhere in the code where the x62 65 72 74 43 6F 64 65 52 6F comes from though. I've been looking for almost everysubroutine with 0x62 with no luck.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on February 05, 2014, 04:22:10 AM
Ah thanks :D

Try these:

64 65 52 6F 62 65 72 74 43 6F
6F 64 65 52 6F 62 65 72 74 43
43 6F 64 65 52 6F 62 65 72 74 <---  
74 43 6F 64 65 52 6F 62 65 72
72 74 43 6F 64 65 52 6F 62 65
65 72 74 43 6F 64 65 52 6F 62
62 65 72 74 43 6F 64 65 52 6F
6F 62 65 72 74 43 6F 64 65 52
52 6F 62 65 72 74 43 6F 64 65
65 52 6F 62 65 72 74 43 6F 64

It's the same ten bytes, but just rotated a bit. Not sure if I got the exact beginning of the file to start with! Basically I'm playing with the offset a bit.

Very curious to see how you get on.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on February 05, 2014, 04:33:14 AM
Oooh, look at this!

So I opened up the 2MB bin and searched through it with a hex editor. Ten searches, one for each rotation of the data above.

I found this one inside:

43 6F 64 65 52 6F 62 65 72 74

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=4983.0;attach=8349;image)

Coincidence? I think not.

Does that match any routine you can see?


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: technic on February 05, 2014, 02:26:34 PM
This is the most interesting I've read in a long time... Very good work


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Aurélien on February 06, 2014, 08:31:10 AM
In fact IDA detect this as some code, I need to work more on this to find what's really going on.

It makes me a bit upset to have something used for decrypting the data you send in the code. How can you perfore a full update ( code + caldata ) if you use something at a place you are overwriting ? Does it means that " xor chain " is uploaded somewhere in ram during flash process ? That could match with your point that your flasher is only flashing the data. I will make some test too, very soon, to have more informations about this.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: nyet on February 06, 2014, 12:56:54 PM
In fact IDA detect this as some code, I need to work more on this to find what's really going on.

It makes me a bit upset to have something used for decrypting the data you send in the code. How can you perfore a full update ( code + caldata ) if you use something at a place you are overwriting ? Does it means that " xor chain " is uploaded somewhere in ram during flash process ? That could match with your point that your flasher is only flashing the data. I will make some test too, very soon, to have more informations about this.

I don't pretend to know much about motronic, but in the embedded designs i do, loader code almost always runs out of RAM (copied from the flash on boot, or before it is run) or out of OTP ROM.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on February 07, 2014, 03:42:07 AM
For those browsing, an explanation of where I’ve gotten to.

As explained earlier, the flash tool takes a binary file as input and writes an encoded version of this binary down to the ECU. I’ve monitored the KWP communication between the flash tool and ECU (simulator) and compared it against the input binary. Small changes to the input binary produce corresponding small changes to the encoded output binary.

I believe the encoding is an XOR obfuscation with a 10 byte repeating pattern

Encoded:   3E 3F 08 35 5A 05 72 74 DB 02 E6 A7 6A EF 62 9A EA F9 C1 AC
XOR:      64 65 52 6F 62 65 72 74 43 6F 64 65 52 6F 62 65 72 74 43 6F
Decoded:   5A 5A 5A 5A 38 60 00 00 98 6D 82 C2 38 80 00 FF 98 8D 82 C3

But although it’s ten bytes, because it repeats I’m unsure which is the first byte and which is the tenth byte ???

Encoded:   3E 3F 08 35 5A 05 72 74 DB 02 E6 A7 6A EF 62 9A EA F9 C1 AC
XOR:      64 65 52 6F 62 65 72 74 43 6F 64 65 52 6F 62 65 72 74 43 6F
Decoded:   5A 5A 5A 5A 38 60 00 00 98 6D 82 C2 38 80 00 FF 98 8D 82 C3

Encoded:   3E 3F 08 35 5A 05 72 74 DB 02 E6 A7 6A EF 62 9A EA F9 C1 AC
XOR:      64 65 52 6F 62 65 72 74 43 6F 64 65 52 6F 62 65 72 74 43 6F
Decoded:   5A 5A 5A 5A 38 60 00 00 98 6D 82 C2 38 80 00 FF 98 8D 82 C3

Encoded:   3E 3F 08 35 5A 05 72 74 DB 02 E6 A7 6A EF 62 9A EA F9 C1 AC
XOR:      64 65 52 6F 62 65 72 74 43 6F 64 65 52 6F 62 65 72 74 43 6F
Decoded:   5A 5A 5A 5A 38 60 00 00 98 6D 82 C2 38 80 00 FF 98 8D 82 C3

All the above give you the same result since the ten bytes repeat. But since I'm looking at a fragment, it's not obvious where it starts.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on February 07, 2014, 03:47:33 AM
I'm going to take a guess and say the ten byte pattern is 0x52 6F 62 65 72 74 43 6F 64 65  (coincidently this reads "RobertCode" in ASCII)

Putting it all together neatly, here’s what it looks like.

Encoded KWPXORDecodeComment
0KWP length MSB (0x00)
F5KWP length LSB (0xF5)
36KWP operation (0x36) - download
415213Encoded data #1
4D6F22Encoded data #2
546236Encoded data #3
206545etc
207252
207454
204363
206F4F
206444
206545
205272
206F4F
206242
206545
1A7268
17475
7C433F
906FFF
3E645AFrom this position the decoded sequence
3F655Acan be found in the original input binary
8525A
356F5A
5A6238
56560
72720
74740
DB4398
26F6D
E66482
A765C2
6A5238
EF6F80
62620
9A65FF
EA7298
F9748D
C14382
AC6FC3
FC6498
8656D
D05282
AF6FC0
FA6298
E8658D
F07282



Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on February 10, 2014, 02:19:31 AM
Spent a bit of time looking through the trace of flash tool write to the ecu in more detail:

KWP Command Comment
(0x34)      download @ 0x20000 size 0x60000 (384kb)
(0x31 0xC4) erase flash start 0x20000 end 0x7ffff
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0x20000 end 0x7ffff = 0xACF9
(0x33 0xC5) results checksum

(0x34)      download @ 0x80000 size 0x20000 (128kb)
(0x31 0xC4) erase flash start 0x80000 end 0x9ffff
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0x80000 end 0x9FFFF = 0x2757
(0x33 0xC5) results checksum

(0x34)      download @ 0xA0000 size 0x120000 (1152kb)
(0x31 0xC4) erase flash start 0xA0000 end 0x1BFFFF
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0xA0000 end 0x1BFFFF = 0xAEFF
(0x33 0xC5) results checksum

(0x34)      download @ 0x1C0000 size 0x30000 (192kb)
(0x31 0xC4) erase flash start 0x1C0000 end 0x1EFFFF
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0x1C0000 end 0x1EFFFF = 0x510C
(0x33 0xC5) results checksum

(0x34)      download @ 0x1F0000 size 0x10000 (64kb)
(0x31 0xC4) erase flash start 0x1F0000 end 0x1FFFFF
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0x1F0000 end 0x1FFFFF = 0x7E4E
(0x33 0xC5) results checksum


There are five distinct writes down to the ecu (even though there's just one big 'write' button on the clone flash tool). Looks like everything except the first 128kb get written to the ECU.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Aurélien on February 10, 2014, 04:19:55 AM
Ok so that's the 5 sectors or / block flash tools are talking about.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: de_Fre on February 26, 2014, 10:02:05 PM
Has anyone tested on an actual ECU what happens when you change "CodeRobert" in the flash to something else ? does it change the XOR ?


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: ddillenger on February 26, 2014, 10:28:52 PM
Very nice work


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: prj on February 27, 2014, 12:10:51 AM
If you are clever, you can first checksum a block in the flash, then checksum the file going in, and if the checksum matches skip writing the block.


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: daniel on April 13, 2014, 04:38:52 AM
Hi Guys,

i'm reading this post and i'm impressed, couse becaouse since last week I'm trying to find solution for the same problem about can bus seed/key challenge. i was trying to figure it out by myself and i also write some codes in c to make something like brute force searching or something like that. But i'm thinking that im walking circles and problem is more sipmle that I thinking.

i was listening on the bus and i have a lot of seed and keys positive answers and I'm 100% sure that there is some connection between bytes

seed 3B   2A   F4   DA
key  C0   2F   80   DD

like for exapmle when 1st byte of seed is 3B the 3d byte of key is always 80, and like that are also connected 2nd byte of seed with 1st byte of key and 3rd seeds byte with 2nd key byte. Last bytes are also always "connected".

Maybe some of you Guys know something about this problem if yes I can share more exapmles and my 'serching-key' codes.

 


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Basano on April 13, 2014, 01:58:17 PM
Hello

What vehicle are you logging these seed/keys from?


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: Russell on May 25, 2014, 02:19:54 AM
Excellent reading Basano, please most more of your interesting work. ;) ;)


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: mattiasclaesson on December 14, 2014, 04:08:31 PM
Hi,

@Basano, excellent work indeed.

I am working on similar task, to find the seed-key algorithm of a ME9.6 hybrid ECU used in saab/opel.

This is what I found so far:

Luckily we have a complete BDM dump of a ME9.6, and 5F BD 5D BD actually is present in the binary.
Further more its refered to from this code, that looks a lot as a seed+key algorithm to me.

Code:
ROM:00015A20 # =============== S U B R O U T I N E =======================================
ROM:00015A20
ROM:00015A20
ROM:00015A20 sub_15A20:                              # CODE XREF: sub_15A68+44p
ROM:00015A20                 cmpwi   %r3, 5          # Compare Word Immediate
ROM:00015A24                 bne     loc_15A34       # Branch if not equal
ROM:00015A28                 lis     %r12, dword_5F80@h # Load Immediate Shifted
ROM:00015A2C                 lwz     %r3, dword_5F80@l(%r12) # Load Word and Zero
ROM:00015A30                 b       loc_15A44       # Branch
ROM:00015A34 # ---------------------------------------------------------------------------
ROM:00015A34
ROM:00015A34 loc_15A34:                              # CODE XREF: sub_15A20+4j
ROM:00015A34                 lis     %r12, dword_5F84@h # Load Immediate Shifted
ROM:00015A38                 addi    %r12, %r12, dword_5F84@l # Add Immediate
ROM:00015A3C                 slwi    %r11, %r3, 2    # Shift Left Immediate
ROM:00015A40                 lwzx    %r3, %r12, %r11 # Load Word and Zero Indexed
ROM:00015A44
ROM:00015A44 loc_15A44:                              # CODE XREF: sub_15A20+10j
ROM:00015A44                 cmpwi   %r3, 0          # Compare Word Immediate
ROM:00015A48                 beq     loc_15A60       # Branch if equal
ROM:00015A4C                 not.    %r12, %r3       # Complement Register
ROM:00015A50                 beq     loc_15A60       # Branch if equal
ROM:00015A54                 add     %r12, %r4, %r4  # Add
ROM:00015A58                 xor     %r3, %r3, %r12  # XOR
ROM:00015A5C                 blr                     # Branch unconditionally
ROM:00015A60 # ---------------------------------------------------------------------------
ROM:00015A60
ROM:00015A60 loc_15A60:                              # CODE XREF: sub_15A20+28j
ROM:00015A60                                         # sub_15A20+30j
ROM:00015A60                 li      %r3, 0          # Load Immediate
ROM:00015A64                 blr                     # Branch unconditionally
ROM:00015A64 # End of function sub_15A20

ROM:00005F80 dword_5F80:     .long 0x52A48911        # DATA XREF: sub_15A20+8o
ROM:00005F80                                         # sub_15A20+Cr ...
ROM:00005F84 dword_5F84:     .long 0x75775EB5, 0x5AEDFED5, 0x6B5F7DD5, 0x6F757B6B, 0x5FBD5DBD, 0x11111111

From the lookup table above:
0x0A221289,0x144890A1,0x24212491,0x290A0285,0x42145091,0x504822C1,0x0A24C4C1,0x14252229,
0x24250525,0x2510A491,0x28488863,0x29148885,0x422184A5,0x49128521,0x50844A85,0x620CC211,
0x124452A9,0x18932251,0x2424A459,0x29149521,0x42352621,0x4A512289,0x52A48911,0x11891475,
0x22346523,0x4A3118D1,0x64497111,0x0AE34529,0x15398989,0x22324A67,0x2D12B489,0x132A4A75,
0x19B13469,0x25D2C453,0x4949349B,0x524E9259,0x1964CA6B,0x24F5249B,0x28979175,0x352A5959,
0x3A391749,0x51D44EA9,0x564A4F25,0x6AD52649,0x76493925,0x25DE52C9,0x332E9333,0x68D64997,
0x494947FB,0x33749ACF,0x5AD55B5D,0x7F272A4F,0x35BD5B75,0x3F5AD55D,0x5B5B6DAD,0x6B5DAD6B,
0x75B57AD5,0x5DBAD56F,0x6DBF6AAD,0x75775EB5,0x5AEDFED5,0x6B5F7DD5,0x6F757B6B,0x5FBD5DBD

Whats the probability of finding those 1+5 dwords from a seed+key lookup table in a ME9.6 binary and that is NOT the seed+key algorithm?

I looked also in the attached MED9.1 binary that you posted in this thread and the subroutine is exactly the same, even at the same address.

The first seed variable seems to be different for your MED9.1 binary, but still part of the same lookup table:
ROM:00005F80 dword_5F80: .long 0x4A3118D1 # DATA XREF: sub_15A20+8o
ROM:00005F80 # sub_15A20+Cr ...
ROM:00005F84 dword_5F84: .long 0x75775EB5, 0x5AEDFED5, 0x6B5F7DD5, 0x6F757B6B, 0x5FBD5DBD, 0xFFFFFFFF

/Mattias Claesson


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: hurane on April 30, 2015, 04:50:17 AM
Well done!

Nice to be able to send any seed you want for testing :)

Hello
I'm working on diagnostic through K-line (between chrono tachograph and tester iSO14230)

I'm trying  to set cetrain parameters in chronotachographe but I failed!

actually the chrono send a seed 64bits but I didn't find the correct key ?

the seed1 0xE1 0x2F 0x63 0xD9 0x57 0x42 0xCF 0x40 -> key1: 0x4A  0x08 0x81 0x43 0x79 0x1F 0x31 0xC6
the seed2 0xE1 0x2F 0x63 0xD9 0x57 0x42 0xCF 0x40 -> key2: 0xE4 0x8E 0x49 0x4C 0xD0 0x56 0x89 0x93


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: dream3R on October 09, 2015, 12:49:16 PM
Spent a bit of time looking through the trace of flash tool write to the ecu in more detail:

KWP Command Comment
(0x34)      download @ 0x20000 size 0x60000 (384kb)
(0x31 0xC4) erase flash start 0x20000 end 0x7ffff
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0x20000 end 0x7ffff = 0xACF9
(0x33 0xC5) results checksum

(0x34)      download @ 0x80000 size 0x20000 (128kb)
(0x31 0xC4) erase flash start 0x80000 end 0x9ffff
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0x80000 end 0x9FFFF = 0x2757
(0x33 0xC5) results checksum

(0x34)      download @ 0xA0000 size 0x120000 (1152kb)
(0x31 0xC4) erase flash start 0xA0000 end 0x1BFFFF
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0xA0000 end 0x1BFFFF = 0xAEFF
(0x33 0xC5) results checksum

(0x34)      download @ 0x1C0000 size 0x30000 (192kb)
(0x31 0xC4) erase flash start 0x1C0000 end 0x1EFFFF
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0x1C0000 end 0x1EFFFF = 0x510C
(0x33 0xC5) results checksum

(0x34)      download @ 0x1F0000 size 0x10000 (64kb)
(0x31 0xC4) erase flash start 0x1F0000 end 0x1FFFFF
(0x33 0xC4) erase flash results
(0x36)      transfer data
(0x37)      exit transfer
(0x31 0xC5) calculate flash checksum start 0x1F0000 end 0x1FFFFF = 0x7E4E
(0x33 0xC5) results checksum


There are five distinct writes down to the ecu (even though there's just one big 'write' button on the clone flash tool). Looks like everything except the first 128kb get written to the ECU.


OLD bump but this is UDS not KWP right?


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: dream3R on October 09, 2015, 12:51:29 PM
If you are clever, you can first checksum a block in the flash, then checksum the file going in, and if the checksum matches skip writing the block.


Good idea but you can send 4k at once so there's not much point if the ecu flash is around 90 secs.  Taking it further and pre-calculating the changes would be nice though.  Something I wanted to-do but never did.





Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: smartauto on July 09, 2017, 05:00:47 PM
Hi Nefmoto
i Found Forum so interesting

I would like to ask you if you can help me seed key codes to unlock the ecu in Mercedes-Benz
i hope you can tech me how to solve
Request 27 0B
            67 0B 06 03 01 80
SEND    27 0C FF C1 B0 0A
            67 0C ------------------- Code Accepted

Request 27 0B
            67 0B FE 73 C5 35
SEND    27 0C 14 BD D5 D2
            67 0C ------------------- Code Accepted




Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: rotax on March 02, 2018, 02:57:10 PM
Hi Basano

1st of all, i really like your work and attitude towards sharing, kudos to you!

You mentioned earlier in this thread that you are using some SW that can do TP2.0, i'm looking for something like that to run on linux, are there any free stacks available? ...done some research but closest i could find is ISOTP, i assume it's a miss?
What are you using?

I have a background implementing some IVLAN reflashing stuff back in the days (>15years ago) on Trionic 7 and would like to hop in the train now on MED9.1 with the goal of using a RPi as a can-datalogger and what not.

Regards,
Daniel


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: john9357 on September 29, 2018, 12:56:13 PM
(http://)


Title: Re: VAG Seed - Key Algorithm Challenge Response via CAN bus
Post by: indexzero on March 15, 2019, 10:36:39 PM
Hello everyone, just in case someone need it, I have discovered and solved the original algo for MED >9.1 and others with Security Access level 2, then implemented it in C. As this algorithm is quite old already I decided to make it public.

The algo is based on a sequence of strings called 'SA2' in VAG implementations, which is an opcode byte sequence used to produce the key from a given seed.
These sequences are stored in .sgo files (at 0x000001bc) and inside ROM dumps in different locations.

Here is a fully working code (named it basano because his posts were essentially helpful during initial research):

Code:
/*
 *
 * gcc baSA2no.c -o /tmp/baSA2no; /tmp/baSA2no 0xSEEEEEED
 *
 * SA2 string starts at 000001bc of an .sgo file and should be read until 0x4C inclusively

 * Permanent code mirror - https://pastebin.com/4z1NeLhn
 *
 * */

#include <stdio.h>
#include <stdint.h>
#define _BYTE  char

int main(int argc, char **argv){
//int SA2[] = { 0x68, 0x03, 0x81, 0x93, 0x54, 0x41, 0x4A, 0x49, 0x4A, 0x05, 0x87, 0x53, 0x41, 0x4A, 0x49, 0x49, 0x4C };
// test OK (09D927750JE_1895.sgo)
// 06 06 06 07 ===> e3 76 c3 c5;   e9 29 ea 29 ===> 7e d3 f7 f4; 0a 0b 0c 0d ===> 10 e2 9e 9c; ab cd ef 00 ===> ac 38 80 06

//int SA2[] = { 0x68, 0x05, 0x81, 0x4A, 0x05, 0x87, 0x5F, 0xBD, 0x5D, 0xBD, 0x49, 0x4C}; // basano
// test OK (03C906056AE_8848.sgo)
// 0C F4 23 3D ===> C1 39 3A 1C;   10 66 74 01 ===> B3 B4 3B 58;

//int SA2[] = { 0x93, 0x00, 0x00, 0x37, 0x19, 0x4C };
// test OK (1Z0035161G_DE2_0033.sgo)
// fa f0 fe 11 ===> fa f1 35 2a;   06 06 06 07 ===> 06 06 3d 20;

//int SA2[] = { 0x68, 0x03, 0x87, 0x00, 0x3F, 0x17, 0x35, 0x93, 0xA3, 0xFF, 0x78, 0x90, 0x4A, 0x01, 0x82, 0x49, 0x4C };
// test OK (v074N0771K0___Lenkung_Reibung.sgo)
// 06 06 06 07 ===> 25 9e 0a c3;   fa f0 fe 11 ===> 4b b3 57 ed

//int SA2[] =  { 0x68, 0x02, 0x81, 0x49, 0x93, 0xa5, 0x5a, 0x55, 0xaa, 0x4a, 0x05, 0x87, 0x81, 0x05, 0x95, 0x26, 0x68, 0x05, 0x82, 0x49, 0x84, 0x5a, 0xa5, 0xaa, 0x55, 0x87, 0x03, 0xf7, 0x80, 0x6a, 0x4c };
// test OK (v0691c1202ea__getriebe_DSG_cT1c_sw.sgo)
// 01 02 03 04 ===> 79 52 e8 d2;   0a 0b 0c 0d ===> 98 31 09 b3;  aa bb cc dd ===> d8 13 36 e1;  ab cd ef 00 ===>  ff f0 91 a5;  11 22 33 44 ===>  7f 5e ee aa;  1a 1b 1c 1d ===>  6a 37 f0 2e;   2a 2b 2c 2d ===>  68 25 ea 2c

//int SA2[] =  { 0x68, 0x05, 0x93, 0x02, 0xe1, 0x42, 0x3a, 0x81, 0x81, 0x87, 0x34, 0x61, 0x12, 0x00, 0x81, 0x4a, 0x06, 0x82, 0x87, 0x06, 0xa3, 0xf2, 0x03, 0x87, 0x0a, 0x45, 0x64, 0x28, 0x49, 0x4c};
// test OK (03C906014CL_1098.sgo, 420910156C__0130.sgo, ...)
// 83 0c 8f 83 ===> fd 77 48 f4;   06 06 06 07 ===> bb 78 d0 98;  e9 29 ea 29 ===> 2f 70 cd 8c; 06 06 06 07 ===> bb 78 d0 98

//int SA2[] =  { 0x68, 0x04, 0x81, 0x93, 0x7f, 0x38, 0xe7, 0x5c, 0x4a, 0x07, 0x87, 0x29, 0x7c, 0x13, 0xa5, 0x6b, 0x05, 0x93, 0x3f, 0x9b, 0x2e, 0x4b, 0x49, 0x4c };
// test OK (1k0035180af_de2_0008.sgo)
// 01 02 03 04 ===> e2 d0 75 6d;   0a 0b 0c 0d ===> 07 da 4b 36;  aa bb cc dd ===> 67 5c 7d 2d; 2a 2b 2c 2d ===> 68 5a 8a d5

int SA2[] =  { 0x68, 0x03, 0x81, 0x93, 0x54, 0x41, 0x4A, 0x49, 0x4A, 0x05, 0x87, 0x53, 0x41, 0x4A, 0x49, 0x49, 0x4C };

int DEBUG_LEVEL = 0;

    if( argc <= 1) {
      printf("USAGE: %s 0xSEEEEEED\n", argv[0]);
      return 0;
    }
   
    unsigned int v11; //seed (i.e.: 0x0a0b0c0d or 0xe929ea29
    v11 = strtol(argv[1], NULL, 16);

unsigned int v12; //rsl
int v14; // rsr

uint16_t opadd_value1; //add
unsigned int v17; //add
int v18; // add

uint16_t opsub_value1; //sub
unsigned int v20; //sub
int v21; // sub

uint16_t opxor_value1; //xor
    int v25; //xor
   
int v34; // bcc position byte

int v36; // bra position byte

int v48 = 0; // C-flag

int v3; // sa2 array position

int v27; // loop
int *v29; // loop
char v32; // loop
int v50; // next
int *v51; // loop & next
int v52;
int *v53;  // loop & next

v3 = 0;
v52 = 0;

v50 = -1;
    v53 = &v50;
    v51 = (int *)&v51;
   
if(DEBUG_LEVEL >= 1)printf("START. SEED = %08lx ", v11);
if(DEBUG_LEVEL >= 1)
{
printf("[%%d DEC: %d  %%u DEC: %u]\n", v11, v11);
} else {
//printf("\n");
}

while(1)
{
  if( SA2[v3] == 0x81 )
  {
if(DEBUG_LEVEL >= 1){ printf("=> RSL\n"); }
          v12 = v11 & 0x80000000;
          v11 <<= 1;
          if ( v12 )
          {
            v11 |= 1u;
            v48 = 1;
          }
          else
          {
            v48 = 0;
          }
          ++v3;
      }
      else if ( SA2[v3] == 0x82 )
      {
         if(DEBUG_LEVEL >= 1){ printf("=> RSR\n"); }
  v14 = v11 & 1;
          v11 >>= 1;
          if ( v14 )
          {
            v11 |= 0x80000000;
            v48 = 1;
          }
          else
          {
            v48 = 0;
          }
          ++v3;
       }
   else if ( SA2[v3] == 0x93 )
      {
     if(DEBUG_LEVEL >= 1){ printf("=> ADD\n"); }
         opadd_value1 = (SA2[v3 + 1] << 8) | SA2[v3 + 2]; // concat 2 bytes
         v17 = v11;
         v18 = SA2[v3 + 4] | ((SA2[v3 + 3] | (opadd_value1 << 8)) << 8);
v11 = v11 + v18;
v48 = v11 < v17;
v3 += 5;
   }
       else if ( SA2[v3] == 0x84 )
       {
     if(DEBUG_LEVEL >= 1){ printf("=> SUB\n"); }

          opsub_value1 = (SA2[v3 + 1] << 8) | SA2[v3 + 2]; // concat 2 bytes
          v20 = SA2[v3 + 4] | ((SA2[v3 + 3] | (opsub_value1 << 8)) << 8);
          v21 = v11 < v20;
          v11 -= v20;
          v48 = v21;
          v3 += 5;
}
else if ( SA2[v3] == 0x87 )
{
if(DEBUG_LEVEL >= 1){ printf("=> XOR\n"); }

         opxor_value1 = (SA2[v3 + 1] << 8) | SA2[v3 + 2]; // concat 2 bytes
         v25 = SA2[v3 + 4] | ((SA2[v3 + 3] | (opxor_value1 << 8)) << 8);

v11 = v11 ^ v25;
v3 += 5;
v48 = 0;
}

else if ( SA2[v3] == 0x68 )
{
if(DEBUG_LEVEL >= 1){ printf("=> LOOP\n"); }
v27 = v3 + 1;
         v51 += 2;
         v29 = v53 + 2;

         v53 += 2;

         v32 = SA2[v27];
         v3 = v27 + 1;
         *(_BYTE *)v51 = v32;
         *v29 = v3;
        }
         
        else if ( SA2[v3] == 0x49 )
        {
      if(DEBUG_LEVEL >= 1){ printf("=> NEXT\n"); }
          if ( *(_BYTE *)v51 <= 1u )
          {
            v51 -= 2;
            --v50;
            v53 -= 2;
            ++v3;
            if(DEBUG_LEVEL >= 2){ printf("NEXT 1: %X at pos %d\n", SA2[v3], v3); }
          }
          else
          {
            --*(_BYTE *)v51;
            v3 = *v53;
            if(DEBUG_LEVEL >= 2){ printf("NEXT 2: %X at pos %d\n", SA2[v3], v3); }
          }
}

        else if ( SA2[v3] == 0x4A )
        {
  if(DEBUG_LEVEL >= 1){ printf("=> BCC\n"); }
          v34 = v3 + 1;

          if ( v48 )
            v3 = v34 + 1;
          else
            v3 = v34 + SA2[v34] + 1;
            if(DEBUG_LEVEL >= 2){ printf("BCC: %X at pos %d\n", SA2[v3], v3); }
        }

        else if ( SA2[v3] == 0x6B )
        {
          if(DEBUG_LEVEL >= 1){ printf("=> BRA\n"); }
          v36 = v3 + 1;
          v3 = v36 + SA2[v36] + 1;
        }

else if ( SA2[v3] == 0x4C )
{
if(DEBUG_LEVEL >= 1){ printf("=> READY\n"); }
printf("DONE. KEY = %08lx \n", v11);
return 0;
}

    else {
     printf("ERROR: ILLEGAL OPCODE %X at pos %d\n", SA2[v3], v3);
return 0;
}
if(DEBUG_LEVEL >= 1)printf("CURRENT SEED = %08lx \n", v11);
}

printf("DONE. KEY = %08lx \n", v11);
}


The code provides some popular SA2 arrays used in most ECUs, just uncomment and comment the existing. You can insert your own sequence into the SA2[] array.