Page 3 of 4
Re: BA Falcon BEM EEPROM via CAN
Posted: Sat Apr 19, 2025 5:45 pm
by pman92
Just writing notes down as I go:
00 00 FF 00 = 50 A5
00 00 F0 00 = 50 55
00 00 0F 00 = 50 55
00 00 A5 00 = 50 55
00 00 5A 00 = 50 55
00 00 C3 00 = 50 55
00 00 3C 00 = 50 55
n3 nibble = (b3 >> 4) | (b3 & 0F), plus something else ??
00 00 CF 00 = 50 95
00 00 CA 00 = 50 E5
00 00 C5 00 = 50 95
00 00 C0 00 = 50 45
00 00 FC 00 = 50 95
00 00 AC 00 = 50 E5
00 00 5C 00 = 50 95
00 00 0C 00 = 50 45
n3 nibble = ( (b3 >> 4) ^ (b3 & 0F) ), plus something else ?? -
00 00 A0 00 = 50 A5
00 00 FF 00 = 50 A5
00 00 0A 00 = 50 A5
00 00 AF 00 = 50 F5
00 00 FA 00 = 50 F5
00 00 50 00 = 50 55
00 00 05 00 = 50 55
00 00 00 00 = 50 05
00 00 84 00 = 50 05
00 00 48 00 = 50 05
00 00 04 00 = 50 65
00 00 40 00 = 50 65
00 00 21 00 = 50 15
00 00 12 00 = 50 15
00 00 11 00 = 50 85
00 00 B0 00 = 50 95
00 00 0B 00 = 50 95
00 00 43 00 = 50 75
00 00 34 00 = 50 75
00 00 32 00 = 50 35
00 00 01 00 = 50 95
00 00 10 00 = 50 95
00 00 02 00 = 50 25
00 00 20 00 = 50 25
00 00 F2 00 = 50 75
00 00 2F 00 = 50 75
00 00 03 00 = 50 15
00 00 30 00 = 50 15
00 00 F3 00 = 50 65
00 00 3F 00 = 50 65
00 00 C3 00 = 50 55
00 00 3C 00 = 50 55
00 00 0F 00 = 50 55
00 00 F0 00 = 50 55
00 00 73 00 = 50 85
00 00 37 00 = 50 85
n3 nibble = (0xA & ((b3 >> 4) ^ (b3 & 0F)) | (0x5 & (b3 >> 4) ^ (b3 & 0F)) ???
Re: BA Falcon BEM EEPROM via CAN
Posted: Sat Apr 19, 2025 6:13 pm
by antus
It looks to me like there is some XOR, probably against 0x05 or 0x50 as well depending which end, or ^5 and bit shifts.
EG 00 00 ^ 50 00 = 50
and 00 00 ^ 00 05 = 05
so sample
00 00 00 00 gets you 50 05.
But I think it is nibbles, not 8 bit shifts... just I think that is where the 5s come from. And if its XOR that has something to do with FFFF becoming AA as 5 is 0101 so XOR F (1111) with 5 (0101) gives A (1010). But I haven't figured out which bits are which, but it might fit in with what you have so far.
The other interesting one that has to do with those patterns is FF FF 00 00 = AA 05
Actually, 8 tests with a single 5 in a different nibble each time would be interesting. If its XOR then the ones that hit an ^5 in the algo should return all zero, and the ones that hit an ^0 should return the 5 wherever it ends up after bit shifts and anything else should return something else.
This sequence is particularly interesting for ^5. The last two make me wonder if the 84 and 48 are nibble swapped then XORd with the result to cancel each other out.
00 00 50 00 = 50 55
00 00 05 00 = 50 55
00 00 00 00 = 50 05
00 00 84 00 = 50 05
00 00 48 00 = 50 05
Re: BA Falcon BEM EEPROM via CAN
Posted: Sat Apr 19, 2025 7:02 pm
by pman92
Yes I agree that makes sense.
And I think the use of A or 5 might have something to do with the non-symmetrical / "overflow" like bit that moves from the 3rd byte to 2nd nibble.
And it will probably become evident once the inner nibble calculation is worked out.
EG. if we are &ing or ^ing a nibble with A or 5, and both sides use the same A or 5, when we reverse/mirror the other stuff but keep the A or 5, we could end up with this kind of thing:
00 00 AA 00 = 51 45
00 AA 00 00 = 54 05
00 0A 0A 00 = 5A 05
00 A0 A0 00 = 5A A5
Where as other than those particular occasions, everything is perfectly mirrored:
00 BA AB 00 = 53 35
00 00 A0 00 = 50 A5
00 0A 00 00 = 5A 05
12 34 43 21 = 77 77
AB CD DC BA = E7 7E
01 2F F2 10 = 47 74
I don't believe the 3rd nibble is using the 2nd byte for its calculation. Because changing it makes no difference other than those special few examples shown above
01 00 F2 10 = 40 74
01 FF F2 10 = 4A 74
01 2F F2 10 = 47 74
01 12 F2 10 = 41 74
01 F0 F2 10 = 45 74
It's also evident the 2nd byte can effect the 1st nibble, but the same mirrored change (3rd byte effecting 4th nibble) does not happen. Again probably because of the use of A or 5:
01 BB F2 10 = 52 74
01 BB BB 10 = 53 24
01 2F BB 10 = 47 24
Re: BA Falcon BEM EEPROM via CAN
Posted: Sat Apr 19, 2025 7:36 pm
by pman92
I'm pretty confident the outer most nibbles (1 and 8) of the 4 seed bytes are irrelevant
33 33 33 33 = 62 26
03 33 33 30 = 62 26
02 33 33 20 = 72 27
02 23 32 20 = 73 37
01 23 32 10 = 43 34
01 FF FF 10 = 4A A4
2nd and 7th nibble of seed map directly to 1st and 4th of key:
01 00 00 10 = 40 04
02 00 00 20 = 70 07
03 00 00 30 = 60 06
04 00 00 40 = 10 01
05 00 00 50 = 00 00
06 00 00 60 = 30 03
07 00 00 70 = 20 02
08 00 00 80 = 90 09
09 00 00 90 = 80 08
0A 00 00 A0 = F0 0F
0B 00 00 B0 = E0 0E
0C 00 00 C0 = 90 09
0D 00 00 D0 = 80 08
0E 00 00 E0 = B0 0B
0F 00 00 F0 = A0 0A
As well as when they are not the same, eg:
01 00 00 F0 = 40 0A
Changing 1st and 8th seed nibble, as well as inner 4 nibbles (bytes 2 and 3) also seems to make no difference.
The mapping for this seems to be exactly "seedNibble XOR 0x5", except for these 2:
08 00 00 80 = 90 09
09 00 00 90 = 80 08
Re: BA Falcon BEM EEPROM via CAN
Posted: Sat Apr 19, 2025 7:46 pm
by antus
hmmm
8 1000
9 1001
so I guess that might just be some custom logic connecting the highest and lowest bits.
It looks a bit messy but maybe it is as simple as:
nibble =^ 1 if (nibble & 0xE == 8);
Just to swap those two nibble values.
There could actually be similar to check the high bit in a nibble and carry to the next nibble in those scenarios where we see a bit change in a different nibble, rather than an overflow.
Re: BA Falcon BEM EEPROM via CAN
Posted: Sat Apr 19, 2025 8:41 pm
by pman92
Ok thinking about it again, I contradicted myself.
That would work perfectly well, except:
pman92 wrote: ↑Sat Apr 19, 2025 7:02 pm
It's also evident the 2nd byte can effect the 1st nibble, but the same mirrored change (3rd byte effecting 4th nibble) does not happen. ....:
01 BB F2 10 =
52 74
01 BB BB 10 = 53 24
01 2F BB 10 = 47 2
4
It still would work perfectly well for the RH side (which is mirrored), but not the LH
01 0A 00 10 = 4A 04
01 A0 00 10 = 4A 04
01 AA 00 10 =
54 04
00 00 00 00 = 5 0 0 5
If the LSB of nibble 2 is set, then nibble 3 and 4 (the byte to the right) both being A or B increments it:
01 00 00 00 =
4 0 0 5
01 A9 00 00 =
4 D 0 5
01 AA 00 00 =
5 4 0 5
01 AB 00 00 =
5 3 0 5
01 BA 00 00 =
5 3 0 5
01 AC 00 00 =
4 E 0 5
01 CA 00 00 =
4 E 0 5
01 AD 00 00 =
4 D 0 5
01 DA 00 00 =
4 D 0 5
05 00 00 00 =
0 0 0 5
05 AA 00 00 =
1 4 0 5
05 AB 00 00 =
1 3 0 5
05 BA 00 00 =
1 3 0 5
05 AC 00 00 =
0 E 0 5
However it doesn't happen if LSB isn't set:
02 00 00 00 =
7 0 0 5
02 AA 00 00 =
7 4 0 5
02 AB 00 00 =
7 3 0 5
And it doesn't happen with 0x5 then either:
02 00 00 00 =
7 0 0 5
02 55 00 00 =
7 0 0 5
02 56 00 00 =
7 3 0 5
Re: BA Falcon BEM EEPROM via CAN
Posted: Sat Apr 19, 2025 11:26 pm
by pman92
This here is getting pretty close, at least for the first and last key nibble:
Code: Select all
calc(seed1, seed2, seed3, seed4) {
sn1 = (seed1 >> 4) & 0xF;
sn2 = seed1 & 0xF;
sn3 = (seed2 >> 4) & 0xF;
sn4 = seed2 & 0xF;
sn5 = (seed3 >> 4) & 0xF;
sn6 = seed3 & 0xF;
sn7 = (seed4 >> 4) & 0xF;
sn8 = seed4 & 0xF;
kn1 = sn2 ^ ((sn2 & 0x8) ? 0x1 : 0x5);
if( (sn2 & 0x1) && ((sn3 ^ 0xA) < 2) && ((sn4 ^ 0xA) < 2) ) {
kn1 = (kn1 + 1) & 0xF;
}
// kn2 yet to be calculated
// kn3 yet to be calculated
kn4 = sn7 ^ ((sn7 & 0x8) ? 0x1 : 0x5);
key1 = (kn1 << 4) | kn2;
key2 = (kn3 << 4) | kn4;
}
29 mismatches found from 199 pairs checked against:
Key Nibble 1:
Out by +4: 8 time(s)
Out by +12: 7 time(s)
Key Nibble 4:
Out by +4: 14 time(s)
Out by +12: 12 time(s)
So the nibbles sometimes end up either 4 more or 4 less than they should be (they wrap around at 16).
Maybe a missing XOR 0x4 ?
Once I work that out I'll move on to looking at the middle nibbles. And then get a script running to pull some random pairs from forscan overnight, and then verify they all match. Probably find some edge cases, then rinse and repeat.
What I'll end up with will probably be much less elegant than how its really done, but if it works it works.
Re: BA Falcon BEM EEPROM via CAN
Posted: Sun Apr 20, 2025 10:48 am
by pman92
This logic seems to work for nibble 1 and nibble 4, at least for all the pairs I've collected to try against so far:
Code: Select all
calc(seed1, seed2, seed3, seed4) {
sn1 = (seed1 >> 4) & 0xF;
sn2 = seed1 & 0xF;
sn3 = (seed2 >> 4) & 0xF;
sn4 = seed2 & 0xF;
sn5 = (seed3 >> 4) & 0xF;
sn6 = seed3 & 0xF;
sn7 = (seed4 >> 4) & 0xF;
sn8 = seed4 & 0xF;
kn1 = sn2 ^ ((sn2 & 0x8) ? 0x1 : 0x5);
if( (sn2 & 0x1) && ((sn3 ^ 0xA) < 2) && ((sn4 ^ 0xA) < 2) ) {
kn1 = (kn1 + 1) & 0xF;
}
if( sn2 >= 0xA ) {
kn1 ^= 0x4;
}
// kn2 yet to be calculated
// kn3 yet to be calculated
kn4 = sn7 ^ ((sn7 & 0x8) ? 0x1 : 0x5);
if( sn7 >= 0xA ) {
kn4 ^= 0x4;
}
key1 = (kn1 << 4) | kn2;
key2 = (kn3 << 4) | kn4;
}
Result: All 335 pairs matched.
Moving on to the inner nibbles.
I'm just going to start working on the LH side because the RH looks to be mirrored of it.
Might have to add additional logic if the byte to the RH side == AA or AB for the edge cases as above (For memory that's definitely the case for 3rd nibble, not sure if it applies to the 2nd as well yet)
00 00 00 00 = 50 05
00 01 00 00 = 59 05
00 10 00 00 = 59 05
00 11 00 00 = 58 05
00 0A 00 00 = 5A 05
00 A0 00 00 = 5A 05
00 AA 00 00 = 54 05
00 50 00 00 = 55 05
00 05 00 00 = 55 05
00 E0 00 00 = 56 05
00 0E 00 00 = 56 05
00 EE 00 00 = 5C 05
Only 1 nibble with a value:
(eg. can all be reversed for same result, eg. 10 20 30 40 etc)
00 01 00 00 = 59 05
00 02 00 00 = 52 05
00 03 00 00 = 51 05
00 04 00 00 = 56 05
00 03 00 00 = 51 05
00 05 00 00 = 55 05
00 06 00 00 = 58 05
00 07 00 00 = 57 05
00 08 00 00 = 58 05
00 09 00 00 = 53 05
00 0A 00 00 = 5A 05
00 0B 00 00 = 59 05
00 0C 00 00 = 54 05
00 0D 00 00 = 53 05
00 0E 00 00 = 56 05
00 0F 00 00 = 55 05
A bunch that all come up with "0" 2nd nibble:
00 00 00 00 = 50 05
00 13 00 00 = 50 05
00 31 00 00 = 50 05
00 26 00 00 = 50 05
00 62 00 00 = 50 05
00 48 00 00 = 50 05
00 84 00 00 = 50 05
00 4C 00 00 = 50 05
00 C4 00 00 = 50 05
00 55 00 00 = 50 05
00 5F 00 00 = 50 05
00 F5 00 00 = 50 05
A bunch more:
I've noticed bit 0 (LSB) of keyNibble2 = seedNibble1 LSB ^ seedNibble2 LSB
Backs up them being XOR with each other (also the order of the nibbles doesn't matter, eg. 12 produces same result as 21)
00 10 00 00 = 59 05
00 11 00 00 = 58 05
00 12 00 00 = 51 05
00 13 00 00 = 50 05
00 14 00 00 = 55 05
00 15 00 00 = 54 05
00 16 00 00 = 57 05
00 17 00 00 = 56 05
00 18 00 00 = 53 05
00 19 00 00 = 52 05
00 1A 00 00 = 59 05
00 1B 00 00 = 58 05
00 1C 00 00 = 53 05
00 1D 00 00 = 52 05
00 1E 00 00 = 55 05
00 1F 00 00 = 54 05
00 20 00 00 = 52 05
00 21 00 00 = 51 05
00 22 00 00 = 54 05
00 23 00 00 = 53 05
00 24 00 00 = 58 05
00 25 00 00 = 57 05
00 26 00 00 = 50 05
00 27 00 00 = 59 05
00 28 00 00 = 56 05
00 29 00 00 = 55 05
00 2A 00 00 = 5C 05
00 2B 00 00 = 5B 05
00 2C 00 00 = 56 05
00 2D 00 00 = 55 05
00 2E 00 00 = 58 05
00 2F 00 00 = 57 05
00 30 00 00 = 51 05
00 31 00 00 = 50 05
00 32 00 00 = 53 05
00 33 00 00 = 52 05
00 34 00 00 = 57 05
00 35 00 00 = 56 05
00 36 00 00 = 59 05
00 37 00 00 = 58 05
00 38 00 00 = 55 05
00 39 00 00 = 54 05
00 3A 00 00 = 5B 05
00 3B 00 00 = 5A 05
00 3C 00 00 = 55 05
00 3D 00 00 = 54 05
00 3E 00 00 = 57 05
00 3F 00 00 = 56 05
00 40 00 00 = 56 05
00 41 00 00 = 55 05
00 42 00 00 = 58 05
00 43 00 00 = 57 05
00 44 00 00 = 52 05
00 45 00 00 = 51 05
00 46 00 00 = 54 05
00 47 00 00 = 53 05
00 48 00 00 = 50 05
00 49 00 00 = 59 05
00 4A 00 00 = 56 05
00 4B 00 00 = 55 05
00 4C 00 00 = 50 05
00 4D 00 00 = 59 05
00 4E 00 00 = 52 05
00 4F 00 00 = 51 05
00 50 00 00 = 55 05
00 51 00 00 = 54 05
00 52 00 00 = 57 05
00 53 00 00 = 56 05
00 54 00 00 = 51 05
00 55 00 00 = 50 05
00 56 00 00 = 53 05
00 57 00 00 = 52 05
00 58 00 00 = 59 05
00 59 00 00 = 58 05
00 5A 00 00 = 55 05
00 5B 00 00 = 54 05
00 5C 00 00 = 59 05
00 5D 00 00 = 58 05
00 5E 00 00 = 51 05
00 5F 00 00 = 50 05
00 60 00 00 = 58 05
00 61 00 00 = 57 05
00 62 00 00 = 50 05
00 63 00 00 = 59 05
00 64 00 00 = 54 05
00 65 00 00 = 53 05
00 66 00 00 = 56 05
00 67 00 00 = 55 05
00 68 00 00 = 52 05
00 69 00 00 = 51 05
00 6A 00 00 = 58 05
00 6B 00 00 = 57 05
00 6C 00 00 = 52 05
00 6D 00 00 = 51 05
00 6E 00 00 = 54 05
00 6F 00 00 = 53 05
Re: BA Falcon BEM EEPROM via CAN
Posted: Mon Apr 21, 2025 11:54 am
by pman92
Haven't found the inner nibble calculation yet.
I've been running a python script that generates regular expressions and runs them on the full set of seed/keys from "00 00 00 00" to "00 FF 00 00".
It was taking hours per pass until chatGPT helped me setup the script to run multicore - now takes less than 40 minutes.
Matches 94 / 256 sets (36% success):
( (SN3 ^ 0xA) & (SN4 | 0x5) ) ^ SN4
or
( (SN3 | 0x5) & (SN4 ^ 0xA) ) ^ SN3
Matches 75/256 (29% success) :
"SN3 ^ 0xA ^ SN4"
I suspect I will have to break the sets up into separate sets that work / don't work with a formula, and try see if there's any way to identify them for conditional logic / branching.
EG. I already know that if both LSB/MSB's of SN3 and SN4 are clear, the formula "SN3 ^ 0xA ^ SN4" fails every time.
It's also possible I may be able to find a formula that get the top 3 bits right, and I can change the LSB using the simple SN3 ^ SN4 expression (assuming it holds true over larger data sets, which it has so far)
Assuming I'm right that the KN2 and KN3 are mirrors of each other in how they are calculated, and my calculations for the rest hold true, I'm really only searching for 4 bits off data. It wouldn't be unfeasible to implement the whole thing with a 256 byte lookup table. If the LSB really is just SN3 ^ SN4, its only 3 bits and needs a 64 byte lookup table. Since we're only looking up nibbles, store 2 in each byte and its now a 32 byte lookup table. If I run into a wall I might even implement that and then start testing with randomly generated seeds / keys.
Here's a heatmap from chatGPT showing the key nibble 2 results from 00 00 00 00 to 00 FF 00 00:
Re: BA Falcon BEM EEPROM via CAN
Posted: Mon Apr 21, 2025 12:21 pm
by antus
I reckon you'll find there is another salt in there, like an and or xor with a 3F or some other value.