Unsachgemäße Einschränkung von Write-Once-Bitfeldern
Beschreibung
Unsachgemäße Einschränkung von Write-Once-Bitfeldern tritt auf, wenn Hardware-Design-Kontrollregister "Sticky Bits" oder Write-Once-Bitfelder unsachgemäß implementiert sind, sodass sie von Software umprogrammiert werden können. Register-Schaltungen in integrierten Schaltungen und Hardware-IP verwenden Write-Once-Schutz, bei dem "Sticky Bits" die initiale Konfiguration durch Boot-Software erlauben, während Laufzeitänderungen verhindert werden. Eine unsachgemäße Implementierung -- wie das Erlauben von Schreibvorgängen nur wenn Bits auf "1" gesetzt werden -- erzeugt "Write-1-Once" anstelle von echtem "Write-Once"-Schutz und macht Register für wiederholte Umprogrammierung anfällig.
Risiko
Unsachgemäß eingeschränkte Write-Once-Bits haben schwerwiegende Sicherheitsauswirkungen. Sicherheitskonfigurationen können nach der initialen Einrichtung modifiziert werden. Sperrbits können löschbar sein und ihren Zweck verfehlen. Boot-Sicherheitseinstellungen können zur Laufzeit änderbar sein. Debug-Schnittstellen können nach der Deaktivierung wieder aktiviert werden. Fuse-Schutz kann umgehbar sein. Sicherheitsrichtlinien können nach der Initialisierung geschwächt werden. Rechteeskalation kann durch Konfigurationsänderungen möglich sein. Systemintegrität kann kompromittiert werden.
Lösung
Implementieren Sie echte Write-Once-Semantik, die bei jedem Schreibvorgang unabhängig vom Wert sperrt. Setzen Sie den Write-Once-Status bedingungslos beim ersten Schreibzugriff. Überprüfen Sie die Write-Once-Implementierung durch formale Verifikation. Testen Sie, dass Bits nach dem ersten Schreibvorgang nicht modifiziert werden können. Verwenden Sie Hardware-Zustandsautomaten zur Durchsetzung des Write-Once-Verhaltens. Dokumentieren Sie das Write-Once-Bitverhalten klar. Prüfen Sie alle Register-Implementierungen auf korrekte Sticky-Bit-Logik. Erwägen Sie die Verwendung nichtflüchtiger Fuses für kritische Sicherheitseinstellungen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit, Integrität, Verfügbarkeit, Zugriffskontrolle | Bereich: Alle Systemkonfiguration kann nicht auf sichere Weise programmiert werden. Angreifer können vermeintlich geschützte Konfigurationsbits umprogrammieren. |
Beispielcode und Lösung
Verwundbarer Code
// VERWUNDBAR: Write-1-Once anstelle von echtem Write-Once
module vulnerable_write_once_register (
input wire clk,
input wire reset_n,
input wire [31:0] write_data,
input wire write_enable,
output reg [31:0] register_value,
output reg [31:0] write_once_status
);
integer i;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
register_value <= 32'h0;
write_once_status <= 32'h0;
end
else if (write_enable) begin
for (i = 0; i < 32; i = i + 1) begin
// VERWUNDBAR: Sperrt nur beim Schreiben von 1
// Auf 0 geschriebene Bits werden nicht gesperrt!
if (write_data[i] == 1'b1) begin
if (write_once_status[i] == 1'b0) begin
register_value[i] <= 1'b1;
write_once_status[i] <= 1'b1;
end
end
else begin
// VERWUNDBAR: Schreiben von 0 funktioniert immer!
if (write_once_status[i] == 1'b0) begin
register_value[i] <= 1'b0;
// Fehler: Status nicht aktualisiert für 0-Schreibvorgänge
end
end
end
end
end
endmodule
Sichere Lösung
// SICHER: Echte Write-Once-Implementierung
module secure_write_once_register (
input wire clk,
input wire reset_n,
input wire [31:0] write_data,
input wire write_enable,
output reg [31:0] register_value,
output reg [31:0] write_once_status
);
integer i;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
register_value <= 32'h0;
write_once_status <= 32'h0;
end
else if (write_enable) begin
for (i = 0; i < 32; i = i + 1) begin
// SICHER: Bei JEDEM Schreibvorgang sperren, unabhängig vom Wert
if (write_once_status[i] == 1'b0) begin
// Erster Schreibvorgang – Wert setzen UND sperren
register_value[i] <= write_data[i];
write_once_status[i] <= 1'b1; // Immer nach erstem Schreiben sperren
end
// Wenn bereits gesperrt, Schreibvorgang vollständig ignorieren
end
end
end
endmodule
// SICHER: Firmware mit korrekter Write-Once-Behandlung
#define SECURITY_CONFIG_REG 0x40001000
#define WRITE_ONCE_STATUS_REG 0x40001004
void secure_set_security_config(uint32_t config) {
// Aktuellen Write-Once-Status prüfen
uint32_t status = *(volatile uint32_t*)WRITE_ONCE_STATUS_REG;
if (status != 0) {
uint32_t current = *(volatile uint32_t*)SECURITY_CONFIG_REG;
if ((current & status) != (config & status)) {
panic("Bereits geschriebene Sicherheitskonfiguration kann nicht modifiziert werden!");
}
}
// Sicherheitskonfiguration schreiben
*(volatile uint32_t*)SECURITY_CONFIG_REG = config;
// Überprüfen, dass Schreibvorgang erfolgreich war
uint32_t readback = *(volatile uint32_t*)SECURITY_CONFIG_REG;
if (readback != config) {
panic("Schreiben der Sicherheitskonfiguration fehlgeschlagen!");
}
// Überprüfen, dass alle Bits jetzt gesperrt sind
status = *(volatile uint32_t*)WRITE_ONCE_STATUS_REG;
if (status != 0xFFFFFFFF) {
panic("Write-Once-Status unvollständig!");
}
}
CVE-Beispiele
Write-Once-Implementierungsfehler wurden in verschiedenen SoC-Designs gefunden, bei denen "Sticky Bits" aufgrund fehlerhafter Sperrlogik gelöscht oder umprogrammiert werden könnten.
Verwandte CWEs
- CWE-284: Improper Access Control (übergeordnet)
- CWE-1199: General Circuit and Logic Design Concerns (Kategoriemitglied)
- CWE-1231: Improper Prevention of Lock Bit Modification (verwandt)
Referenzen
- MITRE Corporation. "CWE-1224: Improper Restriction of Write-Once Bit Fields." https://cwe.mitre.org/data/definitions/1224.html
- CAPEC-680: Exploitation of Improperly Controlled Registers
- Richtlinien zum Hardware-Sicherheitsregister-Design