bluray-drive-bricked-dark

I buy a lot of DVDs and Blu Ray discs, but I very rarely watch them straight from the disc. As soon as I get a new one, it gets ripped to my MythTV backend, from where I can watch it at any time and on any screen in the house. Until recently, I’ve been happily doing this using MakeMKV and a Plextor USB Blu Ray drive, but unfortunately it seems that the film industry thinks the best way to reward me for buying so many is to brick my drive.

Blu Ray discs are encrypted, and to read one the player (or ripper) software has to pass a key to the drive. The drive then uses the key to decrypt the data. However, these decryption keys can be revoked, and once they’ve been revoked the drives will refuse to use them to decrypt any data, even data from old discs that they’ve been happily decoding in the past.

The drives get to know about the revocation because the Blu Ray discs that they play contain revocation lists. When you buy a new disc it may contain a newer version of the revocation list, and as soon as it’s inserted into the drive, the drive will update its internal revocation list… permanently!

This is what happened to my drive… I bought a copy of Robert Rodriguez’ Machete Kills, dropped it into my drive and clicked the button to rip it, only to get an error message telling me that the host key was invalid. This isn’t the first time this has happened, whoever it is that maintains MakeMKV does a good job of acquiring new keys, so usually it’s just a five minute job to download a new version, and then off we go again.

Unfortunately this time the new version needed a newer version of libc, which meant upgrading my MythTV backend, which meant upgrading all of the MythTV frontends in the house too, and that’s a whole lot of effort that I could really do without, and which made me wonder… maybe it might be easier to make the drive forget about the new revocation list. It must be stored in some non-volatile memory somewhere in the drive. All I needed to do was find it and somehow revert it back to the previous version, how hard could it be?

Drive Internals

Inside The Drive

Inside The Drive

So… out came the screwdriver and the four little screws that were hiding under the drive’s feet, and off came the cover.

There’s surprisingly little to be found inside the drive. Other than the motors and mechanical stuff, there’s one main board with a handful of chips on it and a tiny satellite board that just holds two buttons and an LED.

The main board is populated on both sides and contains the following chips:

Manufacturer Part # Description
Sunext SC6300B3 Multi-format optical disc controller
Texas Instruments TPIC1391 ?
Texas Instruments TPIC1356 ?
Prolific PL2571 USB to SATA bridge (datasheet)
PMC Pm25LV512 512Kbit Flash (datasheet)
Macronix 25L8005 8Mbit Flash (datasheet)

So, from the chips on the board there were four potential places where the host revocation list could be stored:

  1. In the 512Kbit flash
  2. In the 8Mbit flash
  3. In one of the two undocumented Texas Instruments chips
  4. In some storage internal to the main Sunext chip

With the Sunext chip and the Texas Instruments chips appearing to have no documentation available anywhere on the Internet, the flash chips were the obvious starting point.

On the board the smaller flash chip is right next to the main Sunext chip and the larger flash is right next to the USB to SATA bridge, but a look at the datasheet for the USB to SATA bridge showed that it only needs a tiny amount of flash to store the vendor IDs and other stuff needed for USB device enumeration. This was confirmed by following the traces on the board, with the traces from both chips going through vias to the other side of the board.

So now the 8Mbit flash was the prime candidate.

Dumping The Flash

bluray-drive-spi-traces-cut

SPI Traces Cut

The flash chips use an SPI serial interface, so I could use my BusPirate to talk to them, but to dump the contents of the flash you have to find a way to get exclusive access to the signals, you can’t just attach some probes while they’re in circuit and start reading because the CPU on the board will interfere and you won’t get any sensible results.

If I had a hot air soldering station the easiest option would probably have been to de-solder the flash chip, but I don’t, so after a half-hearted attempt at de-soldering the chip with an iron, I took the next easiest option and cut the traces to the CS (Chip Select), SI (Serial In), SO (Serial Out) and CLK (Clock) pins. As long as the traces are cut with a thin and sharp blade then they can be reinstated very easily with solder bridges.

BusPirate Connected

BusPirate Connected

With the flash chip isolated, I connected the BusPirate, started minicom and powered up the board. I set the BusPirate to SPI mode with all default settings except for voltage (normal rather than open collector) and speed (a conservative 250KHz), and tried a read request, which as can be seen below, successfully read the first few bytes from the chip:

SPI> [0x03 0x00 0x00 0x00 r:8]
/CS ENABLED
WRITE: 0x03
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
READ: 0x58 0xF0 0x9F 0xE5 0x7E 0x00 0xA0 0xE3

Next, I needed to dump the entire contents of the chip, but I couldn’t really do that through the BusPirate’s interactive serial console. A quick Google found flashrom, which is a utility for reading and writing flash that lists the BusPirate as a supported programming device. After downloading and building the flashrom source, one quick command got me the entire 1MB contents of the chip:

flashrom -p buspirate_spi:dev=/dev/ttyACM0,spispeed=1M -r test.dump

Finding The Revocation List

Found It!

Found It!

With the contents of the flash successfully extracted, I needed to find out what the revocation list might look like. Time for Google again… where the second result for “blu ray host revocation list format” was a handy looking PDF titled “Advanced Access Content System (AACS) – Introduction and Common Cryptographic Elements“. Then searching within the PDF for “host revocation” immediately found a Table of Contents entry for “Updating Host Revocation List in Non-volatile Memory of Drive” and a List of Tables entry for “Host Revocation List Record” and “Host Revocation List Entry”. Perfect!

From reading this document I discovered that the host revocation list is held within a Media Key Block (MKB), and that the MKB starts with a Type and Version Record, which starts with the bytes 0x10 0x00 0x00 0x00 0x0C. 0x10 is the record type identifier and 0x00 0x00 0x00 0x0C is the length of the record.

Searching the flash dump for this byte string found exactly one occurrence at offset 0×5000, and using the document to decode the following data revealed that, yes, this is the host revocation list!

The document also revealed that drives are required to store up to 32KB of data for the revocation list, and looking at the data in the flash I could see that the list was followed by all zeros until offset 0xD000, or exactly 32KB from the start of the revocation list. This last bit was important as it meant that there probably wasn’t a length stored somewhere else in the flash that would need to be updated, and that I could probably just write over the revocation list and make no other changes.

Replacing The Revocation List

Revocation List Diff

Revocation List Diff

Having found the bad revocation list, my next task was to work out what I could replace it with. Where could I get a good version of the revocation list that didn’t lock out the key that my copy of MakeMKV was using?

The bad version was delivered by the Machete Kills disc… older discs must also have revocation lists… lists that don’t revoke the key I’m using.

It turned out that MakeMKV made the next bit particularly easy, it keeps a copy of any new MKB version that it comes across:

mythtv$ ls -l .MakeMKV
...
-rw-r--r-- 1 root    root       15101 2013-12-02 18:52 MKB_v42_ALAN_PARTRIDGE_ALPHA_PAPA.tgz
-rw-r--r-- 1 root    root       14933 2014-06-28 22:47 MKB_v46_MACHETE_KILLS.tgz
...

Unpacking these files and running a diff on the contents revealed that the revocation lists were exactly the same length and only had he following differences:

  1. The version number had increased from 42 (0x2A) to 46 (0x2E)
  2. The last revocation list entry had changed
  3. The signature at the end had changed

So, I used the old version of the revocation list from the Alan Partridge disc to overwrite the data in the flash dump, resulting in the diff shown in the image above. I then used flashrom to write the changes back to the chip:

echo "5000:d000 hostrev" > layout
flashrom -p buspirate_spi:dev=/dev/ttyACM0,spispeed=1M --layout=layout --image=hostrev -w test.dump

Putting It Back Together

SPI Traces Reinstated

SPI Traces Reinstated

With the changes written back and verified, I reinstated the cut tracks to reconnect the flash chip to the controller.

Using some Kapton tape as a solder mask, it just took a single wipe of the iron to reinstate each track. Or at least that’s what I thought, but after testing the continuity, screwing the drive back together and applying power… nothing.

Luckily it was just a bad bridge on one track, after taking it apart again and rechecking the continuity I was able to fix it and this time, when I put it back together, it lit up and wiggled the read head like it should.

It Works!

bluray-drive-working

As the screenshot above shows, it works!

From start to finish I think it took four or five hours, so definitely faster than upgrading all of my MythTV machines, and of course it was interesting, rather than mind numbingly boring.

It’s only a temporary fix, I now need to make sure I don’t put a new disc in the drive. I was hoping for a while that I’d be able to write protect the flash and block the drive from ever updating the revocation list again, it has a physical write protect pin, but unfortunately the pin only protects the status register, which needs configuring via SPI commands to write protect the main data.

Any write protection will need a software element, which will mean changing the firmware, and right now I don’t even know what architecture the controller uses, ARM?, MIPS?, no idea!

It’s good enough for now though, I can at least start to clear the backlog of older discs waiting to be ripped.

