BA Falcon BEM EEPROM via CAN

Ford information and tools can be found here
jakka
Posts: 53
Joined: Mon Dec 11, 2023 11:51 am
cars: 6FPAAAJGSW9E86101
Location: Aus
Contact:

Re: BA Falcon BEM EEPROM via CAN

Post by jakka »

Well looks like somebody's been busy
User avatar
pman92
Posts: 572
Joined: Thu May 03, 2012 10:50 pm
Location: Castlemaine, Vic
Contact:

Re: BA Falcon BEM EEPROM via CAN

Post by pman92 »

jakka wrote: Mon May 05, 2025 3:22 pm Well looks like somebody's been busy
Yes, too busy to do much more on this lately :lol:

This is what I'm up to. Works with 100% success on all 1437 unique pairs I've brute forced out of Forscan so far (I've got a python script for doing that, I did not do them all manually :shock: ).

It's not yet calculating key nibble 3, but anyone reading previous replies will be able to work that out.
I'll sort that out and get a whole bunch more random pairs to test against when I get time.

Code: Select all

def calc_key_nibbles(seed):
    lookup_table = [
        0x09, 0x82, 0x14, 0x10, 0x32, 0x65, 0x87, 0x25,
        0x47, 0x61, 0x08, 0x70, 0x94, 0x36, 0x76, 0x98,
        0x32, 0x54, 0x43, 0x65, 0x09, 0x21, 0x83, 0x25,
        0x49, 0x81, 0x07, 0x6A, 0x9C, 0xB6, 0x58, 0x7E,
        0xD4, 0x98, 0xBA, 0x54, 0x76, 0xDC, 0x32, 0x43,
        0x65, 0x09, 0x21, 0x87, 0xED, 0x83, 0x25, 0x49,
        0x81, 0x07, 0x6D, 0xC7, 0x66, 0x58, 0x72, 0x14,
        0x3A, 0x90, 0xFA, 0x9C, 0x54, 0x76, 0x10, 0x32,
        0x98, 0xFE, 0x98, 0xBA
    ]

    sn1 = (seed[0] >> 4) & 0xF
    sn2 = seed[0] & 0xF
    sn3 = (seed[1] >> 4) & 0xF
    sn4 = seed[1] & 0xF
    sn5 = (seed[2] >> 4) & 0xF
    sn6 = seed[2] & 0xF
    sn7 = (seed[3] >> 4) & 0xF
    sn8 = seed[3] & 0xF

    # KN1 logic
    kn1 = sn2 ^ (0x1 if (sn2 & 0x8) else 0x5)
    if (sn3 ^ 0xA) < 2 and (sn4 ^ 0xA) < 2 and (sn2 & 0x1):
        kn1 = (kn1 + 1) & 0xF
    if (sn2 >= 0xA):
        kn1 ^= 0x4

    # KN2 logic
    tmp_high = sn3
    tmp_low = sn4
    if tmp_low > tmp_high:
        tmp_high, tmp_low = tmp_low, tmp_high
    index = (tmp_high * (tmp_high + 1)) // 2 + tmp_low
    if index & 1:
        kn2 = lookup_table[index >> 1] & 0xF
    else:
        kn2 = (lookup_table[index >> 1] >> 4) & 0xF
    if (sn5 ^ 0xA) < 2 and (sn6 ^ 0xA) < 2 and ((sn3 ^ sn4) & 1) == 0:
        kn2 = (kn2 + 1) & 0xF

    # KN3 logic placeholder
    kn3 = 0

    # KN4 logic
    kn4 = sn7 ^ (0x1 if (sn7 & 0x8) else 0x5)
    if (sn7 >= 0xA):
        kn4 ^= 0x4

    return kn1, kn2, kn3, kn4
User avatar
pman92
Posts: 572
Joined: Thu May 03, 2012 10:50 pm
Location: Castlemaine, Vic
Contact:

Re: BA Falcon BEM EEPROM via CAN

Post by pman92 »

Got stuck back into this today.

The audio module linking / initialization is sorted.

Next problem was the missing 6F6 / 6F8 CAN message data when PATS is off.
After a few hours of mucking around I've determined the audio module is linked directly to these messages. It waits for the 6F6 data to write the eeprom after you do a reset, so it's somehow calculated from that. And it only reads that eeprom back after it has received 6F6 data following a battery reconnection.

I think I understand a little about how 6F6 / 6F8 are formatted.
The first byte is some kind of status / header. Its doesn't seem to change between vehicles / modules (I've logged a couple now).
From the ford workshop manual:
BA_wsm.png
BA_wsm.png (39.2 KiB) Viewed 329 times
I believe:
6F6 PCM messages
C6 - pre challenge request
59 - challenge data
3D - challenge acknowledgement
15 - Unsure what to call it. What it normally transmits when its not in one of the above modes (6F6 is always transmitted, even with PATS off).

6F8 BEM messages
7F - challenge request
A7 - challenge response
93 - not ready / reading transponder

The 2nd byte maybe some sort of rolling counter. The data is constantly changing. PCM data changes every second or so. BEM data in BA this seems to increment by 2 every response. In the FG log it seemed to always be the same.

Rest of it I've got no idea. Would probably take a years work to understand it. You would have to decompile the PCM and probably the BEM as well.

Through process of elimination, I've determined the bare minimum the ACM needs to see to work (seeing when it was accessing eeprom was a huge help to work that out).
I don't want to give too much away, but I will say it doesn't seem to depend on the challenge / response at all. Only the data from one of the modules. And only the 6F6 / 6F8 security data packets.
Also once unlocked and working, it seems to stay that way until battery power is removed. Disconnect everything else, unplug the key reader, turn PATS off, swap in a new PCM - it still works fine (until battery is unplugged).

I've whipped up a proof of concept (running from my PC via a python script):
proof_of_concept.jpg
Next step is to work on some hardware. Either something they can plug into the diagnostic port if the battery's ever disconnected, or wire in permanently.
Also want to double check it works on BF (I'm 99% sure it will) and try it out with some different modules to confirm its going to work.
FG might be slightly different. But looking at the logs I've got so far I think it could also be very similar.

Other thing that would be nice would be turning off the hand warning in the dash. That comes from the 0x427 PCM message and would be something else to change in the binary when turning PATS off (if its even possible).
PATS off it doesn't flash, just stays on. Disabling P1260 doesn't remove it either.
Post Reply