Nicht initialisierter Wert bei Reset für Register mit Sicherheitseinstellungen

Beschreibung

Nicht initialisierter Wert bei Reset für Register mit Sicherheitseinstellungen tritt auf, wenn sicherheitskritische Logik beim Systemreset nicht auf einen bekannten Wert gesetzt wird. Während des Geratestarts erzeugen nicht initialisierte Register ein Verwundbarkeitsfenster, bevor Sicherheitsmechanismen ordnungsgemäß eingerichtet sind. Register können nach dem Reset zufallige oder unbestimmte Werte enthalten, wenn sie nicht explizit initialisiert werden, was das System potenziell in einem unsicheren Zustand belasst, bis die Software die Initialisierung abschließt.

Risiko

Nicht initialisierte Sicherheitsregister haben schwerwiegende Sicherheitsauswirkungen. Debug-Schnittstellen können entsperrt sein. Schutzmechanismen können deaktiviert sein. Zugriffskontrollen können unwirksam sein. Sicherheitsrichtlinien können standardmäßig permissiv sein. Authentifizierung kann umgangen werden. Kryptografische Funktionen können kompromittiert sein. Angreifer können das Initialisierungsfenster ausnutzen. Wiederholte Resets können probabilistisch unsichere Zustände erreichen.

Lösung

Alle Register, die sicherheitskritische Informationen enthalten, sollten beim Reset auf einen bestimmten sicheren Wert gesetzt werden. Fuhren Sie Design-Prüfungen durch, um nicht initialisierte Flip-Flops in sicherheitskritischen Funktionen zu identifizieren. Verwenden Sie Hardware-Reset-Werte, die standardmäßig den sichersten Zustand einnehmen. Implementieren Sie sichere Standardinitialisierung. Verifizieren Sie das Reset-Verhalten durch Simulation und Tests. Dokumentieren Sie alle Sicherheitsregister-Reset-Werte.

Häufige Auswirkungen

AuswirkungDetails
ZugriffskontrolleUmfang: Zugriffskontrolle

Schutzmechanismus umgehen - Nicht initialisierte Register können unbefugten Zugriff ermöglichen.
AuthentifizierungUmfang: Authentifizierung

Authentifizierung umgehen - Sicherheitsprüfungen können vor der Initialisierung umgangen werden.
AutorisierungUmfang: Autorisierung

Berechtigungen erlangen - Angreifer können während des unsicheren Fensters erhöhte Berechtigungen erlangen.

Beispielcode und Lösung

Verwundbarer Code

// VERWUNDBAR: JTAG-Sperre ohne Reset-Initialisierung

module vulnerable_jtag_controller (
    input wire clk,
    input wire reset_n,
    input wire jtag_tck,
    input wire jtag_tms,
    input wire jtag_tdi,
    output wire jtag_tdo,
    // Sperrsteuerung
    input wire lock_command,
    output reg jtag_locked
);

    // VERWUNDBAR: Kein Reset-Wert für jtag_locked
    // Nach dem Reset hat jtag_locked einen unbestimmten Wert

    always @(posedge clk) begin
        if (lock_command) begin
            jtag_locked <= 1'b1;
        end
        // VERWUNDBAR: Keine Reset-Behandlung
        // jtag_locked könnte nach dem Einschalten 0 oder 1 sein
    end

    // VERWUNDBAR: Debug-Zugriff hangt von nicht initialisiertem Register ab
    wire debug_allowed = !jtag_locked;

    // Angriff: Angreifer setzt Gerat wiederholt zurück
    // Irgendwann startet jtag_locked als 0
    // Debug-Schnittstelle ist zuganglich!

endmodule

// VERWUNDBAR: Sicherheitskonfiguration ohne Initialisierung
module vulnerable_security_config (
    input wire clk,
    input wire reset_n,
    input wire [7:0] config_addr,
    input wire [31:0] config_data,
    input wire config_write,
    output reg secure_boot_enabled,
    output reg encryption_enabled,
    output reg debug_disabled,
    output reg tamper_response_enabled
);

    // VERWUNDBAR: Keine Reset-Initialisierung
    // Alle Sicherheitseinstellungen sind nach dem Reset unbestimmt

    always @(posedge clk) begin
        if (config_write) begin
            case (config_addr)
                8'h00: secure_boot_enabled <= config_data[0];
                8'h01: encryption_enabled <= config_data[0];
                8'h02: debug_disabled <= config_data[0];
                8'h03: tamper_response_enabled <= config_data[0];
            endcase
        end
        // VERWUNDBAR: Keine Reset-Klausel
        // Einstellungen sind undefiniert bis Software sie konfiguriert
    end

    // System arbeitet nach dem Reset mit undefinierter Sicherheitslage
    // Bis Software die Initialisierungssequenz ausführt

endmodule

// VERWUNDBAR: Zugriffskontrolle ohne Reset
module vulnerable_access_control (
    input wire clk,
    input wire reset_n,
    input wire [3:0] agent_id,
    input wire [31:0] address,
    input wire access_request,
    output reg access_granted
);

    // Zugriffsberechtigungsbits - eines pro Agent
    reg [15:0] permission_bits;

    // VERWUNDBAR: permission_bits nicht beim Reset initialisiert
    // Konnte alles 1en sein (alles erlaubt) oder zufallig

    always @(posedge clk) begin
        if (access_request) begin
            // VERWUNDBAR: Prüfung gegen nicht initialisierte Berechtigungen
            access_granted <= permission_bits[agent_id];
        end
    end

endmodule
// VERWUNDBAR: Software verlässt sich auf Hardware-Initialisierung

#include <stdint.h>

#define SECURITY_CONFIG_BASE 0x40000000

typedef struct {
    volatile uint32_t secure_boot;
    volatile uint32_t encryption;
    volatile uint32_t debug_lock;
    volatile uint32_t tamper_response;
} security_config_t;

void vulnerable_boot(void) {
    security_config_t* config = (security_config_t*)SECURITY_CONFIG_BASE;

    // VERWUNDBAR: Nimmt an, dass Hardware Register auf sichere Werte initialisiert hat
    // Aber Hardware hat möglicherweise keine Reset-Initialisierung

    if (config->secure_boot) {
        // Kann nie wahr sein, wenn Register nicht initialisiert ist
        verify_firmware_signature();
    }

    // VERWUNDBAR: Nicht initialisiertes Register lesen
    if (config->debug_lock == 0) {
        // Debug erscheint entsperrt aufgrund nicht initialisiertem Register
        // Angreifer kann auf Debug-Schnittstelle zugreifen!
        enable_debug_interface();
    }

    // System kann in unsicherem Zustand booten
    boot_firmware();
}

// VERWUNDBAR: Race Condition bei Initialisierung
void vulnerable_late_initialization(void) {
    security_config_t* config = (security_config_t*)SECURITY_CONFIG_BASE;

    // VERWUNDBAR: Sicherheitskonfiguration erfolgt spat im Boot-Prozess
    // Verwundbarkeitsfenster existiert vom Reset bis hierher

    // ... viele andere Initialisierungsschritte zuerst ...

    // Endlich Sicherheit konfigurieren (zu spat!)
    config->secure_boot = 1;
    config->encryption = 1;
    config->debug_lock = 1;
    config->tamper_response = 1;
}

Sichere Lösung

// SICHER: JTAG-Sperre mit sicherer Reset-Initialisierung

module secure_jtag_controller (
    input wire clk,
    input wire reset_n,
    input wire jtag_tck,
    input wire jtag_tms,
    input wire jtag_tdi,
    output wire jtag_tdo,
    input wire lock_command,
    input wire unlock_auth,      // Authentifizierte Entsperrung
    output reg jtag_locked
);

    // SICHER: Expliziter Reset auf gesperrten Zustand
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            // SICHER: Standardmäßig gesperrter (sicherer) Zustand bei Reset
            jtag_locked <= 1'b1;
        end
        else begin
            if (lock_command) begin
                jtag_locked <= 1'b1;
            end
            else if (unlock_auth) begin
                // Nur mit ordnungsgemäßer Authentifizierung entsperren
                jtag_locked <= 1'b0;
            end
        end
    end

    // Debug nur erlaubt wenn explizit entsperrt
    wire debug_allowed = !jtag_locked;

endmodule

// SICHER: Sicherheitskonfiguration mit sicheren Standardwerten
module secure_security_config (
    input wire clk,
    input wire reset_n,
    input wire [7:0] config_addr,
    input wire [31:0] config_data,
    input wire config_write,
    input wire privileged_access,  // Nur privilegiert kann ändern
    output reg secure_boot_enabled,
    output reg encryption_enabled,
    output reg debug_disabled,
    output reg tamper_response_enabled,
    output reg config_locked       // Weitere Änderungen verhindern
);

    // SICHER: Alle Sicherheitseinstellungen auf sichere Standardwerte bei Reset initialisiert
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            // SICHER: Sichere Standardwerte bei Reset
            secure_boot_enabled <= 1'b1;       // Secure Boot AN
            encryption_enabled <= 1'b1;         // Verschlüsselung AN
            debug_disabled <= 1'b1;             // Debug AUS
            tamper_response_enabled <= 1'b1;    // Manipulationsreaktion AN
            config_locked <= 1'b0;              // Initiale Konfiguration erlauben
        end
        else if (config_write && privileged_access && !config_locked) begin
            case (config_addr)
                8'h00: secure_boot_enabled <= config_data[0];
                8'h01: encryption_enabled <= config_data[0];
                8'h02: debug_disabled <= config_data[0];
                8'h03: tamper_response_enabled <= config_data[0];
                8'hFF: config_locked <= config_data[0];  // Konfiguration sperren
            endcase
        end
    end

endmodule

// SICHER: Zugriffskontrolle mit sicherem Reset
module secure_access_control (
    input wire clk,
    input wire reset_n,
    input wire [3:0] agent_id,
    input wire [31:0] address,
    input wire access_request,
    input wire privileged_config,
    input wire [15:0] new_permissions,
    output reg access_granted
);

    // Zugriffsberechtigungsbits
    reg [15:0] permission_bits;

    // SICHER: Auf restriktivste Berechtigungen initialisieren
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            // SICHER: Standardmäßig alles verweigern außer Agent 0 (sicherer Master)
            permission_bits <= 16'h0001;
            access_granted <= 1'b0;
        end
        else begin
            // Berechtigungen nur aus privilegiertem Kontext aktualisieren
            if (privileged_config) begin
                permission_bits <= new_permissions;
            end

            if (access_request) begin
                access_granted <= permission_bits[agent_id];
            end
        end
    end

endmodule

// SICHER: Umfassende Sicherheitsinitialisierungs-Verifizierung
module security_init_checker (
    input wire clk,
    input wire reset_n,
    input wire [31:0] security_reg_0,
    input wire [31:0] security_reg_1,
    input wire [31:0] security_reg_2,
    input wire [31:0] security_reg_3,
    output reg init_verified,
    output reg init_failed
);

    // Erwartete sichere Werte nach Reset
    parameter EXPECTED_REG_0 = 32'h0000_0001;  // Secure Boot
    parameter EXPECTED_REG_1 = 32'h0000_0001;  // Verschlüsselung
    parameter EXPECTED_REG_2 = 32'h0000_0001;  // Debug gesperrt
    parameter EXPECTED_REG_3 = 32'h0000_0001;  // Manipulationserkennung aktiviert

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            init_verified <= 1'b0;
            init_failed <= 1'b0;
        end
        else begin
            // SICHER: Sicherheitsregister nach Reset verifizieren
            if (security_reg_0 == EXPECTED_REG_0 &&
                security_reg_1 == EXPECTED_REG_1 &&
                security_reg_2 == EXPECTED_REG_2 &&
                security_reg_3 == EXPECTED_REG_3) begin
                init_verified <= 1'b1;
                init_failed <= 1'b0;
            end
            else begin
                init_verified <= 1'b0;
                init_failed <= 1'b1;
            end
        end
    end

endmodule
// SICHER: Software mit ordnungsgemäßer Initialisierungsbehandlung

#include <stdint.h>
#include <stdbool.h>

#define SECURITY_CONFIG_BASE 0x40000000

typedef struct {
    volatile uint32_t secure_boot;
    volatile uint32_t encryption;
    volatile uint32_t debug_lock;
    volatile uint32_t tamper_response;
    volatile uint32_t init_status;
} security_config_t;

// SICHER: Hardware-Initialisierung verifizieren
bool verify_security_init(void) {
    security_config_t* config = (security_config_t*)SECURITY_CONFIG_BASE;

    // SICHER: Verifizieren dass Hardware auf sichere Standardwerte initialisiert wurde
    if (config->secure_boot != 1) {
        log_error("Secure Boot nicht initialisiert");
        return false;
    }

    if (config->encryption != 1) {
        log_error("Verschlüsselung nicht initialisiert");
        return false;
    }

    if (config->debug_lock != 1) {
        log_error("Debug nicht standardmäßig gesperrt");
        return false;
    }

    if (config->tamper_response != 1) {
        log_error("Manipulationsreaktion nicht initialisiert");
        return false;
    }

    return true;
}

void secure_boot(void) {
    // SICHER: Sicherheitsinitialisierung ZUERST verifizieren
    if (!verify_security_init()) {
        // Hardware nicht ordnungsgemäß initialisiert - anhalten
        log_error("Sicherheitsinitialisierung fehlgeschlagen - Anhalten");
        secure_halt();
        return;
    }

    security_config_t* config = (security_config_t*)SECURITY_CONFIG_BASE;

    // Jetzt sicher fortzufahren - Hardware ist in bekanntem sicherem Zustand
    if (config->secure_boot) {
        if (!verify_firmware_signature()) {
            log_error("Firmware-Signaturverifizierung fehlgeschlagen");
            secure_halt();
            return;
        }
    }

    // Mit Boot fortfahren
    boot_firmware();
}

// SICHER: Fruhe Sicherheitsinitialisierung
void __attribute__((section(".init"))) early_security_init(void) {
    security_config_t* config = (security_config_t*)SECURITY_CONFIG_BASE;

    // SICHER: Sichere Standardwerte sofort beim Boot setzen
    // Sogar vor der C-Laufzeit-Initialisierung

    config->secure_boot = 1;
    config->encryption = 1;
    config->debug_lock = 1;
    config->tamper_response = 1;

    // Memory Barrier um sicherzustellen, dass Schreibvorgange abgeschlossen sind
    __asm__ volatile("dmb sy" ::: "memory");

    // Verifizieren dass Schreibvorgange wirksam wurden
    if (config->debug_lock != 1) {
        // Sperren fehlgeschlagen - anhalten
        while(1) { __asm__ volatile("wfi"); }
    }
}

CVE-Beispiele

Schwachstellen bei der Register-Initialisierung wurden in verschiedenen Hardware-Designs gefunden, bei denen Sicherheitsregister in unbestimmten Zuständen gestartet wurden, was Angreifern ermöglichte, Gerate wiederholt zurückzusetzen, bis eine unsichere Konfiguration erreicht wurde.


Verwandte CWEs

  • CWE-909: Fehlende Initialisierung von Ressourcen (ubergeordnet)
  • CWE-1206: Strom-, Takt-, Thermal- und Reset-Bedenken (Kategorie)
  • CWE-1304: Unsachgemäß erhaltene Integritat des Hardware-Konfigurationszustands (verwandt)
  • CAPEC-74: Zustandsmanipulation (Angriffsmuster)

Referenzen

  1. MITRE Corporation. "CWE-1271: Uninitialized Value on Reset for Registers Holding Security Settings." https://cwe.mitre.org/data/definitions/1271.html
  2. ARM. "TrustZone Security Extensions Reset Behavior"
  3. Intel. "Platform Security Best Practices"