Unsachgemäße Übersetzung von Sicherheitsattributen durch Fabric Bridge

Beschreibung

Die unsachgemäße Übersetzung von Sicherheitsattributen durch eine Fabric Bridge tritt auf, wenn eine Bridge, die zwischen verschiedenen Fabric-Protokollen konvertiert, Sicherheitsattribute nicht korrekt übersetzt und dabei möglicherweise nicht vertrauenswürdige Agenten vertrauenswürdigen zuordnet oder umgekehrt. Fabric Bridges integrieren IP-Blöcke, die verschiedene Protokolle wie AHB, AXI und OCP verwenden. Diese Protokolle nutzen dedizierte Signale zur Übermittlung von Sicherheitsattributen -- wie HPROT (AHB), AxPROT (AXI) und MReqInfo/SRespInfo (OCP) -- die Initiator-Identität, Berechtigungsstufe und Transaktionstyp angeben. Verwundbare Bridges behandeln diese Signalübersetzungen fehlerhaft, was Zugriffskontrollumgehung, Privilegienerweiterung oder Denial-of-Service-Angriffe ermöglicht.

Risiko

Unsachgemäße Sicherheitsattribut-Übersetzung hat schwerwiegende Auswirkungen. Nicht vertrauenswürdige Agenten werden vertrauenswürdigen zugeordnet. Vertrauenswürdige Agenten werden nicht vertrauenswürdigen zugeordnet (DoS). Zugriffskontrollumgehung ermöglicht. Privilegienerweiterung möglich. Unbefugter Speicherzugriff. Code-Ausführung durch nicht vertrauenswürdige Agenten. Sicherheitsgrenzen verletzt. Hohe Wahrscheinlichkeit bei unvollständigen Bridge-Zuordnungen.

Lösung

Die Übersetzung muss Signale so zuordnen, dass nicht vertrauenswürdige Agenten während der Architektur-, Entwurfs- und Implementierungsphasen nicht vertrauenswürdigen Agenten zugeordnet werden können und umgekehrt. Erstellen Sie vollständige Zuordnungstabellen für alle möglichen Eingabewerte. Verifizieren Sie, dass keine nicht vertrauenswürdige Kombination eine vertrauenswürdige Ausgabe erzeugen kann. Verwenden Sie formale Verifikation, um die Korrektheit der Zuordnung zu beweisen. Testen Sie alle Protokollkombinationen während der Pre-Silicon- und Post-Silicon-Validierung.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Unbefugter Lesezugriff durch fälschlich erhöhte Vertrauensstufe.
IntegritätBereich: Integrität

Speicheränderung durch Agenten, die höherem Vertrauen zugeordnet werden.
ZugriffskontrolleBereich: Zugriffskontrolle

Schutzumgehung durch Attribut-Fehlzuordnung.

Beispielcode und Lösung

Verwundbarer Code

// VERWUNDBAR: OCP-zu-AHB-Bridge mit unvollständiger Sicherheitszuordnung

