Autoliv NV3 unlock - Page 1
Forum section: electronics / general

author: tmbinc
author_rank: Frequent Contributor
timestamp: March 24, 2023, 09:57:03 pm
content: 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: commandbytes 4..5: lengthbytes 6..7: crc16 of the first 6 bytesbytes 8..n: databytes 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, hashlibxmodem_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 = 6assert xmodem_crc_func(buf[:len]) == int.from_bytes(buf[len : len + 2], "big")datalen = bufassert xmodem_crc_func(buf[8 : 8 + datalen]) == int.from_bytes(buf[8 + datalen : 8 + datalen + 2], "big")def cap(x, data):assert len(x) == 4x += 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"

author: railrun
author_rank: Regular Contributor
timestamp: March 24, 2023, 10:31:14 pm
content: Quote from: tmbinc on March 24, 2023, 09:57:03 pmNo problemI will try to upload some pictures from the ECU

author: newex
author_rank: Contributor
timestamp: April 02, 2023, 09:12:06 pm
content: Excellent work! How did you connect to communicate with the camera? I can't get any response from the uart MAX 9259.

author: tmbinc
author_rank: Frequent Contributor
timestamp: April 06, 2023, 11:17:27 am
content: 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.

author: mzg2000
author_rank: Newbie
timestamp: May 29, 2023, 01:37:42 pm
content: 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?

author: mzg2000
author_rank: Newbie
timestamp: June 08, 2023, 02:43:20 pm
content: 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) 6502why 6502, i guess that should be nios or nios2.then what is the next step?

author: boywai
author_rank: Contributor
timestamp: August 04, 2023, 02:43:33 am
content: I know someone who made his password public

author: tmbinc
author_rank: Frequent Contributor
timestamp: August 08, 2023, 01:40:30 pm
content: 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.

author: BertoldVdb
author_rank: Newbie
timestamp: September 02, 2023, 03:30:49 pm
content: 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'.

author: tmbinc
author_rank: Frequent Contributor
timestamp: September 06, 2023, 05:22:08 pm
content: Quote from: BertoldVdb on September 02, 2023, 03:30:49 pmOooh, 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_OP02 // CAMERA_RESET05 // GET_REVISION, returns 0e0b002f0a02005e0a // GAIN_MODE0b // FEC_MODE_SELECT0c 0001 // DO_FCC11 // VIDEO_ORIENTATION12 // DIGITAL_OUTPUT_MODE1e // LENS_NUMBER20 fffc // READ_SENSOR25 // TEST_PATTERN29 // ??2e fffe // ?? returns fffe3c // FFC_WARN_TIME3d 0001 // ??41 // ?? returns deaddeaddeaddeaddead42 // (we know it's GET_SEED)60 // ?? 5343933323430313643000000000000000000000000000000000000000000000065 // SERIAL_NUMBER66 // CAMERA_PART, returns 343933323430313643000000000000000000000000000000000000000000000074 // ??79 0001 // SHUTTER_POSITION82 // TRANSFER_FRAME85 // ??87 // ??a8 // ??b1 // CORRECTION_MASKb2 // ??c0 // ??c3 // ??c4 // MEMORY_STATUSd2 // READ_MEMORYd3 // ??d4 // ERASE_MEMORY_BLOCK (oops)d5 01fe000000010000 // GET_NV_MEMORY_SIZEThis 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).

author: isuzulake
author_rank: Contributor
timestamp: January 25, 2025, 03:09:04 am
content: unlock success！thank you！

author: isuzulake
author_rank: Contributor
timestamp: February 01, 2025, 07:47:26 am
content: https://youtu.be/9NZ6o4KDZVsI have a zynq board,and next step?

author: Mach
author_rank: Newbie
timestamp: August 13, 2025, 07:39:00 pm
content: Hello,i've not been sure if id post here, or start a new one - but it is linked to Autoliv NV3 afterall, so here we go.My portion of the Autoliv NV3 attempt is linked to install it into a vehicle that does not support it, but shares same platform and CAN/LIN/Flexray network as the supported vehicle.With help and hints of Railrun and Tmbinc i successfuly pulled off module unlock, platform ID removal, image transmission lockout removal. Component protection was done per regular way via the online diagnostics. The latter actually limits me to run it on the bench, as without master IMMO, component protection is automatically triggered. A combination of masking data of 10 bytes could most likely lift it, but the amount of combinations for it, is insane.So, long story short, im stil working on instrument cluster memory dump, as i dont get video feed displayed (i do get warnings, limitations, etc..). From the dumps i've seen, it could be linked with Vsync bits enabling. What i do have however, is video feed via composite signal NTSC/PAL from module, SIG+ and shield, that would otherwise be fed to cluster. Can be fed to any screen basically, that supports it.-image can be launched-adaptations/configurations/calibrations/output tests...basically everythingIt appears though, that sensor/module resolution is not at best with shaking hands with any screen i have...i can configure vertical aim via:-vehicle coding (shifts position vertically, and very slightly to left, dependant of the vehicle variant - or with other words, cluster variant)-Adaptation value Position of picture section (vertical) - this elevates or lowers position by about +/- 5 mm on screenAny idea how to laterally center, or ideally widen the image? Since i dont have ideal portion of area in the car for extra screen, im aiming at 5, 6 - perhaps 7" at most (and anything in between).Since im not that much electronically inclined im pretty sure you guys would have more knowledge of options on how to solve it (digital or analog)..Video output is analog, 2 pins: signal and shield (they call it as sig+ and sig-), can be fed to RCA, 2.5 mm jack,...Regards, M