Author Topic: Autoliv NV3 unlock  (Read 4619 times)

0 Members and 1 Guest are viewing this topic.

Offline tmbincTopic starter

  • Frequent Contributor
  • **
  • Posts: 250
Autoliv NV3 unlock
« on: March 24, 2023, 09:57:03 pm »
I know there is the wonderful OpenIRV project, and it's way more impressive than anything I've ever done.

However, given the difficulty in getting parts, it may not be entirely unreasonable to try doing something with the stock hardware (Altera FPGA). Contrary to the NV2 though, the NV3 uses a more complicated physical layer (MAX9259's "Gigabit Multimedia Serial Link" with a ~650 MHz 8B10B signal, including bidirectional communication), and the MAX9260 (deserializer) was pretty hard to get, and there was little chance of implementing it in an FPGA. So I've never really looked at it.

This all changed when somebody sent me a Flash image of the ECU (thanks again, so much!). I was blindly disassembling around when I found an HMAC-MD5 function, the same one that was used for the NV2 authentication (remember, to enable the NV2, you need to do a security challenge; it involves receiving a seed, and responding with a HMAC of that). The key was "obfuscated" with a XOR table, and after un-XORing, I received a warm hello from Johan and Lennie!

I've traced around and, while I couldn't make much sense of the code, I saw that it sends a command of "65" to read a serial number, a command "42" to receive a seed, and "41" to send back the HMAC. From the functions, it looks exactly like the auth protocol on NV2, except it doesn't seem to involve CAN. (Remember, the NV2 camera had a CAN-Link plus the LVDS downstream link; the NV3 only has the LVDS link, but with the ability for low-speed bidirectional communication).

I've guessed around and though that they probably use UART mode (the MAX9259/9260 can tunnel UART and I2C over the LVDS link), and simply injected some characters on pin 36 of the MAX9259 (there's a 50 Ohm resistor conveniently placed so you can override the MAX9259 TX signal). And, after sending a bunch of random data, I received a message on pin 35 at 115200 baud: "70 05 00 00 00 00 66 CB 00 00".

I could send that message back and would get a "70 04 00 00 00 00 CC 9A 00 00 ". Changing any bit gives the "70 05" message, but replaying either of the received messages gives the "70 04" message. 66CB / CC9A seemed to be some kind of CRC so this behavior makes sense: These two messages have a correct CRC, but are likely otherwise invalid (when sent to the camera), so they return 70 05, likely "invalid message structure". Everything else results in 70 04, "invalid CRC". Being a bit creative, I found that Xmodem_CRC16(70 04 00 00 00 00 ) == 0xcc9a. That still didn't explain the trailing "00 00", but allows me to craft other messages that are not rejected for their CRC. Still, most everything got me "70 04". However, by brute-forcing (i.e. sending random data), I finally got some other looking responses whenever I start with "6E". Sending "6e0000650000af200000" for example would return in "700000650008b40f00112fda00112fda06e1", and - behold - I previously identified command "65" as "read serial number". It also shows a bit more structure of the messagees:

bytes 0..3: command
bytes 4..5: length
bytes 6..7: crc16 of the first 6 bytes
bytes 8..n: data
bytes n..n+2: crc(data)

This was promising. By sending "6e0000420000ac760000" (42 - "Read Seed") it would return "70000042001024605dc17d9dd786bebdf1a2e14300112fda704e" (16 bytes of random data! as expected!), and now I could apply the HMAC(key, seed) and send that back with command "41". Doing that with incorrect data returns "ffff" (=failed), but doing it with the right HMAC returns "0001", and the shutter clicks and the camera consumes (a bit) more current! Just as for the NV2!

I still can't receive the pixel data, but I'm sure if I had a MAX9260, it would deserialize it just fine. I could probe one of the higher bit parallel data pins, see a line being transmitted, and if I would put my finger in front of the lens (so creating "left cold, right warm" image) I would see the appropriate digital response on the scope!

In an act second to Icarus, I continued to brute-force commands, and eventually bricked the camera, likely by sending some command that would erase the flash. Meh. (But I have a backup of the flash somwhere.). So be aware!


import serial, crcmod, os, hmac, hashlib

xmodem_crc_func = crcmod.mkCrcFun(0x11021, rev=False, initCrc=0x0000, xorOut=0x0000)

s = serial.Serial("/dev/ttyUSB0", 115200, timeout=0.01)

def check_crc(buf):
    len = 6
    assert xmodem_crc_func(buf[:len]) == int.from_bytes(buf[len : len + 2], "big")
    datalen = buf[5]
    assert xmodem_crc_func(buf[8 : 8 + datalen]) == int.from_bytes(
        buf[8 + datalen : 8 + datalen + 2], "big"
    )

def cap(x, data):
    assert len(x) == 4
    x += len(data).to_bytes(2, "big")
    return (
        x
        + xmodem_crc_func(x).to_bytes(2, "big")
        + data
        + xmodem_crc_func(data).to_bytes(2, "big")
    )


def cmd(x, data=b""):
    w = cap(x, data)
    check_crc(w)

    s.write(w)
    r = s.read(100)
    check_crc(r)

    if r[:2] == bytes([0x70, 0x4]):
        print(" (CRC wrong)")

    datalen = int.from_bytes(r[4:6], "big")
    return r[:6], r[8 : 8 + datalen]


_, seed = cmd(bytes([0x6E, 0, 0, 0x42]))

key = <you know the key>
res = hmac.new(key, seed, digestmod=hashlib.md5).digest()

