Technical RSA Bypass Explained

carabuser

Lieutenant
Oct 2, 2019
884
1
783
0
UK
Ride
Z4 35i & 335i
I’ve been wanting to make a thread about this for a while. Every single person here tuning their DME has this clever little exploit applied to their DME so I wanted to document it in case anyone was curious.

To give some context on the discussion I’ve put together a high-level memory map of the bin file. This is what the 2MB file that you make changes to actually looks like:

2MB ROM LAYOUT.png


A brief overview of the areas:
The first area, labelled as the Boot-SW (Supplier) is what some refer to as the SBOOT. This is a small bit of code early on in the DME that handles the base functions of the chip. This contains the ISN, serial number and a backup copy of the vehicle VIN and is often referred to as the locked section of memory as it cannot be written to via the normal methods.

After that we have another area of Boot-SW, this one is customer specific often referred to as CBOOT and contains the code that BMW wrote to handle all the serial interfaces and reprogramming procedure. This can be reprogrammed along with everything after this point.

After that we have a section of ECU-SW which is the actual code that is responsible for the operation of the vehicle (boost control, fuel control, torque management). There are 2 that make up what is referred to as the software. This makes up the vast majority of the data in the 2MB file. This is what people refer to when they use terms like I8A0S, IJE0S or INA0S, this is the name of the software in the car.

We then have the calibration data. That is what most people know as the “Tune”. To put this into layman’s terms, this is the engine’s settings. This area is what is manipulated when you use TunerPro and the public XDF.

The sections in between, in white, are areas that contain the RSA signatures which are referred to as security keys and the file checksums which we won’t get into.


Now we get to the purpose of the post. The “RSA Bypass”:

All tools that read and write to the MSD80 and MSD81 (COBB, OpenFlash, MHD etc) use exactly the same process to do so. That all seemed to have copied each other down the line. I’m not sure who exactly created the original RSA bypass but I believe that COBB purchased/licensed their method and then the rest just coped it. Whoever came up with the original bypass is a real genius and undoubtedly put a lot of blood, sweat and tears into the process. I’m not sure if the trick originated on the MSD80, or if it was an existing trick that was used elsewhere that was just adapted for the MSD8x, but I’ll explain how it’s done in the context of the MSD8x.

To give context on what the RSA bypass is, we need to quickly run through what RSA protection actually is. I’m no expert on cryptography but I’ll give my understanding of it and hopefully if I mess it up, someone can correct me.

The overall function of the RSA protection is to prevent anyone from making any changes to the code inside the DME. This is to protect their warrantied engines and probably a legal requirement to protect emissions related inspection routines. To do this, RSA uses a pair of keys, the private key, that BMW keeps and is still completely secret and a public key that is written into the DME. BMW will use their private key and feed it the contents of the bin into it and it will generate a “signature”. This is then written into spare space in the bin. Once the contents of the bin are written into the DME along with the signature, the DME will use its public key to validate that signature, if the signature is valid the DME will accept the code and boot up normally. If not, the DME will reject the new code and stay in a failsafe mode until a valid file is written.

On some older DMEs they used smaller 512bit keys, probably due to hardware capabilities at the time. People (clever ones) were able to crack these by brute-force and just use the cracked private key to sign their modified files, I believe that's what they use on the MSV DMEs and old school slushbox TCUs. To prevent people cracking their new MSD80/81, BMW uses a 1024bit key and thus puts it outside of the capabilities of current brute-forcing (until quantum computing maybe).

Since brute force is off the cards, alternative exploits were investigated. The person responsible for the RSA bypass probably started off by decompiling the 2MB bin file and probing it for weaknesses. The weakness that we currently use relies on an oversight in the developer’s implementation of the RSA key verification process.

To explain the weakness, I need to add a little bit more detail to the above process of the BMW RSA signature generation. There are 2 signatures in the bin. One for the software and one for the calibration. We will just look at the software one since that is all that matters in this exploit. When the BMW software developers generate the RSA signature, they only look at certain sections of the bin. This can’t cover the entire bin contents because things like the signature itself will change after the signing is done and crucially, they also don’t check sections of memory that they expect to be blank which was the reason this exploit is possible. Once they generate the signature and write it into the bin, they convert that bin into an .0pa which is what WinKFP uses to flash the DME.

On the DME side, to match the process that the BMW engineers used at their end, the range of data that the DME looks at is defined in a table like this:
1697372848286.png



So, by looking at this table we can see the DME will take all the data currently in the chip between 80020000-8003FFFF, 80040000-80053DFF and 80080000-801FFC3F and then verify it with the public key. So as long as the data in those areas matches what BMW fed into the RSA generation using their private key we will pass the RSA check in the DME and our new software will be accepted by the DME. This is what happens when you update your DME using WinKFP and the 0pa and 0da files that in the DATEN files.

If you look at those ranges you can see that the second range looks suspect (80040000-80053DFF). This memory range is inside what should be the calibration sector. This is because the area of code that we referred to above as the CBOOT is actually the code that runs this signature check, so naturally it can’t be written to until the code has passed the RSA check. To verify the code before accepting it, the reprograming procedure requires that the area of the bin that contains the CBOOT code is parked into the calibration area temporarily until the DME can verify the signature, then it will take that code and overwrite the existing CBOOT code.

This is where things get clever. The exploit involves making a copy of the CBOOT code and modifying it to remove the part that verifies the signature, this essentially means the DME will always pass the RSA signature verification if we can manage to get the code accepted by the DME. But modifying this code will mean that it will no longer pass the signature verification while it’s parked in the temporary memory range.

To get around this problem we write both versions of our CBOOT code into DME, the first modified one in the area 80040000-80053DFF that will be written into the CBOOT upon a successful signature check, then the second copy of original unmodified code that we write into the spare calibration sector memory (0x80053E00-0x8007FFFF) which will not be used at all and be overwritten by the calibration data later on.

At this point we still have a problem with the signature as you can see in the above table, the DME will check the memory range where the modified CBOOT code is parked and will fail the signature check. To get around this issue we edit this table that lives over in the ECU-SW code. We do a similar process with this data, make a new copy of this table and place it in some spare memory that isn’t normally checked (the area after 801FFC3F). We then modify the original table so that instead of looking at the original areas where our modified code now lives, we point it to the blank memory areas where we wrote copies of the original code.

This now means once we write all this into the DME, it will check all that data and because all the data we are telling it to check is exactly the same as the data the signature was created with originally is all there, it will pass the check and write our modified code into the CBOOT area.

This now means that the code that is actively running in the CBOOT area of the DME will accept any new code. At this point the DME is “unlocked”.
 

shushikiary

Sergeant
Jun 4, 2018
304
173
0
Ride
335xi
Makes me wonder exactly what they do for protection on things like the flex fuel MHD tunes. They have some kind of encryption on them, but to do that they would have had to modify/fix the checking on the DME or else you can just throw a can bus analyzer on during a full flash write and "unlock" any tune you want.

I suppose I could just use a laterbach and get the JTAG or HSSP hooked up on the DME and a tri-core license and literally watch what it's doing.... but I have better things to do with my time at the moment.
 

shushikiary

Sergeant
Jun 4, 2018
304
173
0
Ride
335xi
Yea but there are almost always ways around that unless they do something like fuse bits, which most don't. I may or may not have friends who work for derive and do this for a living. (And I'm an embedded EE).
 

carabuser

Lieutenant
Oct 2, 2019
884
1
783
0
UK
Ride
Z4 35i & 335i
Makes me wonder exactly what they do for protection on things like the flex fuel MHD tunes. They have some kind of encryption on them, but to do that they would have had to modify/fix the checking on the DME or else you can just throw a can bus analyzer on during a full flash write and "unlock" any tune you want.