module vulnerable_ocp2ahb_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // OCP-Schnittstelle
    input  wire [4:0]  ocp_mreqinfo,    // OCP-Sicherheitsinformation
    input  wire [31:0] ocp_maddr,
    input  wire [31:0] ocp_mdata,
    input  wire        ocp_mcmd_valid,

    // AHB-Schnittstelle
    output reg  [1:0]  ahb_hprot,       // AHB-Schutzsignale
    output reg  [31:0] ahb_haddr,
    output reg  [31:0] ahb_hwdata,
    output reg         ahb_htrans_valid
);

    // OCP-MReqInfo-Kodierung (Beispiel):
    // [4:3] = Sicherheitsstufe (00=sicher, 01=nicht-sicher, 10/11=reserviert)
    // [2:0] = Master-ID

    // AHB-HPROT-Kodierung:
    // [1] = Privilegiert (1=privilegiert, 0=Benutzer)
    // [0] = Daten/Opcode (1=Daten, 0=Opcode)

    // VERWUNDBAR: Unvollständige Übersetzungslogik
    always @(*) begin
        case (ocp_mreqinfo[4:2])  // Prüft nur Bits 4:2!
            3'b000: ahb_hprot = 2'b11;  // Sicher -> Privilegierte Daten
            3'b001: ahb_hprot = 2'b00;  // Nicht-sicher -> Benutzer-Opcode

            // VERWUNDBAR: Fehlende Fälle für andere Werte
            // 3'b010, 3'b011, 3'b100, 3'b101, 3'b110, 3'b111 nicht behandelt!

            default: ahb_hprot = 2'b00;  // VERWUNDBAR: Standard ist Benutzer
            // Dies erlaubt nicht vertrauenswürdigen OCP-Werten Benutzerzugriff
            // wenn sie eigentlich komplett abgelehnt werden sollten
        endcase
    end

    // VERWUNDBAR: Bit [1:0] von mreqinfo ignoriert
    // Angreifer kann mreqinfo-Werte wie 5'b00011 (Bits 4:2 = 000) verwenden
    // um privilegierten Zugriff zu erhalten (ahb_hprot = 2'b11)
    // obwohl er nicht tatsächlich sicher ist

    always @(posedge clk) begin
        if (ocp_mcmd_valid) begin
            ahb_haddr <= ocp_maddr;
            ahb_hwdata <= ocp_mdata;
            ahb_htrans_valid <= 1'b1;
        end
    end

endmodule

// VERWUNDBAR: AXI-zu-APB-Bridge mit Verlust von Sicherheitsattributen
module vulnerable_axi2apb_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // AXI-Schnittstelle
    input  wire [2:0]  axi_awprot,      // AXI-Schreibschutz
    input  wire [2:0]  axi_arprot,      // AXI-Leseschutz
    input  wire [31:0] axi_awaddr,
    input  wire [31:0] axi_wdata,
    input  wire        axi_awvalid,
    input  wire        axi_arvalid,

    // APB-Schnittstelle (einfacher, weniger Sicherheitssignale)
    output reg  [31:0] apb_paddr,
    output reg  [31:0] apb_pwdata,
    output reg  [2:0]  apb_pprot,       // APB-Schutz
    output reg         apb_psel
);

    // AXI-AxPROT-Kodierung:
    // [0] = Privilegiert (1=privilegiert)
    // [1] = Nicht-sicher (1=nicht-sicher)
    // [2] = Befehl (1=Befehlszugriff)

    // VERWUNDBAR: Sicherheitsbits nicht vollständig übersetzt
    always @(posedge clk) begin
        if (axi_awvalid) begin
            apb_paddr <= axi_awaddr;
            apb_pwdata <= axi_wdata;

            // VERWUNDBAR: Nur Berechtigungs-Bit kopiert
            apb_pprot[0] <= axi_awprot[0];  // Privilegiert

            // VERWUNDBAR: Sicher/nicht-sicher nicht übersetzt!
            // APB pprot[1] sollte von AXI awprot[1] gesetzt werden
            apb_pprot[1] <= 1'b0;  // Erscheint immer als sicher!

            apb_pprot[2] <= axi_awprot[2];  // Daten/Befehl

            apb_psel <= 1'b1;

            // Angriff: Nicht-sichere AXI-Transaktion (awprot[1]=1)
            // wird sichere APB-Transaktion (pprot[1]=0)
            // Umgeht Sicherheitsprüfungen auf APB-Seite
        end
    end

endmodule

Sichere Lösung

// SICHER: OCP-zu-AHB-Bridge mit vollständiger Sicherheitszuordnung