a, b = cmd(bytes([0x6E, 0, 0, 0x41]), res)
assert b == bytes([0, 1]), "unlock failed"

 
The following users thanked this post: oPossum, railrun, newex, Denis_K, horstmannhid, hoplite, radziorr

Offline railrun

  • Regular Contributor
  • *
  • Posts: 113
Re: Autoliv NV3 unlock
« Reply #1 on: March 24, 2023, 10:31:14 pm »
This all changed when somebody sent me a Flash image of the ECU (thanks again, so much!).

No problem  ;)
I will try to upload some pictures from the ECU
 
The following users thanked this post: newex, Denis_K

Offline newex

  • Contributor
  • Posts: 23
  • Country: 00
Re: Autoliv NV3 unlock
« Reply #2 on: April 02, 2023, 09:12:06 pm »
Excellent work! How did you connect to communicate with the camera? I can't get any response from the uart MAX 9259.
 

Offline tmbincTopic starter

  • Frequent Contributor
  • **
  • Posts: 250
Re: Autoliv NV3 unlock
« Reply #3 on: April 06, 2023, 11:17:27 am »
MAX9259 has two pins, pin 35 (RX) and pin 36 (TX).

RX is input to MAX9259, so FPGA's UART TX. That signal you can just tap.

TX is output from MAX9259, but there's a series resistor to the FPGA, which means you can conveniently tap it after the resistor (i.e. directly to the FPGA side).

Then it's just a normal UART (I forgot the exact voltage) and the script below should work. If not, scope and see what's happening.
 
The following users thanked this post: newex

Offline mzg2000

  • Newbie
  • Posts: 2
  • Country: cn
Re: Autoliv NV3 unlock
« Reply #4 on: May 29, 2023, 01:37:42 pm »
how to find the key? We know that using data2mem to find the key from microblaze bin code. But to NV3, it is the FPGA from Intel, which tool could be used to do that thing?
 

Offline mzg2000

  • Newbie
  • Posts: 2
  • Country: cn
Re: Autoliv NV3 unlock
« Reply #5 on: June 08, 2023, 02:43:20 pm »
Got the flash ROM from the nv3, then using python cpu_rec.py nv3.bin, it tells that:
nv3.bin           full(0x800000) None           chunk(0xbc800;377)  6502

why 6502, i guess that should be nios or nios2.
then what is the next step?
 

Offline boywai

  • Contributor
  • Posts: 14
  • Country: us
Re: Autoliv NV3 unlock
« Reply #6 on: August 04, 2023, 02:43:33 am »
I know someone who made his password public
 

Offline tmbincTopic starter

  • Frequent Contributor
  • **
  • Posts: 250
Re: Autoliv NV3 unlock
« Reply #7 on: August 08, 2023, 01:40:30 pm »
a.) The password can be found on this forum. In fact, it can be found in this very thread if you look carefully and connect the dots.

b.) The (what I assume is) NIOS code is encrypted in flash. It can likely be dumped via the debug commands, but as mentioned, I accidentally hit a "erase flash" command so I'm unwilling to retry this at the moment. If you do - backup your SPI flash before.
 

Offline BertoldVdb

  • Newbie
  • Posts: 2
  • Country: be
Re: Autoliv NV3 unlock
« Reply #8 on: September 02, 2023, 03:30:49 pm »
Interesting, note that the serial protocol you have identified is the same one as used in (amongst others) the FLIR Tau2. Maybe other Tau2 commands work as-is, after unlock? Command 0xD4 would be erase flash. Also 0x65 matches 'return serial number'.
« Last Edit: September 02, 2023, 03:50:20 pm by BertoldVdb »
 
The following users thanked this post: oPossum, tmbinc

Offline tmbincTopic starter

  • Frequent Contributor
  • **
  • Posts: 250
Re: Autoliv NV3 unlock
« Reply #9 on: September 06, 2023, 05:22:08 pm »
Interesting, note that the serial protocol you have identified is the same one as used in (amongst others) the FLIR Tau2. Maybe other Tau2 commands work as-is, after unlock? Command 0xD4 would be erase flash. Also 0x65 matches 'return serial number'.
Oooh, what a nice find!

This was the list of commands that I found to exist, annotated with what they are from the Tau 2 IDD:


00 0001 // NO_OP
02 // CAMERA_RESET
05 // GET_REVISION, returns 0e0b002f0a02005e
0a // GAIN_MODE
0b // FEC_MODE_SELECT
0c 0001 // DO_FCC
11 // VIDEO_ORIENTATION
12 // DIGITAL_OUTPUT_MODE
1e // LENS_NUMBER
20 fffc // READ_SENSOR
25 // TEST_PATTERN
29 // ??
2e fffe // ?? returns fffe
3c // FFC_WARN_TIME
3d 0001 // ??
41 // ?? returns deaddeaddeaddeaddead
42 // (we know it's GET_SEED)
60 // ?? 53439333234303136430000000000000000000000000000000000000000000000
65 // SERIAL_NUMBER
66 // CAMERA_PART, returns 3439333234303136430000000000000000000000000000000000000000000000
74 // ??
79 0001 // SHUTTER_POSITION
82 // TRANSFER_FRAME
85 // ??
87 // ??
a8 // ??
b1 // CORRECTION_MASK
b2 // ??
c0 // ??
c3 // ??
c4 // MEMORY_STATUS
d2 // READ_MEMORY
d3 // ??
d4 // ERASE_MEMORY_BLOCK (oops)
d5 01fe000000010000 // GET_NV_MEMORY_SIZE


This now makes me think about the NV2 again. Any idea which "off-the-shelf" camera that resembles? I vaguely remember the NV2 also having a serial protocol that I never used (because I used CAN).
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf