<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://elvis.hcw.ac.at/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MBasta</id>
	<title>Elvis Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://elvis.hcw.ac.at/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MBasta"/>
	<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php/Special:Contributions/MBasta"/>
	<updated>2026-09-10T19:41:41Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.5</generator>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14089</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14089"/>
		<updated>2024-01-26T14:02:51Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Matter&#039;&#039;&#039; ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Dazu wird eine Umgebung mit einem 64-bit x86 Prozessor und mindestens Debian 11, Ubuntu 20.04 oder MacOS benötigt.&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
&lt;br /&gt;
# git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
# Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
Diese Variante wurde nicht weiter verfolgt, da das Repository rekursiv aufgelöst wird und das Klonen und Ausführen daher sehr viel Zeit in Anspruch nimmt.&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
&lt;br /&gt;
# docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
Dieser Ansatz lädt ein Docker Image herunter, welches größer als 10GB ist. Entpackt hat es dann mehr als 30GB und ist daher als schneller Ansatz für die Entwicklung mit Matter-Geräten ebenfalls nicht tauglich.&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
Das Standalone-Matter-Device wurde relativ neu von Google publiziert, lässt sich aber sehr einfach aufsetzen. Durch seine vergleichsweise geringe Größe mit weniger als 70MB ist es einfach herunterzuladen und ist innerhalb weniger Minuten lauffähig.&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
Installationsschritte (Debian/Ubuntu)&lt;br /&gt;
# wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
# sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
# mvd&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Um mit dem Matter Device zu kommunizieren, wird eine GUI benötigt. Dazu gibt es wieder zwei Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Das Standalone MVD wird mit einer integrierten GUI geliefert, wobei das Gerät auf einem anderen Port (RPC-Port: 33000) angesprochen wird, als den Matter Port (Matter-Port: 5540).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
Dieses Thema wurde im Rahmen des Wahlfachprojektes 2 vorgestellt. Die Aufgabe bestand darin, mit dem MVD einen Angriff nachzustellen und zu zeigen, dass dieser daher bereits während der Entwicklung erkennt und mitigiert werden könnte. Aufgrund der Neuheit des Standards ist dieser aber noch nicht in der Breite etabliert und daher sind auch noch wenige Vulnerabilities und Exploits bekannt. Daher konnten wir nur eine DoS Attacke ausprobieren und damit den Zugriff auf das MVD verhindern. Eine Differenzierung ob es dabei zu einem DoS des Gerätes selbst oder der ausführenden Plattform kam konnte nicht evaluiert werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14088</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14088"/>
		<updated>2024-01-26T14:02:13Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Matter&#039;&#039;&#039; ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Dazu wird eine Umgebung mit einem 64-bit x86 Prozessor und mindestens Debian 11, Ubuntu 20.04 oder MacOS benötigt.&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
&lt;br /&gt;
# git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
# Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
Diese Variante wurde nicht weiter verfolgt, da das Repository rekursiv aufgelöst wird und das Klonen und Ausführen daher sehr viel Zeit in Anspruch nimmt.&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
&lt;br /&gt;
# docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
Dieser Ansatz lädt ein Docker Image herunter, welches größer als 10GB ist. Entpackt hat es dann mehr als 30GB und ist daher als schneller Ansatz für die Entwicklung mit Matter-Geräten ebenfalls nicht tauglich.&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
Das Standalone-Matter-Device wurde relativ neu von Google publiziert, lässt sich aber sehr einfach aufsetzen. Durch seine vergleichsweise geringe Größe mit weniger als 70MB ist es einfach herunterzuladen und ist innerhalb weniger Minuten lauffähig.&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
Installationsschritte (Debian/Ubuntu)&lt;br /&gt;
# wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
# sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
# mvd&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Um mit dem Matter Device zu kommunizieren, wird eine GUI benötigt. Dazu gibt es wieder zwei Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Das Standalone MVD wird mit einer integrierten GUI geliefert, wobei das Gerät auf einem anderen Port (RPC-Port: 33000) angesprochen wird, als den Matter Port (Matter-Port: 5540).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
Dieses Thema wurde im Rahmen des Wahlfachprojektes 2 vorgestellt. Die Aufgabe bestand darin, mit dem MVD einen Angriff nachzustellen und zu zeigen, dass dieser daher bereits während der Entwicklung erkennt und mitigiert werden könnte. Aufgrund der Neuheit des Standards ist dieser aber noch nicht in der Breite etabliert und daher sind auch noch wenige Vulnerabilities und Exploits bekannt. Daher konnten wir nur eine DoS Attacke ausprobieren und damit den Zugriff auf das MVD verhindern. Eine Differenzierung ob es dabei zu einem DoS des Gerätes selbst oder der ausführenden Plattform kam konnte nicht evaluiert werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentations]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14087</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14087"/>
		<updated>2024-01-26T13:57:32Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Matter&#039;&#039;&#039; ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Dazu wird eine Umgebung mit einem 64-bit x86 Prozessor und mindestens Debian 11, Ubuntu 20.04 oder MacOS benötigt.&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
&lt;br /&gt;
# git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
# Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
Diese Variante wurde nicht weiter verfolgt, da das Repository rekursiv aufgelöst wird und das Klonen und Ausführen daher sehr viel Zeit in Anspruch nimmt.&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
&lt;br /&gt;
# docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
Dieser Ansatz lädt ein Docker Image herunter, welches größer als 10GB ist. Entpackt hat es dann mehr als 30GB und ist daher als schneller Ansatz für die Entwicklung mit Matter-Geräten ebenfalls nicht tauglich.&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
Das Standalone-Matter-Device wurde relativ neu von Google publiziert, lässt sich aber sehr einfach aufsetzen. Durch seine vergleichsweise geringe Größe mit weniger als 70MB ist es einfach herunterzuladen und ist innerhalb weniger Minuten lauffähig.&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
Installationsschritte (Debian/Ubuntu)&lt;br /&gt;
# wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
# sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
# mvd&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Um mit dem Matter Device zu kommunizieren, wird eine GUI benötigt. Dazu gibt es wieder zwei Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Das Standalone MVD wird mit einer integrierten GUI geliefert, wobei das Gerät auf einem anderen Port (RPC-Port: 33000) angesprochen wird, als den Matter Port (Matter-Port: 5540).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
Dieses Thema wurde im Rahmen des Wahlfachprojektes 2 vorgestellt. Die Aufgabe bestand darin, mit dem MVD einen Angriff nachzustellen und zu zeigen, dass dieser daher bereits während der Entwicklung erkennt und mitigiert werden könnte. Aufgrund der Neuheit des Standards ist dieser aber noch nicht in der Breite etabliert und daher sind auch noch wenige Vulnerabilities und Exploits bekannt. Daher konnten wir nur eine DoS Attacke ausprobieren und damit den Zugriff auf das MVD verhindern. Eine Differenzierung ob es dabei zu einem DoS des Gerätes selbst oder der ausführenden Plattform kam konnte nicht evaluiert werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14086</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14086"/>
		<updated>2024-01-26T13:49:01Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Matter&#039;&#039;&#039; ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Dazu wird eine Umgebung mit einem 64-bit x86 Prozessor und mindestens Debian 11, Ubuntu 20.04 oder MacOS benötigt.&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
&lt;br /&gt;
# git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
# Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
Diese Variante wurde nicht weiter verfolgt, da das Repository rekursiv aufgelöst wird und das Klonen und Ausführen daher sehr viel Zeit in Anspruch nimmt.&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
# docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
Dieser Ansatz lädt ein Docker Image herunter, welches größer als 10GB ist. Entpackt hat es dann mehr als 30GB und ist daher als schneller Ansatz für die Entwicklung mit Matter-Geräten ebenfalls nicht tauglich.&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
Das Standalone-Matter-Device wurde relativ neu von Google publiziert, lässt sich aber sehr einfach aufsetzen. Durch seine vergleichsweise geringe Größe mit weniger als 70MB ist es einfach herunterzuladen und ist innerhalb weniger Minuten lauffähig.&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
Installationsschritte (Debian/Ubuntu)&lt;br /&gt;
# wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
# sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
# mvd&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Um mit dem Matter Device zu kommunizieren, wird eine GUI benötigt. Dazu gibt es wieder zwei Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Das Standalone MVD wird mit einer integrierten GUI geliefert, wobei das Gerät auf einem anderen Port (RPC-Port: 33000) angesprochen wird, als den Matter Port (Matter-Port: 5540).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14085</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14085"/>
		<updated>2024-01-26T13:48:09Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Matter&#039;&#039;&#039; ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Dazu wird eine Umgebung mit einem 64-bit x86 Prozessor und mindestens Debian 11, Ubuntu 20.04 oder MacOS benötigt.&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
1. git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
2. Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
Diese Variante wurde nicht weiter verfolgt, da das Repository rekursiv aufgelöst wird und das Klonen und Ausführen daher sehr viel Zeit in Anspruch nimmt.&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
1. docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
Dieser Ansatz lädt ein Docker Image herunter, welches größer als 10GB ist. Entpackt hat es dann mehr als 30GB und ist daher als schneller Ansatz für die Entwicklung mit Matter-Geräten ebenfalls nicht tauglich.&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
Das Standalone-Matter-Device wurde relativ neu von Google publiziert, lässt sich aber sehr einfach aufsetzen. Durch seine vergleichsweise geringe Größe mit weniger als 70MB ist es einfach herunterzuladen und ist innerhalb weniger Minuten lauffähig.&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
Installationsschritte (Debian/Ubuntu)&lt;br /&gt;
# wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
# sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
# mvd&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Um mit dem Matter Device zu kommunizieren, wird eine GUI benötigt. Dazu gibt es wieder zwei Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Das Standalone MVD wird mit einer integrierten GUI geliefert, wobei das Gerät auf einem anderen Port (RPC-Port: 33000) angesprochen wird, als den Matter Port (Matter-Port: 5540).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14084</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14084"/>
		<updated>2024-01-26T13:46:41Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Matter&#039;&#039;&#039; ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Dazu wird eine Umgebung mit einem 64-bit x86 Prozessor und mindestens Debian 11, Ubuntu 20.04 oder MacOS benötigt.&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
1. git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
2. Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
Diese Variante wurde nicht weiter verfolgt, da das Repository rekursiv aufgelöst wird und das Klonen und Ausführen daher sehr viel Zeit in Anspruch nimmt.&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
1. docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
Dieser Ansatz lädt ein Docker Image herunter, welches größer als 10GB ist. Entpackt hat es dann mehr als 30GB und ist daher als schneller Ansatz für die Entwicklung mit Matter-Geräten ebenfalls nicht tauglich.&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
Das Standalone-Matter-Device wurde relativ neu von Google publiziert, lässt sich aber sehr einfach aufsetzen. Durch seine vergleichsweise geringe Größe mit weniger als 70MB ist es einfach herunterzuladen und ist innerhalb weniger Minuten lauffähig.&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
Installationsschritte (Debian/Ubuntu)&lt;br /&gt;
1. wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
2. sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
3. mvd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Um mit dem Matter Device zu kommunizieren, wird eine GUI benötigt. Dazu gibt es wieder zwei Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Das Standalone MVD wird mit einer integrierten GUI geliefert, wobei das Gerät auf einem anderen Port (RPC-Port: 33000) angesprochen wird, als den Matter Port (Matter-Port: 5540).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14083</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14083"/>
		<updated>2024-01-26T13:32:51Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Matter&#039;&#039;&#039; ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Bei den anderen Möglichkeiten kann es sehr lange dauern.&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
1. git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
2. Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
3. Ab hier aufgehört, da dieses Skript viel zu lange dauert.&lt;br /&gt;
// Bilder&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
1. docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
2. Ab hier aufgehört, weil Gesamtimage 30.8 GB groß ist und nicht feasible für Constraint Devices&lt;br /&gt;
// Bilder&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
https://developers.home.google.com/matter/tools/virtual-device#install_mvd&lt;br /&gt;
&lt;br /&gt;
Das Standalone ist relativ neu von Google publiziert worden aber es lässt sich auf sehr einfacher Weise aufsetzen.&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
1. wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
2. sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
3. mvd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Um natürlich mit dem Device Matter zu kommunizieren, wird eine GUI benötigt, um das MVD anzusteuern. Dazu gibt es wieder zwei Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Das Standalone kommt mit einer internen GUI geliefert, wobei das Gerät auf einem anderen Port (RPC-Port: 33000) angesprochen wird, als den Matter Port (Matter-Port: 5540).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14082</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14082"/>
		<updated>2024-01-26T13:31:50Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Matter&#039;&#039;&#039; ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Bei den anderen Möglihckeiten kann es sehr lange dauern.&lt;br /&gt;
Das Set-U&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
1. git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
2. Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
3. Ab hier aufgehört, da dieses Skript viel zu lange dauert.&lt;br /&gt;
// Bilder&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
1. docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
2. Ab hier aufgehört, weil Gesamtimage 30.8 GB groß ist und nicht feasible für Constraint Devices&lt;br /&gt;
// Bilder&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
https://developers.home.google.com/matter/tools/virtual-device#install_mvd&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
1. wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
2. sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
3. mvd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14081</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14081"/>
		<updated>2024-01-26T13:30:27Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
```Matter``` ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Bei den anderen Möglihckeiten kann es sehr lange dauern.&lt;br /&gt;
Das Set-U&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
1. git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
2. Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
3. Ab hier aufgehört, da dieses Skript viel zu lange dauert.&lt;br /&gt;
// Bilder&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
1. docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
2. Ab hier aufgehört, weil Gesamtimage 30.8 GB groß ist und nicht feasible für Constraint Devices&lt;br /&gt;
// Bilder&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
https://developers.home.google.com/matter/tools/virtual-device#install_mvd&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
1. wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
2. sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
3. mvd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14080</id>
		<title>Matter</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Matter&amp;diff=14080"/>
		<updated>2024-01-26T13:30:12Z</updated>

		<summary type="html">&lt;p&gt;MBasta: Initial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;More, Better, Matter&lt;br /&gt;
