Compare commits

...

82 Commits

Author SHA1 Message Date
8ea411fd8a doc: added custom EDID programming 2022-08-19 16:45:23 +02:00
18926c4cc9 doc: add firmware link 2022-08-09 10:50:42 +02:00
94a112b154 doc: CEC tester 2022-08-08 19:45:21 +02:00
23511e68e1 doc: add v2 pictures 2022-08-08 19:43:27 +02:00
7358be50e2 doc: fix part position 2022-08-08 19:42:35 +02:00
bf869eee8d lib: update repo 2022-08-08 19:42:19 +02:00
46d106d99c doc: update to v2 capabilities 2022-07-13 13:42:55 +02:00
d72dba822c doc: add v2 changes 2022-07-13 13:42:19 +02:00
867e6949b7 brd: tune length matching 2022-07-13 10:49:27 +02:00
4e82cef602 brd: fix snake spacing 2022-07-13 10:44:11 +02:00
fa94f37ba8 brd: re-fix pad ground keepout 2022-07-13 10:32:08 +02:00
58eacec914 sch: fix HDMI position 2022-07-13 10:25:16 +02:00
3060b0dc05 brd: fix pad ground keepout 2022-07-13 10:12:42 +02:00
ce234c7b01 brd: place refdes 2022-07-12 18:35:38 +02:00
034ddca6f0 brd: minor, add sheet title 2022-07-12 18:28:09 +02:00
759e93f5b7 brd: minor, fix drc 2022-07-12 18:25:28 +02:00
84d4db186d brd: fix inner layer via 2022-07-12 18:20:48 +02:00
4f18284b9e sch: fix HDMI position 2022-07-12 18:20:24 +02:00
f3c0a314bc sch: add position corrections 2022-07-12 16:32:21 +02:00
66a4f4a6c8 brd: add tab position 2022-07-12 16:12:18 +02:00
f0fe042e87 make: make panel fab faster 2022-07-12 15:56:01 +02:00
83f775ae09 brd: fix pin header text 2022-07-12 15:41:29 +02:00
0ed8f07910 brd: minor 5V routing fix 2022-07-12 15:39:34 +02:00
ed8c064687 brd: tune inter-diff-pair length 2022-07-12 15:28:20 +02:00
9581f99519 brd: fix QR code rotation 2022-07-12 14:57:25 +02:00
b66dfda066 brd: fix outline and text 2022-07-12 14:49:28 +02:00
8768c787f8 brd: route changes 2022-07-12 14:26:10 +02:00
ecc0d8434e sch: improve routing 2022-07-12 14:25:54 +02:00
45681e2751 sch: complete BOM 2022-07-12 13:49:42 +02:00
0527253b29 sch: minor fixes 2022-07-12 13:39:32 +02:00
aaaa7a9e06 sch: remove unused UART RX 2022-07-12 13:36:33 +02:00
8ca03d7661 sch: add sink DDC pull-up 2022-07-12 13:36:10 +02:00
0230a77cd5 sch: fix source DDC pull-up 2022-07-12 13:24:57 +02:00
7b81cfd1ac sch: rename HPD 2022-07-12 13:21:15 +02:00
f5707eb56d sch: rename source/sink 2022-07-12 13:19:21 +02:00
977d2d6cc7 sch: remove unused EEPROM 2022-07-12 13:14:17 +02:00
0f76fd4089 brd: fix via 2022-06-24 18:45:20 +02:00
b207b61db9 sch: minor, fix BoM 2022-06-24 18:41:28 +02:00
d83cfc5fe3 make: fix default rule 2022-06-24 18:41:06 +02:00
8b9c72f70c sch: complete BoM 2022-06-24 18:36:57 +02:00
e72c683999 brd: fix outline thickness 2022-06-24 18:36:37 +02:00
cafca73743 doc: update development to makefile 2022-06-24 18:00:49 +02:00
cb7aa78b06 brd: add revision 2022-06-24 17:56:51 +02:00
bc8a9bfc1d make: remove git id from revision 2022-06-24 17:56:35 +02:00
ddfbc49814 brd: remove gnd under pad 2022-06-24 17:54:53 +02:00
c19bc12a7a brd: complete first routing 2022-06-24 17:44:48 +02:00
d90cd5f8b5 lib: add QR url 2022-06-24 17:44:14 +02:00
2afed4573d sch: improve routability 2022-06-24 17:43:56 +02:00
9f2e004521 sch: complete first routing 2022-06-23 18:27:20 +02:00
15302eeda9 lib: improve hdmi symbol 2022-06-23 18:27:02 +02:00
5422ab7704 lib: add dip switch 2022-06-23 18:26:32 +02:00
156ef34a0e llib: add exported parts 2022-06-23 14:53:47 +02:00
e0d9b8377c ignore kicad temp 2022-06-23 14:53:13 +02:00
0c9f27138d lib: add dip switch 2022-06-23 14:52:56 +02:00
9446c621ae switch to KiCAD 2022-06-23 12:51:28 +02:00
71caf5f793 switch to version 2 2022-06-23 12:44:33 +02:00
932f0e07e9 doc: minor, ref slide 2022-06-22 14:46:19 +02:00
9a67bac5f1 doc: add research 2022-06-22 14:44:44 +02:00
ece0aa4730 doc: add availability 2022-06-22 14:34:02 +02:00
432de7d2c8 doc: move limitions higher 2022-06-22 14:27:49 +02:00
3d6d42d1d8 doc: mention programmer 2022-06-21 15:17:00 +02:00
7531f02225 doc: improve installation 2022-06-21 11:09:39 +02:00
dabf167b5f doc: document ground issue 2022-06-21 11:08:53 +02:00
473587a9e8 doc: improve short description 2022-06-20 15:48:27 +02:00
be24d31ddd doc: integrate pictures 2022-06-20 15:38:46 +02:00
588e570e0d doc: add v1 pictures 2022-06-20 15:36:35 +02:00
fd9d7780c9 doc: add v0 pictures 2022-06-20 15:36:07 +02:00
38f031e202 lib: update repo 2022-06-20 15:04:07 +02:00
162f540837 doc: add v1 changes 2022-06-20 13:30:26 +02:00
b35c3526d2 doc: add EDID copying instructions 2022-06-20 13:25:04 +02:00
9087beec8e doc: update usage for v1 2022-06-20 13:01:44 +02:00
ff3fe4f2c4 doc: fix numeros typos 2022-06-20 12:48:58 +02:00
132f2e1317 sch: improve naming 2022-06-20 12:40:32 +02:00
daf23c9afe sch/brd: import design from 2022-07-27 2022-06-20 12:38:44 +02:00
e59a0f732d lib: add HDMI plug 2022-06-20 12:33:11 +02:00
dfc9010874 switch to version 1 2022-06-20 12:15:59 +02:00
a23e5228da doc: describe version 2022-06-20 12:07:05 +02:00
43cb77c7b6 doc: minor, add interface information 2022-06-20 12:01:21 +02:00
7d6caee37e doc: document project 2022-06-20 11:57:52 +02:00
c9adea88e4 sch/brd: import design from 2021-07-22 2022-06-20 11:57:35 +02:00
122543235d lib: add used parts 2022-06-20 11:03:09 +02:00
3b7e68fd46 set project name 2022-06-20 10:57:19 +02:00
60 changed files with 14217 additions and 3522 deletions

