After a LOT of sending challenges and recording the responses I've 'broken' the "encryption" in my car's immobiliser...the reason for doing it is so I can use the engine and transmission in a project car, keeping the HS canbus - for the ECM to TCM comms, but removing the MS canbus - and all modules associated with it...including the body control module which handles the immobiliser functionality in the stock car.

So, "encryption" - it's basically a substitution cipher with a bunch of modifiers. The format is a 32-bit challenge, and 32-bit response - formatted into 4 bytes and 4 bytes.

I've currently coded it in C (for arduino) using arrays for the responses and a bunch of logic and it's working - however there's got to be a better way...right?

I'm a mechanic, not a programmer, and definitely not a mathematician...I just don't have the knowledge (or IQ XD) to make the jump from what I've done so far, to coding a functioning mathematical model/algorithm to do the same job.

As a couple of examples of the logic for the modifiers it's things like if challenge byte 2 >= 0xEC then increment the response by 1, or if bit 2 of challenge byte 3 >= 0x14 then do something else to the appropriate response etc.

But honestly...would love to reduce my 600 lines of code to 50!

I can post up as many C/R pairs as necessary to get some help here and post the flow chart of logic too.

Just hoping for a white knight right now!

Edited to add coded block and other info...

void CalcResp()

  //Calculate response   


  uint32_t  ResponsePreXOR = 0x00000000;
  uint32_t  ResponsePostXOR;
  uint8_t   ChalByte[4];
  uint8_t   RawRespByte[4];
  uint8_t   XORRespByte[4];
  CAN_FRAME ChalFrame;
  CAN_FRAME RespFrame;


  if (Can0.available() > 0)

  // Split the Challenge into raw bytes
  ChalByte[0] = ChalFrame.data.byte[0];
  ChalByte[1] = ChalFrame.data.byte[1];
  ChalByte[2] = ChalFrame.data.byte[2];
  ChalByte[3] = ChalFrame.data.byte[3];

  // if Challenge Byte 3 bit 1 is set

  if (ChalByte[3]&0x02)
    if (ChalByte[3]>=0x16)
        RawRespByte[3] = TableB2A[(ChalByte[2]+1)&0xFF];
        RawRespByte[3] = TableB2A[ChalByte[2]];
  RawRespByte[2] = TableB3[ChalByte[3]];
  RawRespByte[1] = TableB1A[ChalByte[1]];

    if (ChalByte[1]>=0xEC)
        RawRespByte[0] = TableB0A[(ChalByte[0]+1)&0xFF];
        RawRespByte[0] = TableB0A[ChalByte[0]];

  // if Challenge Byte 3 bit 1 is not set


  // Build Response Byte 0
      RawRespByte[3] = TableB3[ChalByte[3]];
  // Build Response Byte 2
        if (RawRespByte[3]>=0x14)
            RawRespByte[2] = TableB2N[(ChalByte[2]+1)&0xFF];
            RawRespByte[2] = TableB2N[ChalByte[2]];

  // if Challenge byte 1 is above or equal to 0xEC
  // Build Response Byte 1

        if (ChalByte[1]>=0xEC) 
            if (ChalByte[0]&0x0F==0x0F)
                RawRespByte[1] = TableB016s[(ChalByte[0]/16)];
              RawRespByte[1] = TableB0N[(ChalByte[0]+1)&0xFF];
        if (ChalByte[1]<0xEC)
            RawRespByte[1] = TableB0N[ChalByte[0]];
  //Build Response Byte 0 

    RawRespByte[0] = TableB1N[ChalByte[1]];


  //Construct the response out of the response bytes
  ResponsePreXOR = uint32_t (RawRespByte[0])<<24;
  ResponsePreXOR += uint32_t (RawRespByte[1])<<16;
  ResponsePreXOR += uint32_t (RawRespByte[2])<<8;
  ResponsePreXOR += uint32_t (RawRespByte[3]);

The car's ECM is a Siemens SID 203 - the immo algo for this hasn't yet been broken I don't think...no-one produces an emulator for it.

I think the synchro is this code snippet from the ECM

  • 2
    this sounds like a programming question rather than RE as such, so may be a better fit for StackOverflow
    – Igor Skochinsky
    Apr 29 at 22:29
  • Added codes snippets and more info :)
    – joehodgy
    Apr 30 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.