Unsachgemäße Behandlung von Single Event Upsets
Beschreibung
Unsachgemäße Behandlung von Single Event Upsets tritt auf, wenn Hardware-Logik nicht effektiv behandelt, wenn Single-Event-Upsets (SEUs) auftreten. Moderne Halbleitertrends – einschließlich Transistorverkleinerung, neuer Materialien und System-on-Chip-Designs – erhöhen die Systemempfindlichkeit gegenüber Soft Errors. Single-Event-Upsets sind temporäre Bit-Flips, die durch geladene Teilchen verursacht werden, die Schaltkreismaterialien ionisieren und Elektron-Loch-Paare erzeugen, die transiente Fehler verursachen. Wenn diese in sicherheitskritischen Modulen auftreten, können sie die Sicherheitsgarantien des Chips kompromittieren, wie z.B. die Erhöhung von Benutzerberechtigungen auf Root-Zugriff.
Risiko
SEUs in Sicherheitshardware haben schwerwiegende Auswirkungen. Privilegstufen können korrumpiert werden. Zugriffskontrollbits können kippen. Kryptographische Operationen können falsche Ergebnisse liefern. Sicherheitszustandsmaschinen können in ungültige Zustände eintreten. Authentifizierungsentscheidungen können korrumpiert werden. Boot-Sicherheit kann umgangen werden. In SRAM gespeicherte Schlüssel können modifiziert werden. Systemintegrität kann stillschweigend kompromittiert werden.
Lösung
Implementieren Sie Triple-Modular-Redundancy (TMR) um sicherheitskritische Module. Für SRAMs, die sicherheitskritische Daten speichern, setzen Sie Error-Correcting Codes (ECC) und Address Interleaving ein. Verwenden Sie Paritätsprüfung zur Fehlererkennung. Implementieren Sie redundante Abstimmungslogik für kritische Entscheidungen. Entwerfen Sie für Fail-Secure-Verhalten bei erkannten Fehlern. Fügen Sie Scrubbing-Mechanismen hinzu, um Fehler vor der Akkumulation zu korrigieren. Erwägen Sie strahlungsgehärtete Designs für kritische Anwendungen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Verfügbarkeit | Bereich: Verfügbarkeit DoS: Absturz, Beendigung oder Neustart - SEU-induzierte Fehler können einen Systemneustart erfordern oder Instabilität verursachen. |
| Verfügbarkeit | Bereich: Verfügbarkeit DoS: Instabilität - Akkumulierte Fehler können unvorhersehbares Verhalten verursachen. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle Privilegien erlangen oder Identität annehmen - SEU-Bit-Flip im Privilegregister könnte Benutzer auf Root erhöhen. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle Schutzmechanismus umgehen - Sicherheitsprüfungen können durch Bit-Flips umgangen werden. |
Beispielcode und Lösung
Verwundbarer Code
// VERWUNDBAR: Sicherheitslogik ohne SEU-Schutz
module vulnerable_privilege_controller (
input wire clk,
input wire reset_n,
input wire [1:0] requested_privilege,
input wire privilege_request,
input wire authenticate_success,
output reg [1:0] current_privilege,
output reg privilege_granted
);
// Privilegstufen
parameter USER = 2'b00;
parameter SUPERVISOR = 2'b01;
parameter HYPERVISOR = 2'b10;
parameter SECURE = 2'b11;
// VERWUNDBAR: Einzelnes Register speichert Privilegstufe
// SEU-Bit-Flip: 00 (USER) -> 11 (SECURE)
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
current_privilege <= USER;
privilege_granted <= 1'b0;
end
else if (privilege_request && authenticate_success) begin
current_privilege <= requested_privilege;
privilege_granted <= 1'b1;
end
end
// VERWUNDBAR: Keine Erkennung von SEU-induzierter Korruption
// Wenn kosmische Strahlung current_privilege von 00 auf 11 flippt,
// erhält Benutzer sichere Privilegien ohne Authentifizierung
endmodule
// VERWUNDBAR: Sicherheitsentscheidung ohne Redundanz
module vulnerable_access_check (
input wire clk,
input wire reset_n,
input wire access_request,
input wire [1:0] requester_privilege,
input wire [1:0] required_privilege,
output reg access_granted
);
// VERWUNDBAR: Einzelner Vergleich für Sicherheitsentscheidung
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
access_granted <= 1'b0;
end
else if (access_request) begin
// VERWUNDBAR: SEU könnte Vergleichsergebnis flippen
access_granted <= (requester_privilege >= required_privilege);
end
end
// VERWUNDBAR: Keine Redundanz zur Fehlererkennunng/-korrektur
endmodule
// VERWUNDBAR: SRAM ohne ECC für Sicherheitsdaten
module vulnerable_key_storage (
input wire clk,
input wire reset_n,
input wire [7:0] addr,
input wire [127:0] write_data,
input wire write_enable,
input wire read_enable,
output reg [127:0] read_data
);
// VERWUNDBAR: Einfaches SRAM ohne ECC
reg [127:0] key_memory [0:255];
always @(posedge clk) begin
if (write_enable) begin
key_memory[addr] <= write_data;
end
if (read_enable) begin
// VERWUNDBAR: SEU könnte Bits im gespeicherten Schlüssel geflippt haben
// Kein Erkennungsmechanismus
read_data <= key_memory[addr];
end
end
endmodule
// VERWUNDBAR: Software ohne SEU-Schutz
#include <stdint.h>
// VERWUNDBAR: Einzelne Variable speichert Privileg
volatile uint32_t current_privilege = PRIVILEGE_USER;
// VERWUNDBAR: Keine Redundanz für Sicherheitsentscheidungen
int vulnerable_check_access(uint32_t resource_id) {
// Wenn SEU current_privilege-Bits flippt, kann Prüfung fälschlich bestehen
if (current_privilege >= get_required_privilege(resource_id)) {
return ACCESS_GRANTED;
}
return ACCESS_DENIED;
}
// VERWUNDBAR: Parität erkennt nur, kann nicht korrigieren
typedef struct {
uint32_t data;
uint8_t parity;
} parity_protected_t;
uint32_t vulnerable_parity_read(parity_protected_t* value) {
// Parität prüfen
uint8_t computed_parity = compute_parity(value->data);
if (computed_parity != value->parity) {
// VERWUNDBAR: Fehler erkannt, aber kann nicht korrigieren
// Muss System neustarten - 2-3 Minuten Ausfallzeit
system_restart();
}
return value->data;
}
Sichere Lösung
// SICHER: Sicherheitslogik mit TMR (Triple Modular Redundancy)
module secure_privilege_controller (
input wire clk,
input wire reset_n,
input wire [1:0] requested_privilege,
input wire privilege_request,
input wire authenticate_success,
output reg [1:0] current_privilege,
output reg privilege_granted,
output reg seu_detected
);
// Privilegstufen
parameter USER = 2'b00;
parameter SUPERVISOR = 2'b01;
parameter HYPERVISOR = 2'b10;
parameter SECURE = 2'b11;
// SICHER: Dreifach redundante Privilegspeicherung
reg [1:0] privilege_a;
reg [1:0] privilege_b;
reg [1:0] privilege_c;
// SICHER: Mehrheitsabstimmungsfunktion
function [1:0] majority_vote;
input [1:0] a, b, c;
begin
majority_vote = (a & b) | (b & c) | (a & c);
end
endfunction
// SICHER: Fehlererkennung
wire error_detected = (privilege_a != privilege_b) ||
(privilege_b != privilege_c) ||
(privilege_a != privilege_c);
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
privilege_a <= USER;
privilege_b <= USER;
privilege_c <= USER;
privilege_granted <= 1'b0;
seu_detected <= 1'b0;
end
else begin
// SICHER: SEU erkennen und melden
seu_detected <= error_detected;
if (privilege_request && authenticate_success) begin
// Alle drei Kopien aktualisieren
privilege_a <= requested_privilege;
privilege_b <= requested_privilege;
privilege_c <= requested_privilege;
privilege_granted <= 1'b1;
end
else if (error_detected) begin
// SICHER: Selbstkorrektur durch Mehrheitsabstimmung
privilege_a <= majority_vote(privilege_a, privilege_b, privilege_c);
privilege_b <= majority_vote(privilege_a, privilege_b, privilege_c);
privilege_c <= majority_vote(privilege_a, privilege_b, privilege_c);
end
end
end
// SICHER: Ausgabe verwendet abgestimmten Wert
assign current_privilege = majority_vote(privilege_a, privilege_b, privilege_c);
endmodule
// SICHER: Sicherheitsentscheidung mit Redundanz
module secure_access_check (
input wire clk,
input wire reset_n,
input wire access_request,
input wire [1:0] requester_privilege,
input wire [1:0] required_privilege,
output reg access_granted,
output reg check_error
);
// SICHER: Prüfung dreimal mit unterschiedlicher Logik durchführen
wire check_a = (requester_privilege >= required_privilege);
wire check_b = (requester_privilege[1] > required_privilege[1]) ||
((requester_privilege[1] == required_privilege[1]) &&
(requester_privilege[0] >= required_privilege[0]));
wire check_c = ~(requester_privilege < required_privilege);
// SICHER: Mehrheitsabstimmung über Ergebnis
wire voted_result = (check_a & check_b) | (check_b & check_c) | (check_a & check_c);
// SICHER: Fehlererkennung
wire checks_inconsistent = (check_a != check_b) || (check_b != check_c);
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
access_granted <= 1'b0;
check_error <= 1'b0;
end
else if (access_request) begin
if (checks_inconsistent) begin
// SICHER: Fehler erkannt - sicher fehlschlagen
check_error <= 1'b1;
access_granted <= 1'b0; // Bei Fehler verweigern
end
else begin
check_error <= 1'b0;
access_granted <= voted_result;
end
end
end
endmodule
// SICHER: SRAM mit ECC für Sicherheitsdaten
module secure_key_storage (
input wire clk,
input wire reset_n,
input wire [7:0] addr,
input wire [127:0] write_data,
input wire write_enable,
input wire read_enable,
output reg [127:0] read_data,
output reg ecc_error_corrected,
output reg ecc_error_uncorrectable
);
// SICHER: Daten mit ECC speichern (SECDED - Single Error Correct, Double Error Detect)
// 128-Bit Daten + 8-Bit ECC = 136 Bits pro Eintrag
reg [135:0] key_memory [0:255];
// ECC-Funktionen (vereinfacht - echte Implementierung verwendet korrekten Hamming-Code)
function [7:0] compute_ecc;
input [127:0] data;
begin
// ECC-Syndrom berechnen
compute_ecc = data[7:0] ^ data[15:8] ^ data[23:16] ^ data[31:24] ^
data[39:32] ^ data[47:40] ^ data[55:48] ^ data[63:56] ^
data[71:64] ^ data[79:72] ^ data[87:80] ^ data[95:88] ^
data[103:96] ^ data[111:104] ^ data[119:112] ^ data[127:120];
end
endfunction
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
read_data <= 128'h0;
ecc_error_corrected <= 1'b0;
ecc_error_uncorrectable <= 1'b0;
end
else begin
ecc_error_corrected <= 1'b0;
ecc_error_uncorrectable <= 1'b0;
if (write_enable) begin
// SICHER: Daten mit ECC speichern
key_memory[addr] <= {compute_ecc(write_data), write_data};
end
if (read_enable) begin
// SICHER: Lesen und ECC prüfen/korrigieren
wire [127:0] stored_data = key_memory[addr][127:0];
wire [7:0] stored_ecc = key_memory[addr][135:128];
wire [7:0] computed_ecc = compute_ecc(stored_data);
wire [7:0] syndrome = stored_ecc ^ computed_ecc;
if (syndrome == 8'h00) begin
// Kein Fehler
read_data <= stored_data;
end
else if (/* Einzelbitfehler */) begin
// SICHER: Einzelbitfehler korrigieren
read_data <= correct_single_bit(stored_data, syndrome);
ecc_error_corrected <= 1'b1;
// Auch Speicher bereinigen
key_memory[addr] <= {compute_ecc(read_data), read_data};
end
else begin
// SICHER: Nicht korrigierbarer Fehler
ecc_error_uncorrectable <= 1'b1;
read_data <= 128'h0; // Null zurückgeben, nicht korrumpierte Daten
end
end
end
end
// SICHER: Hintergrund-Scrubbing zur Verhinderung von Fehlerakkumulation
reg [7:0] scrub_addr;
always @(posedge clk) begin
// Periodisch Speicher lesen und neu schreiben, um akkumulierte Fehler zu korrigieren
scrub_addr <= scrub_addr + 1;
// Scrubbing-Logik würde lesen, ECC prüfen, korrigieren, zurückschreiben
end
endmodule
// SICHER: Software mit SEU-Schutz
#include <stdint.h>
// SICHER: Dreifach-redundante Privilegspeicherung
typedef struct {
uint32_t value_a;
uint32_t value_b;
uint32_t value_c;
} tmr_uint32_t;
static tmr_uint32_t current_privilege = {
.value_a = PRIVILEGE_USER,
.value_b = PRIVILEGE_USER,
.value_c = PRIVILEGE_USER
};
// SICHER: Mehrheitsabstimmungsfunktion
static uint32_t majority_vote(tmr_uint32_t* tmr) {
// Bitweise Mehrheit
return (tmr->value_a & tmr->value_b) |
(tmr->value_b & tmr->value_c) |
(tmr->value_a & tmr->value_c);
}
// SICHER: SEU-Fehler prüfen und korrigieren
static bool check_and_correct_tmr(tmr_uint32_t* tmr) {
uint32_t voted = majority_vote(tmr);
bool error = (tmr->value_a != tmr->value_b) ||
(tmr->value_b != tmr->value_c);
if (error) {
// Selbstkorrektur
tmr->value_a = voted;
tmr->value_b = voted;
tmr->value_c = voted;
log_seu_event("TMR-Korrektur angewendet");
}
return error;
}
// SICHER: Zugriffsprüfung mit Redundanz
int secure_check_access(uint32_t resource_id) {
// Zuerst alle SEU-Fehler prüfen und korrigieren
check_and_correct_tmr(¤t_privilege);
uint32_t privilege = majority_vote(¤t_privilege);
uint32_t required = get_required_privilege(resource_id);
// SICHER: Prüfung dreimal durchführen
int result_a = (privilege >= required);
int result_b = (privilege >= required);
int result_c = (privilege >= required);
// Speicherbarrieren zur Verhinderung von Optimierung
__asm__ volatile("" ::: "memory");
// Mehrheitsabstimmung über Ergebnisse
int voted_result = (result_a & result_b) | (result_b & result_c) | (result_a & result_c);
// Auf Inkonsistenz prüfen
if ((result_a != result_b) || (result_b != result_c)) {
log_seu_event("Zugriffsprüfungs-Inkonsistenz erkannt");
return ACCESS_DENIED; // Sicher fehlschlagen
}
return voted_result ? ACCESS_GRANTED : ACCESS_DENIED;
}
// SICHER: ECC-geschützte Speicherung statt Parität
typedef struct {
uint32_t data;
uint32_t ecc;
} ecc_protected_t;
uint32_t secure_ecc_read(ecc_protected_t* value) {
uint32_t computed_ecc = compute_hamming_ecc(value->data);
uint32_t syndrome = computed_ecc ^ value->ecc;
if (syndrome == 0) {
// Kein Fehler
return value->data;
}
else if (is_single_bit_error(syndrome)) {
// SICHER: Einzelbitfehler korrigieren
uint32_t corrected = value->data ^ get_error_mask(syndrome);
value->data = corrected; // Speicher bereinigen
value->ecc = compute_hamming_ecc(corrected);
log_seu_event("ECC-Korrektur angewendet");
return corrected;
}
else {
// Mehrbitfehler - kann nicht korrigieren
log_seu_event("Nicht korrigierbarer ECC-Fehler");
// Sicheren Wert zurückgeben oder Wiederherstellung auslösen
return SAFE_DEFAULT_VALUE;
}
}
CVE-Beispiele
- Ein Herzschrittmacher-Vorfall 2016 betraf einen kosmische Strahlung-induzierten Bit-Flip in Flughöhe, der den sicheren Modus auslöste und Reverse Engineering ermöglichte, das hartcodierte kryptographische Schlüssel offenlegte.
- Verschiedene Satelliten- und Luft- und Raumfahrtsystemausfälle, die auf SEU-induzierte Bit-Flips in ungeschütztem Speicher zurückgeführt werden.
Verwandte CWEs
- CWE-1384: Unsachgemäße Behandlung physischer oder Umgebungsbedingungen (Eltern)
- CWE-1254: Falsche Vergleichslogik-Granularität (Peer)
- CWE-1247: Unsachgemäßer Schutz gegen Spannungs- und Taktglitches (verwandt)
Referenzen
- MITRE Corporation. "CWE-1261: Improper Handling of Single Event Upsets." https://cwe.mitre.org/data/definitions/1261.html
- Baumann, R. "Radiation-Induced Soft Errors in Advanced Semiconductor Technologies"
- NASA. "Single Event Effects Mitigation Techniques"