46
.gitignore vendored
View File

@ -1,31 +1,35 @@
# schematic lepton-EDA
*.sch
# board layout pcb-rnd
*.lht
*.lht.*
*.versioned.lht
# KiCAD
*.kicad_prl
*.kicad_pro-bak
*.xml
fp-info-cache
# temporary files
*~
*.versioned.sch
\#*\#
# outputs
*.svg
*.png
*.pdf
*.ps
*.zip
*.brd.*
*.ast
*.g2l
*.g3l
*.gbl
*.gbo
*.gbp
*.gbs
*.gko
*.gtl
*.gto
*.gtp
*.gts
*.xln
*.tdx
\#*\#
*.notes.txt
*.bom.csv
*.cost.csv
*.cpl.csv
*.versioned.*
fabrication
# scripts and utilities
*.json
*.rb
geda/footprints/
# panel files
panel.*
panel

View File

@ -1,10 +1,17 @@
config:
output: coraleda
output: kicad
pattern:
densityLevel: 'N'
lineWidth:
silkscreen: 0.2
polarityMark: none
preferManufacturer: false
preferManufacturer: true
smoothPadCorners: false
library:
- connector/hdmi-001s
- ic/eeprom_ft24c16a-e@l
- resistor/r0603
- capacitor/c0603
- mcu/st_stm8s003x3@p
- mechanical/dip-switch_dsicxxls@dsic07ls
- diode/led0805

View File

