Hardware ermöglicht Aktivierung von Test- oder Debug-Logik zur Laufzeit
Beschreibung
Hardware ermöglicht die Aktivierung von Test- oder Debug-Logik zur Laufzeit, wenn während der Laufzeit die Hardware die Aktivierung von Test- oder Debug-Logik (Funktionen) erlaubt, wodurch der Zustand der Hardware geändert werden kann. Diese Aktivierungsfähigkeit erzeugt Sicherheitsrisiken, indem sie Angreifern ermöglicht, das Systemverhalten zu ändern und auf sensible Informationen zuzugreifen. Beispiele umfassen Lese-/Schreibzugriff auf Systemdaten durch Testmodi, Datenänderung durch Fehlerinjektion während Bus-Operationen und unbefugten Zugriff auf Systemgeheimnisse.
Risiko
Laufzeit-Test-/Debug-Aktivierung hat schwerwiegende Auswirkungen. Speicheränderung möglich. Unbefugte Lesezugriffe ermöglicht. Denial of Service durch Instabilität. Unbefugte Code-Ausführung. Privilegienerweiterung. Umgehung von Schutzmechanismen. Ausführungslogik verändert. Leistung beeinträchtigt. Zuverlässigkeitsprobleme. Hardware-Zustand kompromittiert. Hohe Wahrscheinlichkeit wenn Testmodi zugänglich bleiben.
Lösung
Fügen Sie Einschränkungen ein, wann die Test- oder Debug-Funktionen der Hardware aktiviert werden können. Verhindern Sie privilegierten Moduszugriff während des normalen Betriebs. Beschränken Sie die Test-/Debug-Aktivierung auf spezifische Zeitfenster wie Boot oder Konfigurationsphasen. Deaktivieren Sie solche Funktionen während des Laufzeitbetriebs vollständig. Verwenden Sie Hardware-Fuses, um Testfunktionen in der Produktion dauerhaft zu deaktivieren. Fordern Sie Authentifizierung für die Debug-Aktivierung.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit Systemgeheimnisse über Debug-Schnittstellen lesbar. |
| Integrität | Bereich: Integrität Speicher und Ausführungszustand über Testmodi modifizierbar. |
| Verfügbarkeit | Bereich: Verfügbarkeit Denial of Service durch Abstürze, Instabilität oder Ressourcenerschöpfung. |
Beispielcode und Lösung
Verwundbarer Code
// VERWUNDBAR: Testmodus zur Laufzeit aktivierbar
module vulnerable_test_controller (
input wire clk,
input wire rst_n,
input wire test_mode_enable, // Software-steuerbar!
input wire [31:0] test_addr,
input wire [31:0] test_wdata,
input wire test_write,
input wire test_read,
// Systemschnittstellen
output reg [31:0] sys_addr,
output reg [31:0] sys_wdata,
output reg sys_write,
output reg sys_read,
output reg [31:0] sys_rdata,
// Interner Debug-Zugriff
output reg debug_mem_access,
output reg error_inject_enable
);
// VERWUNDBAR: Testmodus kann jederzeit aktiviert werden
// Keine Einschränkungen wann oder wer ihn aktivieren kann
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
debug_mem_access <= 1'b0;
error_inject_enable <= 1'b0;
end else begin
// VERWUNDBAR: Testmodus gewährt spezielle Fähigkeiten
if (test_mode_enable) begin
// VERWUNDBAR: Direkter Speicherzugriff unter Umgehung des Schutzes
sys_addr <= test_addr;
sys_wdata <= test_wdata;
sys_write <= test_write;
sys_read <= test_read;
// VERWUNDBAR: Debug-Funktionen zur Laufzeit aktiviert
debug_mem_access <= 1'b1;
error_inject_enable <= 1'b1;
end else begin
debug_mem_access <= 1'b0;
error_inject_enable <= 1'b0;
end
end
end
// Angriff:
// 1. Bösartige Software setzt test_mode_enable = 1
// 2. Debug-Speicherzugriff aktiviert
// 3. Angreifer liest/schreibt geschützten Speicher
// 4. Fehlerinjektion beschädigt Systemzustand
endmodule
// VERWUNDBAR: Debug-Logik während des normalen Betriebs zugänglich
module vulnerable_cpu_debug (
input wire clk,
input wire rst_n,
input wire debug_request, // VERWUNDBAR: Immer verfügbar
input wire [31:0] debug_addr,
input wire [31:0] debug_data,
input wire debug_write,
// CPU-Interna (sollten geschützt sein)
output reg [31:0] pc_override,
output reg halt_cpu,
output reg single_step,
output reg [31:0] register_write_data,
output reg [4:0] register_write_addr,
output reg register_write_en
);
// VERWUNDBAR: Keine Lebenszyklus-Zustandsprüfung
// Debug auch nach Abschluss von Secure Boot zugänglich
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
halt_cpu <= 1'b0;
single_step <= 1'b0;
register_write_en <= 1'b0;
end else if (debug_request) begin
// VERWUNDBAR: Debug-Befehle werden zur Laufzeit verarbeitet
case (debug_addr[7:0])
8'h00: begin
// CPU anhalten
halt_cpu <= debug_data[0];
end
8'h04: begin
// Programmzähler überschreiben
pc_override <= debug_data; // VERWUNDBAR!
end
8'h08: begin
// CPU-Register schreiben
register_write_addr <= debug_data[4:0];
register_write_data <= debug_data;
register_write_en <= 1'b1; // VERWUNDBAR!
end
8'h0C: begin
// Einzelschritt-Modus aktivieren
single_step <= debug_data[0];
end
endcase
end
end
// VERWUNDBAR: Keine Authentifizierung erforderlich
// VERWUNDBAR: Keine Lebenszyklus-Prüfung (Produktion vs. Entwicklung)
endmodule
// VERWUNDBAR: BIST zur Laufzeit zugänglich
module vulnerable_bist_controller (
input wire clk,
input wire rst_n,
input wire bist_start, // Software-auslösbar
input wire [7:0] bist_pattern,
output reg bist_running,
output reg bist_complete,
output reg bist_pass
);
reg [31:0] memory [0:1023];
reg [9:0] test_addr;
// VERWUNDBAR: BIST kann jederzeit gestartet werden
// Dies kann Speicher während des normalen Betriebs beschädigen!
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
bist_running <= 1'b0;
bist_complete <= 1'b0;
end else if (bist_start && !bist_running) begin
// VERWUNDBAR: BIST zerstört Speicherinhalte!
bist_running <= 1'b1;
test_addr <= 10'b0;
end else if (bist_running) begin
// VERWUNDBAR: Überschreibt Live-Speicher mit Testmustern
memory[test_addr] <= {4{bist_pattern}};
test_addr <= test_addr + 1;
if (test_addr == 10'h3FF) begin
bist_complete <= 1'b1;
bist_running <= 1'b0;
end
end
end
// Angriff:
// BIST während der Laufzeit auslösen um kritische Daten zu beschädigen
// Verursacht Denial of Service oder ausnutzbaren Zustand
endmodule
Sichere Lösung
// SICHER: Testmodus mit Lebenszyklus-Einschränkungen
module secure_test_controller (
input wire clk,
input wire rst_n,
input wire test_mode_request,
input wire [31:0] test_addr,
input wire [31:0] test_wdata,
input wire test_write,
input wire test_read,
// Lebenszyklus-Signale
input wire boot_complete, // Gesetzt wenn Boot abgeschlossen
input wire production_mode_fuse, // OTP-Fuse für Produktion
// Systemschnittstellen
output reg [31:0] sys_addr,
output reg [31:0] sys_wdata,
output reg sys_write,
output reg sys_read,
output reg [31:0] sys_rdata,
// Debug-Zugriff (eingeschränkt)
output reg debug_mem_access,
output reg error_inject_enable,
output reg test_mode_denied
);
// SICHER: Testmodus nur während spezifischer Lebenszyklusphasen erlaubt
wire test_allowed = !boot_complete && // Nur vor Boot-Abschluss
!production_mode_fuse; // Nur im Entwicklungsmodus
// SICHER: Tatsächlicher Testmodus-Zustand
reg test_mode_active;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
test_mode_active <= 1'b0;
debug_mem_access <= 1'b0;
error_inject_enable <= 1'b0;
test_mode_denied <= 1'b0;
end else begin
test_mode_denied <= 1'b0;
// SICHER: Prüfen ob Testmodus-Aktivierung erlaubt ist
if (test_mode_request) begin
if (test_allowed) begin
test_mode_active <= 1'b1;
end else begin
// SICHER: Testmodus nach Boot oder in Produktion ablehnen
test_mode_active <= 1'b0;
test_mode_denied <= 1'b1;
end
end
// SICHER: Testfunktionen nur aktiv wenn erlaubt
if (test_mode_active && test_allowed) begin
sys_addr <= test_addr;
sys_wdata <= test_wdata;
sys_write <= test_write;
sys_read <= test_read;
debug_mem_access <= 1'b1;
error_inject_enable <= 1'b1;
end else begin
// SICHER: Testfunktionen deaktivieren wenn nicht erlaubt
debug_mem_access <= 1'b0;
error_inject_enable <= 1'b0;
test_mode_active <= 1'b0;
end
end
end
// SICHER: Testmodus nach Boot-Abschluss erzwungen deaktivieren
always @(posedge boot_complete) begin
test_mode_active <= 1'b0;
end
endmodule
// SICHER: Debug-Logik mit Authentifizierung und Lebenszyklus-Prüfung
module secure_cpu_debug (
input wire clk,
input wire rst_n,
input wire debug_request,
input wire [31:0] debug_addr,
input wire [31:0] debug_data,
input wire debug_write,
// SICHER: Lebenszyklus und Authentifizierung
input wire debug_authenticated, // Challenge-Response abgeschlossen
input wire development_mode, // Von Fuse
input wire [1:0] lifecycle_state, // 00=Entw, 01=Prod, 10=RMA, 11=Verschrottet
// CPU-Interna
output reg [31:0] pc_override,
output reg halt_cpu,
output reg single_step,
output reg [31:0] register_write_data,
output reg [4:0] register_write_addr,
output reg register_write_en,
output reg debug_denied
);
// SICHER: Debug nur mit ordnungsgemäßer Authentifizierung und Lebenszyklus erlaubt
localparam LC_DEV = 2'b00;
localparam LC_PROD = 2'b01;
localparam LC_RMA = 2'b10;
wire debug_allowed;
// SICHER: Unterschiedliche Fähigkeiten pro Lebenszyklus-Zustand
assign debug_allowed = (lifecycle_state == LC_DEV) ||
(lifecycle_state == LC_RMA && debug_authenticated);
// Produktionsmodus erlaubt niemals Debug
// SICHER: Fähigkeiten auch wenn erlaubt einschränken
wire full_debug = (lifecycle_state == LC_DEV);
wire limited_debug = (lifecycle_state == LC_RMA && debug_authenticated);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
halt_cpu <= 1'b0;
single_step <= 1'b0;
register_write_en <= 1'b0;
debug_denied <= 1'b0;
end else begin
register_write_en <= 1'b0;
debug_denied <= 1'b0;
if (debug_request) begin
if (!debug_allowed) begin
// SICHER: Debug in Produktion ablehnen
debug_denied <= 1'b1;
end else begin
case (debug_addr[7:0])
8'h00: begin
// CPU anhalten - in Debug-Modi erlaubt
halt_cpu <= debug_data[0];
end
8'h04: begin
// PC-Überschreibung - nur im vollen Debug
if (full_debug) begin
pc_override <= debug_data;
end else begin
debug_denied <= 1'b1;
end
end
8'h08: begin
// Register-Schreiben - nur im vollen Debug
if (full_debug) begin
register_write_addr <= debug_data[4:0];
register_write_data <= debug_data;
register_write_en <= 1'b1;
end else begin
debug_denied <= 1'b1;
end
end
8'h0C: begin
// Einzelschritt - im eingeschränkten Debug erlaubt
single_step <= debug_data[0];
end
default: begin
debug_denied <= 1'b1;
end
endcase
end
end
end
end
endmodule
// SICHER: BIST mit Laufzeit-Sperre
module secure_bist_controller (
input wire clk,
input wire rst_n,
input wire bist_start,
input wire [7:0] bist_pattern,
input wire boot_complete, // SICHER: Lebenszyklus-Signal
input wire bist_unlock_fuse, // SICHER: Spezielle Entsperr-Fuse
output reg bist_running,
output reg bist_complete,
output reg bist_pass,
output reg bist_denied
);
reg [31:0] memory [0:1023];
reg [9:0] test_addr;
// SICHER: BIST nur vor Boot-Abschluss erlaubt
wire bist_allowed = !boot_complete || bist_unlock_fuse;
// SICHER: BIST nach Abschluss sperren
reg bist_locked;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
bist_running <= 1'b0;
bist_complete <= 1'b0;
bist_locked <= 1'b0;
bist_denied <= 1'b0;
end else begin
bist_denied <= 1'b0;
if (bist_start && !bist_running) begin
// SICHER: Prüfen ob BIST erlaubt ist
if (bist_allowed && !bist_locked) begin
bist_running <= 1'b1;
test_addr <= 10'b0;
end else begin
// SICHER: BIST nach Boot oder bei Sperre ablehnen
bist_denied <= 1'b1;
end
end else if (bist_running) begin
// BIST ausführen (nur erreichbar wenn erlaubt)
memory[test_addr] <= {4{bist_pattern}};
test_addr <= test_addr + 1;
if (test_addr == 10'h3FF) begin
bist_complete <= 1'b1;
bist_running <= 1'b0;
// SICHER: BIST nach Abschluss sperren
bist_locked <= 1'b1;
end
end
end
end
// SICHER: Auch bei Boot-Abschluss sperren
always @(posedge boot_complete) begin
if (!bist_unlock_fuse) begin
bist_locked <= 1'b1;
end
end
endmodule
CVE-Beispiele
- CVE-2021-33150: Prozessor ermöglicht Test- oder Debug-Logik-Aktivierung zur Laufzeit.
- CVE-2021-0146: Prozessor-Debug-Logik ermöglicht Privilegienerweiterung während des Betriebs.
- CVE-2019-0090: Intel-CSME-Testmodus nach Secure Boot zugänglich.
Verwandte CWEs
- CWE-284: Improper Access Control (Eltern)
- CWE-1207: Debug and Test Problems (Kategorie)
- CWE-1244: Internal Asset Exposed to Unsafe Debug Access (verwandt)
- CWE-1243: Sensitive Non-Volatile Information Not Protected During Debug (verwandt)
Referenzen
- MITRE Corporation. "CWE-1313: Hardware Allows Activation of Test or Debug Logic at Runtime." https://cwe.mitre.org/data/definitions/1313.html
- NIST. "Platform Firmware Resiliency Guidelines"
- ARM. "CoreSight Debug and Trace Architecture"