template and source for hardware projects
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
King Kévin 8ea411fd8a doc: added custom EDID programming 4 months ago
kicad lib: add QR url 6 months ago
library@00e9790a22 lib: update repo 4 months ago
picture doc: add v2 pictures 4 months ago
.gitignore ignore kicad temp 6 months ago
.gitmodules update library 9 months ago
.qeda.yaml lib: add dip switch 6 months ago
CHANGELOG.md doc: add v2 changes 5 months ago
DEVELOPMENT.md doc: update development to makefile 6 months ago
JLCPCB_CORRECTION.csv doc: fix part position 4 months ago
LICENSE.txt add CERN-OHL-S license 1 year ago
Makefile make: make panel fab faster 5 months ago
README.md doc: added custom EDID programming 4 months ago
bom.ini switch to KiCAD 6 months ago
fp-lib-table lib: add QR url 6 months ago
hdmi_firewall.kicad_pcb brd: tune length matching 5 months ago
hdmi_firewall.kicad_pro brd: re-fix pad ground keepout 5 months ago
hdmi_firewall.kicad_sch sch: fix HDMI position 5 months ago
refdes2fab.py switch to KiCAD 6 months ago
sym-lib-table switch to KiCAD 6 months ago
version switch to version 2 6 months ago

README.md

The HDMI firewall prevents devices from hacking HDMI equipment, and vice-versa.

purpose

HDMI is mainly used to transfer audio and video, but also offers a number of additional features (e.g. HDCP, CEC, HEC, ARC, MHL). This increases the attack surface, and since the security of their implement in embedded devices is far from ideal, an attacker could exploit them and inject malicious code. Now your unsuspicious video equipment is compromised and threatens your IT/network security. And your monitor could then in turn hack back any other device connected to it.

For example, let's imagine you invite an external guest for a presentation inside your company. You offer to connect to a smart TV or video-projector so he can show his slides. This is the perfect opportunity for the guest to hack it. Now your smart TV can act as a spy in your network. Or next time an employee connects to the projector, his laptop is hacked back. And voila, the innocent guest managed to infiltrate your company network, and can exfiltrate confidential information.

The HDMI firewall can block all additional interfaces, and only allow audio and video data transfer. It is based on the research of Pierre-Michel Ricordel and José Lopes Esteves from ANSSI/SDE/ST/LSF presented at the IT security conference SSTIC 2021. Some security research and vulnerabilities around CEC and EDID are listed in slide 4.

usage

First plug the HDMI cable going to the monitor on the HDMI firewall on the port labeled MONITOR. Then plug the HDMI cable going to the device on the HDMI firewall on the port labeled DEVICE. That's it, your equipment (monitor and device) are now protected. But the firewall should be fine tuned as described below.

The HDMI firewall comes with a generic HD profile, but this might not correspond to the capabilities of your monitor. The resulting image could be distorted, or completely missing. Thus, you first have to copy the Extended Display Identification Data (EDID) information of the equipment to protect. This data includes information such as the supported resolutions. The HDMI firewall can copy the EDID from the monitor:

  1. ensure the firewall is connected to the monitor
  2. unplug the device from the firewall
  3. toggle the small switch labeled EDID/7 to the ALLOW/ON position
  4. ensure the SDA/2 and SCL/3 switches are on the BLOCK/OFF position
  5. plug the device to the firewall
  6. this will power the firewall, which will copy the monitor EDID onto its internal memory, shown by a short blink of the ERROR LED
  7. unplug the device, and switch back the EDID/7 switch to the BLOCK/OFF position so the firewall keeps and uses the copied EDID information
  8. when connecting the device back in, you should see the same name as the monitor, with a '|' at the end, indicating you are using the EDID from the firewall

The HDMI firewall allows to select which interfaces are blocked using the switches. The highest security is provided when blocking all lines by setting the switches to the BLOCK position. If you still trust your equipment enough and want to use a feature, you can set the corresponding switch to the ALLOW/ON position:

  • 5V: some monitors require this line to detect when a device is plugged in, and since currently no other information is transferred over this line, it is rather safe to enable it
  • Display Data Channel (DDC): High-bandwidth Digital Content Protection (HDCP) uses this interface. To enable it, switch SDA and SCL on. Warning: since the EDID is also transferred over this interface, the firewall can't provide a write-protected copy of it. Instead the original monitor EDID is used, maybe not write-protected.
  • Consumer Electronics Control (CEC): this interface allows to remotely control equipment, such as setting the volume and powering on/off all connected devices and monitors at once
  • HDMI Ethernet Channel (HEC), Audio Return Channel (ARC), and Mobile High-Definition Link (MHL): to enable these interfaces, switch UTIL and HPD on to forward the HEAC+ and HEAC- lines

The HDMI firewall can also be used to provide custom EDID, as it sometimes is faulty in the monitor. For that you need to program the raw binary EDID (with up to 1 extension block) onto the STM8S103 EEPROM using the RST and SWIM lines made available on the back of the board.

limitations

The HDMI firewall use impedance controlled lines: 4-layer impedance controlled board, differential pair routing, intra- and inter-pair length matching. This should allow and audio any video signal to be transmitted to the monitor. But I only have 2K equipment I could test it on. I could not test the firewall against 4K, 8K, or 3D capable monitors. CEC remote control has been tested. But I don't have any equipment using HDCP, HEC, ARC, or MHL. Thus I could also not test these interfaces.

The firewall only supports EDID with up to 1 extension block. This is the case for all monitors I've seen. Some high end monitors supporting numerous features might have additional extensions blocks. Thus the firewall might prevent from using the monitor to its full potential. You can still use the original EDID from the monitor by setting the SDA/2 and SCL/3 switches to the ALLOW/ON position. The DDC channel won't be firewalled anymore though.

Feel free to report any success or issues to hdmi@cuvoodoo.info.

availability

The HDMI firewall is available on tindie.

The schematic pdf and board gerbers are available as release.

firmware

The firmware and sources for the HDMI firewall embedded programmer are available here.

troubleshooting

If the monitor does not detect the device or does not display anything (but should), try to re-enable the 5V forward (as per default) by switching the 5V/1 switch to ALLOW/ON.

If the ERROR LED stays on, it means copying the EDID failed:

  • be sure the monitor is connected before you connect the device (which powers the firewall)
  • be sure the SDA/2 and SCL/3 switches are set to BLOCK so the firewall can use the DDC interface to read the EDID
  • the EDID of the monitor might be corrupted or have an invalid checksum, in which case the firewall will not copy it
  • the firewall EEPROM memory has worn out or is defective (it should last 300 thousand copies)

custom EDID

It is possible to write custom EDID on the HDMI firewall, for example because:

  • the monitor's original EDID is corrupted
  • you want to disable a feature or resolution causing your device to misbehave
  • you want to re-enable a feature the monitor actually supports
  • the KVM switch does not reflect the HDMI monitor change
  • you want to do security research

For that you can use the debugging pins left on the board, and program the raw EDID in the STM8S EEPROM area using an ST-LINK/V2 programmer.

If you switch EDID to the ALLOW position, the HDMI firewall's EEPROM is not write-protected (on devices shipped after 2022-08-19). This allows to use the HDMI connection to write the EEPROM content using the DDC's I²C bus, and does not required an external programmer.

These instructions are for Linux. For Windows see the instructions provided in the original research slides (untested).

Install tools to read/write I²C devices:

  • for Debian-based distributions
sudo apt install i2c-tools

Make the I²C buses user accessible (under /dev/i2c-*):

sudo modprobe i2c-dev

Now we have to figure out which I²C bus corresponds to the HDMI port. First list the available buses:

sudo i2cdetect -l

You should see something like this:

i2c-0	smbus     	SMBus PIIX4 adapter port 0 at 0b00	SMBus adapter
i2c-1	smbus     	SMBus PIIX4 adapter port 2 at 0b00	SMBus adapter
i2c-2	smbus     	SMBus PIIX4 adapter port 1 at 0b20	SMBus adapter
i2c-3	i2c       	AMDGPU DM i2c hw bus 0          	I2C adapter
i2c-4	i2c       	AMDGPU DM i2c hw bus 1          	I2C adapter
i2c-5	i2c       	AMDGPU DM i2c hw bus 2          	I2C adapter
i2c-6	i2c       	AMDGPU DM i2c hw bus 3          	I2C adapter
i2c-7	i2c       	AMDGPU DM aux hw bus 0          	I2C adapter
i2c-8	i2c       	AMDGPU DM aux hw bus 2          	I2C adapter
i2c-9	i2c       	AMDGPU DM aux hw bus 3          	I2C adapter
i2c-10	i2c       	DPMST                           	I2C adapter
i2c-11	i2c       	DPMST                           	I2C adapter

Candidate buses are 3 to 9, used by the GPU (number after i2c- in the first column).

Disconnect everything from the HDMI port, and scan for devices on each I²C bus (replace BUS with the bus number):

sudo i2cdetect -y BUS

Since nothing is connected, no device should be detected, and the output should look like this:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Now connect the HDMI firewall on the device side to your HDMI port and re-scan for devices. If you see the following result, you found the I²C bus of the HDMI port. Else continue with the next bus.

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Write your custom EDID data edid.bin to the HDMI firewall (replace BUS with corresponding bus number):

for addr in `seq 0 255`; do echo $addr; sudo i2cset -y BUS 0x50 $addr 0x`xxd -p -l 1 -s $addr edid.bin`; done

To verify the data has been written correctly, compare original data with the one on the EEPROM:

# display original dumped data
xxd -g 1 edid.bin
# display data written on EEPROM
sudo i2cdump -y BUS 0x50

Once writing the EDID to the HDMI firewall memory succeeded:

  • re-enable write protection by toggling the EDID switch to the BLOCK position
  • re-plug the HDMI firewall for the device to retrieve the newly written EDID

To read and play with EDID under Linux, you can use the tips provided for the previous HDMI firewall v1.