module secure_ocp2ahb_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // OCP-Schnittstelle
    input  wire [4:0]  ocp_mreqinfo,
    input  wire [31:0] ocp_maddr,
    input  wire [31:0] ocp_mdata,
    input  wire        ocp_mcmd_valid,

    // AHB-Schnittstelle
    output reg  [1:0]  ahb_hprot,
    output reg  [31:0] ahb_haddr,
    output reg  [31:0] ahb_hwdata,
    output reg         ahb_htrans_valid,
    output reg         translation_error  // SICHER: Fehlersignal
);

    // OCP-MReqInfo-Kodierung:
    // [4:3] = Sicherheitsstufe (00=sicher-priv, 01=sicher-benutzer, 10=nichtsicher-priv, 11=nichtsicher-benutzer)
    // [2:0] = Master-ID (000-111)

    // AHB-HPROT-Kodierung:
    // [1] = Privilegiert (1=privilegiert, 0=Benutzer)
    // [0] = Daten/Opcode (1=Daten, 0=Opcode)
    // Zusätzlich verfolgen wir sicher/nicht-sicher separat

    reg ahb_nonsecure;  // Zusätzliches Signal für TrustZone-fähiges AHB

    // SICHER: Vollständige Übersetzung, die alle Eingabewerte abdeckt
    always @(*) begin
        translation_error = 1'b0;

        // SICHER: Alle relevanten Bits von mreqinfo prüfen
        case (ocp_mreqinfo[4:3])  // Sicherheitsstufe
            2'b00: begin  // Sicher privilegiert
                ahb_hprot = 2'b11;      // Privilegiert, Daten
                ahb_nonsecure = 1'b0;   // Sicher
            end
            2'b01: begin  // Sicher Benutzer
                ahb_hprot = 2'b01;      // Benutzer, Daten
                ahb_nonsecure = 1'b0;   // Sicher
            end
            2'b10: begin  // Nicht-sicher privilegiert
                ahb_hprot = 2'b11;      // Privilegiert, Daten
                ahb_nonsecure = 1'b1;   // Nicht-sicher
            end
            2'b11: begin  // Nicht-sicher Benutzer
                ahb_hprot = 2'b01;      // Benutzer, Daten
                ahb_nonsecure = 1'b1;   // Nicht-sicher
            end
            default: begin
                // SICHER: Ungültige Werte ablehnen
                ahb_hprot = 2'b01;      // Standard auf niedrigste Berechtigung
                ahb_nonsecure = 1'b1;   // Standard auf nicht-sicher
                translation_error = 1'b1;
            end
        endcase

        // SICHER: Master-ID auf erwarteten Bereich validieren
        if (ocp_mreqinfo[2:0] > 3'b011) begin
            // Unbekannter Master - ablehnen oder herabstufen
            translation_error = 1'b1;
        end
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            ahb_htrans_valid <= 1'b0;
        end else if (ocp_mcmd_valid) begin
            // SICHER: Nur weiterleiten wenn Übersetzung gültig ist
            if (!translation_error) begin
                ahb_haddr <= ocp_maddr;
                ahb_hwdata <= ocp_mdata;
                ahb_htrans_valid <= 1'b1;
            end else begin
                ahb_htrans_valid <= 1'b0;
            end
        end else begin
            ahb_htrans_valid <= 1'b0;
        end
    end

endmodule

// SICHER: AXI-zu-APB-Bridge mit vollständiger Sicherheitsübersetzung
module secure_axi2apb_bridge (
    input  wire        clk,
    input  wire        rst_n,

    // AXI-Schnittstelle
    input  wire [2:0]  axi_awprot,
    input  wire [2:0]  axi_arprot,
    input  wire [31:0] axi_awaddr,
    input  wire [31:0] axi_wdata,
    input  wire        axi_awvalid,
    input  wire        axi_arvalid,

    // APB-Schnittstelle
    output reg  [31:0] apb_paddr,
    output reg  [31:0] apb_pwdata,
    output reg  [2:0]  apb_pprot,
    output reg         apb_psel,
    output reg         apb_pnsec  // SICHER: Explizites Nicht-sicher-Signal
);

    // AXI-AxPROT-Kodierung:
    // [0] = Privilegiert (1=privilegiert)
    // [1] = Nicht-sicher (1=nicht-sicher)
    // [2] = Befehl (1=Befehlszugriff)

    // APB-PPROT-Kodierung (sollte übereinstimmen):
    // [0] = Privilegiert
    // [1] = Nicht-sicher
    // [2] = Befehl

    // SICHER: Vollständige Bit-für-Bit-Übersetzung
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            apb_psel <= 1'b0;
            apb_pprot <= 3'b000;
            apb_pnsec <= 1'b1;  // Standard nicht-sicher
        end else if (axi_awvalid) begin
            apb_paddr <= axi_awaddr;
            apb_pwdata <= axi_wdata;

            // SICHER: ALLE Schutz-Bits übersetzen
            apb_pprot[0] <= axi_awprot[0];  // Privilegiert
            apb_pprot[1] <= axi_awprot[1];  // SICHER: Nicht-sicher korrekt übersetzt
            apb_pprot[2] <= axi_awprot[2];  // Befehl/Daten

            // SICHER: Auch explizites Sicher/Nicht-sicher-Signal bereitstellen
            apb_pnsec <= axi_awprot[1];

            apb_psel <= 1'b1;
        end else begin
            apb_psel <= 1'b0;
        end
    end

endmodule

// SICHER: Generische Protokoll-Bridge mit Validierung
module secure_protocol_bridge #(
    parameter SRC_SECURITY_WIDTH = 5,
    parameter DST_SECURITY_WIDTH = 3
) (
    input  wire                          clk,
    input  wire                          rst_n,
    input  wire [SRC_SECURITY_WIDTH-1:0] src_security,
    input  wire                          src_valid,
    output reg  [DST_SECURITY_WIDTH-1:0] dst_security,
    output reg                           dst_valid,
    output reg                           mapping_error
);

    // SICHER: Explizite Zuordnungstabelle (ROM oder Logik)
    // Bildet jeden möglichen Quellwert auf Zielwert ab
    // Ungültige/reservierte Quellwerte werden auf Fehler abgebildet

    function [DST_SECURITY_WIDTH:0] translate_security;
        input [SRC_SECURITY_WIDTH-1:0] src;
        reg [DST_SECURITY_WIDTH-1:0] dst;
        reg error;
        begin
            error = 1'b0;
            case (src)
                // SICHER: Vollständige Zuordnung
                5'b00000: dst = 3'b000;  // Sicher privilegiert
                5'b00001: dst = 3'b001;  // Sicher Benutzer
                5'b00010: dst = 3'b010;  // Nicht-sicher privilegiert
                5'b00011: dst = 3'b011;  // Nicht-sicher Benutzer
                // ... alle gültigen Zuordnungen hinzufügen

                // SICHER: Alle anderen Werte sind ungültig
                default: begin
                    dst = 3'b011;  // Auf niedrigstes Vertrauen abbilden
                    error = 1'b1;
                end
            endcase
            translate_security = {error, dst};
        end
    endfunction

    wire [DST_SECURITY_WIDTH:0] translation_result;
    assign translation_result = translate_security(src_security);

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            dst_security <= {DST_SECURITY_WIDTH{1'b1}};  // Niedrigstes Vertrauen
            dst_valid <= 1'b0;
            mapping_error <= 1'b0;
        end else if (src_valid) begin
            dst_security <= translation_result[DST_SECURITY_WIDTH-1:0];
            mapping_error <= translation_result[DST_SECURITY_WIDTH];

            // SICHER: Nur weiterleiten wenn Zuordnung gültig ist
            dst_valid <= ~translation_result[DST_SECURITY_WIDTH];
        end else begin
            dst_valid <= 1'b0;
        end
    end

endmodule

CVE-Beispiele

  • CVE-2020-8705: Fabric Bridge in bestimmten Intel-Prozessoren übersetzte Sicherheitsattribute falsch und ermöglichte Privilegienerweiterung.
  • CVE-2019-11157: Protokoll-Bridge behandelte Sicherheitssignale fehlerhaft und ermöglichte unbefugten Zugriff.

Verwandte CWEs

  • CWE-284: Improper Access Control (Eltern)
  • CWE-1203: Peripherals, On-chip Fabric, and Interface/IO Problems (Kategorie)
  • CWE-1292: Incorrect Conversion of Security Identifiers (verwandt)
  • CWE-863: Incorrect Authorization (verwandt)

Referenzen

  1. MITRE Corporation. "CWE-1311: Improper Translation of Security Attributes by Fabric Bridge." https://cwe.mitre.org/data/definitions/1311.html
  2. ARM. "AMBA Protocol Specifications"
  3. OCP-IP. "Open Core Protocol Specification"