Binärprotokoll der L4Re-Bauform
Diese Seite beschreibt jede Nachricht, die die L4Re-Bauform versteht und sendet, Byte für Byte. Sie
gilt für Protokollversion 1. Maßgeblich ist die Headerdatei l4re/pub/include/wvds_crypto.h; diese
Seite fasst sie zusammen und ergänzt das Verhalten des Dienstes, das sich aus dem Header allein nicht
ablesen lässt.
Transport
Anfrage und Antwort laufen über DataspaceEndpoint. Der Dienst meldet sich unter dem IPC-Namen
CRYPTO_SVC an und erwartet die anfragende Seite unter CRYPTO_CLI; der geteilte Bereich je Seite ist
64 KiB groß.
| Schritt | Wer | Aufruf |
|---|---|---|
| Anfrage senden | Client | add_new_req(id, typ, adresse, länge); als typ üblicherweise der Anfragetyp aus dem Kopf |
| Anfrage lesen und freigeben | Dienst | liest die Nachricht, ruft free_peer_req für jede angenommene oder abgewiesene Anfrage |
| Antwort senden | Dienst | add_new_req mit derselben id und dem IPC-Typ 0x80 |
| Antwort lesen und freigeben | Client | wertet den Kopf aus, ruft free_peer_req |
Die id ordnet eine Antwort ihrer Anfrage zu; sie ist frei wählbar und sollte je offener Anfrage
eindeutig sein. Der IPC-Typ einer Antwort ist immer 0x80, auch bei Fehlern. Ob eine Antwort ein Fehler
ist, steht ausschließlich im Feld req_type des Nachrichtenkopfs.
Nachrichtenkopf
Jede Nachricht beginnt mit 16 Byte. Alle Zahlen sind Little Endian.
| Versatz | Länge | Feld | Inhalt |
|---|---|---|---|
| 0 | 4 | magic | 0x43525950, auf der Leitung 50 59 52 43 |
| 4 | 1 | version | 1 |
| 5 | 1 | req_type | Anfrage- oder Antworttyp, siehe unten |
| 6 | 2 | flags | 0; der Dienst wertet das Feld nicht aus |
| 8 | 4 | key_id | Schlüsselkennung, 0 wenn die Anfrage keinen Schlüssel braucht |
| 12 | 4 | payload_len | Länge der Nutzdaten nach dem Kopf |
Der Dienst prüft vor jeder Verarbeitung:
- Die Nachricht ist mindestens 16 Byte und höchstens 16 Byte plus 64 KiB lang.
magicundversionstimmen.payload_lenist höchstens 65 536 und entspricht genau der Nachrichtenlänge minus 16.
Eine leere oder zu lange Nachricht verwirft der Dienst ohne Antwort. Ist sie kürzer als der Kopf, stimmt
der Kopf nicht oder passt payload_len nicht, antwortet er mit WVDS_ERR_INVALID_HEADER.
Anfragetypen
| Wert | Name | key_id | Bedient |
|---|---|---|---|
0x01 | WVDS_REQ_AES_GCM_ENCRYPT | AES-Schlüssel | ja |
0x02 | WVDS_REQ_AES_GCM_DECRYPT | AES-Schlüssel | ja |
0x03 | WVDS_REQ_CHACHA20_ENCRYPT | ChaCha20-Schlüssel | nur mit Bauoption chacha20 |
0x04 | WVDS_REQ_CHACHA20_DECRYPT | ChaCha20-Schlüssel | nur mit Bauoption chacha20 |
0x10 | WVDS_REQ_ML_DSA_SIGN | ML-DSA-Schlüssel | ja |
0x11 | WVDS_REQ_ML_DSA_VERIFY | 0 | ja |
0x12 | WVDS_REQ_ML_DSA_KEYGEN | 0 | ja |
0x20 | WVDS_REQ_ML_KEM_ENCAP | 0 | ja |
0x21 | WVDS_REQ_ML_KEM_DECAP | ML-KEM-Schlüssel | ja |
0x22 | WVDS_REQ_ML_KEM_KEYGEN | 0 | ja |
0x30, 0x31 | WVDS_REQ_SLH_DSA_SIGN, …_VERIFY | – | reserviert |
0x40, 0x41 | WVDS_REQ_LMS_SIGN, …_VERIFY | – | reserviert |
0x50 | WVDS_REQ_DERIVE_KEY | 0 | ja |
0x51 | WVDS_REQ_IMPORT_KEY | – | reserviert |
0x52 | WVDS_REQ_EXPORT_KEY | Schlüsselpaar | ja |
0x80 | WVDS_REQ_RESPONSE | wie Anfrage | Antwort |
0xFF | WVDS_REQ_ERROR | 0 | Fehlerantwort |
Reservierte und nicht eingebaute Typen beantwortet der Dienst mit WVDS_ERR_INVALID_REQ_TYPE.
Eine Anfrage, die einen ChaCha20-Schlüssel braucht, ist heute nicht erfüllbar: Kein Anfragetyp erzeugt einen solchen Schlüssel. Dasselbe gilt für AES; siehe Schlüssel und ihre Ablage.
Nutzdaten je Anfrage
Längenfelder in den Nutzdaten sind 4 Byte, Little Endian. „Rest“ bedeutet: alle Bytes bis zum Ende der Nutzdaten.
AES-GCM
| Typ | Anfrage | Antwort |
|---|---|---|
0x01 | Nonce (12) · AAD-Länge (4) · AAD · Klartext (Rest) | Nonce (12) · Tag (16) · Chiffrat (Rest) |
0x02 | Nonce (12) · Tag (16) · AAD-Länge (4) · AAD · Chiffrat (Rest) | Klartext (Rest) |
Die Nonce liefert die anfragende Seite. Eine Nonce, die der Dienst für diesen Schlüssel unter den letzten
1024 schon gesehen hat, führt zu WVDS_ERR_ENCRYPTION_FAILED. ChaCha20 (0x03, 0x04) verwendet
dieselben Layouts.
ML-DSA
| Typ | Anfrage | Antwort |
|---|---|---|
0x12 | Stufe (1) | Kennung (4) · öffentlicher Schlüssel (Rest) |
0x10 | Stufe (1) · Nachricht (Rest) | Signatur (Rest) |
0x11 | Stufe (1) · Schlüssellänge (4) · öffentlicher Schlüssel · Signaturlänge (4) · Signatur · Nachricht (Rest) | Ergebnis (1): 1 gültig, 0 ungültig |
Stufen: 2 = ML-DSA-44, 3 = ML-DSA-65, 5 = ML-DSA-87. Bei 0x10 signiert der Dienst nur die
Nachricht; das Stufenbyte gehört nicht dazu, und der Dienst nimmt die Stufe aus dem Schlüssel. Bei 0x12
steht die neue Kennung zusätzlich im Feld key_id des Antwortkopfs.
Eine ungültige Signatur ist keine Fehlerantwort, sondern eine Antwort mit Ergebnis 0. Lässt sich der
öffentliche Schlüssel nicht verwenden, antwortet der Dienst mit WVDS_ERR_VERIFICATION_FAILED.
ML-KEM
| Typ | Anfrage | Antwort |
|---|---|---|
0x22 | Stufe (1) | Kennung (4) · öffentlicher Schlüssel (Rest) |
0x20 | Stufe (1) · öffentlicher Schlüssel (Rest) | gemeinsames Geheimnis (32) · Chiffrat (Rest) |
0x21 | Chiffrat (Rest) | gemeinsames Geheimnis (32) |
Stufen: 1 = ML-KEM-512, 3 = ML-KEM-768, 5 = ML-KEM-1024.
Schlüsselableitung und öffentliche Schlüssel
| Typ | Anfrage | Antwort |
|---|---|---|
0x50 | Salt-Länge (4) · Salt · Info-Länge (4) · Info · Ausgabelänge (4) · IKM (Rest) | abgeleiteter Schlüssel (Ausgabelänge) |
0x52 | keine Nutzdaten | öffentlicher Schlüssel (Rest) |
Bei 0x50 muss key_id 0 sein, das IKM darf nicht leer sein und die Ausgabelänge höchstens 1024
Byte betragen. 0x52 liefert den öffentlichen Schlüssel eines ML-DSA- oder ML-KEM-Schlüssels; für
andere Schlüssel antwortet der Dienst mit WVDS_ERR_KEY_NOT_FOUND.
Größen
| Parametersatz | Öffentlicher Schlüssel | Signatur bzw. Chiffrat |
|---|---|---|
| ML-DSA-44 | 1312 | 2420 |
| ML-DSA-65 | 1952 | 3309 |
| ML-DSA-87 | 2592 | 4627 |
| ML-KEM-512 | 800 | 768 |
| ML-KEM-768 | 1184 | 1088 |
| ML-KEM-1024 | 1568 | 1568 |
Alle Werte in Byte; der Header führt sie als Konstanten, etwa WVDS_ML_DSA_65_SIG_SIZE.
Fehlerantwort
Kopf mit req_type = 0xFF und key_id = 0, danach:
| Versatz | Länge | Inhalt |
|---|---|---|
| 0 | 4 | Fehlercode |
| 4 | 4 | Länge der Meldung |
| 8 | Rest | Meldung, UTF-8, nur zur Diagnose |
Die Fehlercodes stehen unter Fehlercodes. Werten Sie den Code aus, nicht die Meldung; ihr Wortlaut kann sich ändern.
Anfragen ohne Antwort
Überschreitet die anfragende Seite die Rate von 60 000 Anfragen in 60 Sekunden, verwirft der Dienst weitere Anfragen ohne Antwort, damit eine Flut keine zweite Flut auslöst. Den geteilten Speicher der Anfrage gibt er trotzdem frei. Planen Sie auf der anfragenden Seite eine Zeitüberschreitung je Anfrage ein.