Unsachgemäße Isolation gemeinsam genutzter Ressourcen im Network On Chip (NoC)

Beschreibung

Die unsachgemäße Isolation gemeinsam genutzter Ressourcen im Network On Chip (NoC) tritt auf, wenn das NoC seine On-Chip-Fabric- und internen Ressourcen wie Puffer, Kreuzschienen, Switches, Ports und Kanäle nicht oder nicht korrekt isoliert, sodass sie zwischen vertrauenswürdigen und nicht vertrauenswürdigen Agenten geteilt werden und Timing-Kanäle entstehen. Interne NoC-Ressourcen erfahren häufig Ressourcenkonflikte, wenn sie domainübergreifend geteilt werden. Diese Interferenz ermöglicht es Angreifern, Daten vertrauenswürdiger Agenten durch Timing-Analyse zu erschließen und gleichzeitig den Netzwerkdurchsatz und die Latenz zu verschlechtern.

Risiko

Unsachgemäße NoC-Isolation hat schwerwiegende Auswirkungen. Timing-Seitenkanale ermöglicht. Vertrauenswürdige Daten durch Konflikte erschließbar. Denial of Service durch Ressourcenerschöpfung. Netzwerkdurchsatz verschlechtert. Latenz erhöht. Verdeckte Kanäle möglich. Sicherheitsgrenzen verletzt. QoS-Garantien gebrochen. Hohe Wahrscheinlichkeit wenn NoC-Ressourcen domainübergreifend ohne Isolation geteilt werden.

Lösung

Implementieren Sie während der Architektur- und Entwurfsphase prioritätsbasierte Arbitrierung innerhalb des NoC und stellen Sie dedizierte Puffer oder virtuelle Kanäle für die Weiterleitung geheimer Daten von vertrauenswürdigen Agenten bereit. Trennen Sie physische oder logische Pfade für verschiedene Sicherheitsdomänen. Verwenden Sie Zeitmultiplexing, um Interferenzen zu verhindern. Implementieren Sie Traffic Shaping, um Timing-Informationslecks zu reduzieren.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Angreifer können sensible Daten durch Timing-Kanalanalyse gemeinsam genutzter NoC-Ressourcen extrahieren.
VerfügbarkeitBereich: Verfügbarkeit

Denial of Service durch Ressourcenverbrauch und Netzwerkverschlechterung.

Beispielcode und Lösung

Verwundbarer Code

// VERWUNDBAR: NoC-Router ohne Isolation

module vulnerable_noc_router (
    input  wire        clk,
    input  wire        rst_n,

    // Eingangsports (von verschiedenen Agenten)
    input  wire [63:0] port_n_data,
    input  wire [7:0]  port_n_dest,
    input  wire        port_n_valid,
    input  wire        port_n_secure,  // Sicherheitsattribut

    input  wire [63:0] port_s_data,
    input  wire [7:0]  port_s_dest,
    input  wire        port_s_valid,
    input  wire        port_s_secure,

    input  wire [63:0] port_e_data,
    input  wire [7:0]  port_e_dest,
    input  wire        port_e_valid,
    input  wire        port_e_secure,

    input  wire [63:0] port_w_data,
    input  wire [7:0]  port_w_dest,
    input  wire        port_w_valid,
    input  wire        port_w_secure,

    // Ausgangsports
    output reg  [63:0] out_n_data,
    output reg         out_n_valid,
    output reg  [63:0] out_s_data,
    output reg         out_s_valid,
    // ... weitere Ausgänge

    // Gegendruck
    output reg         port_n_stall,
    output reg         port_s_stall,
    output reg         port_e_stall,
    output reg         port_w_stall
);

    // VERWUNDBAR: Gemeinsamer Puffer für gesamten Verkehr
    reg [63:0] shared_buffer [0:15];
    reg [3:0]  buffer_head;
    reg [3:0]  buffer_tail;
    reg [3:0]  buffer_count;

    // VERWUNDBAR: Einzelner Arbitrierer für alle Domänen
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            buffer_count <= 4'b0;
        end else begin
            // VERWUNDBAR: Gesamter Verkehr konkurriert um gemeinsamen Puffer
            // Sicherer und nicht-sicherer Verkehr gemischt
            if (port_n_valid && buffer_count < 4'd15) begin
                shared_buffer[buffer_tail] <= port_n_data;
                buffer_tail <= buffer_tail + 1;
                buffer_count <= buffer_count + 1;
            end else if (port_s_valid && buffer_count < 4'd15) begin
                shared_buffer[buffer_tail] <= port_s_data;
                // ...
            end
            // VERWUNDBAR: Keine Priorität für sicheren Verkehr
            // VERWUNDBAR: Timing sichtbar durch Stall-Signale
        end
    end

    // VERWUNDBAR: Gemeinsame Kreuzschiene
    // Konkurrenz zwischen sicher und nicht-sicher erzeugt Timing-Kanal
    always @(*) begin
        // Round-Robin-Arbitrierung berücksichtigt keine Sicherheit
        // Angreifer kann beobachten wann sicherer Verkehr vorhanden ist
        // durch Messung der eigenen Verkehrsverzögerungen
    end

    // Angriff:
    // 1. Angreifer sendet Verkehr um Basis-Latenz zu messen
    // 2. Sicherer Agent sendet vertrauliche Daten
    // 3. Angreifer beobachtet erhöhte Latenz (Konkurrenz)
    // 4. Timing-Kanal offenbart sichere Verkehrsmuster

endmodule

// VERWUNDBAR: Virtual-Channel-Zuweisung ohne Isolation
module vulnerable_vc_allocator (
    input  wire        clk,
    input  wire        rst_n,
    input  wire [3:0]  vc_request,
    input  wire [3:0]  vc_secure,    // Welche Anfragen sicher sind
    output reg  [3:0]  vc_grant,
    output reg  [1:0]  vc_allocated
);

    // VERWUNDBAR: Alle VCs domainübergreifend geteilt
    reg [3:0] vc_busy;

    always @(posedge clk) begin
        // VERWUNDBAR: Keine Isolation der VCs nach Sicherheitsstufe
        // Sicherer Verkehr kann durch nicht-sicheren blockiert werden
        if (vc_request[0] && !vc_busy[0]) begin
            vc_grant <= 4'b0001;
            vc_allocated <= 2'b00;
            vc_busy[0] <= 1'b1;
        end else if (vc_request[1] && !vc_busy[1]) begin
            vc_grant <= 4'b0010;
            // ...
        end

        // VERWUNDBAR: Nicht-sicher kann alle VCs erschöpfen
        // Erzeugt DoS gegen sicheren Verkehr
    end

endmodule

Sichere Lösung

// SICHER: NoC-Router mit Sicherheitsisolation

module secure_noc_router (
    input  wire        clk,
    input  wire        rst_n,

    // Eingangsports mit Sicherheitsattributen
    input  wire [63:0] port_n_data,
    input  wire [7:0]  port_n_dest,
    input  wire        port_n_valid,
    input  wire        port_n_secure,

    input  wire [63:0] port_s_data,
    input  wire [7:0]  port_s_dest,
    input  wire        port_s_valid,
    input  wire        port_s_secure,

    input  wire [63:0] port_e_data,
    input  wire [7:0]  port_e_dest,
    input  wire        port_e_valid,
    input  wire        port_e_secure,

    input  wire [63:0] port_w_data,
    input  wire [7:0]  port_w_dest,
    input  wire        port_w_valid,
    input  wire        port_w_secure,

    // Ausgangsports
    output reg  [63:0] out_n_data,
    output reg         out_n_valid,
    output reg  [63:0] out_s_data,
    output reg         out_s_valid,

    // Gegendruck (isoliert)
    output reg         port_n_stall,
    output reg         port_s_stall,
    output reg         port_e_stall,
    output reg         port_w_stall
);

    // SICHER: Separate Puffer für sicheren und nicht-sicheren Verkehr
    reg [63:0] secure_buffer [0:7];
    reg [2:0]  secure_head, secure_tail;
    reg [3:0]  secure_count;

    reg [63:0] nonsecure_buffer [0:7];
    reg [2:0]  nonsecure_head, nonsecure_tail;
    reg [3:0]  nonsecure_count;

    // SICHER: Separate Arbitrierer für jede Sicherheitsdomäne
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            secure_count <= 4'b0;
            nonsecure_count <= 4'b0;
        end else begin
            // SICHER: An entsprechenden Puffer basierend auf Sicherheit weiterleiten
            if (port_n_valid && port_n_secure && secure_count < 4'd7) begin
                secure_buffer[secure_tail] <= port_n_data;
                secure_tail <= secure_tail + 1;
                secure_count <= secure_count + 1;
            end else if (port_n_valid && !port_n_secure && nonsecure_count < 4'd7) begin
                nonsecure_buffer[nonsecure_tail] <= port_n_data;
                nonsecure_tail <= nonsecure_tail + 1;
                nonsecure_count <= nonsecure_count + 1;
            end
            // Ähnlich für andere Ports...
        end
    end

    // SICHER: Prioritätsbasierte Arbitrierung bevorzugt sicheren Verkehr
    reg secure_has_priority;

    always @(posedge clk) begin
        // SICHER: Sicherer Verkehr erhält bevorzugten Ausgangszugang
        if (secure_count > 0) begin
            out_n_data <= secure_buffer[secure_head];
            out_n_valid <= 1'b1;
            secure_head <= secure_head + 1;
            secure_count <= secure_count - 1;
        end else if (nonsecure_count > 0) begin
            out_n_data <= nonsecure_buffer[nonsecure_head];
            out_n_valid <= 1'b1;
            nonsecure_head <= nonsecure_head + 1;
            nonsecure_count <= nonsecure_count - 1;
        end else begin
            out_n_valid <= 1'b0;
        end
    end

    // SICHER: Isolierte Stall-Signale
    // Nicht-sicherer Gegendruck offenbart nicht den Zustand des sicheren Verkehrs
    always @(*) begin
        port_n_stall = (port_n_secure ? (secure_count >= 4'd7) :
                                        (nonsecure_count >= 4'd7));
        // ...
    end

endmodule

// SICHER: Zeitmultiplex-NoC-Router für starke Isolation
module secure_tdm_noc_router (
    input  wire        clk,
    input  wire        rst_n,

    // Zeitschlitz-Konfiguration
    input  wire [3:0]  current_slot,
    input  wire [3:0]  secure_slots,     // Bitmap der Schlitze für sicheren Verkehr

    // Ports
    input  wire [63:0] in_data,
    input  wire        in_valid,
    input  wire        in_secure,
    output reg  [63:0] out_data,
    output reg         out_valid
);

    // SICHER: Zeitmultiplexing für Isolation
    wire slot_is_secure = secure_slots[current_slot];

    always @(posedge clk) begin
        // SICHER: Nur Verkehr weiterleiten der zum aktuellen Schlitztyp passt
        if (in_valid && (in_secure == slot_is_secure)) begin
            out_data <= in_data;
            out_valid <= 1'b1;
        end else begin
            // SICHER: Füllverkehr um Timing-Analyse zu verhindern
            out_data <= 64'h0;
            out_valid <= slot_is_secure ? 1'b0 : 1'b0;
        end
    end

    // SICHER: TDM stellt keine Interferenz zwischen Domänen sicher
    // Timing ist deterministisch unabhängig von Verkehrsmustern

endmodule

// SICHER: Virtual-Channel-Zuweiser mit Sicherheitsisolation
module secure_vc_allocator (
    input  wire        clk,
    input  wire        rst_n,
    input  wire [3:0]  vc_request,
    input  wire [3:0]  vc_secure,
    output reg  [3:0]  vc_grant,
    output reg  [1:0]  vc_allocated
);

    // SICHER: Dedizierte VCs für jede Sicherheitsdomäne
    // VCs 0-1: Nur sicherer Verkehr
    // VCs 2-3: Nur nicht-sicherer Verkehr
    reg [1:0] secure_vc_busy;
    reg [1:0] nonsecure_vc_busy;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            secure_vc_busy <= 2'b0;
            nonsecure_vc_busy <= 2'b0;
            vc_grant <= 4'b0;
        end else begin
            vc_grant <= 4'b0;

            // SICHER: Aus dem entsprechenden Pool zuweisen
            for (int i = 0; i < 4; i++) begin
                if (vc_request[i]) begin
                    if (vc_secure[i]) begin
                        // SICHER: Sichere Anfragen erhalten sichere VCs
                        if (!secure_vc_busy[0]) begin
                            vc_grant[i] <= 1'b1;
                            vc_allocated <= 2'b00;
                            secure_vc_busy[0] <= 1'b1;
                        end else if (!secure_vc_busy[1]) begin
                            vc_grant[i] <= 1'b1;
                            vc_allocated <= 2'b01;
                            secure_vc_busy[1] <= 1'b1;
                        end
                        // SICHER: Nicht-sicher kann sichere VCs nicht erschöpfen
                    end else begin
                        // SICHER: Nicht-sichere Anfragen erhalten nicht-sichere VCs
                        if (!nonsecure_vc_busy[0]) begin
                            vc_grant[i] <= 1'b1;
                            vc_allocated <= 2'b10;
                            nonsecure_vc_busy[0] <= 1'b1;
                        end else if (!nonsecure_vc_busy[1]) begin
                            vc_grant[i] <= 1'b1;
                            vc_allocated <= 2'b11;
                            nonsecure_vc_busy[1] <= 1'b1;
                        end
                    end
                end
            end
        end
    end

endmodule

CVE-Beispiele

  • CVE-2021-33096: Unsachgemäße Isolation gemeinsam genutzter NoC-Ressourcen verursachte Denial of Service.
  • CVE-2020-0551: Load Value Injection durch NoC-Timing-Kanäle.

Verwandte CWEs

  • CWE-653: Improper Isolation or Compartmentalization (Eltern)
  • CWE-668: Exposure of Resource to Wrong Sphere (Eltern)
  • CWE-1189: Improper Isolation of Shared Resources on System-on-a-Chip (SoC) (Peer)

Referenzen

  1. MITRE Corporation. "CWE-1331: Improper Isolation of Shared Resources in Network On Chip (NoC)." https://cwe.mitre.org/data/definitions/1331.html
  2. ACM. "NoC Security Survey: Attacks, Countermeasures, and Evaluation"
  3. IEEE. "Secure Network-on-Chip Architectures"