===&lt;br /&gt;
&lt;br /&gt;
[[File:Matter_logo.jpg|thumb|Logo of Matter&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
```Matter``` ist ein offener Standard, der von der Arbeitsgruppe &amp;quot;Project Connected Home over IP&amp;quot; (kurz CHIP) seit 2019 entwickelt und im Oktober 2022 erstmals publiziert wurde. Er soll die Kommunikation zwischen Geräten diverser Hersteller wie Google, Samsung, Apple und Amazon ermöglichen und damit die Grenzen bestehender Smart-Home Netze erweitern.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich um ein Application-Layer-Protokoll, welches auf Netzwerkprotokolle wie IPv6, Thread und BLE aufsetzt. Um von IP-Netzwerken auf z.B. Thread- oder BLE-basierte Geräte zugreifen zu können werden Bridges benötigt, welche die Netzwerklayer übersetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Primer-matter-architecture.png|The Matter Stack in the TCP/IP and OSI Model]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Matter Virtual Device ==&lt;br /&gt;
Das Google Developer Center stellt Resourcen zur Entwicklung von Matter-basierten Geräten wie einer Sample App zum Verbinden von Matter-Geräten &amp;lt;ref name=&amp;quot;sample-app&amp;quot; /&amp;gt; oder virtuellen Matter-Geräten &amp;lt;ref name=&amp;quot;virtual-device&amp;quot; /&amp;gt; zum Testen der Schnittstellen bereit.&lt;br /&gt;
&lt;br /&gt;
Ein Matter Virtual Device (MVD) ist eine Emulation eines Matter Devices und simuliert das Verhalten eines Gerätes z.B. das Ein-/Ausschalten eines Lichtschalters.&lt;br /&gt;
&lt;br /&gt;
=== Möglichkeiten ===&lt;br /&gt;
Das Virtual Device kann man über mehrere Wege bauen und starten. Dazu wurden insgesamt drei Möglichkeiten gefunden:&lt;br /&gt;
&lt;br /&gt;
* Standalone&lt;br /&gt;
* Docker Image&lt;br /&gt;
* GitHub Repository&lt;br /&gt;
&lt;br /&gt;
Es hat sich herausgestellt, dass das Standalone am Besten geeignet ist, um schnell ein MVD einzurichten. Bei den anderen Möglihckeiten kann es sehr lange dauern.&lt;br /&gt;
Das Set-U&lt;br /&gt;
&lt;br /&gt;
==== GitHub Repository ====&lt;br /&gt;
1. git clone https://github.com/project-chip/connectedhomeip&lt;br /&gt;
2. Initialisieren des Matter-Projektes durch &amp;quot;source scripts/activate.sh&amp;quot;&lt;br /&gt;
3. Ab hier aufgehört, da dieses Skript viel zu lange dauert.&lt;br /&gt;
// Bilder&lt;br /&gt;
&lt;br /&gt;
==== Docker Image Repository ====&lt;br /&gt;
1. docker pull us-docker.pkg.dev/nest-matter/docker-repo/virtual-device-image:latest&lt;br /&gt;
2. Ab hier aufgehört, weil Gesamtimage 30.8 GB groß ist und nicht feasible für Constraint Devices&lt;br /&gt;
// Bilder&lt;br /&gt;
&lt;br /&gt;
==== Standalone ====&lt;br /&gt;
https://developers.home.google.com/matter/tools/virtual-device#install_mvd&lt;br /&gt;
&lt;br /&gt;
![](https://i.imgur.com/Rjqabwb.png)&lt;br /&gt;
&lt;br /&gt;
1. wget https://dl.google.com/mvd/mvd_1.3.0_amd64.deb&lt;br /&gt;
2. sudo dpkg -i mvd_1.3.0_amd64.deb&lt;br /&gt;
3. mvd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Controller GUI ===&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
&lt;br /&gt;
==== Internal GUI über RPC ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
&lt;br /&gt;
Bild&lt;br /&gt;
&lt;br /&gt;
==== GUI über Mobile App ====&lt;br /&gt;
Lorem Ipsum&lt;br /&gt;
Kotlin&lt;br /&gt;
Codelab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connection ===&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
Android Version&lt;br /&gt;
Google Play Version&lt;br /&gt;
Google Home App&lt;br /&gt;
&lt;br /&gt;
==== Steps ====&lt;br /&gt;
Get QR Code or Code from Logs&lt;br /&gt;
Scan QR or put in manual Code&lt;br /&gt;
Connected&lt;br /&gt;
&lt;br /&gt;
==== Security Aspekt ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;sample-app&amp;quot;&amp;gt;https://developers.home.google.com/codelabs/matter-sample-app#1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;virtual-device&amp;quot;&amp;gt;https://developers.home.google.com/tools/virtual-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=File:Primer-matter-architecture.png&amp;diff=14079</id>
		<title>File:Primer-matter-architecture.png</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=File:Primer-matter-architecture.png&amp;diff=14079"/>
		<updated>2024-01-26T13:29:06Z</updated>

		<summary type="html">&lt;p&gt;MBasta: TCP/IP and OSI Model of the Matter Stack.

Source: https://developers.home.google.com/matter/primer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
TCP/IP and OSI Model of the Matter Stack.&lt;br /&gt;
&lt;br /&gt;
Source: https://developers.home.google.com/matter/primer&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=File:Matter_logo.jpg&amp;diff=14078</id>
		<title>File:Matter logo.jpg</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=File:Matter_logo.jpg&amp;diff=14078"/>
		<updated>2024-01-26T13:19:04Z</updated>

		<summary type="html">&lt;p&gt;MBasta: Logo of the Matter standard.

Source: https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Logo of the Matter standard.&lt;br /&gt;
&lt;br /&gt;
Source: https://commons.wikimedia.org/wiki/File:Matter_logo.jpg&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13576</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13576"/>
		<updated>2024-01-06T13:04:45Z</updated>

		<summary type="html">&lt;p&gt;MBasta: /* Root Me */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:DefendTheWebNetLogo.png|thumb|Logo of DefendTheWeb.net&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&#039;&#039;&#039;Defend The Web&#039;&#039;&#039; is a Capture the Flag Website that teaches topic about Cyber Security and offers users on-hand-training for their theoretical skills. A free account is needed to access every section of the website. This can be either done by registering a new one from scratch or by using one of the available Single Sign On Providers (SSO Providers) Twitter (aka X), Google or GitHub. After logging in, the user gets redirected to a dashboard that offers information about new content in the articles and community sections as well as the progress in solving CTFs and the user&#039;s current level. Every user can earn medals by finishing challenges, participating in the community, writing articles and other actions on the website. &amp;lt;ref name=&amp;quot;dtw&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The landing page after logging in is the dashboard which consists of three main parts A) Articles, B) Playground and C) Community.&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
The article section consists of nine topics. Each article has a read time that depends on the length of the text as well as a counter of how many people have read it. The following list contains the topics and the number of articles within each topic at the time of writing. Topics in bold are directly accessible through the sidebar navigation within the dashboard.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Coding&#039;&#039;&#039; (11)&lt;br /&gt;
* &#039;&#039;&#039;Hacking&#039;&#039;&#039; (21)&lt;br /&gt;
* &#039;&#039;&#039;Privacy&#039;&#039;&#039; (2)&lt;br /&gt;
* Encryption and [https://en.wikipedia.org/wiki/Steganography Steganography] (9)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Lock_picking Lock Picking] (2)&lt;br /&gt;
* Network security (7)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Phreaking Phreaking] (1)&lt;br /&gt;
* Talks / videos (11)&lt;br /&gt;
* Miscellaneous (13)&lt;br /&gt;
&lt;br /&gt;
=== Playground ===&lt;br /&gt;
When navigating to the playground, the user is greeted with a list of all levels as well as a recommendation of the next level that may suit the current experience level. The challenges can be filtered using 12 categories.&lt;br /&gt;
Every challenge has a level which is one of bronze, silver or gold, to show the complexity of the challenge. Statistics on how many users have attempted a challenge and how many of them completed it are available after clicking on one of them. Information about who and when the challenge was solved first is available as well as who and when it was completed lastly.&lt;br /&gt;
All challenges, except those in the category realistic, are kept in the same style, requiring the user to enter data into one or more text fields and clicking a button to send the solution. From a usability perspective it is simple to use and easy to understand, focusing only on the objectives that need to be solved. Below the challenge itself, a notes field is available that gives the user the option to write down things that didn&#039;t work or ideas on how to solve the challenge to find those information at the next attempt. This notes are only visible to the user who wrote them and cannot be shared.&lt;br /&gt;
&lt;br /&gt;
=== Community ===&lt;br /&gt;
A forum and Chat function can be found in the community section as well as a function to exchange private messages between users. At the time of writing, the chat function was not working, but a workaround was mentioned in the forum. &amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Challenge Write-Up ==&lt;br /&gt;
&lt;br /&gt;
To show how the website works we will play one challenge from start to end. For this demonstration, we chose the challenge &#039;SQLi 1 / SQLi&#039;, which is a SQL injection CTF. As most challenges, we are facing a login screen with a short description of the objective. In this case we have to &#039;Gain access to any users account&#039; by providing an username and a password or by exploiting the site. We can also observe that more than 19,000 users have completed this challenge and that only 52\% of the users that attempted this challenge have actually completed it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionA.png|800px|Screenshot of the SQLInjection challenge page showing username and password field]]&lt;br /&gt;
&lt;br /&gt;
To solve this challenge we need some knowledge about SQL injections in general. Before frameworks made it easier and safer to write SQL statements, they were mostly written as strings and the variables were replaced by the script engine. This way an attacker could insert malicious symbols that change the way the query works. The following PHP code snippet uses unchecked user input and inserts it in a SQL query string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$username = $_POST[&#039;username&#039;]; &lt;br /&gt;
$password = $_POST[&#039;password&#039;]; &lt;br /&gt;
&lt;br /&gt;
$q = &amp;quot;SELECT * FROM users WHERE user=&#039;$username&#039; and pass=&#039;$password&#039;&amp;quot;; &lt;br /&gt;
$result = mysqli_query($connection, $q);&lt;br /&gt;
$count = mysqli_num_rows($result);&lt;br /&gt;
&lt;br /&gt;
if($count == 1) {  &lt;br /&gt;
 // User successfully logged in&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we suspect a similar query to be used in the background of the challenge, we use ambiguous characters to get more information. Using the username &amp;quot;silvie&amp;quot; and the password &amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt; (a single quote), we get back the error message &amp;lt;code&amp;gt;&amp;quot;Syntax error: SELECT * FROM users WHERE username = &#039;user&#039; AND password = &amp;lt;nowiki&amp;gt;&#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. We can now see the used query and that the single quote invalidated it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionB.png|600px|Screenshot of the SQLInjection challenge error page the failed execution as stated in the paragraph above]]&lt;br /&gt;
&lt;br /&gt;
For the exploit itself we can now use any username, as the script will not check this anyway after our changes, and the password &amp;lt;code&amp;gt;&amp;quot;&#039; OR 1=1;&amp;quot;&amp;lt;/code&amp;gt;. The query will be rendered in the background to &amp;lt;code&amp;gt;&amp;quot;SELECT * FROM users WHERE username = &#039;silvie&#039; AND password = &#039;&#039; OR 1=1;&#039;&amp;quot;&amp;lt;/code&amp;gt;. The query now evaluates two parts, the one before the OR and the other after. The first one will probably fail because the user may not exist or even if it does, the password will probably not be empty. The second part will always be true, because 1 equals 1. The single quote at the end will be ignored, because we added a semicolon at the end that finishes the query.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionC.png|400px|Screenshot of the SQLInjection challenge succeeded]]&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
=== Root Me ===&lt;br /&gt;
The CTF platform [[Root_Me|Root Me]] has established only two years after Defend The Web in 2010, but offers already more than 540 challenges. &amp;lt;ref name=&amp;quot;rmchallenges&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hack The Box ===&lt;br /&gt;
Another alternative is [https://www.hackthebox.com Hack The Box], which offers over 500 challenges &amp;lt;ref name=&amp;quot;htbchallenges&amp;quot;/&amp;gt; but also attracts by doing community events all over the world. &amp;lt;ref name=&amp;quot;htbcommunityevents&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;dtw&amp;quot;&amp;gt;https://defendtheweb.net&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://www.facebook.com/defendtheweb/photos/a.163821580333961/2395529793829784/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;&amp;gt;https://defendtheweb.net/discussion/83648-irc-chat&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;htbcommunityevents&amp;quot;&amp;gt;https://www.hackthebox.com/events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;rmchallenges&amp;quot;&amp;gt;https://www.root-me.org/en/Challenges/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;htbchallenges&amp;quot;&amp;gt;https://www.hackthebox.com/about-us&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* https://defendtheweb.net&lt;br /&gt;
* https://owasp.org/www-project-top-ten/&lt;br /&gt;
* https://www.root-me.org&lt;br /&gt;
* https://www.hackthebox.com&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13575</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13575"/>
		<updated>2024-01-06T13:03:12Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:DefendTheWebNetLogo.png|thumb|Logo of DefendTheWeb.net&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&#039;&#039;&#039;Defend The Web&#039;&#039;&#039; is a Capture the Flag Website that teaches topic about Cyber Security and offers users on-hand-training for their theoretical skills. A free account is needed to access every section of the website. This can be either done by registering a new one from scratch or by using one of the available Single Sign On Providers (SSO Providers) Twitter (aka X), Google or GitHub. After logging in, the user gets redirected to a dashboard that offers information about new content in the articles and community sections as well as the progress in solving CTFs and the user&#039;s current level. Every user can earn medals by finishing challenges, participating in the community, writing articles and other actions on the website. &amp;lt;ref name=&amp;quot;dtw&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The landing page after logging in is the dashboard which consists of three main parts A) Articles, B) Playground and C) Community.&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
The article section consists of nine topics. Each article has a read time that depends on the length of the text as well as a counter of how many people have read it. The following list contains the topics and the number of articles within each topic at the time of writing. Topics in bold are directly accessible through the sidebar navigation within the dashboard.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Coding&#039;&#039;&#039; (11)&lt;br /&gt;
* &#039;&#039;&#039;Hacking&#039;&#039;&#039; (21)&lt;br /&gt;
* &#039;&#039;&#039;Privacy&#039;&#039;&#039; (2)&lt;br /&gt;
* Encryption and [https://en.wikipedia.org/wiki/Steganography Steganography] (9)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Lock_picking Lock Picking] (2)&lt;br /&gt;
* Network security (7)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Phreaking Phreaking] (1)&lt;br /&gt;
* Talks / videos (11)&lt;br /&gt;
* Miscellaneous (13)&lt;br /&gt;
&lt;br /&gt;
=== Playground ===&lt;br /&gt;
When navigating to the playground, the user is greeted with a list of all levels as well as a recommendation of the next level that may suit the current experience level. The challenges can be filtered using 12 categories.&lt;br /&gt;
Every challenge has a level which is one of bronze, silver or gold, to show the complexity of the challenge. Statistics on how many users have attempted a challenge and how many of them completed it are available after clicking on one of them. Information about who and when the challenge was solved first is available as well as who and when it was completed lastly.&lt;br /&gt;
All challenges, except those in the category realistic, are kept in the same style, requiring the user to enter data into one or more text fields and clicking a button to send the solution. From a usability perspective it is simple to use and easy to understand, focusing only on the objectives that need to be solved. Below the challenge itself, a notes field is available that gives the user the option to write down things that didn&#039;t work or ideas on how to solve the challenge to find those information at the next attempt. This notes are only visible to the user who wrote them and cannot be shared.&lt;br /&gt;
&lt;br /&gt;
=== Community ===&lt;br /&gt;
A forum and Chat function can be found in the community section as well as a function to exchange private messages between users. At the time of writing, the chat function was not working, but a workaround was mentioned in the forum. &amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Challenge Write-Up ==&lt;br /&gt;
&lt;br /&gt;
To show how the website works we will play one challenge from start to end. For this demonstration, we chose the challenge &#039;SQLi 1 / SQLi&#039;, which is a SQL injection CTF. As most challenges, we are facing a login screen with a short description of the objective. In this case we have to &#039;Gain access to any users account&#039; by providing an username and a password or by exploiting the site. We can also observe that more than 19,000 users have completed this challenge and that only 52\% of the users that attempted this challenge have actually completed it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionA.png|800px|Screenshot of the SQLInjection challenge page showing username and password field]]&lt;br /&gt;
&lt;br /&gt;
To solve this challenge we need some knowledge about SQL injections in general. Before frameworks made it easier and safer to write SQL statements, they were mostly written as strings and the variables were replaced by the script engine. This way an attacker could insert malicious symbols that change the way the query works. The following PHP code snippet uses unchecked user input and inserts it in a SQL query string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$username = $_POST[&#039;username&#039;]; &lt;br /&gt;
$password = $_POST[&#039;password&#039;]; &lt;br /&gt;
&lt;br /&gt;
$q = &amp;quot;SELECT * FROM users WHERE user=&#039;$username&#039; and pass=&#039;$password&#039;&amp;quot;; &lt;br /&gt;
$result = mysqli_query($connection, $q);&lt;br /&gt;
$count = mysqli_num_rows($result);&lt;br /&gt;
&lt;br /&gt;
if($count == 1) {  &lt;br /&gt;
 // User successfully logged in&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we suspect a similar query to be used in the background of the challenge, we use ambiguous characters to get more information. Using the username &amp;quot;silvie&amp;quot; and the password &amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt; (a single quote), we get back the error message &amp;lt;code&amp;gt;&amp;quot;Syntax error: SELECT * FROM users WHERE username = &#039;user&#039; AND password = &amp;lt;nowiki&amp;gt;&#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. We can now see the used query and that the single quote invalidated it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionB.png|600px|Screenshot of the SQLInjection challenge error page the failed execution as stated in the paragraph above]]&lt;br /&gt;
&lt;br /&gt;
For the exploit itself we can now use any username, as the script will not check this anyway after our changes, and the password &amp;lt;code&amp;gt;&amp;quot;&#039; OR 1=1;&amp;quot;&amp;lt;/code&amp;gt;. The query will be rendered in the background to &amp;lt;code&amp;gt;&amp;quot;SELECT * FROM users WHERE username = &#039;silvie&#039; AND password = &#039;&#039; OR 1=1;&#039;&amp;quot;&amp;lt;/code&amp;gt;. The query now evaluates two parts, the one before the OR and the other after. The first one will probably fail because the user may not exist or even if it does, the password will probably not be empty. The second part will always be true, because 1 equals 1. The single quote at the end will be ignored, because we added a semicolon at the end that finishes the query.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionC.png|400px|Screenshot of the SQLInjection challenge succeeded]]&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
=== Root Me ===&lt;br /&gt;
The CTF platform [https://www.root-me.org Root Me] has established only two years after Defend The Web in 2010, but offers already more than 540 challenges. &amp;lt;ref name=&amp;quot;rmchallenges&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hack The Box ===&lt;br /&gt;
Another alternative is [https://www.hackthebox.com Hack The Box], which offers over 500 challenges &amp;lt;ref name=&amp;quot;htbchallenges&amp;quot;/&amp;gt; but also attracts by doing community events all over the world. &amp;lt;ref name=&amp;quot;htbcommunityevents&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;dtw&amp;quot;&amp;gt;https://defendtheweb.net&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://www.facebook.com/defendtheweb/photos/a.163821580333961/2395529793829784/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;&amp;gt;https://defendtheweb.net/discussion/83648-irc-chat&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;htbcommunityevents&amp;quot;&amp;gt;https://www.hackthebox.com/events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;rmchallenges&amp;quot;&amp;gt;https://www.root-me.org/en/Challenges/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;htbchallenges&amp;quot;&amp;gt;https://www.hackthebox.com/about-us&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* https://defendtheweb.net&lt;br /&gt;
* https://owasp.org/www-project-top-ten/&lt;br /&gt;
* https://www.root-me.org&lt;br /&gt;
* https://www.hackthebox.com&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13574</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13574"/>
		<updated>2024-01-06T13:02:02Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:DefendTheWebNetLogo.png|thumb|Logo of DefendTheWeb.net&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&#039;&#039;&#039;Defend The Web&#039;&#039;&#039; is a Capture the Flag Website that teaches topic about Cyber Security and offers users on-hand-training for their theoretical skills. A free account is needed to access every section of the website. This can be either done by registering a new one from scratch or by using one of the available Single Sign On Providers (SSO Providers) Twitter (aka X), Google or GitHub. After logging in, the user gets redirected to a dashboard that offers information about new content in the articles and community sections as well as the progress in solving CTFs and the user&#039;s current level. Every user can earn medals by finishing challenges, participating in the community, writing articles and other actions on the website.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The landing page after logging in is the dashboard which consists of three main parts A) Articles, B) Playground and C) Community.&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
The article section consists of nine topics. Each article has a read time that depends on the length of the text as well as a counter of how many people have read it. The following list contains the topics and the number of articles within each topic at the time of writing. Topics in bold are directly accessible through the sidebar navigation within the dashboard.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Coding&#039;&#039;&#039; (11)&lt;br /&gt;
* &#039;&#039;&#039;Hacking&#039;&#039;&#039; (21)&lt;br /&gt;
* &#039;&#039;&#039;Privacy&#039;&#039;&#039; (2)&lt;br /&gt;
* Encryption and [https://en.wikipedia.org/wiki/Steganography Steganography] (9)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Lock_picking Lock Picking] (2)&lt;br /&gt;
* Network security (7)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Phreaking Phreaking] (1)&lt;br /&gt;
* Talks / videos (11)&lt;br /&gt;
* Miscellaneous (13)&lt;br /&gt;
&lt;br /&gt;
=== Playground ===&lt;br /&gt;
When navigating to the playground, the user is greeted with a list of all levels as well as a recommendation of the next level that may suit the current experience level. The challenges can be filtered using 12 categories.&lt;br /&gt;
Every challenge has a level which is one of bronze, silver or gold, to show the complexity of the challenge. Statistics on how many users have attempted a challenge and how many of them completed it are available after clicking on one of them. Information about who and when the challenge was solved first is available as well as who and when it was completed lastly.&lt;br /&gt;
All challenges, except those in the category realistic, are kept in the same style, requiring the user to enter data into one or more text fields and clicking a button to send the solution. From a usability perspective it is simple to use and easy to understand, focusing only on the objectives that need to be solved. Below the challenge itself, a notes field is available that gives the user the option to write down things that didn&#039;t work or ideas on how to solve the challenge to find those information at the next attempt. This notes are only visible to the user who wrote them and cannot be shared.&lt;br /&gt;
&lt;br /&gt;
=== Community ===&lt;br /&gt;
A forum and Chat function can be found in the community section as well as a function to exchange private messages between users. At the time of writing, the chat function was not working, but a workaround was mentioned in the forum. &amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Challenge Write-Up ==&lt;br /&gt;
&lt;br /&gt;
To show how the website works we will play one challenge from start to end. For this demonstration, we chose the challenge &#039;SQLi 1 / SQLi&#039;, which is a SQL injection CTF. As most challenges, we are facing a login screen with a short description of the objective. In this case we have to &#039;Gain access to any users account&#039; by providing an username and a password or by exploiting the site. We can also observe that more than 19,000 users have completed this challenge and that only 52\% of the users that attempted this challenge have actually completed it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionA.png|800px|Screenshot of the SQLInjection challenge page showing username and password field]]&lt;br /&gt;
&lt;br /&gt;
To solve this challenge we need some knowledge about SQL injections in general. Before frameworks made it easier and safer to write SQL statements, they were mostly written as strings and the variables were replaced by the script engine. This way an attacker could insert malicious symbols that change the way the query works. The following PHP code snippet uses unchecked user input and inserts it in a SQL query string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$username = $_POST[&#039;username&#039;]; &lt;br /&gt;
$password = $_POST[&#039;password&#039;]; &lt;br /&gt;
&lt;br /&gt;
$q = &amp;quot;SELECT * FROM users WHERE user=&#039;$username&#039; and pass=&#039;$password&#039;&amp;quot;; &lt;br /&gt;
$result = mysqli_query($connection, $q);&lt;br /&gt;
$count = mysqli_num_rows($result);&lt;br /&gt;
&lt;br /&gt;
if($count == 1) {  &lt;br /&gt;
 // User successfully logged in&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we suspect a similar query to be used in the background of the challenge, we use ambiguous characters to get more information. Using the username &amp;quot;silvie&amp;quot; and the password &amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt; (a single quote), we get back the error message &amp;lt;code&amp;gt;&amp;quot;Syntax error: SELECT * FROM users WHERE username = &#039;user&#039; AND password = &amp;lt;nowiki&amp;gt;&#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. We can now see the used query and that the single quote invalidated it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionB.png|600px|Screenshot of the SQLInjection challenge error page the failed execution as stated in the paragraph above]]&lt;br /&gt;
&lt;br /&gt;
For the exploit itself we can now use any username, as the script will not check this anyway after our changes, and the password &amp;lt;code&amp;gt;&amp;quot;&#039; OR 1=1;&amp;quot;&amp;lt;/code&amp;gt;. The query will be rendered in the background to &amp;lt;code&amp;gt;&amp;quot;SELECT * FROM users WHERE username = &#039;silvie&#039; AND password = &#039;&#039; OR 1=1;&#039;&amp;quot;&amp;lt;/code&amp;gt;. The query now evaluates two parts, the one before the OR and the other after. The first one will probably fail because the user may not exist or even if it does, the password will probably not be empty. The second part will always be true, because 1 equals 1. The single quote at the end will be ignored, because we added a semicolon at the end that finishes the query.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionC.png|400px|Screenshot of the SQLInjection challenge succeeded]]&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
=== Root Me ===&lt;br /&gt;
The CTF platform [https://www.root-me.org Root Me] has established only two years after Defend The Web in 2010, but offers already more than 540 challenges. &amp;lt;ref name=&amp;quot;rmchallenges&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hack The Box ===&lt;br /&gt;
Another alternative is [https://www.hackthebox.com Hack The Box], which offers over 500 challenges &amp;lt;ref name=&amp;quot;htbchallenges&amp;quot;/&amp;gt; but also attracts by doing community events all over the world. &amp;lt;ref name=&amp;quot;htbcommunityevents&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://www.facebook.com/defendtheweb/photos/a.163821580333961/2395529793829784/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;&amp;gt;https://defendtheweb.net/discussion/83648-irc-chat&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;htbcommunityevents&amp;quot;&amp;gt;https://www.hackthebox.com/events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;rmchallenges&amp;quot;&amp;gt;https://www.root-me.org/en/Challenges/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;htbchallenges&amp;quot;&amp;gt;https://www.hackthebox.com/about-us&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* https://defendtheweb.net&lt;br /&gt;
* https://owasp.org/www-project-top-ten/&lt;br /&gt;
* https://www.root-me.org&lt;br /&gt;
* https://www.hackthebox.com&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13573</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13573"/>
		<updated>2024-01-06T12:58:44Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:DefendTheWebNetLogo.png|thumb|Logo of DefendTheWeb.net&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&#039;&#039;&#039;Defend The Web&#039;&#039;&#039; is a Capture the Flag Website that teaches topic about Cyber Security and offers users on-hand-training for their theoretical skills. A free account is needed to access every section of the website. This can be either done by registering a new one from scratch or by using one of the available Single Sign On Providers (SSO Providers) Twitter (aka X), Google or GitHub. After logging in, the user gets redirected to a dashboard that offers information about new content in the articles and community sections as well as the progress in solving CTFs and the user&#039;s current level. Every user can earn medals by finishing challenges, participating in the community, writing articles and other actions on the website.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The landing page after logging in is the dashboard which consists of three main parts A) Articles, B) Playground and C) Community.&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
The article section consists of nine topics. Each article has a read time that depends on the length of the text as well as a counter of how many people have read it. The following list contains the topics and the number of articles within each topic at the time of writing. Topics in bold are directly accessible through the sidebar navigation within the dashboard.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Coding&#039;&#039;&#039; (11)&lt;br /&gt;
* &#039;&#039;&#039;Hacking&#039;&#039;&#039; (21)&lt;br /&gt;
* &#039;&#039;&#039;Privacy&#039;&#039;&#039; (2)&lt;br /&gt;
* Encryption and [https://en.wikipedia.org/wiki/Steganography Steganography] (9)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Lock_picking Lock Picking] (2)&lt;br /&gt;
* Network security (7)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Phreaking Phreaking] (1)&lt;br /&gt;
* Talks / videos (11)&lt;br /&gt;
* Miscellaneous (13)&lt;br /&gt;
&lt;br /&gt;
=== Playground ===&lt;br /&gt;
When navigating to the playground, the user is greeted with a list of all levels as well as a recommendation of the next level that may suit the current experience level. The challenges can be filtered using 12 categories.&lt;br /&gt;
Every challenge has a level which is one of bronze, silver or gold, to show the complexity of the challenge. Statistics on how many users have attempted a challenge and how many of them completed it are available after clicking on one of them. Information about who and when the challenge was solved first is available as well as who and when it was completed lastly.&lt;br /&gt;
All challenges, except those in the category realistic, are kept in the same style, requiring the user to enter data into one or more text fields and clicking a button to send the solution. From a usability perspective it is simple to use and easy to understand, focusing only on the objectives that need to be solved. Below the challenge itself, a notes field is available that gives the user the option to write down things that didn&#039;t work or ideas on how to solve the challenge to find those information at the next attempt. This notes are only visible to the user who wrote them and cannot be shared.&lt;br /&gt;
&lt;br /&gt;
=== Community ===&lt;br /&gt;
A forum and Chat function can be found in the community section as well as a function to exchange private messages between users. At the time of writing, the chat function was not working, but a workaround was mentioned in the forum. &amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Challenge Write-Up ==&lt;br /&gt;
&lt;br /&gt;
To show how the website works we will play one challenge from start to end. For this demonstration, we chose the challenge &#039;SQLi 1 / SQLi&#039;, which is a SQL injection CTF. As most challenges, we are facing a login screen with a short description of the objective. In this case we have to &#039;Gain access to any users account&#039; by providing an username and a password or by exploiting the site. We can also observe that more than 19,000 users have completed this challenge and that only 52\% of the users that attempted this challenge have actually completed it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionA.png|800px|Screenshot of the SQLInjection challenge page showing username and password field]]&lt;br /&gt;
&lt;br /&gt;
To solve this challenge we need some knowledge about SQL injections in general. Before frameworks made it easier and safer to write SQL statements, they were mostly written as strings and the variables were replaced by the script engine. This way an attacker could insert malicious symbols that change the way the query works. The following PHP code snippet uses unchecked user input and inserts it in a SQL query string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$username = $_POST[&#039;username&#039;]; &lt;br /&gt;
$password = $_POST[&#039;password&#039;]; &lt;br /&gt;
&lt;br /&gt;
$q = &amp;quot;SELECT * FROM users WHERE user=&#039;$username&#039; and pass=&#039;$password&#039;&amp;quot;; &lt;br /&gt;
$result = mysqli_query($connection, $q);&lt;br /&gt;
$count = mysqli_num_rows($result);&lt;br /&gt;
&lt;br /&gt;
if($count == 1) {  &lt;br /&gt;
 // User successfully logged in&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we suspect a similar query to be used in the background of the challenge, we use ambiguous characters to get more information. Using the username &amp;quot;username&amp;quot; and the password &amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt; (a single quote), we get back the error message &amp;lt;code&amp;gt;&amp;quot;Syntax error: SELECT * FROM users WHERE username = &#039;user&#039; AND password = &amp;lt;nowiki&amp;gt;&#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. We can now see the used query and that the single quote invalidated it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionB.png|600px|Screenshot of the SQLInjection challenge error page the failed execution as stated in the paragraph above]]&lt;br /&gt;
&lt;br /&gt;
For the exploit itself we can now use any username, as the script will not check this anyway after our changes, and the password &amp;lt;code&amp;gt;&amp;quot;&#039; OR 1=1;&amp;quot;&amp;lt;/code&amp;gt;. The query will be rendered in the background to &amp;lt;code&amp;gt;&amp;quot;SELECT * FROM users WHERE username = &#039;silvie&#039; AND password = &#039;&#039; OR 1=1;&#039;&amp;quot;&amp;lt;/code&amp;gt;. The query now evaluates two parts, the one before the OR and the other after. The first one will probably fail because the user may not exist or even if it does, the password will probably not be empty. The second part will always be true, because 1 equals 1. The single quote at the end will be ignored, because we added a semicolon at the end that finishes the query.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionC.png|400px|Screenshot of the SQLInjection challenge succeeded]]&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
=== Root Me ===&lt;br /&gt;
The CTF platform [https://www.root-me.org Root Me] has established only two years after Defend The Web in 2010, but offers already more than 540 challenges. &amp;lt;ref name=&amp;quot;rmchallenges&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hack The Box ===&lt;br /&gt;
Another alternative is [https://www.hackthebox.com Hack The Box], which offers over 500 challenges &amp;lt;ref name=&amp;quot;htbchallenges&amp;quot;/&amp;gt; but also attracts by doing community events all over the world. &amp;lt;ref name=&amp;quot;htbcommunityevents&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://www.facebook.com/defendtheweb/photos/a.163821580333961/2395529793829784/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;&amp;gt;https://defendtheweb.net/discussion/83648-irc-chat&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;htbcommunityevents&amp;quot;&amp;gt;https://www.hackthebox.com/events&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;rmchallenges&amp;quot;&amp;gt;https://www.root-me.org/en/Challenges/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;htbchallenges&amp;quot;&amp;gt;https://www.hackthebox.com/about-us&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetSqlInjectionC.png&amp;diff=13572</id>
		<title>File:DefendTheWebNetSqlInjectionC.png</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetSqlInjectionC.png&amp;diff=13572"/>
		<updated>2024-01-06T12:40:04Z</updated>

		<summary type="html">&lt;p&gt;MBasta: DefendTheWeb.net Screenshot of the SQL Injection Challenge succeeded&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
DefendTheWeb.net Screenshot of the SQL Injection Challenge succeeded&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13571</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13571"/>
		<updated>2024-01-06T12:38:58Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:DefendTheWebNetLogo.png|thumb|Logo of DefendTheWeb.net&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&#039;&#039;&#039;Defend The Web&#039;&#039;&#039; is a Capture the Flag Website that teaches topic about Cyber Security and offers users on-hand-training for their theoretical skills. A free account is needed to access every section of the website. This can be either done by registering a new one from scratch or by using one of the available Single Sign On Providers (SSO Providers) Twitter (aka X), Google or GitHub. After logging in, the user gets redirected to a dashboard that offers information about new content in the articles and community sections as well as the progress in solving CTFs and the user&#039;s current level. Every user can earn medals by finishing challenges, participating in the community, writing articles and other actions on the website.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The landing page after logging in is the dashboard which consists of three main parts A) Articles, B) Playground and C) Community.&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
The article section consists of nine topics. Each article has a read time that depends on the length of the text as well as a counter of how many people have read it. The following list contains the topics and the number of articles within each topic at the time of writing. Topics in bold are directly accessible through the sidebar navigation within the dashboard.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Coding&#039;&#039;&#039; (11)&lt;br /&gt;
* &#039;&#039;&#039;Hacking&#039;&#039;&#039; (21)&lt;br /&gt;
* &#039;&#039;&#039;Privacy&#039;&#039;&#039; (2)&lt;br /&gt;
* Encryption and [https://en.wikipedia.org/wiki/Steganography Steganography] (9)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Lock_picking Lock Picking] (2)&lt;br /&gt;
* Network security (7)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Phreaking Phreaking] (1)&lt;br /&gt;
* Talks / videos (11)&lt;br /&gt;
* Miscellaneous (13)&lt;br /&gt;
&lt;br /&gt;
=== Playground ===&lt;br /&gt;
When navigating to the playground, the user is greeted with a list of all levels as well as a recommendation of the next level that may suit the current experience level. The challenges can be filtered using 12 categories.&lt;br /&gt;
Every challenge has a level which is one of bronze, silver or gold, to show the complexity of the challenge. Statistics on how many users have attempted a challenge and how many of them completed it are available after clicking on one of them. Information about who and when the challenge was solved first is available as well as who and when it was completed lastly.&lt;br /&gt;
All challenges, except those in the category realistic, are kept in the same style, requiring the user to enter data into one or more text fields and clicking a button to send the solution. From a usability perspective it is simple to use and easy to understand, focusing only on the objectives that need to be solved. Below the challenge itself, a notes field is available that gives the user the option to write down things that didn&#039;t work or ideas on how to solve the challenge to find those information at the next attempt. This notes are only visible to the user who wrote them and cannot be shared.&lt;br /&gt;
&lt;br /&gt;
=== Community ===&lt;br /&gt;
A forum and Chat function can be found in the community section as well as a function to exchange private messages between users. At the time of writing, the chat function was not working, but a workaround was mentioned in the forum. &amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Challenge Write-Up ==&lt;br /&gt;
&lt;br /&gt;
To show how the website works we will play one challenge from start to end. For this demonstration, we chose the challenge &#039;SQLi 1 / SQLi&#039;, which is a SQL injection CTF. As most challenges, we are facing a login screen with a short description of the objective. In this case we have to &#039;Gain access to any users account&#039; by providing an username and a password or by exploiting the site. We can also observe that more than 19,000 users have completed this challenge and that only 52\% of the users that attempted this challenge have actually completed it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionA.png|800px|Screenshot of the SQLInjection challenge page showing username and password field]]&lt;br /&gt;
&lt;br /&gt;
To solve this challenge we need some knowledge about SQL injections in general. Before frameworks made it easier and safer to write SQL statements, they were mostly written as strings and the variables were replaced by the script engine. This way an attacker could insert malicious symbols that change the way the query works. The following PHP code snippet uses unchecked user input and inserts it in a SQL query string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$username = $_POST[&#039;username&#039;]; &lt;br /&gt;
$password = $_POST[&#039;password&#039;]; &lt;br /&gt;
&lt;br /&gt;
$q = &amp;quot;SELECT * FROM users WHERE user=&#039;$username&#039; and pass=&#039;$password&#039;&amp;quot;; &lt;br /&gt;
$result = mysqli_query($connection, $q);&lt;br /&gt;
$count = mysqli_num_rows($result);&lt;br /&gt;
&lt;br /&gt;
if($count == 1) {  &lt;br /&gt;
 // User successfully logged in&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we suspect a similar query to be used in the background of the challenge, we use ambiguous characters to get more information. Using the username &amp;quot;username&amp;quot; and the password &amp;quot;&#039;&amp;quot; (a simple quote), we get back the error message &amp;quot;Syntax error: SELECT * FROM users WHERE username = &#039;user&#039; AND password = &#039;&#039;&#039;&amp;quot;. We can now see the used query and that the single quote invalidated it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionB.png|600px|Screenshot of the SQLInjection challenge error page the failed execution as stated in the paragraph above]]&lt;br /&gt;
&lt;br /&gt;
For the exploit itself we can now use any username, as the script will not check this anyway after our changes, and the password &amp;quot;&#039; OR 1=1;&amp;quot;. The query will be rendered in the background to &amp;quot;SELECT * FROM users WHERE username = &#039;silvie&#039; AND password = &#039;&#039; OR 1=1;&#039;&amp;quot;. The query now evaluates two parts, the one before the OR and the other after. The first one will probably fail because the user may not exist or even if it does, the password will probably not be empty. The second part will always be true, because 1 equals 1. The single quote at the end will be ignored, because we added a semicolon at the end that finishes the query.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionC.png|600px|Screenshot of the SQLInjection challenge succeeded]]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://www.facebook.com/defendtheweb/photos/a.163821580333961/2395529793829784/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;&amp;gt;https://defendtheweb.net/discussion/83648-irc-chat&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetSqlInjectionB.png&amp;diff=13570</id>
		<title>File:DefendTheWebNetSqlInjectionB.png</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetSqlInjectionB.png&amp;diff=13570"/>
		<updated>2024-01-06T12:37:08Z</updated>

		<summary type="html">&lt;p&gt;MBasta: Screenshot of the SQLInjection challenge error page showing the message &amp;quot;Syntax error: SELECT * FROM users WHERE username = &amp;#039;user&amp;#039; AND password = &amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Screenshot of the SQLInjection challenge error page showing the message &amp;quot;Syntax error: SELECT * FROM users WHERE username = &#039;user&#039; AND password = &amp;quot;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetSqlInjectionA.png&amp;diff=13569</id>
		<title>File:DefendTheWebNetSqlInjectionA.png</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetSqlInjectionA.png&amp;diff=13569"/>
		<updated>2024-01-06T12:32:07Z</updated>

		<summary type="html">&lt;p&gt;MBasta: MBasta uploaded a new version of File:DefendTheWebNetSqlInjectionA.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Screenshot of the DefendTheWeb.net SQL Injection Challange 1 showing a username and password field as well as a submit button.&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13568</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13568"/>
		<updated>2024-01-06T12:32:05Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:DefendTheWebNetLogo.png|thumb|Logo of DefendTheWeb.net&amp;lt;ref name=&amp;quot;logo&amp;quot;/&amp;gt;]]&lt;br /&gt;
&#039;&#039;&#039;Defend The Web&#039;&#039;&#039; is a Capture the Flag Website that teaches topic about Cyber Security and offers users on-hand-training for their theoretical skills. A free account is needed to access every section of the website. This can be either done by registering a new one from scratch or by using one of the available Single Sign On Providers (SSO Providers) Twitter (aka X), Google or GitHub. After logging in, the user gets redirected to a dashboard that offers information about new content in the articles and community sections as well as the progress in solving CTFs and the user&#039;s current level. Every user can earn medals by finishing challenges, participating in the community, writing articles and other actions on the website.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The landing page after logging in is the dashboard which consists of three main parts A) Articles, B) Playground and C) Community.&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
The article section consists of nine topics. Each article has a read time that depends on the length of the text as well as a counter of how many people have read it. The following list contains the topics and the number of articles within each topic at the time of writing. Topics in bold are directly accessible through the sidebar navigation within the dashboard.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Coding&#039;&#039;&#039; (11)&lt;br /&gt;
* &#039;&#039;&#039;Hacking&#039;&#039;&#039; (21)&lt;br /&gt;
* &#039;&#039;&#039;Privacy&#039;&#039;&#039; (2)&lt;br /&gt;
* Encryption and [https://en.wikipedia.org/wiki/Steganography Steganography] (9)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Lock_picking Lock Picking] (2)&lt;br /&gt;
* Network security (7)&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Phreaking Phreaking] (1)&lt;br /&gt;
* Talks / videos (11)&lt;br /&gt;
* Miscellaneous (13)&lt;br /&gt;
&lt;br /&gt;
=== Playground ===&lt;br /&gt;
When navigating to the playground, the user is greeted with a list of all levels as well as a recommendation of the next level that may suit the current experience level. The challenges can be filtered using 12 categories.&lt;br /&gt;
Every challenge has a level which is one of bronze, silver or gold, to show the complexity of the challenge. Statistics on how many users have attempted a challenge and how many of them completed it are available after clicking on one of them. Information about who and when the challenge was solved first is available as well as who and when it was completed lastly.&lt;br /&gt;
All challenges, except those in the category realistic, are kept in the same style, requiring the user to enter data into one or more text fields and clicking a button to send the solution. From a usability perspective it is simple to use and easy to understand, focusing only on the objectives that need to be solved. Below the challenge itself, a notes field is available that gives the user the option to write down things that didn&#039;t work or ideas on how to solve the challenge to find those information at the next attempt. This notes are only visible to the user who wrote them and cannot be shared.&lt;br /&gt;
&lt;br /&gt;
=== Community ===&lt;br /&gt;
A forum and Chat function can be found in the community section as well as a function to exchange private messages between users. At the time of writing, the chat function was not working, but a workaround was mentioned in the forum. &amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Challenge Write-Up ==&lt;br /&gt;
&lt;br /&gt;
To show how the website works we will play one challenge from start to end. For this demonstration, we chose the challenge &#039;SQLi 1 / SQLi&#039;, which is a SQL injection CTF. As most challenges, we are facing a login screen with a short description of the objective. In this case we have to &#039;Gain access to any users account&#039; by providing an username and a password or by exploiting the site. We can also observe that more than 19,000 users have completed this challenge and that only 52\% of the users that attempted this challenge have actually completed it.&lt;br /&gt;
&lt;br /&gt;
[[File:DefendTheWebNetSqlInjectionA.png|600px|Screenshot of the SQLInjection challenge page showing username and password field]]&lt;br /&gt;
&lt;br /&gt;
To solve this challenge we need some knowledge about SQL injections in general. Before frameworks made it easier and safer to write SQL statements, they were mostly written as strings and the variables were replaced by the script engine. This way an attacker could insert malicious symbols that change the way the query works. The following PHP code snippet uses unchecked user input and inserts it in a SQL query string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$username = $_POST[&#039;username&#039;]; &lt;br /&gt;
$password = $_POST[&#039;password&#039;]; &lt;br /&gt;
&lt;br /&gt;
$q = &amp;quot;SELECT * FROM users WHERE user=&#039;$username&#039; and pass=&#039;$password&#039;&amp;quot;; &lt;br /&gt;
$result = mysqli_query($connection, $q);&lt;br /&gt;
$count = mysqli_num_rows($result);&lt;br /&gt;
&lt;br /&gt;
if($count == 1) {  &lt;br /&gt;
 // User successfully logged in&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;logo&amp;quot;&amp;gt;https://www.facebook.com/defendtheweb/photos/a.163821580333961/2395529793829784/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chatworkaround&amp;quot;&amp;gt;https://defendtheweb.net/discussion/83648-irc-chat&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetSqlInjectionA.png&amp;diff=13567</id>
		<title>File:DefendTheWebNetSqlInjectionA.png</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetSqlInjectionA.png&amp;diff=13567"/>
		<updated>2024-01-06T12:29:33Z</updated>

		<summary type="html">&lt;p&gt;MBasta: Screenshot of the DefendTheWeb.net SQL Injection Challange 1 showing a username and password field as well as a submit button.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Screenshot of the DefendTheWeb.net SQL Injection Challange 1 showing a username and password field as well as a submit button.&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13566</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13566"/>
		<updated>2024-01-06T11:56:58Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:DefendTheWebNetLogo.png|thumb|Logo of DefendTheWeb.net]]&lt;br /&gt;
&#039;&#039;&#039;Defend The Web&#039;&#039;&#039; is a Capture the Flag Website that teaches topic about Cyber Security and offers users on-hand-training for their theoretical skills. A free account is needed to access every section of the website. This can be either done by registering a new one from scratch or by using one of the available Single Sign On Providers (SSO Providers) Twitter (aka X), Google or GitHub. After logging in, the user gets redirected to a dashboard that offers information about new content in the articles and community sections as well as the progress in solving CTFs and the user&#039;s current level. Every user can earn medals by finishing challenges, participating in the community, writing articles and other actions on the website.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The landing page after logging in is the dashboard which consists of three main parts A) Articles, B) Playground and C) Community.&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
The article section consists of nine topics. Each article has a read time that depends on the length of the text as well as a counter of how many people have read it. The following list contains the topics and the number of articles within each topic at the time of writing. Topics in bold are directly accessible through the sidebar navigation within the dashboard.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Coding&#039;&#039;&#039; (11)&lt;br /&gt;
* &#039;&#039;&#039;Hacking&#039;&#039;&#039; (21)&lt;br /&gt;
* &#039;&#039;&#039;Privacy&#039;&#039;&#039; (2)&lt;br /&gt;
* Encryption and Steganography (9)&lt;br /&gt;
* Lock Picking (2)&lt;br /&gt;
* Network security (7)&lt;br /&gt;
* Phreaking (1)&lt;br /&gt;
* Talks / videos (11)&lt;br /&gt;
* Miscellaneous (13)&lt;br /&gt;
&lt;br /&gt;
=== Playground ===&lt;br /&gt;
The Playground contains the challenges itself and provides the user with an overview of the next challenges and the ones that are already completed.&lt;br /&gt;
&lt;br /&gt;
=== Community ===&lt;br /&gt;
A forum and Chat function can be found in the community section as well as a function to exchange private messages between users.&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetDashboard.png&amp;diff=13565</id>
		<title>File:DefendTheWebNetDashboard.png</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetDashboard.png&amp;diff=13565"/>
		<updated>2024-01-06T11:37:01Z</updated>

		<summary type="html">&lt;p&gt;MBasta: Screenshot of the DefendTheWeb.net Dashboard page

Source: https://defendtheweb.net/dashboard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Screenshot of the DefendTheWeb.net Dashboard page&lt;br /&gt;
&lt;br /&gt;
Source: https://defendtheweb.net/dashboard&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13564</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13564"/>
		<updated>2024-01-06T11:35:22Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:DefendTheWebNetLogo.png|thumb|Logo of DefendTheWeb.net]]&lt;br /&gt;
&#039;&#039;&#039;Defend The Web&#039;&#039;&#039; is a Capture the Flag Website that teaches topic about Cyber Security and offers users on-hand-training for their theoretical skills. A free account is needed to access every section of the website. This can be either done by registering a new one from scratch or by using one of the available Single Sign On Providers (SSO Providers) Twitter (aka X), Google or GitHub. After logging in, the user gets redirected to a dashboard that offers information about new content in the articles and community sections as well as the progress in solving CTFs and the user&#039;s current level. Every user can earn medals by finishing challenges, participating in the community, writing articles and other actions on the website.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetLogo.png&amp;diff=13563</id>
		<title>File:DefendTheWebNetLogo.png</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=File:DefendTheWebNetLogo.png&amp;diff=13563"/>
		<updated>2024-01-06T11:26:34Z</updated>

		<summary type="html">&lt;p&gt;MBasta: Logo of Defend The Web

Source: https://www.facebook.com/defendtheweb/photos/a.163821580333961/2395529793829784/&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Logo of Defend The Web&lt;br /&gt;
&lt;br /&gt;
Source: https://www.facebook.com/defendtheweb/photos/a.163821580333961/2395529793829784/&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13562</id>
		<title>Defend The Web</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Defend_The_Web&amp;diff=13562"/>
		<updated>2024-01-06T11:10:23Z</updated>

		<summary type="html">&lt;p&gt;MBasta: Create the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;empty&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11677</id>
		<title>CoMatrix: OSCORE</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11677"/>
		<updated>2023-07-04T21:35:16Z</updated>

		<summary type="html">&lt;p&gt;MBasta: /* Adopt liboscore */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This documentation describes the usage of an application-layer protocol OSCORE to provide end-to-end protection between the [https://comatrix.eu/setup/architecture_and_testbed CoMatrix Gateway and CoMatrix Client].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: &lt;br /&gt;
** Ubuntu 22.04 (Gateway)&lt;br /&gt;
** RIOT OS (Client)&lt;br /&gt;
* See [[#Used Hardware]]&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must set up the [https://comatrix.eu/setup/ CoMatrix project] before.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
OSCORE is a security protocol designed to provide end-to-end protection between endpoints communicating using CoAP.&lt;br /&gt;
&lt;br /&gt;
The keys are pre-shared between the client and the gateway because there is no key exchange protocol in OSCORE itself. However, there is ongoing work with key exchange protocols such as EDHOC or [https://datatracker.ietf.org/doc/html/draft-ietf-ace-oscore-profile-11 ACE-OSCORE]&lt;br /&gt;
&lt;br /&gt;
== Gateway ==&lt;br /&gt;
&lt;br /&gt;
The Python library aiocoap provides the OSCORE functionality and was used in order for the gateway to understand OSCORE within CoAP.&lt;br /&gt;
&lt;br /&gt;
=== Imports ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following imports were added&lt;br /&gt;
&lt;br /&gt;
 from aiocoap.oscore_sitewrapper import OscoreSiteWrapper&lt;br /&gt;
 from aiocoap.credentials import CredentialsMap&lt;br /&gt;
 from plugtest_common import *&lt;br /&gt;
 from aiocoap.cli.common import server_context_from_arguments, add_server_arguments&lt;br /&gt;
&lt;br /&gt;
* The plugtest_common import was extracted from the aiocoap OSCORE plugtest and provides verification for external AADs and returning the security context.&lt;br /&gt;
&lt;br /&gt;
=== Main ===&lt;br /&gt;
&lt;br /&gt;
When starting the gateway, new parameters have been added to list the directory where the pre-shared secrets are held and sequence numbers will be saved. These sequence numbers are necessary for replay protection.&lt;br /&gt;
&lt;br /&gt;
 parser.add_argument(&amp;quot;contextdir&amp;quot;, help=&amp;quot;Directory name where to persist sequence numbers and the location of the secrets&amp;quot;, type=Path)&lt;br /&gt;
 &lt;br /&gt;
 // Necessary to add these arguments provided by the aiocoap library in order for the server to start correctly. More info under aiocoap/cli/common.py&lt;br /&gt;
 add_server_arguments(parser)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The context directory may contain two files:&lt;br /&gt;
* secrets.json&lt;br /&gt;
* settings.json&lt;br /&gt;
As per implementation it is sufficient to only have one of these files in the directory.&lt;br /&gt;
&lt;br /&gt;
The format of the file is the following JSON:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
Important properties are:&lt;br /&gt;
* sender-id&lt;br /&gt;
* recipient-id&lt;br /&gt;
* secret&lt;br /&gt;
&lt;br /&gt;
These three properties must be appended with either _hex or _ascii and have the values according to the suffix.&lt;br /&gt;
&lt;br /&gt;
Assume that the file above was for the server and for our client we would need the following file:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notice how sender-id and recipient-id had to be swapped.&lt;br /&gt;
With these two secret files it is now possible to start a gateway and a client each using a different JSON file with the ids flipped.&lt;br /&gt;
&lt;br /&gt;
For further information see [https://aiocoap.readthedocs.io/en/latest/stateofoscore.html#oscore-credentials aiocoap-OSCORE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loading these in the code was done in the following way - For testing purposes there were two pairs of credentials a / b and c / d whereas the first one is used for the test client and the latter for the gateway:&lt;br /&gt;
 &lt;br /&gt;
 // Loading the pre-shared secrets&lt;br /&gt;
 server_credentials = CredentialsMap()&lt;br /&gt;
 // the first parameter states the name of the context in this case it&#039;s b but can be named in any way and the second parameter is the path to the folder e.g. the file would be located in /contextdir/b/settings.json&lt;br /&gt;
 server_credentials[&#039;:b&#039;] = get_security_context(&#039;b&#039;, args.contextdir / &amp;quot;b&amp;quot;)&lt;br /&gt;
 server_credentials[&#039;:d&#039;] = get_security_context(&#039;d&#039;, args.contextdir / &amp;quot;d&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To enable OSCORE for the server now the following code was added/adjusted:&lt;br /&gt;
 // root is the variable for the site&lt;br /&gt;
 // Enable the site to talK OSCORE with the credentials loaded from before&lt;br /&gt;
 root = OscoreSiteWrapper(root, server_credentials)&lt;br /&gt;
 args.bind = bind&lt;br /&gt;
 // Now we create a server context with arguments added&lt;br /&gt;
 asyncio.Task(server_context_from_arguments(root, args))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./comatrix_gateway.py contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:CoMatrix-Gateway-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
To test if the gateway actually talks in OSCORE the plugtest-client from the aiocoap library was adjusted to meet our needs for comatrix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./unit-tests.py host contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:Unittest-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
=== Wireshark Capture ===&lt;br /&gt;
&lt;br /&gt;
The Wireshark Capture can be downloaded here:&lt;br /&gt;
[[Media:OSCORE-wireshark-capture.zip]]&lt;br /&gt;
&lt;br /&gt;
[[File:OSCORE-wireshark.png]]&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
The Comatrix project already uses RIOT-OS for the client board so we continued using it. For the implementation of OSCORE on RIOT-OS we tried using liboscore. It comes with it&#039;s own build stack and is therefore different from the instructions provided by the Comatrix project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setup the build stack ===&lt;br /&gt;
&lt;br /&gt;
First, the liboscore project has to be cloned locally with the recursive parameter so that it contains RIOT-OS itself. This can be achieved by following the steps provided in [https://oscore.gitlab.io/liboscore/demo_common.html Common set-up instructions for RIOT-based demos]&lt;br /&gt;
The folders &#039;comatrix&#039;, &#039;example_comatrix_chat&#039; and &#039;example_comatrix_tempsensor&#039; from the Comatrix client directory then have to be copied into the folder &#039;liboscore/tests/riot-tests/&#039;.&lt;br /&gt;
Because the RIOT-OS code is now in a different location in relation to the Makefile, it has to be adapted.&lt;br /&gt;
&lt;br /&gt;
Remove this line:&lt;br /&gt;
 include $(RIOTBASE)/Makefile.include&lt;br /&gt;
&lt;br /&gt;
Add this line:&lt;br /&gt;
 include ../Makefile.include&lt;br /&gt;
&lt;br /&gt;
The project can then be built by using&lt;br /&gt;
 make all&lt;br /&gt;
&lt;br /&gt;
=== Adopt liboscore ===&lt;br /&gt;
&lt;br /&gt;
The comatrix examples for the chat and the tempsensor both use the source code in the comatrix folder which handles the CoAP messaging. This is why we did not change the examples but rather the comatrix code to implement OSCORE centrally.&lt;br /&gt;
Because the liboscore is still in a very early state and wasn&#039;t maintained for about two years we rarely found working examples so the focus was set onto the file &#039;demo-server.c&#039; within the test &#039;plugtest-server&#039; within the riot-tests folder which is documented as [https://oscore.gitlab.io/liboscore/demo_plugtest_linux.html Demo: Running the OSCORE plug test server on RIOT native ].&lt;br /&gt;
This code makes use of threading and mutex because it also acts as a server which we don&#039;t need because the chat and tempsensor examples only act as clients. We have to work around those parts and only use the functions for preparing and encrypting the OSCORE message.&lt;br /&gt;
&lt;br /&gt;
First we added the includes to oscore&lt;br /&gt;
 #include &amp;lt;oscore_native/message.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/contextpair.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/primitive.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/b1.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/protection.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, to generate the security context, we need to call the script &#039;oscore-key-derivation&#039; as documented in [https://oscore.gitlab.io/liboscore/demo_peertopeer.html Demo: Peer-to-peer exchanges in 6LoWPAN network], but we used the parameter &#039;--format header&#039; to retrieve the context in a matter that the compiler understands.&lt;br /&gt;
This block is then copied to the comatrix.c file. An example of this is:&lt;br /&gt;
&lt;br /&gt;
 #define SENDER_KEY {255, 177, 78, 9, 60, 148, 201, 202, 201, 71, 22, 72, 180, 249, 135, 16}&lt;br /&gt;
 #define RECIPIENT_KEY {240, 145, 14, 215, 41, 94, 106, 212, 181, 79, 199, 147, 21, 67, 2, 255}&lt;br /&gt;
 #define COMMON_IV {70, 34, 212, 221, 109, 148, 65, 104, 238, 251, 84, 152, 124}&lt;br /&gt;
 #define SENDER_ID {1}&lt;br /&gt;
 #define RECIPIENT_ID {}&lt;br /&gt;
&lt;br /&gt;
The security context then has to be created&lt;br /&gt;
 static struct oscore_context_primitive_immutables immutables_d = {&lt;br /&gt;
     .common_iv = COMMON_IV,&lt;br /&gt;
     &lt;br /&gt;
     .recipient_id_len = 0,&lt;br /&gt;
     .recipient_key = RECIPIENT_KEY,&lt;br /&gt;
     &lt;br /&gt;
     .sender_id_len = 1,&lt;br /&gt;
     .sender_id = &amp;quot;\x01&amp;quot;,&lt;br /&gt;
     .sender_key = SENDER_KEY,&lt;br /&gt;
 };&lt;br /&gt;
 static struct oscore_context_primitive primitive_d = { .immutables = &amp;amp;immutables_d };&lt;br /&gt;
 oscore_context_t secctx_d = {&lt;br /&gt;
     .type = OSCORE_CONTEXT_PRIMITIVE,&lt;br /&gt;
     .data = (void*)(&amp;amp;primitive_d),&lt;br /&gt;
 };&lt;br /&gt;
 int16_t secctx_d_change = 0;&lt;br /&gt;
&lt;br /&gt;
As the first function to adapt we decided to use the function comatrix_sendmsg as we can set different text at runtime in the CLI and immediately get the results while capturing with Wireshark.&lt;br /&gt;
The following code is not working at the moment as we are facing issues with the method &#039;oscore_encrypt_message&#039;. While debugging it we found out that the payload gets a special character somewhere during the preparation so that the length of the ciphertext cannot be calculated correctly.&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  *  @brief sends a COAP send message PUT request to the gateway, type is non-confirmable and no response handler is called&lt;br /&gt;
  *&lt;br /&gt;
  *  Send message request is non-confirmable for very constraint devices like sensor nodes, when communication errors occur the packet will not be resent&lt;br /&gt;
  *&lt;br /&gt;
  *  @param[in] msgbuf               message buffer.&lt;br /&gt;
  *  @param[in] msglen               length of message buffer.&lt;br /&gt;
  *  @param[in] callback_handler     should be 0; not implemented yet because it is non-confirmable&lt;br /&gt;
  *&lt;br /&gt;
  *  @return length of the payload&lt;br /&gt;
  *  @return 0   when the message exceeds PDU payload buffer size&lt;br /&gt;
  *  @return -1  when CoAP send message PUT request failed&lt;br /&gt;
  **/&lt;br /&gt;
 int comatrix_sendmsg(char *msgbuf, size_t msglen, comatrix_callback_t callback_handler) {&lt;br /&gt;
    (void)callback_handler;   /* not used by now because CoAP type is non-confirmable */&lt;br /&gt;
    coap_pkt_t pdu;&lt;br /&gt;
    uint8_t    pdu_buf[CONFIG_GCOAP_PDU_BUF_SIZE];&lt;br /&gt;
    size_t     len       = 0;&lt;br /&gt;
    char       separator = &#039;\0&#039;;&lt;br /&gt;
    oscore_msg_protected_t oscmsg;&lt;br /&gt;
 &lt;br /&gt;
    struct static_request_data request_data = { .done = MUTEX_INIT_LOCKED };&lt;br /&gt;
 &lt;br /&gt;
    /* build proxy string */&lt;br /&gt;
   #ifdef CONFIG_COMATRIX_ENABLE_SHORTURL&lt;br /&gt;
    int  proxy_buf_size = 20 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/9/%s/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #else&lt;br /&gt;
    int  proxy_buf_size = 49 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/_matrix/client/r0/rooms/%s/send/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #endif&lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] proxystring len: %d \n&amp;quot;, le);&lt;br /&gt;
 &lt;br /&gt;
    /* increment message counter */&lt;br /&gt;
    _cstate.tx_id = _cstate.tx_id + 1;&lt;br /&gt;
 &lt;br /&gt;
    /* initialize coap packet and set header and options */&lt;br /&gt;
    gcoap_req_init(&amp;amp;pdu, pdu_buf, CONFIG_GCOAP_PDU_BUF_SIZE, COAP_METHOD_PUT, COMATRIX_SENDMSG_PATH);&lt;br /&gt;
    coap_hdr_set_type(pdu.hdr, COAP_TYPE_NON);&lt;br /&gt;
    coap_opt_add_format(&amp;amp;pdu, COAP_FORMAT_CBOR);&lt;br /&gt;
    coap_opt_add_proxy_uri(&amp;amp;pdu, proxy_buf);&lt;br /&gt;
    coap_opt_add_chars(&amp;amp;pdu, COMATRIX_OPT_NUM, _cstate.comatrix_token, strlen(_cstate.comatrix_token), separator);&lt;br /&gt;
    len = coap_opt_finish(&amp;amp;pdu, COAP_OPT_FINISH_PAYLOAD);&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t native = { .pkt = &amp;amp;pdu };&lt;br /&gt;
    secctx_d_change += 1;&lt;br /&gt;
 &lt;br /&gt;
    if (oscore_prepare_request(native, &amp;amp;oscmsg, &amp;amp;secctx_d, &amp;amp;request_data.request_id) != OSCORE_PREPARE_OK) {&lt;br /&gt;
       printf(&amp;quot;Failed to prepare request encryption\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_protected_set_code(&amp;amp;oscmsg, 0x02 /* POST */);&lt;br /&gt;
 &lt;br /&gt;
    /* validate input length and encode payload to cbor {&amp;quot;msgtype&amp;quot;:&amp;quot;m.text&amp;quot;,&amp;quot;body&amp;quot;:&amp;quot;&amp;quot;} - 22 bytes cbor without msg */&lt;br /&gt;
    if (pdu.payload_len &amp;gt;= msglen + 23) {&lt;br /&gt;
       size_t cborlen = encbor_comatrixmsg((uint8_t *)pdu.payload, msgbuf, msglen);;&lt;br /&gt;
       len += cborlen;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] ERROR. The message buffer is too small for the message\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msgerr_protected_t oscerr;&lt;br /&gt;
    oscerr = oscore_msg_protected_append_option(&amp;amp;oscmsg, 11 /* Uri-Path */, (uint8_t*)&amp;quot;uripath&amp;quot;, 7);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to add option\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    uint8_t *payload;&lt;br /&gt;
    size_t payload_length;&lt;br /&gt;
    oscerr = oscore_msg_protected_map_payload(&amp;amp;oscmsg, &amp;amp;payload, &amp;amp;payload_length);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to map payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;map_payload: %s&amp;quot;, payload);&lt;br /&gt;
 &lt;br /&gt;
    /*payload = (uint8_t*)malloc(100 * sizeof(*payload));&lt;br /&gt;
    memcpy(payload, msgbuf, len);&lt;br /&gt;
    printf(&amp;quot;new payload: %s&amp;quot;, payload);*/&lt;br /&gt;
 &lt;br /&gt;
    oscerr = oscore_msg_protected_trim_payload(&amp;amp;oscmsg, 1);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to truncate payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t pdu_write_out;&lt;br /&gt;
    if (oscore_encrypt_message(&amp;amp;oscmsg, &amp;amp;pdu_write_out) != OSCORE_FINISH_OK) {&lt;br /&gt;
       // see FIXME in oscore_encrypt_message description&lt;br /&gt;
       printf(&amp;quot;Failed to encrypt payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] sending msg ID %u, %u bytes\n&amp;quot;, coap_get_id(&amp;amp;pdu), (unsigned)len);&lt;br /&gt;
    if (!gcoap_req_send(pdu_buf, len, &amp;amp;_cstate.remote, NULL, &amp;amp;request_data)) {&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] msg send failed\n&amp;quot;);&lt;br /&gt;
       return(-1);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 error:&lt;br /&gt;
     {}&lt;br /&gt;
     // FIXME: abort encryption (but no PDU recovery and PDU freeing necessary on this backend as it&#039;s all stack allocated)&lt;br /&gt;
 &lt;br /&gt;
    return(len);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Current status ===&lt;br /&gt;
&lt;br /&gt;
As we are facing issues regarding the liboscore code that lacks maintenance and documentation we have to deep dive into the functions.&lt;br /&gt;
After these issues are resolved the remaining implementation is assumed to be straight forward for the other comatrix_* functions.&lt;br /&gt;
&lt;br /&gt;
== Used Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 3B+ Model (CoMatrix Gateway)&lt;br /&gt;
* OpenLabs 802.15.4. radio module&lt;br /&gt;
* SAMR21-xpro (CoMatrix Client)&lt;br /&gt;
* (optional) Raspberry Pi 4 (Matrix Homeserver)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://comatrix.eu&lt;br /&gt;
* https://aiocoap.readthedocs.io&lt;br /&gt;
* https://github.com/chrysn/liboscore&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11676</id>
		<title>CoMatrix: OSCORE</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11676"/>
		<updated>2023-07-04T21:34:17Z</updated>

		<summary type="html">&lt;p&gt;MBasta: /* Setup the build stack */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This documentation describes the usage of an application-layer protocol OSCORE to provide end-to-end protection between the [https://comatrix.eu/setup/architecture_and_testbed CoMatrix Gateway and CoMatrix Client].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: &lt;br /&gt;
** Ubuntu 22.04 (Gateway)&lt;br /&gt;
** RIOT OS (Client)&lt;br /&gt;
* See [[#Used Hardware]]&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must set up the [https://comatrix.eu/setup/ CoMatrix project] before.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
OSCORE is a security protocol designed to provide end-to-end protection between endpoints communicating using CoAP.&lt;br /&gt;
&lt;br /&gt;
The keys are pre-shared between the client and the gateway because there is no key exchange protocol in OSCORE itself. However, there is ongoing work with key exchange protocols such as EDHOC or [https://datatracker.ietf.org/doc/html/draft-ietf-ace-oscore-profile-11 ACE-OSCORE]&lt;br /&gt;
&lt;br /&gt;
== Gateway ==&lt;br /&gt;
&lt;br /&gt;
The Python library aiocoap provides the OSCORE functionality and was used in order for the gateway to understand OSCORE within CoAP.&lt;br /&gt;
&lt;br /&gt;
=== Imports ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following imports were added&lt;br /&gt;
&lt;br /&gt;
 from aiocoap.oscore_sitewrapper import OscoreSiteWrapper&lt;br /&gt;
 from aiocoap.credentials import CredentialsMap&lt;br /&gt;
 from plugtest_common import *&lt;br /&gt;
 from aiocoap.cli.common import server_context_from_arguments, add_server_arguments&lt;br /&gt;
&lt;br /&gt;
* The plugtest_common import was extracted from the aiocoap OSCORE plugtest and provides verification for external AADs and returning the security context.&lt;br /&gt;
&lt;br /&gt;
=== Main ===&lt;br /&gt;
&lt;br /&gt;
When starting the gateway, new parameters have been added to list the directory where the pre-shared secrets are held and sequence numbers will be saved. These sequence numbers are necessary for replay protection.&lt;br /&gt;
&lt;br /&gt;
 parser.add_argument(&amp;quot;contextdir&amp;quot;, help=&amp;quot;Directory name where to persist sequence numbers and the location of the secrets&amp;quot;, type=Path)&lt;br /&gt;
 &lt;br /&gt;
 // Necessary to add these arguments provided by the aiocoap library in order for the server to start correctly. More info under aiocoap/cli/common.py&lt;br /&gt;
 add_server_arguments(parser)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The context directory may contain two files:&lt;br /&gt;
* secrets.json&lt;br /&gt;
* settings.json&lt;br /&gt;
As per implementation it is sufficient to only have one of these files in the directory.&lt;br /&gt;
&lt;br /&gt;
The format of the file is the following JSON:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
Important properties are:&lt;br /&gt;
* sender-id&lt;br /&gt;
* recipient-id&lt;br /&gt;
* secret&lt;br /&gt;
&lt;br /&gt;
These three properties must be appended with either _hex or _ascii and have the values according to the suffix.&lt;br /&gt;
&lt;br /&gt;
Assume that the file above was for the server and for our client we would need the following file:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notice how sender-id and recipient-id had to be swapped.&lt;br /&gt;
With these two secret files it is now possible to start a gateway and a client each using a different JSON file with the ids flipped.&lt;br /&gt;
&lt;br /&gt;
For further information see [https://aiocoap.readthedocs.io/en/latest/stateofoscore.html#oscore-credentials aiocoap-OSCORE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loading these in the code was done in the following way - For testing purposes there were two pairs of credentials a / b and c / d whereas the first one is used for the test client and the latter for the gateway:&lt;br /&gt;
 &lt;br /&gt;
 // Loading the pre-shared secrets&lt;br /&gt;
 server_credentials = CredentialsMap()&lt;br /&gt;
 // the first parameter states the name of the context in this case it&#039;s b but can be named in any way and the second parameter is the path to the folder e.g. the file would be located in /contextdir/b/settings.json&lt;br /&gt;
 server_credentials[&#039;:b&#039;] = get_security_context(&#039;b&#039;, args.contextdir / &amp;quot;b&amp;quot;)&lt;br /&gt;
 server_credentials[&#039;:d&#039;] = get_security_context(&#039;d&#039;, args.contextdir / &amp;quot;d&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To enable OSCORE for the server now the following code was added/adjusted:&lt;br /&gt;
 // root is the variable for the site&lt;br /&gt;
 // Enable the site to talK OSCORE with the credentials loaded from before&lt;br /&gt;
 root = OscoreSiteWrapper(root, server_credentials)&lt;br /&gt;
 args.bind = bind&lt;br /&gt;
 // Now we create a server context with arguments added&lt;br /&gt;
 asyncio.Task(server_context_from_arguments(root, args))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./comatrix_gateway.py contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:CoMatrix-Gateway-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
To test if the gateway actually talks in OSCORE the plugtest-client from the aiocoap library was adjusted to meet our needs for comatrix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./unit-tests.py host contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:Unittest-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
=== Wireshark Capture ===&lt;br /&gt;
&lt;br /&gt;
The Wireshark Capture can be downloaded here:&lt;br /&gt;
[[Media:OSCORE-wireshark-capture.zip]]&lt;br /&gt;
&lt;br /&gt;
[[File:OSCORE-wireshark.png]]&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
The Comatrix project already uses RIOT-OS for the client board so we continued using it. For the implementation of OSCORE on RIOT-OS we tried using liboscore. It comes with it&#039;s own build stack and is therefore different from the instructions provided by the Comatrix project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setup the build stack ===&lt;br /&gt;
&lt;br /&gt;
First, the liboscore project has to be cloned locally with the recursive parameter so that it contains RIOT-OS itself. This can be achieved by following the steps provided in [https://oscore.gitlab.io/liboscore/demo_common.html Common set-up instructions for RIOT-based demos]&lt;br /&gt;
The folders &#039;comatrix&#039;, &#039;example_comatrix_chat&#039; and &#039;example_comatrix_tempsensor&#039; from the Comatrix client directory then have to be copied into the folder &#039;liboscore/tests/riot-tests/&#039;.&lt;br /&gt;
Because the RIOT-OS code is now in a different location in relation to the Makefile, it has to be adapted.&lt;br /&gt;
&lt;br /&gt;
Remove this line:&lt;br /&gt;
 include $(RIOTBASE)/Makefile.include&lt;br /&gt;
&lt;br /&gt;
Add this line:&lt;br /&gt;
 include ../Makefile.include&lt;br /&gt;
&lt;br /&gt;
The project can then be built by using&lt;br /&gt;
 make all&lt;br /&gt;
&lt;br /&gt;
=== Adopt liboscore ===&lt;br /&gt;
&lt;br /&gt;
The comatrix examples for the chat and the tempsensor both use the source code in the comatrix folder which handles the CoAP messaging. This is why we did not change the examples but rather the comatrix code to implement OSCORE centrally.&lt;br /&gt;
Because the liboscore is still in a very early state and wasn&#039;t maintained for about two years we rarely found working examples so the focus was set onto the file &#039;demo-server.c&#039; within the test &#039;plugtest-server&#039; within the riot-tests folder which is documented as [https://oscore.gitlab.io/liboscore/demo_plugtest_linux.html Demo: Running the OSCORE plug test server on RIOT native ].&lt;br /&gt;
This code makes use of threading and mutex because it also acts as a server which we don&#039;t need because the chat and tempsensor examples only act as clients. We needed to remvove those parts and only use the functions for preparing and encrypting the OSCORE message.&lt;br /&gt;
&lt;br /&gt;
First we added the includes to oscore&lt;br /&gt;
 #include &amp;lt;oscore_native/message.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/contextpair.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/primitive.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/b1.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/protection.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, to generate the security context, we need to call the script &#039;oscore-key-derivation&#039; as documented in [https://oscore.gitlab.io/liboscore/demo_peertopeer.html Demo: Peer-to-peer exchanges in 6LoWPAN network], but we used the parameter &#039;--format header&#039; to retrieve the context in a matter that the compiler understands.&lt;br /&gt;
This block is then copied to the comatrix.c file. An example of this is:&lt;br /&gt;
&lt;br /&gt;
 #define SENDER_KEY {255, 177, 78, 9, 60, 148, 201, 202, 201, 71, 22, 72, 180, 249, 135, 16}&lt;br /&gt;
 #define RECIPIENT_KEY {240, 145, 14, 215, 41, 94, 106, 212, 181, 79, 199, 147, 21, 67, 2, 255}&lt;br /&gt;
 #define COMMON_IV {70, 34, 212, 221, 109, 148, 65, 104, 238, 251, 84, 152, 124}&lt;br /&gt;
 #define SENDER_ID {1}&lt;br /&gt;
 #define RECIPIENT_ID {}&lt;br /&gt;
&lt;br /&gt;
The security context then has to be created&lt;br /&gt;
 static struct oscore_context_primitive_immutables immutables_d = {&lt;br /&gt;
     .common_iv = COMMON_IV,&lt;br /&gt;
     &lt;br /&gt;
     .recipient_id_len = 0,&lt;br /&gt;
     .recipient_key = RECIPIENT_KEY,&lt;br /&gt;
     &lt;br /&gt;
     .sender_id_len = 1,&lt;br /&gt;
     .sender_id = &amp;quot;\x01&amp;quot;,&lt;br /&gt;
     .sender_key = SENDER_KEY,&lt;br /&gt;
 };&lt;br /&gt;
 static struct oscore_context_primitive primitive_d = { .immutables = &amp;amp;immutables_d };&lt;br /&gt;
 oscore_context_t secctx_d = {&lt;br /&gt;
     .type = OSCORE_CONTEXT_PRIMITIVE,&lt;br /&gt;
     .data = (void*)(&amp;amp;primitive_d),&lt;br /&gt;
 };&lt;br /&gt;
 int16_t secctx_d_change = 0;&lt;br /&gt;
&lt;br /&gt;
As the first function to adapt we decided to use the function comatrix_sendmsg as we can set different text at runtime in the CLI and immediately get the results while capturing with Wireshark.&lt;br /&gt;
The following code is not working at the moment as we are facing issues with the method &#039;oscore_encrypt_message&#039;. While debugging it we found out that the payload gets a special character somewhere during the preparation so that the length of the ciphertext cannot be calculated correctly.&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  *  @brief sends a COAP send message PUT request to the gateway, type is non-confirmable and no response handler is called&lt;br /&gt;
  *&lt;br /&gt;
  *  Send message request is non-confirmable for very constraint devices like sensor nodes, when communication errors occur the packet will not be resent&lt;br /&gt;
  *&lt;br /&gt;
  *  @param[in] msgbuf               message buffer.&lt;br /&gt;
  *  @param[in] msglen               length of message buffer.&lt;br /&gt;
  *  @param[in] callback_handler     should be 0; not implemented yet because it is non-confirmable&lt;br /&gt;
  *&lt;br /&gt;
  *  @return length of the payload&lt;br /&gt;
  *  @return 0   when the message exceeds PDU payload buffer size&lt;br /&gt;
  *  @return -1  when CoAP send message PUT request failed&lt;br /&gt;
  **/&lt;br /&gt;
 int comatrix_sendmsg(char *msgbuf, size_t msglen, comatrix_callback_t callback_handler) {&lt;br /&gt;
    (void)callback_handler;   /* not used by now because CoAP type is non-confirmable */&lt;br /&gt;
    coap_pkt_t pdu;&lt;br /&gt;
    uint8_t    pdu_buf[CONFIG_GCOAP_PDU_BUF_SIZE];&lt;br /&gt;
    size_t     len       = 0;&lt;br /&gt;
    char       separator = &#039;\0&#039;;&lt;br /&gt;
    oscore_msg_protected_t oscmsg;&lt;br /&gt;
 &lt;br /&gt;
    struct static_request_data request_data = { .done = MUTEX_INIT_LOCKED };&lt;br /&gt;
 &lt;br /&gt;
    /* build proxy string */&lt;br /&gt;
   #ifdef CONFIG_COMATRIX_ENABLE_SHORTURL&lt;br /&gt;
    int  proxy_buf_size = 20 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/9/%s/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #else&lt;br /&gt;
    int  proxy_buf_size = 49 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/_matrix/client/r0/rooms/%s/send/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #endif&lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] proxystring len: %d \n&amp;quot;, le);&lt;br /&gt;
 &lt;br /&gt;
    /* increment message counter */&lt;br /&gt;
    _cstate.tx_id = _cstate.tx_id + 1;&lt;br /&gt;
 &lt;br /&gt;
    /* initialize coap packet and set header and options */&lt;br /&gt;
    gcoap_req_init(&amp;amp;pdu, pdu_buf, CONFIG_GCOAP_PDU_BUF_SIZE, COAP_METHOD_PUT, COMATRIX_SENDMSG_PATH);&lt;br /&gt;
    coap_hdr_set_type(pdu.hdr, COAP_TYPE_NON);&lt;br /&gt;
    coap_opt_add_format(&amp;amp;pdu, COAP_FORMAT_CBOR);&lt;br /&gt;
    coap_opt_add_proxy_uri(&amp;amp;pdu, proxy_buf);&lt;br /&gt;
    coap_opt_add_chars(&amp;amp;pdu, COMATRIX_OPT_NUM, _cstate.comatrix_token, strlen(_cstate.comatrix_token), separator);&lt;br /&gt;
    len = coap_opt_finish(&amp;amp;pdu, COAP_OPT_FINISH_PAYLOAD);&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t native = { .pkt = &amp;amp;pdu };&lt;br /&gt;
    secctx_d_change += 1;&lt;br /&gt;
 &lt;br /&gt;
    if (oscore_prepare_request(native, &amp;amp;oscmsg, &amp;amp;secctx_d, &amp;amp;request_data.request_id) != OSCORE_PREPARE_OK) {&lt;br /&gt;
       printf(&amp;quot;Failed to prepare request encryption\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_protected_set_code(&amp;amp;oscmsg, 0x02 /* POST */);&lt;br /&gt;
 &lt;br /&gt;
    /* validate input length and encode payload to cbor {&amp;quot;msgtype&amp;quot;:&amp;quot;m.text&amp;quot;,&amp;quot;body&amp;quot;:&amp;quot;&amp;quot;} - 22 bytes cbor without msg */&lt;br /&gt;
    if (pdu.payload_len &amp;gt;= msglen + 23) {&lt;br /&gt;
       size_t cborlen = encbor_comatrixmsg((uint8_t *)pdu.payload, msgbuf, msglen);;&lt;br /&gt;
       len += cborlen;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] ERROR. The message buffer is too small for the message\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msgerr_protected_t oscerr;&lt;br /&gt;
    oscerr = oscore_msg_protected_append_option(&amp;amp;oscmsg, 11 /* Uri-Path */, (uint8_t*)&amp;quot;uripath&amp;quot;, 7);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to add option\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    uint8_t *payload;&lt;br /&gt;
    size_t payload_length;&lt;br /&gt;
    oscerr = oscore_msg_protected_map_payload(&amp;amp;oscmsg, &amp;amp;payload, &amp;amp;payload_length);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to map payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;map_payload: %s&amp;quot;, payload);&lt;br /&gt;
 &lt;br /&gt;
    /*payload = (uint8_t*)malloc(100 * sizeof(*payload));&lt;br /&gt;
    memcpy(payload, msgbuf, len);&lt;br /&gt;
    printf(&amp;quot;new payload: %s&amp;quot;, payload);*/&lt;br /&gt;
 &lt;br /&gt;
    oscerr = oscore_msg_protected_trim_payload(&amp;amp;oscmsg, 1);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to truncate payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t pdu_write_out;&lt;br /&gt;
    if (oscore_encrypt_message(&amp;amp;oscmsg, &amp;amp;pdu_write_out) != OSCORE_FINISH_OK) {&lt;br /&gt;
       // see FIXME in oscore_encrypt_message description&lt;br /&gt;
       printf(&amp;quot;Failed to encrypt payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] sending msg ID %u, %u bytes\n&amp;quot;, coap_get_id(&amp;amp;pdu), (unsigned)len);&lt;br /&gt;
    if (!gcoap_req_send(pdu_buf, len, &amp;amp;_cstate.remote, NULL, &amp;amp;request_data)) {&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] msg send failed\n&amp;quot;);&lt;br /&gt;
       return(-1);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 error:&lt;br /&gt;
     {}&lt;br /&gt;
     // FIXME: abort encryption (but no PDU recovery and PDU freeing necessary on this backend as it&#039;s all stack allocated)&lt;br /&gt;
 &lt;br /&gt;
    return(len);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Current status ===&lt;br /&gt;
&lt;br /&gt;
As we are facing issues regarding the liboscore code that lacks maintenance and documentation we have to deep dive into the functions.&lt;br /&gt;
After these issues are resolved the remaining implementation is assumed to be straight forward for the other comatrix_* functions.&lt;br /&gt;
&lt;br /&gt;
== Used Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 3B+ Model (CoMatrix Gateway)&lt;br /&gt;
* OpenLabs 802.15.4. radio module&lt;br /&gt;
* SAMR21-xpro (CoMatrix Client)&lt;br /&gt;
* (optional) Raspberry Pi 4 (Matrix Homeserver)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://comatrix.eu&lt;br /&gt;
* https://aiocoap.readthedocs.io&lt;br /&gt;
* https://github.com/chrysn/liboscore&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11675</id>
		<title>CoMatrix: OSCORE</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11675"/>
		<updated>2023-07-04T21:29:18Z</updated>

		<summary type="html">&lt;p&gt;MBasta: /* Adapt liboscore */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This documentation describes the usage of an application-layer protocol OSCORE to provide end-to-end protection between the [https://comatrix.eu/setup/architecture_and_testbed CoMatrix Gateway and CoMatrix Client].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: &lt;br /&gt;
** Ubuntu 22.04 (Gateway)&lt;br /&gt;
** RIOT OS (Client)&lt;br /&gt;
* See [[#Used Hardware]]&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must set up the [https://comatrix.eu/setup/ CoMatrix project] before.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
OSCORE is a security protocol designed to provide end-to-end protection between endpoints communicating using CoAP.&lt;br /&gt;
&lt;br /&gt;
The keys are pre-shared between the client and the gateway because there is no key exchange protocol in OSCORE itself. However, there is ongoing work with key exchange protocols such as EDHOC or [https://datatracker.ietf.org/doc/html/draft-ietf-ace-oscore-profile-11 ACE-OSCORE]&lt;br /&gt;
&lt;br /&gt;
== Gateway ==&lt;br /&gt;
&lt;br /&gt;
The Python library aiocoap provides the OSCORE functionality and was used in order for the gateway to understand OSCORE within CoAP.&lt;br /&gt;
&lt;br /&gt;
=== Imports ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following imports were added&lt;br /&gt;
&lt;br /&gt;
 from aiocoap.oscore_sitewrapper import OscoreSiteWrapper&lt;br /&gt;
 from aiocoap.credentials import CredentialsMap&lt;br /&gt;
 from plugtest_common import *&lt;br /&gt;
 from aiocoap.cli.common import server_context_from_arguments, add_server_arguments&lt;br /&gt;
&lt;br /&gt;
* The plugtest_common import was extracted from the aiocoap OSCORE plugtest and provides verification for external AADs and returning the security context.&lt;br /&gt;
&lt;br /&gt;
=== Main ===&lt;br /&gt;
&lt;br /&gt;
When starting the gateway, new parameters have been added to list the directory where the pre-shared secrets are held and sequence numbers will be saved. These sequence numbers are necessary for replay protection.&lt;br /&gt;
&lt;br /&gt;
 parser.add_argument(&amp;quot;contextdir&amp;quot;, help=&amp;quot;Directory name where to persist sequence numbers and the location of the secrets&amp;quot;, type=Path)&lt;br /&gt;
 &lt;br /&gt;
 // Necessary to add these arguments provided by the aiocoap library in order for the server to start correctly. More info under aiocoap/cli/common.py&lt;br /&gt;
 add_server_arguments(parser)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The context directory may contain two files:&lt;br /&gt;
* secrets.json&lt;br /&gt;
* settings.json&lt;br /&gt;
As per implementation it is sufficient to only have one of these files in the directory.&lt;br /&gt;
&lt;br /&gt;
The format of the file is the following JSON:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
Important properties are:&lt;br /&gt;
* sender-id&lt;br /&gt;
* recipient-id&lt;br /&gt;
* secret&lt;br /&gt;
&lt;br /&gt;
These three properties must be appended with either _hex or _ascii and have the values according to the suffix.&lt;br /&gt;
&lt;br /&gt;
Assume that the file above was for the server and for our client we would need the following file:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notice how sender-id and recipient-id had to be swapped.&lt;br /&gt;
With these two secret files it is now possible to start a gateway and a client each using a different JSON file with the ids flipped.&lt;br /&gt;
&lt;br /&gt;
For further information see [https://aiocoap.readthedocs.io/en/latest/stateofoscore.html#oscore-credentials aiocoap-OSCORE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loading these in the code was done in the following way - For testing purposes there were two pairs of credentials a / b and c / d whereas the first one is used for the test client and the latter for the gateway:&lt;br /&gt;
 &lt;br /&gt;
 // Loading the pre-shared secrets&lt;br /&gt;
 server_credentials = CredentialsMap()&lt;br /&gt;
 // the first parameter states the name of the context in this case it&#039;s b but can be named in any way and the second parameter is the path to the folder e.g. the file would be located in /contextdir/b/settings.json&lt;br /&gt;
 server_credentials[&#039;:b&#039;] = get_security_context(&#039;b&#039;, args.contextdir / &amp;quot;b&amp;quot;)&lt;br /&gt;
 server_credentials[&#039;:d&#039;] = get_security_context(&#039;d&#039;, args.contextdir / &amp;quot;d&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To enable OSCORE for the server now the following code was added/adjusted:&lt;br /&gt;
 // root is the variable for the site&lt;br /&gt;
 // Enable the site to talK OSCORE with the credentials loaded from before&lt;br /&gt;
 root = OscoreSiteWrapper(root, server_credentials)&lt;br /&gt;
 args.bind = bind&lt;br /&gt;
 // Now we create a server context with arguments added&lt;br /&gt;
 asyncio.Task(server_context_from_arguments(root, args))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./comatrix_gateway.py contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:CoMatrix-Gateway-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
To test if the gateway actually talks in OSCORE the plugtest-client from the aiocoap library was adjusted to meet our needs for comatrix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./unit-tests.py host contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:Unittest-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
=== Wireshark Capture ===&lt;br /&gt;
&lt;br /&gt;
The Wireshark Capture can be downloaded here:&lt;br /&gt;
[[Media:OSCORE-wireshark-capture.zip]]&lt;br /&gt;
&lt;br /&gt;
[[File:OSCORE-wireshark.png]]&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
The Comatrix project already uses RIOT-OS for the client board so we continued using it. For the implementation of OSCORE on RIOT-OS we tried using liboscore. It comes with it&#039;s own build stack and is therefore different from the instructions provided by the Comatrix project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setup the build stack ===&lt;br /&gt;
&lt;br /&gt;
First, the liboscore project has to be cloned locally with the recursive parameter so that it contains RIOT-OS itself. This can be achieved by following the steps provided in [https://oscore.gitlab.io/liboscore/demo_common.html Common set-up instructions for RIOT-based demos]&lt;br /&gt;
The folders &#039;comatrix&#039;, &#039;example_comatrix_chat&#039; and &#039;example_comatrix_tempsensor&#039; from the Comatrix client directory then have to be copied into the folder &#039;liboscore/tests/riot-tests/&#039;.&lt;br /&gt;
Because the RIOT-OS is now different in relation to the code the Makefile has to be adapted.&lt;br /&gt;
&lt;br /&gt;
Remove this line:&lt;br /&gt;
 include $(RIOTBASE)/Makefile.include&lt;br /&gt;
&lt;br /&gt;
Add this line:&lt;br /&gt;
 include ../Makefile.include&lt;br /&gt;
&lt;br /&gt;
The project can then be built by using&lt;br /&gt;
 make all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adopt liboscore ===&lt;br /&gt;
&lt;br /&gt;
The comatrix examples for the chat and the tempsensor both use the source code in the comatrix folder which handles the CoAP messaging. This is why we did not change the examples but rather the comatrix code to implement OSCORE centrally.&lt;br /&gt;
Because the liboscore is still in a very early state and wasn&#039;t maintained for about two years we rarely found working examples so the focus was set onto the file &#039;demo-server.c&#039; within the test &#039;plugtest-server&#039; within the riot-tests folder which is documented as [https://oscore.gitlab.io/liboscore/demo_plugtest_linux.html Demo: Running the OSCORE plug test server on RIOT native ].&lt;br /&gt;
This code makes use of threading and mutex because it also acts as a server which we don&#039;t need because the chat and tempsensor examples only act as clients. We needed to remvove those parts and only use the functions for preparing and encrypting the OSCORE message.&lt;br /&gt;
&lt;br /&gt;
First we added the includes to oscore&lt;br /&gt;
 #include &amp;lt;oscore_native/message.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/contextpair.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/primitive.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/b1.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/protection.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, to generate the security context, we need to call the script &#039;oscore-key-derivation&#039; as documented in [https://oscore.gitlab.io/liboscore/demo_peertopeer.html Demo: Peer-to-peer exchanges in 6LoWPAN network], but we used the parameter &#039;--format header&#039; to retrieve the context in a matter that the compiler understands.&lt;br /&gt;
This block is then copied to the comatrix.c file. An example of this is:&lt;br /&gt;
&lt;br /&gt;
 #define SENDER_KEY {255, 177, 78, 9, 60, 148, 201, 202, 201, 71, 22, 72, 180, 249, 135, 16}&lt;br /&gt;
 #define RECIPIENT_KEY {240, 145, 14, 215, 41, 94, 106, 212, 181, 79, 199, 147, 21, 67, 2, 255}&lt;br /&gt;
 #define COMMON_IV {70, 34, 212, 221, 109, 148, 65, 104, 238, 251, 84, 152, 124}&lt;br /&gt;
 #define SENDER_ID {1}&lt;br /&gt;
 #define RECIPIENT_ID {}&lt;br /&gt;
&lt;br /&gt;
The security context then has to be created&lt;br /&gt;
 static struct oscore_context_primitive_immutables immutables_d = {&lt;br /&gt;
     .common_iv = COMMON_IV,&lt;br /&gt;
     &lt;br /&gt;
     .recipient_id_len = 0,&lt;br /&gt;
     .recipient_key = RECIPIENT_KEY,&lt;br /&gt;
     &lt;br /&gt;
     .sender_id_len = 1,&lt;br /&gt;
     .sender_id = &amp;quot;\x01&amp;quot;,&lt;br /&gt;
     .sender_key = SENDER_KEY,&lt;br /&gt;
 };&lt;br /&gt;
 static struct oscore_context_primitive primitive_d = { .immutables = &amp;amp;immutables_d };&lt;br /&gt;
 oscore_context_t secctx_d = {&lt;br /&gt;
     .type = OSCORE_CONTEXT_PRIMITIVE,&lt;br /&gt;
     .data = (void*)(&amp;amp;primitive_d),&lt;br /&gt;
 };&lt;br /&gt;
 int16_t secctx_d_change = 0;&lt;br /&gt;
&lt;br /&gt;
As the first function to adapt we decided to use the function comatrix_sendmsg as we can set different text at runtime in the CLI and immediately get the results while capturing with Wireshark.&lt;br /&gt;
The following code is not working at the moment as we are facing issues with the method &#039;oscore_encrypt_message&#039;. While debugging it we found out that the payload gets a special character somewhere during the preparation so that the length of the ciphertext cannot be calculated correctly.&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  *  @brief sends a COAP send message PUT request to the gateway, type is non-confirmable and no response handler is called&lt;br /&gt;
  *&lt;br /&gt;
  *  Send message request is non-confirmable for very constraint devices like sensor nodes, when communication errors occur the packet will not be resent&lt;br /&gt;
  *&lt;br /&gt;
  *  @param[in] msgbuf               message buffer.&lt;br /&gt;
  *  @param[in] msglen               length of message buffer.&lt;br /&gt;
  *  @param[in] callback_handler     should be 0; not implemented yet because it is non-confirmable&lt;br /&gt;
  *&lt;br /&gt;
  *  @return length of the payload&lt;br /&gt;
  *  @return 0   when the message exceeds PDU payload buffer size&lt;br /&gt;
  *  @return -1  when CoAP send message PUT request failed&lt;br /&gt;
  **/&lt;br /&gt;
 int comatrix_sendmsg(char *msgbuf, size_t msglen, comatrix_callback_t callback_handler) {&lt;br /&gt;
    (void)callback_handler;   /* not used by now because CoAP type is non-confirmable */&lt;br /&gt;
    coap_pkt_t pdu;&lt;br /&gt;
    uint8_t    pdu_buf[CONFIG_GCOAP_PDU_BUF_SIZE];&lt;br /&gt;
    size_t     len       = 0;&lt;br /&gt;
    char       separator = &#039;\0&#039;;&lt;br /&gt;
    oscore_msg_protected_t oscmsg;&lt;br /&gt;
 &lt;br /&gt;
    struct static_request_data request_data = { .done = MUTEX_INIT_LOCKED };&lt;br /&gt;
 &lt;br /&gt;
    /* build proxy string */&lt;br /&gt;
   #ifdef CONFIG_COMATRIX_ENABLE_SHORTURL&lt;br /&gt;
    int  proxy_buf_size = 20 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/9/%s/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #else&lt;br /&gt;
    int  proxy_buf_size = 49 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/_matrix/client/r0/rooms/%s/send/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #endif&lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] proxystring len: %d \n&amp;quot;, le);&lt;br /&gt;
 &lt;br /&gt;
    /* increment message counter */&lt;br /&gt;
    _cstate.tx_id = _cstate.tx_id + 1;&lt;br /&gt;
 &lt;br /&gt;
    /* initialize coap packet and set header and options */&lt;br /&gt;
    gcoap_req_init(&amp;amp;pdu, pdu_buf, CONFIG_GCOAP_PDU_BUF_SIZE, COAP_METHOD_PUT, COMATRIX_SENDMSG_PATH);&lt;br /&gt;
    coap_hdr_set_type(pdu.hdr, COAP_TYPE_NON);&lt;br /&gt;
    coap_opt_add_format(&amp;amp;pdu, COAP_FORMAT_CBOR);&lt;br /&gt;
    coap_opt_add_proxy_uri(&amp;amp;pdu, proxy_buf);&lt;br /&gt;
    coap_opt_add_chars(&amp;amp;pdu, COMATRIX_OPT_NUM, _cstate.comatrix_token, strlen(_cstate.comatrix_token), separator);&lt;br /&gt;
    len = coap_opt_finish(&amp;amp;pdu, COAP_OPT_FINISH_PAYLOAD);&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t native = { .pkt = &amp;amp;pdu };&lt;br /&gt;
    secctx_d_change += 1;&lt;br /&gt;
 &lt;br /&gt;
    if (oscore_prepare_request(native, &amp;amp;oscmsg, &amp;amp;secctx_d, &amp;amp;request_data.request_id) != OSCORE_PREPARE_OK) {&lt;br /&gt;
       printf(&amp;quot;Failed to prepare request encryption\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_protected_set_code(&amp;amp;oscmsg, 0x02 /* POST */);&lt;br /&gt;
 &lt;br /&gt;
    /* validate input length and encode payload to cbor {&amp;quot;msgtype&amp;quot;:&amp;quot;m.text&amp;quot;,&amp;quot;body&amp;quot;:&amp;quot;&amp;quot;} - 22 bytes cbor without msg */&lt;br /&gt;
    if (pdu.payload_len &amp;gt;= msglen + 23) {&lt;br /&gt;
       size_t cborlen = encbor_comatrixmsg((uint8_t *)pdu.payload, msgbuf, msglen);;&lt;br /&gt;
       len += cborlen;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] ERROR. The message buffer is too small for the message\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msgerr_protected_t oscerr;&lt;br /&gt;
    oscerr = oscore_msg_protected_append_option(&amp;amp;oscmsg, 11 /* Uri-Path */, (uint8_t*)&amp;quot;uripath&amp;quot;, 7);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to add option\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    uint8_t *payload;&lt;br /&gt;
    size_t payload_length;&lt;br /&gt;
    oscerr = oscore_msg_protected_map_payload(&amp;amp;oscmsg, &amp;amp;payload, &amp;amp;payload_length);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to map payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;map_payload: %s&amp;quot;, payload);&lt;br /&gt;
 &lt;br /&gt;
    /*payload = (uint8_t*)malloc(100 * sizeof(*payload));&lt;br /&gt;
    memcpy(payload, msgbuf, len);&lt;br /&gt;
    printf(&amp;quot;new payload: %s&amp;quot;, payload);*/&lt;br /&gt;
 &lt;br /&gt;
    oscerr = oscore_msg_protected_trim_payload(&amp;amp;oscmsg, 1);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to truncate payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t pdu_write_out;&lt;br /&gt;
    if (oscore_encrypt_message(&amp;amp;oscmsg, &amp;amp;pdu_write_out) != OSCORE_FINISH_OK) {&lt;br /&gt;
       // see FIXME in oscore_encrypt_message description&lt;br /&gt;
       printf(&amp;quot;Failed to encrypt payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] sending msg ID %u, %u bytes\n&amp;quot;, coap_get_id(&amp;amp;pdu), (unsigned)len);&lt;br /&gt;
    if (!gcoap_req_send(pdu_buf, len, &amp;amp;_cstate.remote, NULL, &amp;amp;request_data)) {&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] msg send failed\n&amp;quot;);&lt;br /&gt;
       return(-1);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 error:&lt;br /&gt;
     {}&lt;br /&gt;
     // FIXME: abort encryption (but no PDU recovery and PDU freeing necessary on this backend as it&#039;s all stack allocated)&lt;br /&gt;
 &lt;br /&gt;
    return(len);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Current status ===&lt;br /&gt;
&lt;br /&gt;
As we are facing issues regarding the liboscore code that lacks maintenance and documentation we have to deep dive into the functions.&lt;br /&gt;
After these issues are resolved the remaining implementation is assumed to be straight forward for the other comatrix_* functions.&lt;br /&gt;
&lt;br /&gt;
== Used Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 3B+ Model (CoMatrix Gateway)&lt;br /&gt;
* OpenLabs 802.15.4. radio module&lt;br /&gt;
* SAMR21-xpro (CoMatrix Client)&lt;br /&gt;
* (optional) Raspberry Pi 4 (Matrix Homeserver)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://comatrix.eu&lt;br /&gt;
* https://aiocoap.readthedocs.io&lt;br /&gt;
* https://github.com/chrysn/liboscore&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11674</id>
		<title>CoMatrix: OSCORE</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11674"/>
		<updated>2023-07-04T21:26:37Z</updated>

		<summary type="html">&lt;p&gt;MBasta: /* Current status */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This documentation describes the usage of an application-layer protocol OSCORE to provide end-to-end protection between the [https://comatrix.eu/setup/architecture_and_testbed CoMatrix Gateway and CoMatrix Client].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: &lt;br /&gt;
** Ubuntu 22.04 (Gateway)&lt;br /&gt;
** RIOT OS (Client)&lt;br /&gt;
* See [[#Used Hardware]]&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must set up the [https://comatrix.eu/setup/ CoMatrix project] before.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
OSCORE is a security protocol designed to provide end-to-end protection between endpoints communicating using CoAP.&lt;br /&gt;
&lt;br /&gt;
The keys are pre-shared between the client and the gateway because there is no key exchange protocol in OSCORE itself. However, there is ongoing work with key exchange protocols such as EDHOC or [https://datatracker.ietf.org/doc/html/draft-ietf-ace-oscore-profile-11 ACE-OSCORE]&lt;br /&gt;
&lt;br /&gt;
== Gateway ==&lt;br /&gt;
&lt;br /&gt;
The Python library aiocoap provides the OSCORE functionality and was used in order for the gateway to understand OSCORE within CoAP.&lt;br /&gt;
&lt;br /&gt;
=== Imports ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following imports were added&lt;br /&gt;
&lt;br /&gt;
 from aiocoap.oscore_sitewrapper import OscoreSiteWrapper&lt;br /&gt;
 from aiocoap.credentials import CredentialsMap&lt;br /&gt;
 from plugtest_common import *&lt;br /&gt;
 from aiocoap.cli.common import server_context_from_arguments, add_server_arguments&lt;br /&gt;
&lt;br /&gt;
* The plugtest_common import was extracted from the aiocoap OSCORE plugtest and provides verification for external AADs and returning the security context.&lt;br /&gt;
&lt;br /&gt;
=== Main ===&lt;br /&gt;
&lt;br /&gt;
When starting the gateway, new parameters have been added to list the directory where the pre-shared secrets are held and sequence numbers will be saved. These sequence numbers are necessary for replay protection.&lt;br /&gt;
&lt;br /&gt;
 parser.add_argument(&amp;quot;contextdir&amp;quot;, help=&amp;quot;Directory name where to persist sequence numbers and the location of the secrets&amp;quot;, type=Path)&lt;br /&gt;
 &lt;br /&gt;
 // Necessary to add these arguments provided by the aiocoap library in order for the server to start correctly. More info under aiocoap/cli/common.py&lt;br /&gt;
 add_server_arguments(parser)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The context directory may contain two files:&lt;br /&gt;
* secrets.json&lt;br /&gt;
* settings.json&lt;br /&gt;
As per implementation it is sufficient to only have one of these files in the directory.&lt;br /&gt;
&lt;br /&gt;
The format of the file is the following JSON:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
Important properties are:&lt;br /&gt;
* sender-id&lt;br /&gt;
* recipient-id&lt;br /&gt;
* secret&lt;br /&gt;
&lt;br /&gt;
These three properties must be appended with either _hex or _ascii and have the values according to the suffix.&lt;br /&gt;
&lt;br /&gt;
Assume that the file above was for the server and for our client we would need the following file:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notice how sender-id and recipient-id had to be swapped.&lt;br /&gt;
With these two secret files it is now possible to start a gateway and a client each using a different JSON file with the ids flipped.&lt;br /&gt;
&lt;br /&gt;
For further information see [https://aiocoap.readthedocs.io/en/latest/stateofoscore.html#oscore-credentials aiocoap-OSCORE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loading these in the code was done in the following way - For testing purposes there were two pairs of credentials a / b and c / d whereas the first one is used for the test client and the latter for the gateway:&lt;br /&gt;
 &lt;br /&gt;
 // Loading the pre-shared secrets&lt;br /&gt;
 server_credentials = CredentialsMap()&lt;br /&gt;
 // the first parameter states the name of the context in this case it&#039;s b but can be named in any way and the second parameter is the path to the folder e.g. the file would be located in /contextdir/b/settings.json&lt;br /&gt;
 server_credentials[&#039;:b&#039;] = get_security_context(&#039;b&#039;, args.contextdir / &amp;quot;b&amp;quot;)&lt;br /&gt;
 server_credentials[&#039;:d&#039;] = get_security_context(&#039;d&#039;, args.contextdir / &amp;quot;d&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To enable OSCORE for the server now the following code was added/adjusted:&lt;br /&gt;
 // root is the variable for the site&lt;br /&gt;
 // Enable the site to talK OSCORE with the credentials loaded from before&lt;br /&gt;
 root = OscoreSiteWrapper(root, server_credentials)&lt;br /&gt;
 args.bind = bind&lt;br /&gt;
 // Now we create a server context with arguments added&lt;br /&gt;
 asyncio.Task(server_context_from_arguments(root, args))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./comatrix_gateway.py contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:CoMatrix-Gateway-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
To test if the gateway actually talks in OSCORE the plugtest-client from the aiocoap library was adjusted to meet our needs for comatrix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./unit-tests.py host contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:Unittest-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
=== Wireshark Capture ===&lt;br /&gt;
&lt;br /&gt;
The Wireshark Capture can be downloaded here:&lt;br /&gt;
[[Media:OSCORE-wireshark-capture.zip]]&lt;br /&gt;
&lt;br /&gt;
[[File:OSCORE-wireshark.png]]&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
The Comatrix project already uses RIOT-OS for the client board so we continued using it. For the implementation of OSCORE on RIOT-OS we tried using liboscore. It comes with it&#039;s own build stack and is therefore different from the instructions provided by the Comatrix project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setup the build stack ===&lt;br /&gt;
&lt;br /&gt;
First, the liboscore project has to be cloned locally with the recursive parameter so that it contains RIOT-OS itself. This can be achieved by following the steps provided in [https://oscore.gitlab.io/liboscore/demo_common.html Common set-up instructions for RIOT-based demos]&lt;br /&gt;
The folders &#039;comatrix&#039;, &#039;example_comatrix_chat&#039; and &#039;example_comatrix_tempsensor&#039; from the Comatrix client directory then have to be copied into the folder &#039;liboscore/tests/riot-tests/&#039;.&lt;br /&gt;
Because the RIOT-OS is now different in relation to the code the Makefile has to be adapted.&lt;br /&gt;
&lt;br /&gt;
Remove this line:&lt;br /&gt;
 include $(RIOTBASE)/Makefile.include&lt;br /&gt;
&lt;br /&gt;
Add this line:&lt;br /&gt;
 include ../Makefile.include&lt;br /&gt;
&lt;br /&gt;
The project can then be built by using&lt;br /&gt;
 make all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adapt liboscore ===&lt;br /&gt;
&lt;br /&gt;
The comatrix examples for the chat and the tempsensor both use the source code in the comatrix folder which handles the CoAP messaging. This is why we did not change the examples but rather the comatrix code to implement OSCORE centrally.&lt;br /&gt;
Because the liboscore is still in a very early state and wasn&#039;t maintained for about two years we rarely found working examples so the focus was set onto the &#039;plugtest-server&#039; code within the riot-tests folder which is documented as [https://oscore.gitlab.io/liboscore/demo_plugtest_linux.html Demo: Running the OSCORE plug test server on RIOT native ].&lt;br /&gt;
This code makes use of threading and mutex because it also acts as a server which we don&#039;t need because the chat and tempsensor examples only act as clients. We needed to remvove those parts and only use the functions for preparing and encrypting the OSCORE message.&lt;br /&gt;
&lt;br /&gt;
First we added the includes to oscore&lt;br /&gt;
 #include &amp;lt;oscore_native/message.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/contextpair.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/primitive.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/b1.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/protection.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, to generate the security context, we need to call the script &#039;oscore-key-derivation&#039; as documented in [https://oscore.gitlab.io/liboscore/demo_peertopeer.html Demo: Peer-to-peer exchanges in 6LoWPAN network], but we used the parameter &#039;--format header&#039; to retrieve the context in a matter that the compiler understands.&lt;br /&gt;
This block is then copied to the comatrix.c file. An example of this is:&lt;br /&gt;
&lt;br /&gt;
 #define SENDER_KEY {255, 177, 78, 9, 60, 148, 201, 202, 201, 71, 22, 72, 180, 249, 135, 16}&lt;br /&gt;
 #define RECIPIENT_KEY {240, 145, 14, 215, 41, 94, 106, 212, 181, 79, 199, 147, 21, 67, 2, 255}&lt;br /&gt;
 #define COMMON_IV {70, 34, 212, 221, 109, 148, 65, 104, 238, 251, 84, 152, 124}&lt;br /&gt;
 #define SENDER_ID {1}&lt;br /&gt;
 #define RECIPIENT_ID {}&lt;br /&gt;
&lt;br /&gt;
The security context then has to be created&lt;br /&gt;
 static struct oscore_context_primitive_immutables immutables_d = {&lt;br /&gt;
     .common_iv = COMMON_IV,&lt;br /&gt;
     &lt;br /&gt;
     .recipient_id_len = 0,&lt;br /&gt;
     .recipient_key = RECIPIENT_KEY,&lt;br /&gt;
     &lt;br /&gt;
     .sender_id_len = 1,&lt;br /&gt;
     .sender_id = &amp;quot;\x01&amp;quot;,&lt;br /&gt;
     .sender_key = SENDER_KEY,&lt;br /&gt;
 };&lt;br /&gt;
 static struct oscore_context_primitive primitive_d = { .immutables = &amp;amp;immutables_d };&lt;br /&gt;
 oscore_context_t secctx_d = {&lt;br /&gt;
     .type = OSCORE_CONTEXT_PRIMITIVE,&lt;br /&gt;
     .data = (void*)(&amp;amp;primitive_d),&lt;br /&gt;
 };&lt;br /&gt;
 int16_t secctx_d_change = 0;&lt;br /&gt;
&lt;br /&gt;
As the first function to adapt we decided to use the function comatrix_sendmsg as we can set different text at runtime in the CLI and immediately get the results while capturing with Wireshark.&lt;br /&gt;
The following code is not working at the moment as we are facing issues with the method &#039;oscore_encrypt_message&#039;. While debugging it we found out that the payload gets a special character somewhere during the preparation so that the length of the ciphertext cannot be calculated correctly.&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  *  @brief sends a COAP send message PUT request to the gateway, type is non-confirmable and no response handler is called&lt;br /&gt;
  *&lt;br /&gt;
  *  Send message request is non-confirmable for very constraint devices like sensor nodes, when communication errors occur the packet will not be resent&lt;br /&gt;
  *&lt;br /&gt;
  *  @param[in] msgbuf               message buffer.&lt;br /&gt;
  *  @param[in] msglen               length of message buffer.&lt;br /&gt;
  *  @param[in] callback_handler     should be 0; not implemented yet because it is non-confirmable&lt;br /&gt;
  *&lt;br /&gt;
  *  @return length of the payload&lt;br /&gt;
  *  @return 0   when the message exceeds PDU payload buffer size&lt;br /&gt;
  *  @return -1  when CoAP send message PUT request failed&lt;br /&gt;
  **/&lt;br /&gt;
 int comatrix_sendmsg(char *msgbuf, size_t msglen, comatrix_callback_t callback_handler) {&lt;br /&gt;
    (void)callback_handler;   /* not used by now because CoAP type is non-confirmable */&lt;br /&gt;
    coap_pkt_t pdu;&lt;br /&gt;
    uint8_t    pdu_buf[CONFIG_GCOAP_PDU_BUF_SIZE];&lt;br /&gt;
    size_t     len       = 0;&lt;br /&gt;
    char       separator = &#039;\0&#039;;&lt;br /&gt;
    oscore_msg_protected_t oscmsg;&lt;br /&gt;
 &lt;br /&gt;
    struct static_request_data request_data = { .done = MUTEX_INIT_LOCKED };&lt;br /&gt;
 &lt;br /&gt;
    /* build proxy string */&lt;br /&gt;
   #ifdef CONFIG_COMATRIX_ENABLE_SHORTURL&lt;br /&gt;
    int  proxy_buf_size = 20 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/9/%s/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #else&lt;br /&gt;
    int  proxy_buf_size = 49 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/_matrix/client/r0/rooms/%s/send/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #endif&lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] proxystring len: %d \n&amp;quot;, le);&lt;br /&gt;
 &lt;br /&gt;
    /* increment message counter */&lt;br /&gt;
    _cstate.tx_id = _cstate.tx_id + 1;&lt;br /&gt;
 &lt;br /&gt;
    /* initialize coap packet and set header and options */&lt;br /&gt;
    gcoap_req_init(&amp;amp;pdu, pdu_buf, CONFIG_GCOAP_PDU_BUF_SIZE, COAP_METHOD_PUT, COMATRIX_SENDMSG_PATH);&lt;br /&gt;
    coap_hdr_set_type(pdu.hdr, COAP_TYPE_NON);&lt;br /&gt;
    coap_opt_add_format(&amp;amp;pdu, COAP_FORMAT_CBOR);&lt;br /&gt;
    coap_opt_add_proxy_uri(&amp;amp;pdu, proxy_buf);&lt;br /&gt;
    coap_opt_add_chars(&amp;amp;pdu, COMATRIX_OPT_NUM, _cstate.comatrix_token, strlen(_cstate.comatrix_token), separator);&lt;br /&gt;
    len = coap_opt_finish(&amp;amp;pdu, COAP_OPT_FINISH_PAYLOAD);&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t native = { .pkt = &amp;amp;pdu };&lt;br /&gt;
    secctx_d_change += 1;&lt;br /&gt;
 &lt;br /&gt;
    if (oscore_prepare_request(native, &amp;amp;oscmsg, &amp;amp;secctx_d, &amp;amp;request_data.request_id) != OSCORE_PREPARE_OK) {&lt;br /&gt;
       printf(&amp;quot;Failed to prepare request encryption\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_protected_set_code(&amp;amp;oscmsg, 0x02 /* POST */);&lt;br /&gt;
 &lt;br /&gt;
    /* validate input length and encode payload to cbor {&amp;quot;msgtype&amp;quot;:&amp;quot;m.text&amp;quot;,&amp;quot;body&amp;quot;:&amp;quot;&amp;quot;} - 22 bytes cbor without msg */&lt;br /&gt;
    if (pdu.payload_len &amp;gt;= msglen + 23) {&lt;br /&gt;
       size_t cborlen = encbor_comatrixmsg((uint8_t *)pdu.payload, msgbuf, msglen);;&lt;br /&gt;
       len += cborlen;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] ERROR. The message buffer is too small for the message\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msgerr_protected_t oscerr;&lt;br /&gt;
    oscerr = oscore_msg_protected_append_option(&amp;amp;oscmsg, 11 /* Uri-Path */, (uint8_t*)&amp;quot;uripath&amp;quot;, 7);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to add option\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    uint8_t *payload;&lt;br /&gt;
    size_t payload_length;&lt;br /&gt;
    oscerr = oscore_msg_protected_map_payload(&amp;amp;oscmsg, &amp;amp;payload, &amp;amp;payload_length);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to map payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;map_payload: %s&amp;quot;, payload);&lt;br /&gt;
 &lt;br /&gt;
    /*payload = (uint8_t*)malloc(100 * sizeof(*payload));&lt;br /&gt;
    memcpy(payload, msgbuf, len);&lt;br /&gt;
    printf(&amp;quot;new payload: %s&amp;quot;, payload);*/&lt;br /&gt;
 &lt;br /&gt;
    oscerr = oscore_msg_protected_trim_payload(&amp;amp;oscmsg, 1);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to truncate payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t pdu_write_out;&lt;br /&gt;
    if (oscore_encrypt_message(&amp;amp;oscmsg, &amp;amp;pdu_write_out) != OSCORE_FINISH_OK) {&lt;br /&gt;
       // see FIXME in oscore_encrypt_message description&lt;br /&gt;
       printf(&amp;quot;Failed to encrypt payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] sending msg ID %u, %u bytes\n&amp;quot;, coap_get_id(&amp;amp;pdu), (unsigned)len);&lt;br /&gt;
    if (!gcoap_req_send(pdu_buf, len, &amp;amp;_cstate.remote, NULL, &amp;amp;request_data)) {&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] msg send failed\n&amp;quot;);&lt;br /&gt;
       return(-1);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 error:&lt;br /&gt;
     {}&lt;br /&gt;
     // FIXME: abort encryption (but no PDU recovery and PDU freeing necessary on this backend as it&#039;s all stack allocated)&lt;br /&gt;
 &lt;br /&gt;
    return(len);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Current status ===&lt;br /&gt;
&lt;br /&gt;
As we are facing issues regarding the liboscore code that lacks maintenance and documentation we have to deep dive into the functions.&lt;br /&gt;
After these issues are resolved the remaining implementation is assumed to be straight forward for the other comatrix_* functions.&lt;br /&gt;
&lt;br /&gt;
== Used Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 3B+ Model (CoMatrix Gateway)&lt;br /&gt;
* OpenLabs 802.15.4. radio module&lt;br /&gt;
* SAMR21-xpro (CoMatrix Client)&lt;br /&gt;
* (optional) Raspberry Pi 4 (Matrix Homeserver)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://comatrix.eu&lt;br /&gt;
* https://aiocoap.readthedocs.io&lt;br /&gt;
* https://github.com/chrysn/liboscore&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11673</id>
		<title>CoMatrix: OSCORE</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11673"/>
		<updated>2023-07-04T21:23:49Z</updated>

		<summary type="html">&lt;p&gt;MBasta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This documentation describes the usage of an application-layer protocol OSCORE to provide end-to-end protection between the [https://comatrix.eu/setup/architecture_and_testbed CoMatrix Gateway and CoMatrix Client].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: &lt;br /&gt;
** Ubuntu 22.04 (Gateway)&lt;br /&gt;
** RIOT OS (Client)&lt;br /&gt;
* See [[#Used Hardware]]&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must set up the [https://comatrix.eu/setup/ CoMatrix project] before.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
OSCORE is a security protocol designed to provide end-to-end protection between endpoints communicating using CoAP.&lt;br /&gt;
&lt;br /&gt;
The keys are pre-shared between the client and the gateway because there is no key exchange protocol in OSCORE itself. However, there is ongoing work with key exchange protocols such as EDHOC or [https://datatracker.ietf.org/doc/html/draft-ietf-ace-oscore-profile-11 ACE-OSCORE]&lt;br /&gt;
&lt;br /&gt;
== Gateway ==&lt;br /&gt;
&lt;br /&gt;
The Python library aiocoap provides the OSCORE functionality and was used in order for the gateway to understand OSCORE within CoAP.&lt;br /&gt;
&lt;br /&gt;
=== Imports ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following imports were added&lt;br /&gt;
&lt;br /&gt;
 from aiocoap.oscore_sitewrapper import OscoreSiteWrapper&lt;br /&gt;
 from aiocoap.credentials import CredentialsMap&lt;br /&gt;
 from plugtest_common import *&lt;br /&gt;
 from aiocoap.cli.common import server_context_from_arguments, add_server_arguments&lt;br /&gt;
&lt;br /&gt;
* The plugtest_common import was extracted from the aiocoap OSCORE plugtest and provides verification for external AADs and returning the security context.&lt;br /&gt;
&lt;br /&gt;
=== Main ===&lt;br /&gt;
&lt;br /&gt;
When starting the gateway, new parameters have been added to list the directory where the pre-shared secrets are held and sequence numbers will be saved. These sequence numbers are necessary for replay protection.&lt;br /&gt;
&lt;br /&gt;
 parser.add_argument(&amp;quot;contextdir&amp;quot;, help=&amp;quot;Directory name where to persist sequence numbers and the location of the secrets&amp;quot;, type=Path)&lt;br /&gt;
 &lt;br /&gt;
 // Necessary to add these arguments provided by the aiocoap library in order for the server to start correctly. More info under aiocoap/cli/common.py&lt;br /&gt;
 add_server_arguments(parser)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The context directory may contain two files:&lt;br /&gt;
* secrets.json&lt;br /&gt;
* settings.json&lt;br /&gt;
As per implementation it is sufficient to only have one of these files in the directory.&lt;br /&gt;
&lt;br /&gt;
The format of the file is the following JSON:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
Important properties are:&lt;br /&gt;
* sender-id&lt;br /&gt;
* recipient-id&lt;br /&gt;
* secret&lt;br /&gt;
&lt;br /&gt;
These three properties must be appended with either _hex or _ascii and have the values according to the suffix.&lt;br /&gt;
&lt;br /&gt;
Assume that the file above was for the server and for our client we would need the following file:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notice how sender-id and recipient-id had to be swapped.&lt;br /&gt;
With these two secret files it is now possible to start a gateway and a client each using a different JSON file with the ids flipped.&lt;br /&gt;
&lt;br /&gt;
For further information see [https://aiocoap.readthedocs.io/en/latest/stateofoscore.html#oscore-credentials aiocoap-OSCORE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loading these in the code was done in the following way - For testing purposes there were two pairs of credentials a / b and c / d whereas the first one is used for the test client and the latter for the gateway:&lt;br /&gt;
 &lt;br /&gt;
 // Loading the pre-shared secrets&lt;br /&gt;
 server_credentials = CredentialsMap()&lt;br /&gt;
 // the first parameter states the name of the context in this case it&#039;s b but can be named in any way and the second parameter is the path to the folder e.g. the file would be located in /contextdir/b/settings.json&lt;br /&gt;
 server_credentials[&#039;:b&#039;] = get_security_context(&#039;b&#039;, args.contextdir / &amp;quot;b&amp;quot;)&lt;br /&gt;
 server_credentials[&#039;:d&#039;] = get_security_context(&#039;d&#039;, args.contextdir / &amp;quot;d&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To enable OSCORE for the server now the following code was added/adjusted:&lt;br /&gt;
 // root is the variable for the site&lt;br /&gt;
 // Enable the site to talK OSCORE with the credentials loaded from before&lt;br /&gt;
 root = OscoreSiteWrapper(root, server_credentials)&lt;br /&gt;
 args.bind = bind&lt;br /&gt;
 // Now we create a server context with arguments added&lt;br /&gt;
 asyncio.Task(server_context_from_arguments(root, args))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./comatrix_gateway.py contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:CoMatrix-Gateway-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
To test if the gateway actually talks in OSCORE the plugtest-client from the aiocoap library was adjusted to meet our needs for comatrix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./unit-tests.py host contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:Unittest-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
=== Wireshark Capture ===&lt;br /&gt;
&lt;br /&gt;
The Wireshark Capture can be downloaded here:&lt;br /&gt;
[[Media:OSCORE-wireshark-capture.zip]]&lt;br /&gt;
&lt;br /&gt;
[[File:OSCORE-wireshark.png]]&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
The Comatrix project already uses RIOT-OS for the client board so we continued using it. For the implementation of OSCORE on RIOT-OS we tried using liboscore. It comes with it&#039;s own build stack and is therefore different from the instructions provided by the Comatrix project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setup the build stack ===&lt;br /&gt;
&lt;br /&gt;
First, the liboscore project has to be cloned locally with the recursive parameter so that it contains RIOT-OS itself. This can be achieved by following the steps provided in [https://oscore.gitlab.io/liboscore/demo_common.html Common set-up instructions for RIOT-based demos]&lt;br /&gt;
The folders &#039;comatrix&#039;, &#039;example_comatrix_chat&#039; and &#039;example_comatrix_tempsensor&#039; from the Comatrix client directory then have to be copied into the folder &#039;liboscore/tests/riot-tests/&#039;.&lt;br /&gt;
Because the RIOT-OS is now different in relation to the code the Makefile has to be adapted.&lt;br /&gt;
&lt;br /&gt;
Remove this line:&lt;br /&gt;
 include $(RIOTBASE)/Makefile.include&lt;br /&gt;
&lt;br /&gt;
Add this line:&lt;br /&gt;
 include ../Makefile.include&lt;br /&gt;
&lt;br /&gt;
The project can then be built by using&lt;br /&gt;
 make all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adapt liboscore ===&lt;br /&gt;
&lt;br /&gt;
The comatrix examples for the chat and the tempsensor both use the source code in the comatrix folder which handles the CoAP messaging. This is why we did not change the examples but rather the comatrix code to implement OSCORE centrally.&lt;br /&gt;
Because the liboscore is still in a very early state and wasn&#039;t maintained for about two years we rarely found working examples so the focus was set onto the &#039;plugtest-server&#039; code within the riot-tests folder which is documented as [https://oscore.gitlab.io/liboscore/demo_plugtest_linux.html Demo: Running the OSCORE plug test server on RIOT native ].&lt;br /&gt;
This code makes use of threading and mutex because it also acts as a server which we don&#039;t need because the chat and tempsensor examples only act as clients. We needed to remvove those parts and only use the functions for preparing and encrypting the OSCORE message.&lt;br /&gt;
&lt;br /&gt;
First we added the includes to oscore&lt;br /&gt;
 #include &amp;lt;oscore_native/message.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/contextpair.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/primitive.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/b1.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/protection.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, to generate the security context, we need to call the script &#039;oscore-key-derivation&#039; as documented in [https://oscore.gitlab.io/liboscore/demo_peertopeer.html Demo: Peer-to-peer exchanges in 6LoWPAN network], but we used the parameter &#039;--format header&#039; to retrieve the context in a matter that the compiler understands.&lt;br /&gt;
This block is then copied to the comatrix.c file. An example of this is:&lt;br /&gt;
&lt;br /&gt;
 #define SENDER_KEY {255, 177, 78, 9, 60, 148, 201, 202, 201, 71, 22, 72, 180, 249, 135, 16}&lt;br /&gt;
 #define RECIPIENT_KEY {240, 145, 14, 215, 41, 94, 106, 212, 181, 79, 199, 147, 21, 67, 2, 255}&lt;br /&gt;
 #define COMMON_IV {70, 34, 212, 221, 109, 148, 65, 104, 238, 251, 84, 152, 124}&lt;br /&gt;
 #define SENDER_ID {1}&lt;br /&gt;
 #define RECIPIENT_ID {}&lt;br /&gt;
&lt;br /&gt;
The security context then has to be created&lt;br /&gt;
 static struct oscore_context_primitive_immutables immutables_d = {&lt;br /&gt;
     .common_iv = COMMON_IV,&lt;br /&gt;
     &lt;br /&gt;
     .recipient_id_len = 0,&lt;br /&gt;
     .recipient_key = RECIPIENT_KEY,&lt;br /&gt;
     &lt;br /&gt;
     .sender_id_len = 1,&lt;br /&gt;
     .sender_id = &amp;quot;\x01&amp;quot;,&lt;br /&gt;
     .sender_key = SENDER_KEY,&lt;br /&gt;
 };&lt;br /&gt;
 static struct oscore_context_primitive primitive_d = { .immutables = &amp;amp;immutables_d };&lt;br /&gt;
 oscore_context_t secctx_d = {&lt;br /&gt;
     .type = OSCORE_CONTEXT_PRIMITIVE,&lt;br /&gt;
     .data = (void*)(&amp;amp;primitive_d),&lt;br /&gt;
 };&lt;br /&gt;
 int16_t secctx_d_change = 0;&lt;br /&gt;
&lt;br /&gt;
As the first function to adapt we decided to use the function comatrix_sendmsg as we can set different text at runtime in the CLI and immediately get the results while capturing with Wireshark.&lt;br /&gt;
The following code is not working at the moment as we are facing issues with the method &#039;oscore_encrypt_message&#039;. While debugging it we found out that the payload gets a special character somewhere during the preparation so that the length of the ciphertext cannot be calculated correctly.&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  *  @brief sends a COAP send message PUT request to the gateway, type is non-confirmable and no response handler is called&lt;br /&gt;
  *&lt;br /&gt;
  *  Send message request is non-confirmable for very constraint devices like sensor nodes, when communication errors occur the packet will not be resent&lt;br /&gt;
  *&lt;br /&gt;
  *  @param[in] msgbuf               message buffer.&lt;br /&gt;
  *  @param[in] msglen               length of message buffer.&lt;br /&gt;
  *  @param[in] callback_handler     should be 0; not implemented yet because it is non-confirmable&lt;br /&gt;
  *&lt;br /&gt;
  *  @return length of the payload&lt;br /&gt;
  *  @return 0   when the message exceeds PDU payload buffer size&lt;br /&gt;
  *  @return -1  when CoAP send message PUT request failed&lt;br /&gt;
  **/&lt;br /&gt;
 int comatrix_sendmsg(char *msgbuf, size_t msglen, comatrix_callback_t callback_handler) {&lt;br /&gt;
    (void)callback_handler;   /* not used by now because CoAP type is non-confirmable */&lt;br /&gt;
    coap_pkt_t pdu;&lt;br /&gt;
    uint8_t    pdu_buf[CONFIG_GCOAP_PDU_BUF_SIZE];&lt;br /&gt;
    size_t     len       = 0;&lt;br /&gt;
    char       separator = &#039;\0&#039;;&lt;br /&gt;
    oscore_msg_protected_t oscmsg;&lt;br /&gt;
 &lt;br /&gt;
    struct static_request_data request_data = { .done = MUTEX_INIT_LOCKED };&lt;br /&gt;
 &lt;br /&gt;
    /* build proxy string */&lt;br /&gt;
   #ifdef CONFIG_COMATRIX_ENABLE_SHORTURL&lt;br /&gt;
    int  proxy_buf_size = 20 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/9/%s/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #else&lt;br /&gt;
    int  proxy_buf_size = 49 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/_matrix/client/r0/rooms/%s/send/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #endif&lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] proxystring len: %d \n&amp;quot;, le);&lt;br /&gt;
 &lt;br /&gt;
    /* increment message counter */&lt;br /&gt;
    _cstate.tx_id = _cstate.tx_id + 1;&lt;br /&gt;
 &lt;br /&gt;
    /* initialize coap packet and set header and options */&lt;br /&gt;
    gcoap_req_init(&amp;amp;pdu, pdu_buf, CONFIG_GCOAP_PDU_BUF_SIZE, COAP_METHOD_PUT, COMATRIX_SENDMSG_PATH);&lt;br /&gt;
    coap_hdr_set_type(pdu.hdr, COAP_TYPE_NON);&lt;br /&gt;
    coap_opt_add_format(&amp;amp;pdu, COAP_FORMAT_CBOR);&lt;br /&gt;
    coap_opt_add_proxy_uri(&amp;amp;pdu, proxy_buf);&lt;br /&gt;
    coap_opt_add_chars(&amp;amp;pdu, COMATRIX_OPT_NUM, _cstate.comatrix_token, strlen(_cstate.comatrix_token), separator);&lt;br /&gt;
    len = coap_opt_finish(&amp;amp;pdu, COAP_OPT_FINISH_PAYLOAD);&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t native = { .pkt = &amp;amp;pdu };&lt;br /&gt;
    secctx_d_change += 1;&lt;br /&gt;
 &lt;br /&gt;
    if (oscore_prepare_request(native, &amp;amp;oscmsg, &amp;amp;secctx_d, &amp;amp;request_data.request_id) != OSCORE_PREPARE_OK) {&lt;br /&gt;
       printf(&amp;quot;Failed to prepare request encryption\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_protected_set_code(&amp;amp;oscmsg, 0x02 /* POST */);&lt;br /&gt;
 &lt;br /&gt;
    /* validate input length and encode payload to cbor {&amp;quot;msgtype&amp;quot;:&amp;quot;m.text&amp;quot;,&amp;quot;body&amp;quot;:&amp;quot;&amp;quot;} - 22 bytes cbor without msg */&lt;br /&gt;
    if (pdu.payload_len &amp;gt;= msglen + 23) {&lt;br /&gt;
       size_t cborlen = encbor_comatrixmsg((uint8_t *)pdu.payload, msgbuf, msglen);;&lt;br /&gt;
       len += cborlen;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] ERROR. The message buffer is too small for the message\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msgerr_protected_t oscerr;&lt;br /&gt;
    oscerr = oscore_msg_protected_append_option(&amp;amp;oscmsg, 11 /* Uri-Path */, (uint8_t*)&amp;quot;uripath&amp;quot;, 7);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to add option\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    uint8_t *payload;&lt;br /&gt;
    size_t payload_length;&lt;br /&gt;
    oscerr = oscore_msg_protected_map_payload(&amp;amp;oscmsg, &amp;amp;payload, &amp;amp;payload_length);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to map payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;map_payload: %s&amp;quot;, payload);&lt;br /&gt;
 &lt;br /&gt;
    /*payload = (uint8_t*)malloc(100 * sizeof(*payload));&lt;br /&gt;
    memcpy(payload, msgbuf, len);&lt;br /&gt;
    printf(&amp;quot;new payload: %s&amp;quot;, payload);*/&lt;br /&gt;
 &lt;br /&gt;
    oscerr = oscore_msg_protected_trim_payload(&amp;amp;oscmsg, 1);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to truncate payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t pdu_write_out;&lt;br /&gt;
    if (oscore_encrypt_message(&amp;amp;oscmsg, &amp;amp;pdu_write_out) != OSCORE_FINISH_OK) {&lt;br /&gt;
       // see FIXME in oscore_encrypt_message description&lt;br /&gt;
       printf(&amp;quot;Failed to encrypt payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] sending msg ID %u, %u bytes\n&amp;quot;, coap_get_id(&amp;amp;pdu), (unsigned)len);&lt;br /&gt;
    if (!gcoap_req_send(pdu_buf, len, &amp;amp;_cstate.remote, NULL, &amp;amp;request_data)) {&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] msg send failed\n&amp;quot;);&lt;br /&gt;
       return(-1);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 error:&lt;br /&gt;
     {}&lt;br /&gt;
     // FIXME: abort encryption (but no PDU recovery and PDU freeing necessary on this backend as it&#039;s all stack allocated)&lt;br /&gt;
 &lt;br /&gt;
    return(len);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Current status ===&lt;br /&gt;
&lt;br /&gt;
== Used Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 3B+ Model (CoMatrix Gateway)&lt;br /&gt;
* OpenLabs 802.15.4. radio module&lt;br /&gt;
* SAMR21-xpro (CoMatrix Client)&lt;br /&gt;
* (optional) Raspberry Pi 4 (Matrix Homeserver)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://comatrix.eu&lt;br /&gt;
* https://aiocoap.readthedocs.io&lt;br /&gt;
* https://github.com/chrysn/liboscore&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11672</id>
		<title>CoMatrix: OSCORE</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11672"/>
		<updated>2023-07-04T21:23:12Z</updated>

		<summary type="html">&lt;p&gt;MBasta: /* Adapt liboscore */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This documentation describes the usage of an application-layer protocol OSCORE to provide end-to-end protection between the [https://comatrix.eu/setup/architecture_and_testbed CoMatrix Gateway and CoMatrix Client].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: &lt;br /&gt;
** Ubuntu 22.04 (Gateway)&lt;br /&gt;
** RIOT OS (Client)&lt;br /&gt;
* See [[#Used Hardware]]&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must set up the [https://comatrix.eu/setup/ CoMatrix project] before.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
OSCORE is a security protocol designed to provide end-to-end protection between endpoints communicating using CoAP.&lt;br /&gt;
&lt;br /&gt;
The keys are pre-shared between the client and the gateway because there is no key exchange protocol in OSCORE itself. However, there is ongoing work with key exchange protocols such as EDHOC or [https://datatracker.ietf.org/doc/html/draft-ietf-ace-oscore-profile-11 ACE-OSCORE]&lt;br /&gt;
&lt;br /&gt;
== Gateway ==&lt;br /&gt;
&lt;br /&gt;
The Python library aiocoap provides the OSCORE functionality and was used in order for the gateway to understand OSCORE within CoAP.&lt;br /&gt;
&lt;br /&gt;
=== Imports ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following imports were added&lt;br /&gt;
&lt;br /&gt;
 from aiocoap.oscore_sitewrapper import OscoreSiteWrapper&lt;br /&gt;
 from aiocoap.credentials import CredentialsMap&lt;br /&gt;
 from plugtest_common import *&lt;br /&gt;
 from aiocoap.cli.common import server_context_from_arguments, add_server_arguments&lt;br /&gt;
&lt;br /&gt;
* The plugtest_common import was extracted from the aiocoap OSCORE plugtest and provides verification for external AADs and returning the security context.&lt;br /&gt;
&lt;br /&gt;
=== Main ===&lt;br /&gt;
&lt;br /&gt;
When starting the gateway, new parameters have been added to list the directory where the pre-shared secrets are held and sequence numbers will be saved. These sequence numbers are necessary for replay protection.&lt;br /&gt;
&lt;br /&gt;
 parser.add_argument(&amp;quot;contextdir&amp;quot;, help=&amp;quot;Directory name where to persist sequence numbers and the location of the secrets&amp;quot;, type=Path)&lt;br /&gt;
 &lt;br /&gt;
 // Necessary to add these arguments provided by the aiocoap library in order for the server to start correctly. More info under aiocoap/cli/common.py&lt;br /&gt;
 add_server_arguments(parser)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The context directory may contain two files:&lt;br /&gt;
* secrets.json&lt;br /&gt;
* settings.json&lt;br /&gt;
As per implementation it is sufficient to only have one of these files in the directory.&lt;br /&gt;
&lt;br /&gt;
The format of the file is the following JSON:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
Important properties are:&lt;br /&gt;
* sender-id&lt;br /&gt;
* recipient-id&lt;br /&gt;
* secret&lt;br /&gt;
&lt;br /&gt;
These three properties must be appended with either _hex or _ascii and have the values according to the suffix.&lt;br /&gt;
&lt;br /&gt;
Assume that the file above was for the server and for our client we would need the following file:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notice how sender-id and recipient-id had to be swapped.&lt;br /&gt;
With these two secret files it is now possible to start a gateway and a client each using a different JSON file with the ids flipped.&lt;br /&gt;
&lt;br /&gt;
For further information see [https://aiocoap.readthedocs.io/en/latest/stateofoscore.html#oscore-credentials aiocoap-OSCORE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loading these in the code was done in the following way - For testing purposes there were two pairs of credentials a / b and c / d whereas the first one is used for the test client and the latter for the gateway:&lt;br /&gt;
 &lt;br /&gt;
 // Loading the pre-shared secrets&lt;br /&gt;
 server_credentials = CredentialsMap()&lt;br /&gt;
 // the first parameter states the name of the context in this case it&#039;s b but can be named in any way and the second parameter is the path to the folder e.g. the file would be located in /contextdir/b/settings.json&lt;br /&gt;
 server_credentials[&#039;:b&#039;] = get_security_context(&#039;b&#039;, args.contextdir / &amp;quot;b&amp;quot;)&lt;br /&gt;
 server_credentials[&#039;:d&#039;] = get_security_context(&#039;d&#039;, args.contextdir / &amp;quot;d&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To enable OSCORE for the server now the following code was added/adjusted:&lt;br /&gt;
 // root is the variable for the site&lt;br /&gt;
 // Enable the site to talK OSCORE with the credentials loaded from before&lt;br /&gt;
 root = OscoreSiteWrapper(root, server_credentials)&lt;br /&gt;
 args.bind = bind&lt;br /&gt;
 // Now we create a server context with arguments added&lt;br /&gt;
 asyncio.Task(server_context_from_arguments(root, args))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./comatrix_gateway.py contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:CoMatrix-Gateway-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
To test if the gateway actually talks in OSCORE the plugtest-client from the aiocoap library was adjusted to meet our needs for comatrix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./unit-tests.py host contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:Unittest-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
=== Wireshark Capture ===&lt;br /&gt;
&lt;br /&gt;
The Wireshark Capture can be downloaded here:&lt;br /&gt;
[[Media:OSCORE-wireshark-capture.zip]]&lt;br /&gt;
&lt;br /&gt;
[[File:OSCORE-wireshark.png]]&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
The Comatrix project already uses RIOT-OS for the client board so we continued using it. For the implementation of OSCORE on RIOT-OS we tried using liboscore. It comes with it&#039;s own build stack and is therefore different from the instructions provided by the Comatrix project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setup the build stack ===&lt;br /&gt;
&lt;br /&gt;
First, the liboscore project has to be cloned locally with the recursive parameter so that it contains RIOT-OS itself. This can be achieved by following the steps provided in [https://oscore.gitlab.io/liboscore/demo_common.html Common set-up instructions for RIOT-based demos]&lt;br /&gt;
The folders &#039;comatrix&#039;, &#039;example_comatrix_chat&#039; and &#039;example_comatrix_tempsensor&#039; from the Comatrix client directory then have to be copied into the folder &#039;liboscore/tests/riot-tests/&#039;.&lt;br /&gt;
Because the RIOT-OS is now different in relation to the code the Makefile has to be adapted.&lt;br /&gt;
&lt;br /&gt;
Remove this line:&lt;br /&gt;
 include $(RIOTBASE)/Makefile.include&lt;br /&gt;
&lt;br /&gt;
Add this line:&lt;br /&gt;
 include ../Makefile.include&lt;br /&gt;
&lt;br /&gt;
The project can then be built by using&lt;br /&gt;
 make all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adapt liboscore ===&lt;br /&gt;
&lt;br /&gt;
The comatrix examples for the chat and the tempsensor both use the source code in the comatrix folder which handles the CoAP messaging. This is why we did not change the examples but rather the comatrix code to implement OSCORE centrally.&lt;br /&gt;
Because the liboscore is still in a very early state and wasn&#039;t maintained for about two years we rarely found working examples so the focus was set onto the &#039;plugtest-server&#039; code within the riot-tests folder which is documented as [https://oscore.gitlab.io/liboscore/demo_plugtest_linux.html Demo: Running the OSCORE plug test server on RIOT native ].&lt;br /&gt;
This code makes use of threading and mutex because it also acts as a server which we don&#039;t need because the chat and tempsensor examples only act as clients. We needed to remvove those parts and only use the functions for preparing and encrypting the OSCORE message.&lt;br /&gt;
&lt;br /&gt;
First we added the includes to oscore&lt;br /&gt;
 #include &amp;lt;oscore_native/message.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/contextpair.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/primitive.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/b1.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/protection.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, to generate the security context, we need to call the script &#039;oscore-key-derivation&#039; as documented in [https://oscore.gitlab.io/liboscore/demo_peertopeer.html Demo: Peer-to-peer exchanges in 6LoWPAN network], but we used the parameter &#039;--format header&#039; to retrieve the context in a matter that the compiler understands.&lt;br /&gt;
This block is then copied to the comatrix.c file. An example of this is:&lt;br /&gt;
&lt;br /&gt;
 #define SENDER_KEY {255, 177, 78, 9, 60, 148, 201, 202, 201, 71, 22, 72, 180, 249, 135, 16}&lt;br /&gt;
 #define RECIPIENT_KEY {240, 145, 14, 215, 41, 94, 106, 212, 181, 79, 199, 147, 21, 67, 2, 255}&lt;br /&gt;
 #define COMMON_IV {70, 34, 212, 221, 109, 148, 65, 104, 238, 251, 84, 152, 124}&lt;br /&gt;
 #define SENDER_ID {1}&lt;br /&gt;
 #define RECIPIENT_ID {}&lt;br /&gt;
&lt;br /&gt;
The security context then has to be created&lt;br /&gt;
 static struct oscore_context_primitive_immutables immutables_d = {&lt;br /&gt;
     .common_iv = COMMON_IV,&lt;br /&gt;
     &lt;br /&gt;
     .recipient_id_len = 0,&lt;br /&gt;
     .recipient_key = RECIPIENT_KEY,&lt;br /&gt;
     &lt;br /&gt;
     .sender_id_len = 1,&lt;br /&gt;
     .sender_id = &amp;quot;\x01&amp;quot;,&lt;br /&gt;
     .sender_key = SENDER_KEY,&lt;br /&gt;
 };&lt;br /&gt;
 static struct oscore_context_primitive primitive_d = { .immutables = &amp;amp;immutables_d };&lt;br /&gt;
 oscore_context_t secctx_d = {&lt;br /&gt;
     .type = OSCORE_CONTEXT_PRIMITIVE,&lt;br /&gt;
     .data = (void*)(&amp;amp;primitive_d),&lt;br /&gt;
 };&lt;br /&gt;
 int16_t secctx_d_change = 0;&lt;br /&gt;
&lt;br /&gt;
As the first function to adapt we decided to use the function comatrix_sendmsg as we can set different text at runtime in the CLI and immediately get the results while capturing with Wireshark.&lt;br /&gt;
The following code is not working at the moment as we are facing issues with the method &#039;oscore_encrypt_message&#039;. While debugging it we found out that the payload gets a special character somewhere during the preparation so that the length of the ciphertext cannot be calculated correctly.&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  *  @brief sends a COAP send message PUT request to the gateway, type is non-confirmable and no response handler is called&lt;br /&gt;
  *&lt;br /&gt;
  *  Send message request is non-confirmable for very constraint devices like sensor nodes, when communication errors occur the packet will not be resent&lt;br /&gt;
  *&lt;br /&gt;
  *  @param[in] msgbuf               message buffer.&lt;br /&gt;
  *  @param[in] msglen               length of message buffer.&lt;br /&gt;
  *  @param[in] callback_handler     should be 0; not implemented yet because it is non-confirmable&lt;br /&gt;
  *&lt;br /&gt;
  *  @return length of the payload&lt;br /&gt;
  *  @return 0   when the message exceeds PDU payload buffer size&lt;br /&gt;
  *  @return -1  when CoAP send message PUT request failed&lt;br /&gt;
  **/&lt;br /&gt;
 int comatrix_sendmsg(char *msgbuf, size_t msglen, comatrix_callback_t callback_handler) {&lt;br /&gt;
    (void)callback_handler;   /* not used by now because CoAP type is non-confirmable */&lt;br /&gt;
    coap_pkt_t pdu;&lt;br /&gt;
    uint8_t    pdu_buf[CONFIG_GCOAP_PDU_BUF_SIZE];&lt;br /&gt;
    size_t     len       = 0;&lt;br /&gt;
    char       separator = &#039;\0&#039;;&lt;br /&gt;
    oscore_msg_protected_t oscmsg;&lt;br /&gt;
 &lt;br /&gt;
    struct static_request_data request_data = { .done = MUTEX_INIT_LOCKED };&lt;br /&gt;
 &lt;br /&gt;
    /* build proxy string */&lt;br /&gt;
   #ifdef CONFIG_COMATRIX_ENABLE_SHORTURL&lt;br /&gt;
    int  proxy_buf_size = 20 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/9/%s/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #else&lt;br /&gt;
    int  proxy_buf_size = 49 + strlen(CONFIG_COMATRIX_SYNAPSE) + strlen(_cstate.comatrix_roomid) + snprintf(NULL, 0, &amp;quot;%d&amp;quot;, _cstate.tx_id);&lt;br /&gt;
    char proxy_buf[proxy_buf_size];&lt;br /&gt;
    int  le = snprintf(proxy_buf, proxy_buf_size, &amp;quot;%s/_matrix/client/r0/rooms/%s/send/m.room.message/%d&amp;quot;, CONFIG_COMATRIX_SYNAPSE, _cstate.comatrix_roomid, _cstate.tx_id);&lt;br /&gt;
   #endif&lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] proxystring len: %d \n&amp;quot;, le);&lt;br /&gt;
 &lt;br /&gt;
    /* increment message counter */&lt;br /&gt;
    _cstate.tx_id = _cstate.tx_id + 1;&lt;br /&gt;
 &lt;br /&gt;
    /* initialize coap packet and set header and options */&lt;br /&gt;
    gcoap_req_init(&amp;amp;pdu, pdu_buf, CONFIG_GCOAP_PDU_BUF_SIZE, COAP_METHOD_PUT, COMATRIX_SENDMSG_PATH);&lt;br /&gt;
    coap_hdr_set_type(pdu.hdr, COAP_TYPE_NON);&lt;br /&gt;
    coap_opt_add_format(&amp;amp;pdu, COAP_FORMAT_CBOR);&lt;br /&gt;
    coap_opt_add_proxy_uri(&amp;amp;pdu, proxy_buf);&lt;br /&gt;
    coap_opt_add_chars(&amp;amp;pdu, COMATRIX_OPT_NUM, _cstate.comatrix_token, strlen(_cstate.comatrix_token), separator);&lt;br /&gt;
    len = coap_opt_finish(&amp;amp;pdu, COAP_OPT_FINISH_PAYLOAD);&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t native = { .pkt = &amp;amp;pdu };&lt;br /&gt;
    secctx_d_change += 1;&lt;br /&gt;
 &lt;br /&gt;
    if (oscore_prepare_request(native, &amp;amp;oscmsg, &amp;amp;secctx_d, &amp;amp;request_data.request_id) != OSCORE_PREPARE_OK) {&lt;br /&gt;
       printf(&amp;quot;Failed to prepare request encryption\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_protected_set_code(&amp;amp;oscmsg, 0x02 /* POST */);&lt;br /&gt;
 &lt;br /&gt;
    /* validate input length and encode payload to cbor {&amp;quot;msgtype&amp;quot;:&amp;quot;m.text&amp;quot;,&amp;quot;body&amp;quot;:&amp;quot;&amp;quot;} - 22 bytes cbor without msg */&lt;br /&gt;
    if (pdu.payload_len &amp;gt;= msglen + 23) {&lt;br /&gt;
       size_t cborlen = encbor_comatrixmsg((uint8_t *)pdu.payload, msgbuf, msglen);;&lt;br /&gt;
       len += cborlen;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] ERROR. The message buffer is too small for the message\n&amp;quot;);&lt;br /&gt;
       return(0);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msgerr_protected_t oscerr;&lt;br /&gt;
    oscerr = oscore_msg_protected_append_option(&amp;amp;oscmsg, 11 /* Uri-Path */, (uint8_t*)&amp;quot;uripath&amp;quot;, 7);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to add option\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    uint8_t *payload;&lt;br /&gt;
    size_t payload_length;&lt;br /&gt;
    oscerr = oscore_msg_protected_map_payload(&amp;amp;oscmsg, &amp;amp;payload, &amp;amp;payload_length);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to map payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;map_payload: %s&amp;quot;, payload);&lt;br /&gt;
 &lt;br /&gt;
    /*payload = (uint8_t*)malloc(100 * sizeof(*payload));&lt;br /&gt;
    memcpy(payload, msgbuf, len);&lt;br /&gt;
    printf(&amp;quot;new payload: %s&amp;quot;, payload);*/&lt;br /&gt;
 &lt;br /&gt;
    oscerr = oscore_msg_protected_trim_payload(&amp;amp;oscmsg, 1);&lt;br /&gt;
    if (oscore_msgerr_protected_is_error(oscerr)) {&lt;br /&gt;
       printf(&amp;quot;Failed to truncate payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    oscore_msg_native_t pdu_write_out;&lt;br /&gt;
    if (oscore_encrypt_message(&amp;amp;oscmsg, &amp;amp;pdu_write_out) != OSCORE_FINISH_OK) {&lt;br /&gt;
       // see FIXME in oscore_encrypt_message description&lt;br /&gt;
       printf(&amp;quot;Failed to encrypt payload\n&amp;quot;);&lt;br /&gt;
       goto error;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    DEBUG(&amp;quot;[comatrix_sendmsg:] sending msg ID %u, %u bytes\n&amp;quot;, coap_get_id(&amp;amp;pdu), (unsigned)len);&lt;br /&gt;
    if (!gcoap_req_send(pdu_buf, len, &amp;amp;_cstate.remote, NULL, &amp;amp;request_data)) {&lt;br /&gt;
       DEBUG(&amp;quot;[comatrix_sendmsg:] msg send failed\n&amp;quot;);&lt;br /&gt;
       return(-1);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
 error:&lt;br /&gt;
     {}&lt;br /&gt;
     // FIXME: abort encryption (but no PDU recovery and PDU freeing necessary on this backend as it&#039;s all stack allocated)&lt;br /&gt;
 &lt;br /&gt;
    return(len);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Used Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 3B+ Model (CoMatrix Gateway)&lt;br /&gt;
* OpenLabs 802.15.4. radio module&lt;br /&gt;
* SAMR21-xpro (CoMatrix Client)&lt;br /&gt;
* (optional) Raspberry Pi 4 (Matrix Homeserver)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://comatrix.eu&lt;br /&gt;
* https://aiocoap.readthedocs.io&lt;br /&gt;
* https://github.com/chrysn/liboscore&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11671</id>
		<title>CoMatrix: OSCORE</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11671"/>
		<updated>2023-07-04T21:16:33Z</updated>

		<summary type="html">&lt;p&gt;MBasta: /* Adapt liboscore */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This documentation describes the usage of an application-layer protocol OSCORE to provide end-to-end protection between the [https://comatrix.eu/setup/architecture_and_testbed CoMatrix Gateway and CoMatrix Client].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: &lt;br /&gt;
** Ubuntu 22.04 (Gateway)&lt;br /&gt;
** RIOT OS (Client)&lt;br /&gt;
* See [[#Used Hardware]]&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must set up the [https://comatrix.eu/setup/ CoMatrix project] before.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
OSCORE is a security protocol designed to provide end-to-end protection between endpoints communicating using CoAP.&lt;br /&gt;
&lt;br /&gt;
The keys are pre-shared between the client and the gateway because there is no key exchange protocol in OSCORE itself. However, there is ongoing work with key exchange protocols such as EDHOC or [https://datatracker.ietf.org/doc/html/draft-ietf-ace-oscore-profile-11 ACE-OSCORE]&lt;br /&gt;
&lt;br /&gt;
== Gateway ==&lt;br /&gt;
&lt;br /&gt;
The Python library aiocoap provides the OSCORE functionality and was used in order for the gateway to understand OSCORE within CoAP.&lt;br /&gt;
&lt;br /&gt;
=== Imports ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following imports were added&lt;br /&gt;
&lt;br /&gt;
 from aiocoap.oscore_sitewrapper import OscoreSiteWrapper&lt;br /&gt;
 from aiocoap.credentials import CredentialsMap&lt;br /&gt;
 from plugtest_common import *&lt;br /&gt;
 from aiocoap.cli.common import server_context_from_arguments, add_server_arguments&lt;br /&gt;
&lt;br /&gt;
* The plugtest_common import was extracted from the aiocoap OSCORE plugtest and provides verification for external AADs and returning the security context.&lt;br /&gt;
&lt;br /&gt;
=== Main ===&lt;br /&gt;
&lt;br /&gt;
When starting the gateway, new parameters have been added to list the directory where the pre-shared secrets are held and sequence numbers will be saved. These sequence numbers are necessary for replay protection.&lt;br /&gt;
&lt;br /&gt;
 parser.add_argument(&amp;quot;contextdir&amp;quot;, help=&amp;quot;Directory name where to persist sequence numbers and the location of the secrets&amp;quot;, type=Path)&lt;br /&gt;
 &lt;br /&gt;
 // Necessary to add these arguments provided by the aiocoap library in order for the server to start correctly. More info under aiocoap/cli/common.py&lt;br /&gt;
 add_server_arguments(parser)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The context directory may contain two files:&lt;br /&gt;
* secrets.json&lt;br /&gt;
* settings.json&lt;br /&gt;
As per implementation it is sufficient to only have one of these files in the directory.&lt;br /&gt;
&lt;br /&gt;
The format of the file is the following JSON:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
Important properties are:&lt;br /&gt;
* sender-id&lt;br /&gt;
* recipient-id&lt;br /&gt;
* secret&lt;br /&gt;
&lt;br /&gt;
These three properties must be appended with either _hex or _ascii and have the values according to the suffix.&lt;br /&gt;
&lt;br /&gt;
Assume that the file above was for the server and for our client we would need the following file:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notice how sender-id and recipient-id had to be swapped.&lt;br /&gt;
With these two secret files it is now possible to start a gateway and a client each using a different JSON file with the ids flipped.&lt;br /&gt;
&lt;br /&gt;
For further information see [https://aiocoap.readthedocs.io/en/latest/stateofoscore.html#oscore-credentials aiocoap-OSCORE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loading these in the code was done in the following way - For testing purposes there were two pairs of credentials a / b and c / d whereas the first one is used for the test client and the latter for the gateway:&lt;br /&gt;
 &lt;br /&gt;
 // Loading the pre-shared secrets&lt;br /&gt;
 server_credentials = CredentialsMap()&lt;br /&gt;
 // the first parameter states the name of the context in this case it&#039;s b but can be named in any way and the second parameter is the path to the folder e.g. the file would be located in /contextdir/b/settings.json&lt;br /&gt;
 server_credentials[&#039;:b&#039;] = get_security_context(&#039;b&#039;, args.contextdir / &amp;quot;b&amp;quot;)&lt;br /&gt;
 server_credentials[&#039;:d&#039;] = get_security_context(&#039;d&#039;, args.contextdir / &amp;quot;d&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To enable OSCORE for the server now the following code was added/adjusted:&lt;br /&gt;
 // root is the variable for the site&lt;br /&gt;
 // Enable the site to talK OSCORE with the credentials loaded from before&lt;br /&gt;
 root = OscoreSiteWrapper(root, server_credentials)&lt;br /&gt;
 args.bind = bind&lt;br /&gt;
 // Now we create a server context with arguments added&lt;br /&gt;
 asyncio.Task(server_context_from_arguments(root, args))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./comatrix_gateway.py contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:CoMatrix-Gateway-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
To test if the gateway actually talks in OSCORE the plugtest-client from the aiocoap library was adjusted to meet our needs for comatrix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./unit-tests.py host contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:Unittest-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
=== Wireshark Capture ===&lt;br /&gt;
&lt;br /&gt;
The Wireshark Capture can be downloaded here:&lt;br /&gt;
[[Media:OSCORE-wireshark-capture.zip]]&lt;br /&gt;
&lt;br /&gt;
[[File:OSCORE-wireshark.png]]&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
The Comatrix project already uses RIOT-OS for the client board so we continued using it. For the implementation of OSCORE on RIOT-OS we tried using liboscore. It comes with it&#039;s own build stack and is therefore different from the instructions provided by the Comatrix project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setup the build stack ===&lt;br /&gt;
&lt;br /&gt;
First, the liboscore project has to be cloned locally with the recursive parameter so that it contains RIOT-OS itself. This can be achieved by following the steps provided in [https://oscore.gitlab.io/liboscore/demo_common.html Common set-up instructions for RIOT-based demos]&lt;br /&gt;
The folders &#039;comatrix&#039;, &#039;example_comatrix_chat&#039; and &#039;example_comatrix_tempsensor&#039; from the Comatrix client directory then have to be copied into the folder &#039;liboscore/tests/riot-tests/&#039;.&lt;br /&gt;
Because the RIOT-OS is now different in relation to the code the Makefile has to be adapted.&lt;br /&gt;
&lt;br /&gt;
Remove this line:&lt;br /&gt;
 include $(RIOTBASE)/Makefile.include&lt;br /&gt;
&lt;br /&gt;
Add this line:&lt;br /&gt;
 include ../Makefile.include&lt;br /&gt;
&lt;br /&gt;
The project can then be built by using&lt;br /&gt;
 make all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adapt liboscore ===&lt;br /&gt;
&lt;br /&gt;
The comatrix examples for the chat and the tempsensor both use the source code in the comatrix folder which handles the CoAP messaging. This is why we did not change the examples but rather the comatrix code to implement OSCORE centrally.&lt;br /&gt;
Because the liboscore is still in a very early state and wasn&#039;t maintained for about two years we rarely found working examples so the focus was set onto the &#039;plugtest-server&#039; code within the riot-tests folder which is documented as [https://oscore.gitlab.io/liboscore/demo_plugtest_linux.html Demo: Running the OSCORE plug test server on RIOT native ].&lt;br /&gt;
This code makes use of threading and mutex because it also acts as a server which we don&#039;t need because the chat and tempsensor examples only act as clients. We needed to remvove those parts and only use the functions for preparing and encrypting the OSCORE message.&lt;br /&gt;
&lt;br /&gt;
First we added the includes to oscore&lt;br /&gt;
 #include &amp;lt;oscore_native/message.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/contextpair.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/primitive.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/b1.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/protection.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, to generate the security context, we need to call the script &#039;oscore-key-derivation&#039; as documented in [https://oscore.gitlab.io/liboscore/demo_peertopeer.html Demo: Peer-to-peer exchanges in 6LoWPAN network], but we used the parameter &#039;--format header&#039; to retrieve the context in a matter that the compiler understands.&lt;br /&gt;
This block is then copied to the comatrix.c file. An example of this is:&lt;br /&gt;
&lt;br /&gt;
 #define SENDER_KEY {255, 177, 78, 9, 60, 148, 201, 202, 201, 71, 22, 72, 180, 249, 135, 16}&lt;br /&gt;
 #define RECIPIENT_KEY {240, 145, 14, 215, 41, 94, 106, 212, 181, 79, 199, 147, 21, 67, 2, 255}&lt;br /&gt;
 #define COMMON_IV {70, 34, 212, 221, 109, 148, 65, 104, 238, 251, 84, 152, 124}&lt;br /&gt;
 #define SENDER_ID {1}&lt;br /&gt;
 #define RECIPIENT_ID {}&lt;br /&gt;
&lt;br /&gt;
The security context then has to be created&lt;br /&gt;
 static struct oscore_context_primitive_immutables immutables_d = {&lt;br /&gt;
     .common_iv = COMMON_IV,&lt;br /&gt;
     &lt;br /&gt;
     .recipient_id_len = 0,&lt;br /&gt;
     .recipient_key = RECIPIENT_KEY,&lt;br /&gt;
     &lt;br /&gt;
     .sender_id_len = 1,&lt;br /&gt;
     .sender_id = &amp;quot;\x01&amp;quot;,&lt;br /&gt;
     .sender_key = SENDER_KEY,&lt;br /&gt;
 };&lt;br /&gt;
 static struct oscore_context_primitive primitive_d = { .immutables = &amp;amp;immutables_d };&lt;br /&gt;
 oscore_context_t secctx_d = {&lt;br /&gt;
     .type = OSCORE_CONTEXT_PRIMITIVE,&lt;br /&gt;
     .data = (void*)(&amp;amp;primitive_d),&lt;br /&gt;
 };&lt;br /&gt;
 int16_t secctx_d_change = 0;&lt;br /&gt;
&lt;br /&gt;
== Used Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 3B+ Model (CoMatrix Gateway)&lt;br /&gt;
* OpenLabs 802.15.4. radio module&lt;br /&gt;
* SAMR21-xpro (CoMatrix Client)&lt;br /&gt;
* (optional) Raspberry Pi 4 (Matrix Homeserver)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://comatrix.eu&lt;br /&gt;
* https://aiocoap.readthedocs.io&lt;br /&gt;
* https://github.com/chrysn/liboscore&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11670</id>
		<title>CoMatrix: OSCORE</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=CoMatrix:_OSCORE&amp;diff=11670"/>
		<updated>2023-07-04T21:16:10Z</updated>

		<summary type="html">&lt;p&gt;MBasta: Zwischenspeichern&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This documentation describes the usage of an application-layer protocol OSCORE to provide end-to-end protection between the [https://comatrix.eu/setup/architecture_and_testbed CoMatrix Gateway and CoMatrix Client].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: &lt;br /&gt;
** Ubuntu 22.04 (Gateway)&lt;br /&gt;
** RIOT OS (Client)&lt;br /&gt;
* See [[#Used Hardware]]&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must set up the [https://comatrix.eu/setup/ CoMatrix project] before.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
OSCORE is a security protocol designed to provide end-to-end protection between endpoints communicating using CoAP.&lt;br /&gt;
&lt;br /&gt;
The keys are pre-shared between the client and the gateway because there is no key exchange protocol in OSCORE itself. However, there is ongoing work with key exchange protocols such as EDHOC or [https://datatracker.ietf.org/doc/html/draft-ietf-ace-oscore-profile-11 ACE-OSCORE]&lt;br /&gt;
&lt;br /&gt;
== Gateway ==&lt;br /&gt;
&lt;br /&gt;
The Python library aiocoap provides the OSCORE functionality and was used in order for the gateway to understand OSCORE within CoAP.&lt;br /&gt;
&lt;br /&gt;
=== Imports ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following imports were added&lt;br /&gt;
&lt;br /&gt;
 from aiocoap.oscore_sitewrapper import OscoreSiteWrapper&lt;br /&gt;
 from aiocoap.credentials import CredentialsMap&lt;br /&gt;
 from plugtest_common import *&lt;br /&gt;
 from aiocoap.cli.common import server_context_from_arguments, add_server_arguments&lt;br /&gt;
&lt;br /&gt;
* The plugtest_common import was extracted from the aiocoap OSCORE plugtest and provides verification for external AADs and returning the security context.&lt;br /&gt;
&lt;br /&gt;
=== Main ===&lt;br /&gt;
&lt;br /&gt;
When starting the gateway, new parameters have been added to list the directory where the pre-shared secrets are held and sequence numbers will be saved. These sequence numbers are necessary for replay protection.&lt;br /&gt;
&lt;br /&gt;
 parser.add_argument(&amp;quot;contextdir&amp;quot;, help=&amp;quot;Directory name where to persist sequence numbers and the location of the secrets&amp;quot;, type=Path)&lt;br /&gt;
 &lt;br /&gt;
 // Necessary to add these arguments provided by the aiocoap library in order for the server to start correctly. More info under aiocoap/cli/common.py&lt;br /&gt;
 add_server_arguments(parser)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The context directory may contain two files:&lt;br /&gt;
* secrets.json&lt;br /&gt;
* settings.json&lt;br /&gt;
As per implementation it is sufficient to only have one of these files in the directory.&lt;br /&gt;
&lt;br /&gt;
The format of the file is the following JSON:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
Important properties are:&lt;br /&gt;
* sender-id&lt;br /&gt;
* recipient-id&lt;br /&gt;
* secret&lt;br /&gt;
&lt;br /&gt;
These three properties must be appended with either _hex or _ascii and have the values according to the suffix.&lt;br /&gt;
&lt;br /&gt;
Assume that the file above was for the server and for our client we would need the following file:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;sender-id_ascii&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
   &amp;quot;recipient-id_hex&amp;quot;: &amp;quot;01&amp;quot;,&lt;br /&gt;
   &amp;quot;secret_ascii&amp;quot;: &amp;quot;Correct Horse Battery Staple&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notice how sender-id and recipient-id had to be swapped.&lt;br /&gt;
With these two secret files it is now possible to start a gateway and a client each using a different JSON file with the ids flipped.&lt;br /&gt;
&lt;br /&gt;
For further information see [https://aiocoap.readthedocs.io/en/latest/stateofoscore.html#oscore-credentials aiocoap-OSCORE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loading these in the code was done in the following way - For testing purposes there were two pairs of credentials a / b and c / d whereas the first one is used for the test client and the latter for the gateway:&lt;br /&gt;
 &lt;br /&gt;
 // Loading the pre-shared secrets&lt;br /&gt;
 server_credentials = CredentialsMap()&lt;br /&gt;
 // the first parameter states the name of the context in this case it&#039;s b but can be named in any way and the second parameter is the path to the folder e.g. the file would be located in /contextdir/b/settings.json&lt;br /&gt;
 server_credentials[&#039;:b&#039;] = get_security_context(&#039;b&#039;, args.contextdir / &amp;quot;b&amp;quot;)&lt;br /&gt;
 server_credentials[&#039;:d&#039;] = get_security_context(&#039;d&#039;, args.contextdir / &amp;quot;d&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To enable OSCORE for the server now the following code was added/adjusted:&lt;br /&gt;
 // root is the variable for the site&lt;br /&gt;
 // Enable the site to talK OSCORE with the credentials loaded from before&lt;br /&gt;
 root = OscoreSiteWrapper(root, server_credentials)&lt;br /&gt;
 args.bind = bind&lt;br /&gt;
 // Now we create a server context with arguments added&lt;br /&gt;
 asyncio.Task(server_context_from_arguments(root, args))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./comatrix_gateway.py contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:CoMatrix-Gateway-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
To test if the gateway actually talks in OSCORE the plugtest-client from the aiocoap library was adjusted to meet our needs for comatrix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USAGE:&#039;&#039;&#039; ./unit-tests.py host contextdir&lt;br /&gt;
&lt;br /&gt;
[[File:Unittest-OSCORE.png]]&lt;br /&gt;
&lt;br /&gt;
=== Wireshark Capture ===&lt;br /&gt;
&lt;br /&gt;
The Wireshark Capture can be downloaded here:&lt;br /&gt;
[[Media:OSCORE-wireshark-capture.zip]]&lt;br /&gt;
&lt;br /&gt;
[[File:OSCORE-wireshark.png]]&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
The Comatrix project already uses RIOT-OS for the client board so we continued using it. For the implementation of OSCORE on RIOT-OS we tried using liboscore. It comes with it&#039;s own build stack and is therefore different from the instructions provided by the Comatrix project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setup the build stack ===&lt;br /&gt;
&lt;br /&gt;
First, the liboscore project has to be cloned locally with the recursive parameter so that it contains RIOT-OS itself. This can be achieved by following the steps provided in [https://oscore.gitlab.io/liboscore/demo_common.html Common set-up instructions for RIOT-based demos]&lt;br /&gt;
The folders &#039;comatrix&#039;, &#039;example_comatrix_chat&#039; and &#039;example_comatrix_tempsensor&#039; from the Comatrix client directory then have to be copied into the folder &#039;liboscore/tests/riot-tests/&#039;.&lt;br /&gt;
Because the RIOT-OS is now different in relation to the code the Makefile has to be adapted.&lt;br /&gt;
&lt;br /&gt;
Remove this line:&lt;br /&gt;
 include $(RIOTBASE)/Makefile.include&lt;br /&gt;
&lt;br /&gt;
Add this line:&lt;br /&gt;
 include ../Makefile.include&lt;br /&gt;
&lt;br /&gt;
The project can then be built by using&lt;br /&gt;
 make all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adapt liboscore ===&lt;br /&gt;
&lt;br /&gt;
The comatrix examples for the chat and the tempsensor both use the source code in the comatrix folder which handles the CoAP messaging. This is why we did not change the examples but rather the comatrix code to implement OSCORE centrally.&lt;br /&gt;
Because the liboscore is still in a very early state and wasn&#039;t maintained for about two years we rarely found working examples so the focus was set onto the &#039;plugtest-server&#039; code within the riot-tests folder which is documented as [https://oscore.gitlab.io/liboscore/demo_plugtest_linux.html Demo: Running the OSCORE plug test server on RIOT native ].&lt;br /&gt;
This code makes use of threading and mutex because it also acts as a server which we don&#039;t need because the chat and tempsensor examples only act as clients. We needed to remvove those parts and only use the functions for preparing and encrypting the OSCORE message.&lt;br /&gt;
&lt;br /&gt;
First we added the includes to oscore&lt;br /&gt;
 #include &amp;lt;oscore_native/message.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/contextpair.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/primitive.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/context_impl/b1.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;oscore/protection.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, to generate the security context, we need to call the script &#039;oscore-key-derivation&#039; as documented in [https://oscore.gitlab.io/liboscore/demo_peertopeer.html Demo: Peer-to-peer exchanges in 6LoWPAN network], but we used the parameter &#039;--format header&#039; to retrieve the context in a matter that the compiler understands.&lt;br /&gt;
This block is then copied to the comatrix.c file. An example of this is:&lt;br /&gt;
&lt;br /&gt;
 #define SENDER_KEY {255, 177, 78, 9, 60, 148, 201, 202, 201, 71, 22, 72, 180, 249, 135, 16}&lt;br /&gt;
 #define RECIPIENT_KEY {240, 145, 14, 215, 41, 94, 106, 212, 181, 79, 199, 147, 21, 67, 2, 255}&lt;br /&gt;
 #define COMMON_IV {70, 34, 212, 221, 109, 148, 65, 104, 238, 251, 84, 152, 124}&lt;br /&gt;
 #define SENDER_ID {1}&lt;br /&gt;
 #define RECIPIENT_ID {}&lt;br /&gt;
&lt;br /&gt;
The security context then has to be created&lt;br /&gt;
 static struct oscore_context_primitive_immutables immutables_d = {&lt;br /&gt;
     .common_iv = COMMON_IV,&lt;br /&gt;
&lt;br /&gt;
     .recipient_id_len = 0,&lt;br /&gt;
     .recipient_key = RECIPIENT_KEY,&lt;br /&gt;
&lt;br /&gt;
     .sender_id_len = 1,&lt;br /&gt;
     .sender_id = &amp;quot;\x01&amp;quot;,&lt;br /&gt;
     .sender_key = SENDER_KEY,&lt;br /&gt;
 };&lt;br /&gt;
 static struct oscore_context_primitive primitive_d = { .immutables = &amp;amp;immutables_d };&lt;br /&gt;
 oscore_context_t secctx_d = {&lt;br /&gt;
     .type = OSCORE_CONTEXT_PRIMITIVE,&lt;br /&gt;
     .data = (void*)(&amp;amp;primitive_d),&lt;br /&gt;
 };&lt;br /&gt;
 int16_t secctx_d_change = 0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Used Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 3B+ Model (CoMatrix Gateway)&lt;br /&gt;
* OpenLabs 802.15.4. radio module&lt;br /&gt;
* SAMR21-xpro (CoMatrix Client)&lt;br /&gt;
* (optional) Raspberry Pi 4 (Matrix Homeserver)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://comatrix.eu&lt;br /&gt;
* https://aiocoap.readthedocs.io&lt;br /&gt;
* https://github.com/chrysn/liboscore&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>MBasta</name></author>
	</entry>
</feed>