@ -0,0 +1,34 @@
v2
==
instead of an edge plug, the monitor connector is also a receptacle.
this prevents the firewall from sticking out of the monitor too much, particularly when installed in tight spaces.
it also allows to place the HDMI firewall inline even if you don't have access to the monitor's HDMI port.
finally it also allows the board to be manufactured more easily.
the programmer is now included in the firewall.
this offers very easy copy of the EDID data.
no need to use complex linux commands or stand-alone separate programmer.
the programmer uses the embedded EEPROM and acts as I²C slave.
a DIP switch allows to selectively block or forward interfaces.
v1
==
this version comes as dongle, which can directly be plugged in the monitor.
the impedance and length of the differential signal pairs are properly taken care of.
a breakable tab replaces the WP switch.
pads are still present to override the disabled WP and 5V.
the shield is not connected to ground, which causes EEPROM read errors with cheap HDMI cables skimping on the ground wire (pin 17).
the workaround is to scratch the solder mask near one of the HDMI receptacle shell tab and solder it.
v0
==
first working version.
based on the design of the original research.
the HDMI connectors are on opposite sides of the board to make the routing easy (the differential signals are straight lines).
the impedance does not seem to by optimal, leading to EMF leakage (reported by the original researchers).

View File

@ -1,19 +1,23 @@
this will describe how to generate the output file form the sources.
this will describe how to generate the output files form the sources.
requirements
============
to be able to generate the outputs you need following software:
to be able to generate the outputs, you need following software:
- rake: the central script taking care of generating the output files (Makefile is too cumbersome to parse files)
- make: takes care of generating the output files
- [QEDA](http://qeda.org/): to generate footprints for the parts
- [Lepton EDA](https://github.com/lepton-eda/lepton-eda): for the schematic capture
- [pcb-rnd](http://repo.hu/projects/pcb-rnd/): for the board layout
the output generation is automatized.
- [KiCad](https://www.kicad.org/): EDA software used for schematic capture and board layout
- [PcbDraw](https://github.com/yaqwsx/PcbDraw): to generate board layout rendering
- [KiKit](https://github.com/yaqwsx/KiKit): to generate fabrications files (Gerber, Excellon)
- [KiAuto](https://github.com/INTI-CMNB/KiAuto): to generate schematic printout (PDF)
- [KiBoM](https://github.com/SchrodingersGat/KiBoM): to generate Bill of Material (CSV)
compiling
=========
to generate schematic, BoM, board render, and fabrication output, run `make`.
library
-------
@ -35,26 +39,23 @@ sudo npm install --global
to generate the parts:
~~~
rake library
make lib
~~~
this will use the parts definition (.yaml files) in the `library` to generate [gEDA gschem](http://wiki.geda-project.org/geda:gaf)/[Lepton EDA](https://github.com/lepton-eda/lepton-eda) symbols (.sym files) in the `geda/symbols` folder, and [coralEDA pcb-rnd](http://repo.hu/projects/pcb-rnd/) footprints (.lht files) in the `coraleda/subc` folder.
only the QEDA parts in subfolders within `library` come from the [QEDA library](https://doc.qeda.org/library/), but the files are included in this project for simplicity and archiving purposes.
all other parts are custom and written for this project.
this will use the parts definition (.yaml files) in the `library` to generate the symbols (.sym files) and footprints used by KiCAD in the `kicad` folder.
schematic
---------
the `.sch` file is the schematic source file.
it has been drawn using [Lepton EDA](https://github.com/lepton-eda/lepton-eda).
the `.kicad_sch` file is the schematic source file.
it has been drawn using the [KiCAD eeschema](https://www.kicad.org/) schematic editor.
it uses standard symbols, and the ones in the `geda/symbols/` folder.
it uses standard symbols, and the ones in the `kicad/` folder.
most symbols are generated by QEDA as described above.
to export as pdf:
~~~
rake print
make print
~~~
BOM
@ -62,21 +63,30 @@ BOM
to export the bill of material (as CSV):
~~~
rake bom
make bom
~~~
board
-----
the `.lht` file is the board layout source file.
it has been drawn using [coralEDA pcb-rnd](http://repo.hu/projects/pcb-rnd/).
the `.kicad_brd` file is the board layout source file.
it has been drawn using the [KiCAD pcbnew](https://docs.kicad.org/6.0/en/pcbnew/pcbnew.html) PCB editor.
it uses the symbols from the `coraleda/subc/` folder.
most symbols are generated by QEDA as described above.
`oshw_logo.lht` is just the Open Source Hardware Logo.
it been generated from https://oshwlogo.cuvoodoo.info/.
it uses the footprints from the `kicad/` folder.
most footprints are generated by QEDA as described above.
to export gerber files for PCB manufacturer (and photo preview + overview document):
~~~
rake fabrication
make fabrication
~~~
versioning
----------
the source schematic and board layout do not include version information.
when generating schematic or board fabrication output, a copy of the source files with date and version information is done as `.versioned.` files.
the date corresponds to the last changes (i.e. commit).
the version is formatted as `v.r`:
- `v` corresponds to the major version information defined in `version`
- `r` corresponds to the total number of changes done to the source files

11
JLCPCB_CORRECTION.csv Normal file
View File

@ -0,0 +1,11 @@
package;x;y;rot
LEDC2012X80N;0;0;-90
UC1608X55N;0;0;-90
CAPC1608X92N;0;0;-90
SOT95P237X112-3N;0;0;180
CONNECTOR_MY-1220-03;0;-1.1;0
CONNECTOR_XKB_U262-24XN-4BV64;0;-1.3;180
CONNECTOR_U231-09XN-4BLRA00;0;-3.0;0
SOP254P976X355-14N;0;0;-90
SOP65P640X120-20N;0;0;-90
CONNECTOR_HDMI-001S;0;1.1;0
1 package x y rot
2 LEDC2012X80N 0 0 -90
3 UC1608X55N 0 0 -90
4 CAPC1608X92N 0 0 -90
5 SOT95P237X112-3N 0 0 180
6 CONNECTOR_MY-1220-03 0 -1.1 0
7 CONNECTOR_XKB_U262-24XN-4BV64 0 -1.3 180
8 CONNECTOR_U231-09XN-4BLRA00 0 -3.0 0
9 SOP254P976X355-14N 0 0 -90
10 SOP65P640X120-20N 0 0 -90
11 CONNECTOR_HDMI-001S 0 1.1 0

71
Makefile Normal file
View File

@ -0,0 +1,71 @@
# project file name (use for schematic and board layout)
NAME ?= hdmi_firewall
# path to qeda
QEDA := qeda
# read project version
VERSION := $(shell cat version)
# current date for stamping output
DATE = $(shell date +%Y-%m-%d)
# revision based on number of changes on schematic or board layout and current git commit
REVISION := $(shell git log --pretty=oneline "${NAME}.kicad_sch" "${NAME}.kicad_pcb" | wc -l)
# generate file with version information
VERSIONED_EXT = kicad_sch kicad_pcb kicad_pro json
define version_rule
%.versioned.$1: %.$1
cp $$< $$@
sed --in-place 's/\$$$$version\$$$$/${VERSION}/g' $$@
sed --in-place 's/\$$$$date\$$$$/${DATE}/g' $$@
sed --in-place 's/\$$$$revision\$$$$/${REVISION}/g' $$@
endef
$(foreach EXT,$(VERSIONED_EXT),$(eval $(call version_rule,$(EXT))))
all: print fabrication
print: ${NAME}.sch.pdf ${NAME}.brd-top.png ${NAME}.brd-bot.png ${NAME}.bom.csv
# generate fabrication files (gerbers/drill/BoM/PnP)
FABRICATION_DIR := fabrication
fabrication: ${NAME}.versioned.kicad_sch ${NAME}.versioned.kicad_pcb
kikit fab jlcpcb --drc --assembly --schematic $^ ${FABRICATION_DIR}
# generate symbols and footprints from parts
lib:
$(QEDA) generate qeda
# generate printable version (PDF) of schematic
%.sch.pdf: %.versioned.kicad_sch %.versioned.kicad_pro
eeschema_do export $< .
mv $*.versioned.pdf $@
# generate render from layout (top side)
%.brd-top.png: %.versioned.kicad_pcb
pcbdraw --silent $< --dpi 600 $@
# generate render from layout (bottom side)
%.brd-bot.png: %.versioned.kicad_pcb
pcbdraw --silent $< --dpi 600 --back $@
# export Bill of Material (as CSV)
%.bom.csv: %.versioned.kicad_sch %.versioned.kicad_pro
eeschema_do bom_xml $< .
kibom $*.versioned.xml $@
# generate panel
PANEL_DIR := panel
panel: panel.kicad_pcb
panel.kicad_pcb: ${NAME}.versioned.kicad_pcb ${NAME}.versioned.kicad_pro ${NAME}.versioned.kicad_sch ${NAME}.versioned.json
kikit panelize -p ${NAME}.versioned.json ${NAME}.versioned.kicad_pcb $@
sed --in-place 's/\"missing_courtyard\": \"warning\"/\"missing_courtyard\": \"ignore\"/g' $(patsubst %.kicad_pcb,%.kicad_pro,$@) # the mouse bites don't have a courtyard
kikit fab jlcpcb --drc --assembly --missingError --schematic ${NAME}.versioned.kicad_sch $@ ${PANEL_DIR}
pcbdraw --silent $@ --dpi 600 panel.brd-top.png
pcbdraw --silent $@ --dpi 600 --back panel.brd-bot.png
clean:
rm -f $(foreach EXT,$(VERSIONED_EXT),${NAME}.versioned.$(EXT))
rm -f ${NAME}.sch.pdf ${NAME}.brd-top.png ${NAME}.brd-bot.png ${NAME}.versioned.xml ${NAME}.bom.csv
rm -f ${NAME}.versioned.kicad_prl ${NAME}.versioned.kicad_pro-bak ${NAME}.versioned.xml ${NAME}.versioned.csv
rm -rf ${FABRICATION_DIR}
rm -f panel.kicad_pcb panel.kicad_pro
rm -rf ${PANEL_DIR}

214
README.md
View File

@ -1,7 +1,219 @@
these are the hardware design files for **insert project name here**.
The HDMI firewall prevents devices from hacking HDMI equipment, and vice-versa.
<img src="picture/front_v2.webp" title="front" height="250"/>
<img src="picture/back_v2.webp" title="back" height="250"/>
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](https://sstic.org/2021/presentation/un_pare_feu_pour_le_hdmi/).
Some security research and vulnerabilities around CEC and EDID are listed in [slide 4](https://www.sstic.org/media/SSTIC2021/SSTIC-actes/un_pare_feu_pour_le_hdmi/SSTIC2021-Slides-un_pare_feu_pour_le_hdmi-lopes-esteves_ricordel.pdf).
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
1. unplug the device from the firewall
1. toggle the small switch labeled EDID/7 to the ALLOW/ON position
1. ensure the SDA/2 and SCL/3 switches are on the BLOCK/OFF position
1. plug the device to the firewall
1. this will power the firewall, which will copy the monitor EDID onto its internal memory, shown by a short blink of the ERROR LED
1. 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
1. 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](https://www.tindie.com/products/cuvoodoo/hdmi-firewall/).
The schematic pdf and board gerbers are available as [release](https://git.cuvoodoo.info/kingkevin/board/releases/tag/hdmi_firewall_v2).
firmware
========
The firmware and sources for the HDMI firewall embedded programmer are available [here](https://git.cuvoodoo.info/kingkevin/stm8s/src/branch/hdmi_firewall).
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](https://git.cuvoodoo.info/kingkevin/stm8s/src/branch/hdmi_firewall/README.md) 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](https://www.sstic.org/media/SSTIC2021/SSTIC-actes/un_pare_feu_pour_le_hdmi/SSTIC2021-Slides-un_pare_feu_pour_le_hdmi-lopes-esteves_ricordel.pdf) (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](https://git.cuvoodoo.info/kingkevin/board/src/tag/hdmi_firewall_v1/README.md).

181
Rakefile
View File

@ -1,181 +0,0 @@
# encoding: utf-8
# ruby: 2.1.0
=begin
Rakefile to manage hardware projects
uses Lepton EDA for schematic and pcb-rnd for board layouts.
Rakefile instead of Makefile for better text file parsing capabilities.
=end
require 'rake/clean'
require 'csv' # to export BOM and costs
# =================
# project variables
# =================
# common name used for file names
name = "template"
# project version, read from "version" file
raise "define project version in 'version' file" unless File.exist? "version"
version = IO.read("version").split("\n")[0]
# current date for stamping output
date = Time.now.strftime("%Y-%m-%d")
# revision based on number of changes on schematic or board layout and current git commit
changes = `git log --pretty=oneline "#{name}.sch" "#{name}.lht" | wc -l`.chomp.to_i
commit = `git rev-parse --short HEAD`.chomp
revision = "#{changes} (#{commit})"
# path to qeda"
qeda = "qeda"
# ==========
# main tasks
# ==========
desc "main building task"
task :default => [:print, :fabrication, :bom, :pnp]
desc "print schematic and layout (as pdf)"
prints = [ "#{name}.sch.pdf", "#{name}.brd.pdf", "#{name}.brd-top.svg", "#{name}.brd-bottom.svg" ]
task :print => prints
CLEAN.include([ "#{name}.versioned.sch", "#{name}.versioned.lht" ])
CLOBBER.include(prints)
desc "generate fabrication gerbers (as archive)"
gerbers = [ "#{name}.brd.asb", "#{name}.brd.ast", "#{name}.brd.gbl", "#{name}.brd.gbo", "#{name}.brd.gbp", "#{name}.brd.gbs", "#{name}.brd.gko", "#{name}.brd.gtl", "#{name}.brd.gto", "#{name}.brd.gtp", "#{name}.brd.gts", "#{name}.brd.xln", "#{name}.brd.g2l", "#{name}.brd.g3l" ]
fab = [ "#{name}.brd.zip" ]
task :fabrication => fab
CLEAN.include(gerbers)
CLOBBER.include(fab)
desc "generate symbols and footprints from parts"
task :library do
sh "#{qeda} config output geda"
sh "#{qeda} generate ."
sh "#{qeda} config output coraleda"
sh "#{qeda} generate ."
end
desc "export BOMs from schematic"
boms = [ "#{name}.bom.csv" ]
task :bom => boms
CLOBBER.include(boms)
desc "export PnP placement"
pnps = [ "#{name}.cpl.csv" ]
task :pnp => pnps
CLOBBER.include(pnps)
# ===============
# file generation
# ===============
desc "generate schematic with version information all symbols embedded"
rule ".versioned.sch" => ".sch" do |t|
sh "cp #{t.source} #{t.name}"
sh "lepton-embed --embed #{t.name} 2> /dev/null"
sh "sed --in-place 's/\\$version\\$/#{version}/' #{t.name}"
sh "sed --in-place 's/\\$date\\$/#{date}/' #{t.name}"
sh "sed --in-place 's/\\$revision\\$/#{revision}/' #{t.name}"
end
desc "generate board layout with version information"
rule ".versioned.lht" => ".lht" do |t|
sh "cp #{t.source} #{t.name}"
sh "sed --in-place 's/\\$version\\$/#{version}/' #{t.name}"
sh "sed --in-place 's/\\$date\\$/#{date}/' #{t.name}"
sh "sed --in-place 's/\\$revision\\$/#{revision}/' #{t.name}"
end
desc "generate printable version (PDF) of schematic"
rule ".sch.pdf" => ".versioned.sch" do |t|
sh "lepton-cli export --color --paper=iso_a4 --layout=landscape --output=#{t.name} #{t.source} 2> /dev/null"
end
desc "generate printable version (PostScript) of board layout"
rule ".brd.ps" => ".versioned.lht" do |t|
sh "pcb-rnd -x ps --ps-color --media A4 --psfile #{t.name} #{t.source} 2> /dev/null"
end
desc "generate printable version (PDF) of board layout"
rule ".brd.pdf" => ".brd.ps" do |t|
sh "ps2pdf -sPAPERSIZE=a4 -dEPSCrop #{t.source} #{t.name}"
end
desc "generate photo realistic picture from layout (top side)"
rule ".brd-top.svg" => ".versioned.lht" do |t|
sh "pcb-rnd -x svg --photo-mode --outfile #{t.name} #{t.source} 1> /dev/null"
end
desc "generate photo realistic picture from layout (bottom side)"
rule ".brd-bottom.svg" => ".versioned.lht" do |t|
sh "pcb-rnd -x svg --photo-mode --flip --outfile #{t.name} #{t.source} 1> /dev/null"
end
desc "archive gerbers"
rule ".brd.zip" => ".versioned.lht" do |t|
base = File.basename(t.source, ".versioned.lht")
dir = "fabrication"
sh "mkdir #{dir}" unless File.directory?(dir)
sh "pcb-rnd -x cam gerber:JLC_PCB --outfile #{dir}/#{base}.brd #{t.source} 2> /dev/null"
sh "zip --quiet #{t.name} #{dir}/*"
end
desc "generate BOM file from schematic"
rule ".bom.csv" => ".sch" do |t|
attributes = ["device", "value", "description", "footprint", "manufacturer", "mpn", "datasheet", "lcsc", "digikey"]
bom_data = bom2(t.prerequisites[0], attributes)
CSV.open(t.name, "wb") do |csv|
all_attributes = ["refdes","qty"] + attributes
csv << all_attributes
bom_data.each do |line|
csv << all_attributes.collect{|attribute| line[attribute]}
end
end
end
desc "generate pick-and-place file from board"
rule ".cpl.csv" => [".versioned.lht", "mass_prop.sh", "pnp_fab.tab"] do |t|
sh "./mass_prop.sh #{t.prerequisites[0]} pnp_fab.tab" # add fab placement offsets
sh "pcb-rnd -x XY --xyfile #{t.name} --xy-unit mm --format 'JLCPCB' --vendor jlcpcb #{t.prerequisites[0]}" # export XY file in JLCPCB format
end
# ================
# helper functions
# ================
# generate gnetlist bom2 and parse them
# arguments: schematic=schematic to use, attributes=attributes to use for generating bom2
# returns an array of hash. key is the attribute name, value is the attribute value
def bom2(schematic, attributes)
to_return = []
# force attributes to be an array
attributes = case attributes
when String
[attributes]
when Array
attributes
else
[attributes.to_s]
end
# generate bom2
list = `lepton-netlist --backend bom2 --backend-option attribs=#{attributes*','} --quiet --output - #{schematic} 2> /dev/null`
list = list.each_line {|l| '"' + l + '"' + '\n' }
list.gsub!(/^(.+)/, '"\1')
list.gsub!(/(.+)$/, '\1"')
list.gsub!(/(?!http):(?!\/\/)/, '\1":"\2') # protect the values between ':' (such as URLs)
# parse bom2
csv = CSV.parse(list, col_sep: ":", quote_char: '"')
if csv.empty? then
$stderr.puts "no parts found for BOM"
return []
end
csv[1..-1].each do |row|
line = {}
row.each_index do |col|
line[csv[0][col]] = row[col] unless row[col] == "unknown"
end
to_return << line
end
return to_return
end

42
bom.ini Normal file
View File

@ -0,0 +1,42 @@
[BOM_OPTIONS]
ignore_dnf = 0
number_rows = 0
group_connectors = 1
test_regex = 0
merge_blank_fields = 1
output_file_name = %O%V
[IGNORE_COLUMNS]
; Any column heading that appears here will be excluded from the Generated BoM
; Titles are case-insensitive
Part
Part Lib
Footprint
Footprint Lib
Build Quantity
sheetpath
[COLUMN_ORDER]
; Columns will apear in the order they are listed here
; Titles are case-insensitive
References
Value
Quantity Per PCB
Description
Part
Part Lib
Footprint
Footprint Lib
Build Quantity
LCSC
Datasheet
[GROUP_FIELDS]
; List of fields used for sorting individual components into groups
; Components which match (comparing *all* fields) will be grouped together
; Field names are case-insensitive
Part
Part Lib
Value
Footprint
Footprint Lib

View File

@ -1,421 +0,0 @@
# footprint generated from CuVoodoo Land Pattern
# author: King Kévin
# version: 1
# date: 2019-05-13
li:pcb-rnd-subcircuit-v6 {
ha:subc.1 {
uid = any_24_ASCII_characters_
ha:attributes {
footprint = open source hardware logo
}
ha:data {
li:padstack_prototypes {
}
li:objects {
}
li:layers {
ha:top-silkscreen {
lid = 1
ha:type {
top = 1
silk = 1
}
li:objects {
ha:line.2{
clearance = 0
x1 = 0.15mm
y1 = 1.8mm
x2 = 0.75mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.3{
clearance = 0
x1 = 1.8mm
y1 = 5.8500000000000005mm
x2 = 1.8mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.4{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 1.8mm
x2 = 6.45mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.5{
clearance = 0
x1 = 1.8mm
y1 = 0.15mm
x2 = 1.8mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.6{
clearance = 0
x1 = 0.15mm
y1 = 2.4mm
x2 = 0.75mm
y2 = 2.4mm
thickness = 0.3mm
}
ha:line.7{
clearance = 0
x1 = 2.4mm
y1 = 5.8500000000000005mm
x2 = 2.4mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.8{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 2.4mm
x2 = 6.45mm
y2 = 2.4mm
thickness = 0.3mm
}
ha:line.9{
clearance = 0
x1 = 2.4mm
y1 = 0.15mm
x2 = 2.4mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.10{
clearance = 0
x1 = 0.15mm
y1 = 3mm
x2 = 0.75mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.11{
clearance = 0
x1 = 3mm
y1 = 5.8500000000000005mm
x2 = 3mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.12{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 3mm
x2 = 6.45mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.13{
clearance = 0
x1 = 3mm
y1 = 0.15mm
x2 = 3mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.14{
clearance = 0
x1 = 0.15mm
y1 = 3.5999999999999996mm
x2 = 0.75mm
y2 = 3.5999999999999996mm
thickness = 0.3mm
}
ha:line.15{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 5.8500000000000005mm
x2 = 3.5999999999999996mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.16{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 3.5999999999999996mm
x2 = 6.45mm
y2 = 3.5999999999999996mm
thickness = 0.3mm
}
ha:line.17{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 0.15mm
x2 = 3.5999999999999996mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.18{
clearance = 0
x1 = 0.15mm
y1 = 4.2mm
x2 = 0.75mm
y2 = 4.2mm
thickness = 0.3mm
}
ha:line.19{
clearance = 0
x1 = 4.2mm
y1 = 5.8500000000000005mm
x2 = 4.2mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.20{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 4.2mm
x2 = 6.45mm
y2 = 4.2mm
thickness = 0.3mm
}
ha:line.21{
clearance = 0
x1 = 4.2mm
y1 = 0.15mm
x2 = 4.2mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.22{
clearance = 0
x1 = 0.15mm
y1 = 4.8mm
x2 = 0.75mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.23{
clearance = 0
x1 = 4.8mm
y1 = 5.8500000000000005mm
x2 = 4.8mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.24{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 4.8mm
x2 = 6.45mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.25{
clearance = 0
x1 = 4.8mm
y1 = 0.15mm
x2 = 4.8mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.26{
clearance = 0
x1 = 1.8mm
y1 = 1.35mm
x2 = 4.8mm
y2 = 1.35mm
thickness = 0.3mm
}
ha:line.27{
clearance = 0
x1 = 5.25mm
y1 = 1.8mm
x2 = 5.25mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.28{
clearance = 0
x1 = 4.8mm
y1 = 5.25mm
x2 = 1.8mm
y2 = 5.25mm
thickness = 0.3mm
}
ha:line.29{
clearance = 0
x1 = 1.35mm
y1 = 4.8mm
x2 = 1.35mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:arc.30{
clearance = 0
x = 1.8mm
y = 1.8mm
width = 0.45mm
height = 0.45mm
thickness = 0.3mm
astart = 0
adelta = -90
}
ha:arc.31{
clearance = 0
x = 4.8mm
y = 1.8mm
width = 0.45mm
height = 0.45mm
thickness = 0.3mm
astart = -90
adelta = -90
}
ha:arc.32{
clearance = 0
x = 4.8mm
y = 4.8mm
width = 0.45mm
height = 0.45mm
thickness = 0.3mm
astart = 180
adelta = -90
}
ha:arc.33{
clearance = 0
x = 1.8mm
y = 4.8mm
width = 0.45mm
height = 0.45mm
thickness = 0.3mm
astart = 90
adelta = -90
}
ha:line.34{
clearance = 0
x1 = 1.8mm
y1 = 1.8mm
x2 = 3mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.35{
clearance = 0
x1 = 3mm
y1 = 1.8mm
x2 = 3mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.36{
clearance = 0
x1 = 3mm
y1 = 3mm
x2 = 1.8mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.37{
clearance = 0
x1 = 1.8mm
y1 = 3mm
x2 = 1.8mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.38{
clearance = 0
x1 = 4.8mm
y1 = 1.8mm
x2 = 3.5999999999999996mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.39{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 1.8mm
x2 = 3.5999999999999996mm
y2 = 2.4mm
thickness = 0.3mm
}
ha:line.40{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 2.4mm
x2 = 4.8mm
y2 = 2.4mm
thickness = 0.3mm
}
ha:line.41{
clearance = 0
x1 = 4.8mm
y1 = 2.4mm
x2 = 4.8mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.42{
clearance = 0
x1 = 4.8mm
y1 = 3mm
x2 = 3.5999999999999996mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.43{
clearance = 0
x1 = 1.8mm
y1 = 3.5999999999999996mm
x2 = 1.8mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.44{
clearance = 0
x1 = 1.8mm
y1 = 4.199999999999999mm
x2 = 3mm
y2 = 4.199999999999999mm
thickness = 0.3mm
}
ha:line.45{
clearance = 0
x1 = 3mm
y1 = 3.5999999999999996mm
x2 = 3mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.46{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 3.5999999999999996mm
x2 = 3.5999999999999996mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.47{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 4.8mm
x2 = 4.199999999999999mm
y2 = 4.2mm
thickness = 0.3mm
}
ha:line.48{
clearance = 0
x1 = 4.199999999999999mm
y1 = 4.2mm
x2 = 4.799999999999999mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.49{
clearance = 0
x1 = 4.799999999999999mm
y1 = 4.8mm
x2 = 4.799999999999999mm
y2 = 3.5999999999999996mm
thickness = 0.3mm
}
}
}
}
}
}
}

View File

@ -1,39 +0,0 @@
#!/bin/sh
#@@example qr(hello world, 1mm)
#@@purpose Generate QR code on silk
#@@desc Generate the specified QR code as silk lines
#@@params text,pixel_size,level
#@@thumbsize 2
#@@param:text ASCII text to encode
#@@param:pixel_size width and height of each pixel
#@@dim:pixel_size
#@@param:level error correction level
#@@optional:level
#@@enum:level:L low
#@@enum:level:H high
#@@default:L
libdir=""
for n in $PCB_RND_PCBLIB/parametric `dirname $0` /usr/local/share/pcb-rnd/pcblib/parametric /usr/share/pcb-rnd/pcblib/parametric
do
if test -f "$n/common.awk"
then
libdir="$n"
break
fi
done
if test -z "$libdir"
then
echo "pcblib/parametric/common.awk not found." >&2
exit 1
fi
awk -f $libdir/common.awk -f `dirname $0`/qr.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0"

View File

@ -1,62 +0,0 @@
function flush_line(x1, x2, y, w ,n,yy)
{
x1/=2
x2/=2
for(n = 0; n < 3; n++) {
yy = y*w + w/6 + w/3 * n
element_line(x1*w + w/6, yy, x2*w - w/6, yy, w/3)
}
element_line(x1*w + w/6, y*w + w/6, x1*w + w/6, (y+1)*w - w/6,