Fehlerhafte Konvertierung von Sicherheitskennungen
Beschreibung
Fehlerhafte Konvertierung von Sicherheitskennungen tritt auf, wenn die Zuordnung von Bus-Transaktionssignalen zu Sicherheitskennungen eines Produkts Konvertierungsfehler enthält, die es nicht vertrauenswürdigen Agenten potenziell ermöglichen, unbefugten Zugriff auf Assets zu erhalten. In System-on-Chip (SoC)-Umgebungen tragen Transaktionen zwischen integrierten Schaltungen Quell- und Zielidentitäten zusammen mit Sicherheitskennungen, die es Zielagenten ermöglichen, Zugriffskontrollen durchzusetzen. Protokollbrücken, die inkompatible Bustypen verbinden (z.B. AHB-zu-OCP, APB-zu-AXI), müssen Sicherheitskennungsinformationen zwischen Protokollen korrekt übersetzen. Wenn diese Brücken Sicherheitskennungen falsch konvertieren, können nicht vertrauenswürdige Agenten Zugriffsbeschränkungen umgehen.
Risiko
Fehlerhafte Konvertierung von Sicherheitskennungen hat schwerwiegende Auswirkungen. Nicht vertrauenswürdige Agenten umgehen Zugriffskontrollen. Speichermodifikation möglich. Unbefugte Lesezugriffe aktiviert. Denial-of-Service-Angriffe. Ausführung von unbefugtem Code. Privilegieneskalation. Identitätsübernahme. Vollständige Umgehung der Zugriffskontrollrichtlinien. Hohe Ausnutzungswahrscheinlichkeit wenn Protokollbrücken Konvertierungsfehler haben.
Lösung
Konvertierer/Brücken für Sicherheitskennungen erfordern eine Designüberprüfung auf Inkonsistenz und häufige Schwachstellen während der Architektur- und Entwurfsphase. Stellen Sie sicher, dass Protokollzuordnungen die Sicherheitssemantik beibehalten. Zugriffs- und Programmierabläufe müssen in Pre-Silicon- und Post-Silicon-Tests getestet werden. Erstellen Sie umfassende Testvektoren, die alle Sicherheitskennungswerte über Protokollgrenzen hinweg abdecken. Verwenden Sie formale Verifikation, um die Konvertierungskorrektheit zu beweisen. Dokumentieren Sie Sicherheitskennungszuordnungen explizit.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit Unbefugter Lesezugriff auf geschützten Speicher und Assets. |
| Integrität | Bereich: Integrität Speichermodifikation durch nicht vertrauenswürdige Agenten über Protokollbrücke. |
| Verfügbarkeit | Bereich: Verfügbarkeit Denial of Service durch Ressourcenverbrauch. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle Privilegieneskalation und Identitätsübernahme durch fehlerhafte Zuordnung. |
Beispielcode und Lösung
Verwundbarer Code
// VERWUNDBAR: AHB-zu-OCP-Brücke mit fehlerhafter Sicherheits-ID-Konvertierung
module vulnerable_ahb_to_ocp_bridge (
input wire clk,
input wire rst_n,
// AHB-Signale
input wire [31:0] ahb_haddr,
input wire [2:0] ahb_hburst,
input wire [3:0] ahb_hprot, // AHB-Schutzsignale
input wire ahb_hwrite,
input wire [31:0] ahb_hwdata,
input wire [1:0] ahb_htrans,
// OCP-Signale
output reg [31:0] ocp_maddr,
output reg [2:0] ocp_mburstlength,
output reg [1:0] ocp_mcmd,
output reg [31:0] ocp_mdata,
output reg [7:0] ocp_mtagid, // OCP-Sicherheitstag
output reg ocp_mreqinfo // OCP-Sicherheitsinfo
);
// AHB HPROT-Bits:
// [0] = Daten/Opcode (1=Daten, 0=Opcode)
// [1] = Privilegiert (1=privilegiert, 0=Benutzer)
// [2] = Pufferbar
// [3] = Cachebar
// OCP-Sicherheitsmodell (Beispiel):
// mtagid[7:6] = Sicherheitsstufe (00=nicht vertrauenswürdig, 01=Benutzer, 10=priv, 11=sicher)
// mtagid[5:0] = Master-ID
// VERWUNDBAR: Fehlerhafte Konvertierung der Sicherheitskennungen
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
ocp_maddr <= 32'b0;
ocp_mtagid <= 8'b0;
end else begin
ocp_maddr <= ahb_haddr;
// VERWUNDBAR: Nur Bit [1] von hprot wird geprüft
// Fehlendes Bit [3], das in einigen Implementierungen sicheren Zugriff anzeigt
if (ahb_hprot[1]) begin
ocp_mtagid[7:6] <= 2'b10; // Privilegiert
end else begin
ocp_mtagid[7:6] <= 2'b01; // Benutzer
end
// VERWUNDBAR: Master-ID nicht korrekt konvertiert
// AHB hat keine explizite Master-ID, aber OCP erfordert sie
ocp_mtagid[5:0] <= 6'b000000; // Alle Master auf ID 0 abgebildet!
end
end
// VERWUNDBAR: Sicherheitsinfo-Bit nicht korrekt gesetzt
always @(*) begin
// Sollte sicher/nicht-sicher basierend auf Bus-Master anzeigen
ocp_mreqinfo = 1'b0; // Zeigt immer nicht-sicher an!
end
endmodule
// VERWUNDBAR: APB-zu-AXI-Brücke mit Sicherheitszuordnungsproblemen
module vulnerable_apb_to_axi_bridge (
input wire clk,
input wire rst_n,
// APB-Signale
input wire [31:0] paddr,
input wire pwrite,
input wire [31:0] pwdata,
input wire psel,
input wire penable,
input wire [2:0] pprot, // APB-Schutz
// AXI-Signale
output reg [31:0] axi_awaddr,
output reg [2:0] axi_awprot, // AXI-Schutz
output reg [3:0] axi_awcache,
output reg [31:0] axi_wdata,
output reg axi_awvalid
);
// APB PPROT:
// [0] = Normal/Privilegiert
// [1] = Sicher/Nicht-sicher
// [2] = Daten/Instruktion
// AXI AWPROT:
// [0] = Privilegiert
// [1] = Nicht-sicher
// [2] = Instruktion
// VERWUNDBAR: Fehlerhafte Bit-Zuordnung zwischen Protokollen
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
axi_awprot <= 3'b0;
end else begin
// VERWUNDBAR: Bits sind an verschiedenen Positionen!
// APB pprot[0] ist Privileg, aber direktes Kopieren
axi_awprot <= pprot; // FALSCH! Bit-Positionen stimmen nicht überein!
// Korrekte Zuordnung sollte sein:
// axi_awprot[0] = pprot[0] (Privileg stimmt überein)
// axi_awprot[1] = ~pprot[1] (APB sicher=0, AXI nicht-sicher=0, INVERTIERT!)
// axi_awprot[2] = pprot[2] (Daten/Instruktion stimmt überein)
end
end
endmodule
// VERWUNDBAR: Software-Brücke mit Sicherheits-ID-Konvertierungsproblemen
#include <stdint.h>
#include <stdbool.h>
// Protokoll-A-Sicherheitsstufen
#define PROTO_A_UNTRUSTED 0x00
#define PROTO_A_USER 0x01
#define PROTO_A_SUPERVISOR 0x02
#define PROTO_A_SECURE 0x03
// Protokoll-B-Sicherheitsstufen (ändere Kodierung)
#define PROTO_B_PUBLIC 0x00
#define PROTO_B_NORMAL 0x04
#define PROTO_B_PRIVILEGED 0x08
#define PROTO_B_HYPERVISOR 0x0C
// VERWUNDBAR: Fehlerhafte Zuordnungstabelle
uint8_t vulnerable_convert_security_id(uint8_t proto_a_id) {
// VERWUNDBAR: Direktes Kopieren der Werte - Kodierungen stimmen nicht überein!
return proto_a_id; // Werte bedeuten verschiedene Dinge!
// PROTO_A_USER (0x01) wird zu PROTO_B_PUBLIC (0x00 + etwas)
// Sicherheitssemantik geht verloren!
}
// VERWUNDBAR: Brückenanfragestruktur
typedef struct {
uint32_t address;
uint32_t data;
uint8_t security_id;
bool is_write;
} bridge_request_t;
void vulnerable_forward_request(bridge_request_t* req) {
// VERWUNDBAR: Sicherheits-ID nicht korrekt konvertiert
uint8_t proto_b_security = vulnerable_convert_security_id(req->security_id);
// An Protokoll-B-Endpunkt weiterleiten
send_proto_b_request(req->address, req->data, proto_b_security, req->is_write);
}
Sichere Lösung
// SICHER: AHB-zu-OCP-Brücke mit korrekter Sicherheits-ID-Konvertierung
module secure_ahb_to_ocp_bridge (
input wire clk,
input wire rst_n,
// AHB-Signale
input wire [31:0] ahb_haddr,
input wire [2:0] ahb_hburst,
input wire [3:0] ahb_hprot,
input wire ahb_hwrite,
input wire [31:0] ahb_hwdata,
input wire [1:0] ahb_htrans,
input wire [3:0] ahb_hmaster, // AHB-Master-ID (implementierungsspezifisch)
input wire ahb_hnonsec, // AHB-Nicht-Sicher-Indikator
// OCP-Signale
output reg [31:0] ocp_maddr,
output reg [2:0] ocp_mburstlength,
output reg [1:0] ocp_mcmd,
output reg [31:0] ocp_mdata,
output reg [7:0] ocp_mtagid,
output reg ocp_mreqinfo
);
// SICHER: Vollständige Sicherheitszuordnung mit allen relevanten Signalen
reg [1:0] security_level;
always @(*) begin
// SICHER: Umfassende Sicherheitsstufenbestimmung
if (!ahb_hnonsec) begin
// Sicherer Zugriff
if (ahb_hprot[1]) begin
security_level = 2'b11; // Sicher privilegiert
end else begin
security_level = 2'b10; // Sicher Benutzer
end
end else begin
// Nicht-sicherer Zugriff
if (ahb_hprot[1]) begin
security_level = 2'b01; // Nicht-sicher privilegiert
end else begin
security_level = 2'b00; // Nicht-sicher Benutzer (nicht vertrauenswürdig)
end
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
ocp_maddr <= 32'b0;
ocp_mtagid <= 8'b0;
ocp_mreqinfo <= 1'b0;
end else begin
ocp_maddr <= ahb_haddr;
// SICHER: Ordnungsgemäße Sicherheitsstufenkonvertierung
ocp_mtagid[7:6] <= security_level;
// SICHER: Master-ID korrekt zugeordnet
ocp_mtagid[5:2] <= ahb_hmaster;
ocp_mtagid[1:0] <= 2'b00; // Reserviert
// SICHER: Sicherheitsinfo zeigt sicher/nicht-sicher korrekt an
ocp_mreqinfo <= ahb_hnonsec;
end
end
// SICHER: Assertions zur Verifizierung der Konvertierung
// synthesis translate_off
always @(posedge clk) begin
if (!rst_n) begin
// Reset
end else begin
// Verifizieren dass sicherer Zugriff korrekt abgebildet wird
if (!ahb_hnonsec && ahb_hprot[1]) begin
assert(ocp_mtagid[7:6] == 2'b11)
else $error("Sichere privilegierte Zuordnung fehlgeschlagen");
end
end
end
// synthesis translate_on
endmodule
// SICHER: APB-zu-AXI-Brücke mit korrekter Schutzbit-Zuordnung
module secure_apb_to_axi_bridge (
input wire clk,
input wire rst_n,
// APB-Signale
input wire [31:0] paddr,
input wire pwrite,
input wire [31:0] pwdata,
input wire psel,
input wire penable,
input wire [2:0] pprot,
// AXI-Signale
output reg [31:0] axi_awaddr,
output reg [2:0] axi_awprot,
output reg [3:0] axi_awcache,
output reg [31:0] axi_wdata,
output reg axi_awvalid
);
// APB PPROT:
// [0] = Normal(0)/Privilegiert(1)
// [1] = Sicher(0)/Nicht-sicher(1)
// [2] = Daten(0)/Instruktion(1)
// AXI AWPROT:
// [0] = Unprivilegiert(0)/Privilegiert(1)
// [1] = Sicher(0)/Nicht-sicher(1)
// [2] = Daten(0)/Instruktion(1)
// SICHER: Explizite Bit-für-Bit-Zuordnung mit Dokumentation
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
axi_awprot <= 3'b000; // Sicherer Standard: unprivilegiert, sicher, Daten
end else begin
// SICHER: Korrekte Zuordnung - Bits stimmen in diesem Fall zufällig überein
// aber wir ordnen jedes einzeln zu für Klarheit und Wartbarkeit
// Privileg-Bit: beide Protokolle verwenden gleiche Kodierung
axi_awprot[0] <= pprot[0];
// Sicherheits-Bit: beide Protokolle verwenden gleiche Kodierung (1=nicht-sicher)
axi_awprot[1] <= pprot[1];
// Daten/Instruktion-Bit: beide Protokolle verwenden gleiche Kodierung
axi_awprot[2] <= pprot[2];
end
end
// SICHER: Validierungslogik
// synthesis translate_off
always @(posedge clk) begin
// Verifizieren dass privilegierter Zugriff erhalten bleibt
if (pprot[0]) begin
assert(axi_awprot[0]) else $error("Privileg nicht erhalten");
end
// Verifizieren dass sicher/nicht-sicher erhalten bleibt
assert(axi_awprot[1] == pprot[1]) else $error("Sicherheit nicht erhalten");
end
// synthesis translate_on
endmodule
// SICHER: Software-Brücke mit korrekter Sicherheits-ID-Konvertierung
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
// Protokoll-A-Sicherheitsstufen
typedef enum {
PROTO_A_UNTRUSTED = 0x00,
PROTO_A_USER = 0x01,
PROTO_A_SUPERVISOR = 0x02,
PROTO_A_SECURE = 0x03
} proto_a_security_t;
// Protokoll-B-Sicherheitsstufen (ändere Kodierung)
typedef enum {
PROTO_B_PUBLIC = 0x00,
PROTO_B_NORMAL = 0x04,
PROTO_B_PRIVILEGED = 0x08,
PROTO_B_HYPERVISOR = 0x0C
} proto_b_security_t;
// SICHER: Explizite Konvertierungstabelle
static const proto_b_security_t security_conversion_table[] = {
[PROTO_A_UNTRUSTED] = PROTO_B_PUBLIC, // Niedrigste auf niedrigste abgebildet
[PROTO_A_USER] = PROTO_B_NORMAL, // Benutzer auf normal abgebildet
[PROTO_A_SUPERVISOR] = PROTO_B_PRIVILEGED, // Supervisor auf privilegiert abgebildet
[PROTO_A_SECURE] = PROTO_B_HYPERVISOR // Höchste auf höchste abgebildet
};
// SICHER: Validierte Konvertierungsfunktion
proto_b_security_t secure_convert_security_id(proto_a_security_t proto_a_id) {
// SICHER: Eingabe validieren
if (proto_a_id > PROTO_A_SECURE) {
// Ungültige Eingabe - restriktivste Stufe zurückgeben
log_security_error("Ungültige Protokoll-A-Sicherheits-ID: %d", proto_a_id);
return PROTO_B_PUBLIC; // Sicherer Standardwert
}
// SICHER: Explizite Zuordnungstabelle verwenden
return security_conversion_table[proto_a_id];
}
// SICHER: Brücke mit validierter Konvertierung
typedef struct {
uint32_t address;
uint32_t data;
proto_a_security_t security_id;
bool is_write;
} bridge_request_t;
bool secure_forward_request(const bridge_request_t* req) {
if (req == NULL) {
return false;
}
// SICHER: Sicherheits-ID mit Validierung konvertieren
proto_b_security_t proto_b_security = secure_convert_security_id(req->security_id);
// SICHER: Konvertierung für Audit-Trail protokollieren
audit_log("Sicherheitskonvertierung: ProtoA=%d -> ProtoB=%d",
req->security_id, proto_b_security);
// An Protokoll-B-Endpunkt weiterleiten
return send_proto_b_request(req->address, req->data,
proto_b_security, req->is_write);
}
// SICHER: Umgekehrte Konvertierung für Antworten
proto_a_security_t secure_convert_security_id_reverse(proto_b_security_t proto_b_id) {
switch (proto_b_id) {
case PROTO_B_PUBLIC: return PROTO_A_UNTRUSTED;
case PROTO_B_NORMAL: return PROTO_A_USER;
case PROTO_B_PRIVILEGED: return PROTO_A_SUPERVISOR;
case PROTO_B_HYPERVISOR: return PROTO_A_SECURE;
default:
log_security_error("Ungültige Protokoll-B-Sicherheits-ID: %d", proto_b_id);
return PROTO_A_UNTRUSTED; // Sicherer Standardwert
}
}
// SICHER: Bidirektionale Brückenverifizierung
void verify_security_mapping(void) {
// Round-Trip-Konvertierung erhält Sicherheitsstufe
for (int i = PROTO_A_UNTRUSTED; i <= PROTO_A_SECURE; i++) {
proto_b_security_t b = secure_convert_security_id(i);
proto_a_security_t a_back = secure_convert_security_id_reverse(b);
assert(a_back == i && "Sicherheitszuordnung ist nicht bijektiv!");
}
}
CVE-Beispiele
- CVE-2020-24512: Protokollbrücke in bestimmten Intel-Prozessoren ordnete Sicherheitsattribute bei Bus-Transaktionen falsch zu.
- CVE-2019-11091: Fehler bei der Konvertierung von Sicherheitskennungen beim Microarchitectural Data Sampling.
Verwandte CWEs
- CWE-284: Unsachgemäße Zugriffskontrolle (übergeordnet)
- CWE-1294: Unsicherer Sicherheitskennungsmechanismus (übergeordnet)
- CWE-1290: Fehlerhafte Dekodierung von Sicherheitskennungen (verwandt)
- CWE-863: Fehlerhafte Autorisierung (verwandt)
Referenzen
- MITRE Corporation. "CWE-1292: Incorrect Conversion of Security Identifiers." https://cwe.mitre.org/data/definitions/1292.html
- ARM. "AMBA Protocol Specifications"
- OCP-IP. "Open Core Protocol Specification"