I suppose I could just use a laterbach and get the JTAG or HSSP hooked up on the DME and a tri-core license and literally watch what it's doing.... but I have better things to do with my time at the moment.
While the data exchange between the DME and tester are unencrypted I don't think there's anything stopping you reversing it. As you said, you can analyse the CAN traffic, but once you have the data you still need to understand it. I don't think there's any way of truly locking things down in a DME without doing something like changing the RSA keys for both security access file signing and fixing the exploit that I posted about here so that you actually go back to signing tuned files and locking them to ECU serial numbers. Even that would be vulnerable to someone sniffing the CAN traffic but they would then need their own flashing solution to make use of the data and the current flashing solutions out there don't offer the ability to flash custom code.

If you just intended on capturing the locked OTS maps and flashing it as a custom map in MHD that'll work, but there's nothing special in there. If you can't produce a custom tune to achieve the same result as the OTS maps then you are going to struggle to improve on the OTS map by making any changes yourself.
 

shushikiary

Sergeant
Jun 4, 2018
304
173
0
Ride
335xi
No the point would be to modify the tune to how I want it rather than being annoying and asking for 50 revisions of the tune, or how it can sometimes take more than week for a tuner to get back to you. I've asked to pay for a base tune in the past and everyone says no. I'm happy to tune it my self, I did it before I went large single, but the changes were big enough with a large single turbo I didn't want to start from scratch so I paid for a tune, but now I'm beholden to the tuner to make any changes (that's what I hate). There are issues, like it trying to do silly things with lean spool mode under 3k RPM that drive me nuts, and I'd love to go in and just disable it. Or be able to go in and tweak my WGDC number to get them how I want them, etc.

So for me, it would totally be about modifying the tune. The hardest part about the can bus sniff on full write is pulling the data out of the packets and organizing it properly to get a bin file. Easiest thing to do would be to record a full write back to stock as you have the bin to compare already, use it to figure out the order of what data in what packet goes to what address in the bin, then do a full write of the tune and piece it back together hoping its the same. That's where I'd start if I was going to do it.

Heck, I'd be happy to sign an NDA so I can get my pants sued off if I shared the tune if someone was willing to unlock it so I don't have to pester them over and over again for changes, I'd rather do that then do all the work mentioned above. So far though the minor annoyances combined with other projects have made it not high enough on my priority list to attempt. Currently building an LS 408 stroker for my jeep, and I'll just throw a holley dominator on it and tune it my self.
 
  • Like
Reactions: wheela

78dec3b1

New Member
Oct 28, 2023
1
2
0
So for me, it would totally be about modifying the tune. The hardest part about the can bus sniff on full write is pulling the data out of the packets and organizing it properly to get a bin file. Easiest thing to do would be to record a full write back to stock as you have the bin to compare already, use it to figure out the order of what data in what packet goes to what address in the bin, then do a full write of the tune and piece it back together hoping its the same. That's where I'd start if I was going to do it.
FYI: The Continental specification 4CC3KM0S.pdf documents the flash messages requestDownload and transferData ~page 7752, which are sent using ISO 15765-2.
 

Attachments

  • tool.zip
    55 KB · Views: 49

darchap

New Member
Jan 16, 2021
4
0
0
Hello, is this behaviour MSD's only or could the same exploit be applied to other ECUs? (ie EDC)
 

darchap

New Member
Jan 16, 2021
4
0
0
Could possibly work anywhere that the RSA table isn't covered by the signature itself.
Is there any way I could check this? I would like to try modifying a 0da file and see if I could flash it back with winkfp, but first I would like to know a way to check if RSA could be bypassed or not
 

carabuser

Lieutenant
Oct 2, 2019
884
1
783
0
UK
Ride
Z4 35i & 335i
Is there any way I could check this? I would like to try modifying a 0da file and see if I could flash it back with winkfp, but first I would like to know a way to check if RSA could be bypassed or not
You would need to look at the 0pa sector and find the RSA table then see of it covers itself. You also need empty space that isn't covered by the RSA table that you can redirect to.