Fehlerhafte Verkettung oder Granularität von Debug-Komponenten
Beschreibung
Fehlerhafte Verkettung oder Granularität von Debug-Komponenten tritt auf, wenn die Debug-Komponenten eines Produkts fehlerhafte Verkettungs- oder Granularitätskonfigurationen enthalten. Die Debug-Infrastruktur in Chips umfasst typischerweise Test Access Ports (TAPs), Scan-Zellen zur Beobachtung interner Komponenten und hierarchische Tracing-Hubs. Logikfehler während des Designs oder der Synthese können die Verbindung dieser Debug-Komponenten falsch konfigurieren und potenziell unbeabsichtigte Zugriffsberechtigungen schaffen, die Sicherheitskontrollen umgehen. Zum Beispiel gewährt die Implementierung einer Daisy-Chain-TAP-Struktur, wenn eine hierarchische Autorisierung erforderlich wäre, unbefugten Zugriff auf interne TAPs, die separate Anmeldeinformationen erfordern sollten.
Risiko
Fehlerhafte Debug-Komponentenverkettung hat schwerwiegende Auswirkungen. Privilegieneskalation durch Debug-Schnittstellen. Umgehung von Schutzmechanismen. Unbefugte Codeausführung. Speichermodifikation über Debug. Kompromittierte Vertraulichkeit. Authentifizierungsumgehung. Unbefugter Zugriff auf interne Komponenten. Gesamte Debug-Hierarchie durch einzelnen Zugangspunkt exponiert. Mittlere Ausnutzungswahrscheinlichkeit.
Lösung
Stellen Sie sicher, dass Debug-Komponenten ordnungsgemäß verkettet sind und ihre Granularität auf verschiedenen Authentifizierungsebenen beibehalten wird. Überprüfen Sie die Debug-Architektur während der Entwurfsphase. Implementieren Sie hierarchische TAP-Strukturen mit separater Authentifizierung für sensible Komponenten. Testen Sie den Debug-Zugriff auf verschiedenen Autorisierungsebenen in Pre-Silicon- und Post-Silicon-Tests. Verwenden Sie formale Verifikation der Debug-Konnektivität. Dokumentieren Sie beabsichtigte Debug-Zugriffsrichtlinien und verifizieren Sie, dass die Implementierung übereinstimmt.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit Unbefugter Zugriff auf interne Register und Speicher. |
| Integrität | Bereich: Integrität Speichermodifikation durch unsachgemäß exponiertes Debug. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle, Authentifizierung Debug-Authentifizierung durch fehlerhafte Verkettung umgangen. |
| Verfügbarkeit | Bereich: Verfügbarkeit Systemstörung durch unbefugte Debug-Befehle. |
Beispielcode und Lösung
Verwundbarer Code
// VERWUNDBAR: Fehlerhafte TAP-Verkettung - Daisy-Chain wo Hierarchie nötig
module vulnerable_tap_controller (
input wire tck,
input wire tms,
input wire tdi,
input wire trst_n,
output wire tdo,
output wire cpu_debug_enable,
output wire secure_debug_enable,
output wire key_debug_enable // VERWUNDBAR: Sensibler Schlüsselzugriff
);
// VERWUNDBAR: Alle TAPs in einzelner Daisy-Chain
// Keine separate Authentifizierung für sensible TAPs
wire cpu_tap_tdo;
wire secure_tap_tdo;
wire key_tap_tdo;
// TAP-Zustandsmaschine
reg [3:0] state;
reg [7:0] instruction;
// VERWUNDBAR: Daisy-Chain aller TAPs
// Sobald ein TAP zugegriffen wird, sind alle zugänglich
cpu_tap u_cpu_tap (
.tck(tck), .tms(tms),
.tdi(tdi), // Eingabe von oben
.trst_n(trst_n),
.tdo(cpu_tap_tdo), // Ausgabe zum nächsten
.debug_enable(cpu_debug_enable)
);
// VERWUNDBAR: Sicherer TAP verkettet ohne separate Auth
secure_tap u_secure_tap (
.tck(tck), .tms(tms),
.tdi(cpu_tap_tdo), // VERWUNDBAR: Vom CPU-TAP verkettet
.trst_n(trst_n),
.tdo(secure_tap_tdo),
.debug_enable(secure_debug_enable)
);
// VERWUNDBAR: Schlüssel-TAP auch in derselben Kette
key_tap u_key_tap (
.tck(tck), .tms(tms),
.tdi(secure_tap_tdo), // VERWUNDBAR: Ohne Auth verkettet
.trst_n(trst_n),
.tdo(key_tap_tdo),
.debug_enable(key_debug_enable)
);
assign tdo = key_tap_tdo; // VERWUNDBAR: Volle Kette exponiert
// Angriff: Zugriff TDI -> durch CPU-TAP schieben -> sicheren TAP erreichen -> Schlüssel-TAP erreichen
// Keine Authentifizierung für sensible Komponenten erforderlich
endmodule
// VERWUNDBAR: Fehlerhafte Granularität - einzelne Entsperrung für alles
module vulnerable_debug_unlock (
input wire clk,
input wire rst_n,
input wire [63:0] unlock_key,
input wire unlock_request,
output reg all_debug_enabled // VERWUNDBAR: Einzelner Aktivierungsschalter für alles
);
// VERWUNDBAR: Ein Schlüssel entsperrt alles
localparam MASTER_KEY = 64'hDEAD_BEEF_CAFE_BABE;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
all_debug_enabled <= 1'b0;
end else if (unlock_request) begin
// VERWUNDBAR: Einzelne Prüfung aktiviert alles Debug
if (unlock_key == MASTER_KEY) begin
all_debug_enabled <= 1'b1; // Aktiviert CPU-, Sicher- und Schlüssel-Debug!
end
end
end
endmodule
// VERWUNDBAR: Fehlende Granularität in Scan-Kette
module vulnerable_scan_controller (
input wire scan_enable,
input wire scan_in,
output wire scan_out,
// Interne Register einschließlich sensibler
output wire [127:0] aes_key_shadow, // VERWUNDBAR: Schlüssel über Scan zugänglich
output wire [255:0] private_key_shadow // VERWUNDBAR: Privater Schlüssel zugänglich
);
// VERWUNDBAR: Alle Register in einzelner Scan-Kette
// Keine Trennung zwischen sensiblen und nicht-sensiblen Daten
reg [127:0] aes_key_reg;
reg [255:0] private_key_reg;
reg [31:0] status_reg;
reg [31:0] config_reg;
// VERWUNDBAR: Einzelne Scan-Kette enthält alles
assign aes_key_shadow = aes_key_reg;
assign private_key_shadow = private_key_reg;
// Volle Scan-Kette: scan_in -> config -> status -> aes_key -> private_key -> scan_out
// Angreifer kann alle Werte einschließlich Schlüssel herausschieben
endmodule
Sichere Lösung
// SICHER: Hierarchische TAP-Struktur mit ordnungsgemäßer Authentifizierung
module secure_tap_controller (
input wire tck, tms, tdi, trst_n,
output wire tdo,
input wire basic_auth_valid,
input wire secure_auth_valid,
input wire key_auth_valid,
output wire cpu_debug_enable,
output wire secure_debug_enable,
output wire key_debug_enable
);
// SICHER: Hierarchische TAP-Struktur mit separater Authentifizierung
// SICHER: TAP-Router mit Authentifizierungsgating
tap_router u_router (
.tck(tck), .tms(tms), .tdi(tdi), .trst_n(trst_n), .tdo(tdo),
.basic_auth(basic_auth_valid),
.secure_auth(secure_auth_valid),
.key_auth(key_auth_valid),
// TAP-Auswahl-Ausgaben und -Eingaben...
);
// SICHER: Basis-TAP - Produktionstest
basic_tap u_basic_tap (
.tck(tck), .tms(tms), .tdi(tdi), .trst_n(trst_n),
.selected(basic_tap_selected),
.tdo(basic_tap_tdo)
);
// SICHER: CPU-TAP - erfordert Basis-Authentifizierung
cpu_tap u_cpu_tap (
.tck(tck), .tms(tms), .tdi(tdi), .trst_n(trst_n),
.selected(cpu_tap_selected & basic_auth_valid), // SICHER: Gegated
.debug_enable(cpu_debug_enable)
);
// SICHER: Sicherer TAP - erfordert erweiterte Authentifizierung
secure_tap u_secure_tap (
.tck(tck), .tms(tms), .tdi(tdi), .trst_n(trst_n),
.selected(secure_tap_selected & secure_auth_valid), // SICHER: Gegated
.debug_enable(secure_debug_enable)
);
// SICHER: Schlüssel-TAP - erfordert höchste Authentifizierung
key_tap u_key_tap (
.tck(tck), .tms(tms), .tdi(tdi), .trst_n(trst_n),
.selected(key_tap_selected & key_auth_valid), // SICHER: Gegated
.debug_enable(key_debug_enable)
);
endmodule
// SICHER: Granulare Debug-Entsperrung mit separaten Stufen
module secure_debug_unlock (
input wire clk, rst_n,
input wire [63:0] basic_unlock_key,
input wire basic_unlock_request,
input wire [127:0] secure_unlock_key,
input wire secure_unlock_request,
input wire [255:0] key_unlock_key,
input wire key_unlock_request,
output reg basic_debug_enabled,
output reg secure_debug_enabled,
output reg key_debug_enabled
);
// SICHER: Separate Schlüssel für jede Stufe (aus OTP)
// SICHER: Ratenbegrenzung für Entsperrversuche
reg [3:0] basic_fail_count, secure_fail_count, key_fail_count;
localparam MAX_ATTEMPTS = 4'd5;
// SICHER: Sperrung bei zu vielen Fehlversuchen
wire basic_locked = (basic_fail_count >= MAX_ATTEMPTS);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
basic_debug_enabled <= 1'b0;
secure_debug_enabled <= 1'b0;
key_debug_enabled <= 1'b0;
end else begin
// SICHER: Basis-Stufe Entsperrung
if (basic_unlock_request && !basic_locked) begin
if (basic_unlock_key == basic_key_otp) begin
basic_debug_enabled <= 1'b1;
end else begin
basic_fail_count <= basic_fail_count + 1;
end
end
// SICHER: Sichere Stufe erfordert zuerst Basis
if (secure_unlock_request && basic_debug_enabled) begin
// ... Sichere Entsperrlogik
end
// SICHER: Schlüssel-Stufe erfordert zuerst Sicher
if (key_unlock_request && secure_debug_enabled) begin
// ... Schlüssel-Entsperrlogik
end
end
end
endmodule
// SICHER: Scan-Kette mit ordnungsgemäßer Granularität
module secure_scan_controller (
input wire scan_enable,
input wire scan_in,
input wire secure_scan_auth, // SICHER: Separate Auth für sicheren Scan
output wire scan_out
);
// SICHER: Separate Scan-Ketten für verschiedene Sicherheitsstufen
// SICHER: Schlüssel NICHT in irgendeiner Scan-Kette
// Schlüssel in isoliertem Block ohne Scan-Fähigkeit gespeichert
// SICHER: Nur nicht-sensible Register in Scan-Kette
scan_chain #(.WIDTH(64)) u_public_scan (
.scan_enable(scan_enable),
.scan_in(scan_in),
.scan_out(scan_out),
.regs({status_reg, config_reg})
);
// SICHER: Kein Scan-Pfad zu kryptographischen Schlüsseln
// Schlüssel in isoliertem Block ohne Scan-Fähigkeit gespeichert
assign scan_out = public_scan_out;
endmodule
// SICHER: TAP-Router mit Authentifizierung
module tap_router (
input wire tck,
input wire tms,
input wire tdi,
input wire trst_n,
output reg tdo,
input wire basic_auth,
input wire secure_auth,
input wire key_auth,
output reg basic_tap_sel,
output reg cpu_tap_sel,
output reg secure_tap_sel,
output reg key_tap_sel,
input wire basic_tap_tdo,
input wire cpu_tap_tdo,
input wire secure_tap_tdo,
input wire key_tap_tdo
);
// SICHER: Routing basierend auf IR-Wert UND Authentifizierung
reg [3:0] current_ir;
always @(*) begin
// Standard: kein TAP ausgewählt
basic_tap_sel = 1'b0;
cpu_tap_sel = 1'b0;
secure_tap_sel = 1'b0;
key_tap_sel = 1'b0;
tdo = 1'b0;
case (current_ir)
4'h0: begin // Basis-TAP - immer zugänglich
basic_tap_sel = 1'b1;
tdo = basic_tap_tdo;
end
4'h1: begin // CPU-TAP - erfordert Basis-Auth
if (basic_auth) begin
cpu_tap_sel = 1'b1;
tdo = cpu_tap_tdo;
end
// SICHER: Kein Zugriff ohne Auth
end
4'h2: begin // Sicherer TAP - erfordert sichere Auth
if (secure_auth) begin
secure_tap_sel = 1'b1;
tdo = secure_tap_tdo;
end
end
4'h3: begin // Schlüssel-TAP - erfordert Schlüssel-Auth
if (key_auth) begin
key_tap_sel = 1'b1;
tdo = key_tap_tdo;
end
end
default: begin
// Ungültiger IR - kein Zugriff
end
endcase
end
endmodule
CVE-Beispiele
- CVE-2021-33097: Debug-Ketten-Fehlkonfiguration in Prozessor ermöglichte unbefugten Zugriff auf sichere Debug-Funktionen.
- CVE-2019-11090: JTAG-Daisy-Chain exponierte sichere Komponenten ohne ordnungsgemäße Authentifizierung.
Verwandte CWEs
- CWE-284: Unsachgemäße Zugriffskontrolle (übergeordnet)
- CWE-1207: Debug- und Testprobleme (Kategorie)
- CWE-1295: Debug-Nachrichten enthüllen unnötige Informationen (verwandt)
- CWE-1244: Internes Asset unsicherem Debug-Zugriff ausgesetzt (verwandt)
Referenzen
- MITRE Corporation. "CWE-1296: Incorrect Chaining or Granularity of Debug Components." https://cwe.mitre.org/data/definitions/1296.html
- IEEE 1149.1: Standard Test Access Port and Boundary-Scan Architecture
- CAPEC-702: Exploiting Incorrect Chaining or Granularity of Hardware Debug Components