21 Thoughts on “Un-Bricking A Blu Ray Drive

  1. Pingback: Unbricking a BluRay Drive

  2. Pingback: Unbricking a BluRay Drive - RaspberryPiBoards

  3. Amaterasu on September 9, 2014 at 2:09 am said:

    You can very likely just cut the trace to the WP pin on the flash device and tie them high to prevent the revocation list from being written! (assuming nothing else is being stored by the drive on a regular basis like calibration data to offset mechanical wear.)

    • That was my first thought when I saw that there was a WP pin. Unfortunately, after reading the datasheet it looks like the WP pin only write protects the status register. To protect the stored data you have to set a few bits in the status register and then toggle the WP pin.

      I don’t think the status register is non-volatile, so I don’t think I can just do it once and then permanently tie the WP pin in the protected state.

  4. Pingback: Unbricking a BluRay Drive - Tech key | Techzone | Tech data

  5. Brenton Roskopf on September 9, 2014 at 3:09 am said:

    Nice! Down with DRM… Depending on the software that writes the flash, perhaps one could set the version number to 0xFF and change nothing else to inform the drive that it should NOT update the revocation lists any further (assuming of course that the list is not cryptographically signed).

    • Nice idea, but they’ve thought of that one. The revocation list is signed so changing the version number would require the signature to be updated.

      We just need their signing key to get leaked and then I’m pretty sure this would work.

    • Thinking about it a bit more… I wonder if the drive checks the signature of the revocation list stored in its flash?

      It will (or would be really stupid not to) check the signature of the revocation list on a disc before it uses it to replace its internal list, but once it’s stored internally, would it bother to check it again, why would it bother?

      Hmm… I might have to give this a go.

      • I’ve just given this a quick try, but it looks like it’s more complicated.

        I now have version 42 of the revocation list in the drive’s flash, but with the version set to 0xFFFFFF. This is working OK and decrypting old discs.

        However MakeMKV is reporting that the drive is still using version 46 of AACS. So it must have the current version stored somewhere else in addition to the header of the revocation list itself. I suspect that if a disc with a version greater than 46 is inserted then it’ll replace the revocation list in the flash.

        Of course there are a lot of 46′s in the flash, so it’s not obvious where it’s stored. I’ll revisit again when I’ve got more time.

  6. Well done!

    Just one thought: What if you set the version number to 0xFF?

    Will the firmware see that any new disks after that have an ‘older’ revocation file and thus not update?

    • See my replies to Brenton above, the revocation list is signed, so this should be protected against, but I might get lucky if the drive trusts its internal copy and doesn’t check the signature.

  7. Pingback: Unbricking a BluRay Drive | Hack The Planet

  8. Is there a way to fill up the flash revocation with bogus revocation information so it has no way of adding anything more?

    • Unfortunately, I suspect not. It looks like it doesn’t add to it’s internal revocation list, instead it just replaces the whole list with the new one from the disc. So even if I filled it up it could still just overwrite it all.

      • DaVolfman on September 9, 2014 at 2:45 pm said:

        It’s pretty simple: you rig the election. Make sure to give your list a version number that’s absurdly high so that it is always the “newest” list. SAMBA does something similar when you tell it to be the browse-master in a workgroup, labeling itself as windows version 40 or something like that so only uptime between ‘nix boxes factors in the election. Still might not help you if that list is signed and the signature actually checked from flash.

  9. Perry Harrington on September 9, 2014 at 6:29 am said:

    I would make a microcontroller board that went in place of the flash. You could easily do this with a Parallax Propeller, having it emulate an SPI flash.

    You could upload the contents of the revocation list to the EEPROM the prop uses, then load the 32K into system ram once booted. A single core PASM program could handle pretending to be an SPI flash chip. You would simply not allow updates to the EEPROM. There might be a validation routine that checks for a properly updated MKB, so you could write to system ram, do the validation, then reload the RAM from EEPROM and continue serving the old revocation list.

    You might consider a zero length revocation list :-)

    • Yeah, that could work, though it would need to be able to pass through all the other data that’s stored in the flash chip. All of the firmware for the drive appears to be in the same chip, and a surprisingly large amount of the 1MB of storage is in use.

      I had thought about using a Xilinx CoolRunner CPLD that I’ve got lying around to filter the SPI commands. It could block the write enable command that has to be issued before any writes can succeed.

  10. Pusalieth on September 21, 2014 at 5:24 pm said:

    To make the list permanent just check to see if the chip goes high to write to the flash, and put a smd resistor in between, otherwise modify the list on the flash to think its version 100 or something so when the chip does a check to see if its the newest your version will always be higher.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation