template and source for hardware projects
Go to file
King Kévin 162f540837 doc: add v1 changes 2022-06-20 13:30:26 +02:00
coraleda/subc lib: add HDMI plug 2022-06-20 12:33:11 +02:00
geda/symbols lib: add HDMI plug 2022-06-20 12:33:11 +02:00
library@939ae5450b lib: update repo 2022-05-17 11:14:21 +02:00
.gitignore ignore other manual fabrication export (not from Rakefile) 2022-02-02 15:29:48 +01:00
.gitmodules update library 2022-03-07 14:42:51 +01:00
.qeda.yaml lib: add HDMI plug 2022-06-20 12:33:11 +02:00
CHANGELOG.md doc: add v1 changes 2022-06-20 13:30:26 +02:00
DEVELOPMENT.md put development instructions in seperate file 2022-03-23 10:32:24 +01:00
LICENSE.txt add CERN-OHL-S license 2021-07-22 12:22:58 +02:00
README.md doc: add EDID copying instructions 2022-06-20 13:25:04 +02:00
Rakefile set project name 2022-06-20 10:57:19 +02:00
gafrc add schematic configuration and template 2021-07-22 12:28:19 +02:00
hdmi_firewall.lht sch/brd: import design from 2022-07-27 2022-06-20 12:38:44 +02:00
hdmi_firewall.sch sch: improve naming 2022-06-20 12:40:32 +02:00
mass_prop.sh add PnP export 2021-12-19 11:24:57 +01:00
pnp_fab.tab pnp: fix USB-C orientation 2022-03-23 10:34:20 +01:00
version switch to version 1 2022-06-20 12:15:59 +02:00

README.md

The HDMI firewall protects your HDMI equipment from being hacked.

purpose

HDMI is mainly used to transfer audio and video, but also offers a number of additional features (e.g. HPD, CEC, HEAC, 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 equipment 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 video-projector so he can show his slides. This is the perfect opportunity for the guest to hack the video-projector. Next time an employee connects to this 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 blocks all additional interfaces, and only allows 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.

usage

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. You can read it out using the I²C-based Display Data Channel (DDC) interface. Write the EDID data on the EEPROM of the HDMI firewall, and break the tab using pliers to enable write protection. It will prevent attackers from injecting any malicious payload. This only has to be done once (per monitor to protect). See installation for detailed instruction on copied the EDID.

Now plug in the HDMI firewall in the monitor to be protected. Connect the cable going to the untrusted device on the HDMI firewall. Your equipment is now protected.

To re-write the EEPROM of the HDMI firewall in case you want to protect another monitor, you can re-disable write protection by putting a solder blob across the two pads marked WP.

By default, the 5V supplied by the monitor are forwarded to the device. To further reduce the attack surface, you can disable this by cutting the trace between the two pads marked 5V. The risk is that some monitors rely on this signal to detect when a device is plugged in.

installation

For the HDMI firewall to be used, it needs a local copy of the EDID data from the monitor to protect.

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
  • for Arch-based distributions
sudo pacman -S i2c-tools

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

sudo modprobe i2c-dev

To figure out which I²C device corresponds to your HDMI port, simply test them all. There might be a better way, but I don't know it.

Disconnect everything from the HDMI port, and scan for devices on the I²C bus (0 corresponds to the bus number, at the end of /dev/i2c-0):

sudo i2cdetect -y 0

Since nothing is connected, no device should be detected:

     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 (in this example it is bus 4). 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 51 52 53 54 55 56 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Now connect the monitor you want to copy the EDID from directly to the HDMI port. We will use the EDID-RW tool to make the copy.

Install these prerequisites:

  • for Debian-based distributions
sudo apt-get install python3-smbus edid-decode
  • for Arch-based distributions
pikaur -S python-smbus-git edid-decode-git

Get EDID-RW:

git clone https://github.com/bulletmark/edid-rw
cd edid-rw/

To retrieve the EDID data from the monitor you connected:

sudo ./edid-rw 4 > edid.bin

To view the decoded EDID data (feel free to adjust it):

edid-decode edid.bin

Now connect the HDMI firewall device port to the your HDMI output. Ensure Write Protect is disabled (by default until the tab is broken, and no solder across the WP pads is added). Write the extracted EDID data to the HDMI firewall:

sudo ./edid-rw -w 4 < edid.bin

To verify of the data has been written correctly, read it back:

sudo ./edid-rw 4 | edid-decode

If the EDID information could not be decoded, the data write was unsuccessful. See troubleshooting for possible solutions.

Once writing the EDID to the HDMI firewall memory succeeded, break the tab using pliers to write protect the memory. You can now use the HDMI firewall (only for this monitor). Fell free to put shrink tube around the HDMI firewall (and shrink it using hot air at 200°C, or carefully using a lighter). This will prevent the electronics from getting shorted when entering in contact with neighbouring metal objects.

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 putting solder across the 5V pads. In the HDMI cable there is a 5V line, with power provided by the monitor. In our case we use it is to power the HDMI firewall memory. Forwarding it to the device can be disabled by cutting the trace across the 5V pads.

If the device does not detect the monitor (actually the HDMI firewall), or writing the EDID data to the HDMI firewall fails (better indication), try connecting the HDMI firewall with another (better quality) HDMI cable. Some cheap cables have a very thin 5V cable, enough to detect connected devices, but not to power the EEPROM for write operations.

tips

xrandr

xrandr can also dump the EDID information:

xrandr --properties

sysfs also exposes the raw EDID information:

edid-decode /sys/devices/pci0000:00/0000:00:08.1/0000:05:00.0/drm/card0/card0-HDMI-A-1/edid

to access I²C devices as non-root:

# add UDEV rule
cat << EOF | sudo tee /etc/udev/rules.d/20-i2c.rules
KERNEL=="i2c-[0-9]*", GROUP="i2c"
EOF
# give user access to devices
sudo groupadd i2c
sudo gpasswd -a $USER i2c
# reload rules
sudo udevadm control --reload-rules
sudo udevadm trigger

erase

If you want to clear the HDMI firewall memory (for usage with another monitor):

for page in `seq 50 57`; do echo 0x$page; for addr in `seq 0 255`; do echo $addr; sudo i2cset -y 4 0x$page $addr 0xff; done; done

limitations

High-bandwidth Digital Content Protection (HDCP) is not supported since the DDC interface is limited to the EDID information.

mode of operation

To protect the monitor, the HDMI firewall only forwards the signal lines used for audio/video (A/V) data transfer (D0, D1, D2, CK). All other signal lines are unconnected (CEC, SDA, SCL, utility/HEAC+, HPD). This will block all non A/V interfaces (e.g. DDC, HPD, CEC, HEAC, MHL) The SDA/SCL lines used for the DDC interface to provide the EDID information to the device are connected to an EEPROM on the firewall. This is where you need to copy the monitor information to. This limits the DDC interface to the EDID information.