Weitergabe von Gerateentsperrungs-Anmeldedaten

Beschreibung

Weitergabe von Gerateentsperrungs-Anmeldedaten tritt auf, wenn die für das Entsperren eines Gerats erforderlichen Anmeldedaten an mehrere Parteien weitergegeben werden und sensible Informationen preisgeben können. Die Gerateentsperrung aktiviert typischerweise Debug- und herstellerspezifische Fahigkeiten unter Verwendung sensibler Anmeldedaten, die für die Fehlerbehebung benötigt werden. Das Risiko einer Kompromittierung der Anmeldedaten steigt erheblich in Lieferketten mit mehreren Unternehmen, in denen Chip-Designer, Hersteller und Tester für verschiedene Organisationen arbeiten. Jede Partei benötigt Zugang zu Entsperrungs-Anmeldedaten, was größere Offenlegungsrisiken als bei vertikal integrierten Unternehmen schafft.

Risiko

Geteilte Entsperrungs-Anmeldedaten haben schwerwiegende Sicherheitsauswirkungen. Anmeldedaten können an unbefugte Parteien durchsickern. Debug-Schnittstellen können für Angreifer zuganglich sein. Geschutzte Funktionalitaten können freigelegt werden. Berechtigungserweiterung wird möglich. Speicher und Dateien können ohne Berechtigung zugegriffen werden. Schutzmechanismen können umgangen werden. Lieferkettenangriffe werden machbar. Geistiges Eigentum kann freigelegt werden.

Lösung

Begrenzen Sie die Weitergabe von Anmeldedaten auf die minimal notwendigen Parteien. Bewahren Sie hochste Geheimhaltungsprotokolle für alle geteilten Anmeldedaten. Implementieren Sie teil- oder chargenspezifische Anmeldedaten wo machbar. Wenden Sie strenge Zugriffskontrolle und Need-to-Know-Prinzipien an. Verwenden Sie kryptografische Methoden für die Ableitung von Anmeldedaten. Implementieren Sie Richtlinien für die Rotation von Anmeldedaten. Uberprüfen Sie die Nutzung und den Zugriff auf Anmeldedaten. Erwagen Sie Hardware-Sicherheitsmodule für die Speicherung von Anmeldedaten.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitUmfang: Vertraulichkeit

Speicher lesen - Kompromittierte Anmeldedaten ermöglichen unbefugten Speicherzugriff.
IntegritatUmfang: Integritat

Dateien ändern - Angreifer können Geratekonfiguration und Firmware ändern.
ZugriffskontrolleUmfang: Zugriffskontrolle

Schutzmechanismus umgehen - Debug-Zugriff umgeht Sicherheitskontrollen.
AutorisierungUmfang: Autorisierung

Berechtigungen erlangen - Gerateentsperrung ermöglicht privilegierte Operationen.

Beispielcode und Lösung

Verwundbarer Code

// VERWUNDBAR: Einzelne globale Entsperrungs-Anmeldedaten

module vulnerable_device_unlock (
    input wire clk,
    input wire reset_n,
    input wire [127:0] unlock_credential,
    input wire unlock_request,
    output reg device_unlocked,
    output reg debug_enabled
);

    // VERWUNDBAR: Einzelne globale Anmeldedaten für alle Gerate
    // Dieselben Anmeldedaten in der gesamten Lieferkette verwendet
    parameter GLOBAL_UNLOCK_KEY = 128'h0123456789ABCDEF0123456789ABCDEF;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            device_unlocked <= 1'b0;
            debug_enabled <= 1'b0;
        end
        else if (unlock_request) begin
            // VERWUNDBAR: Prüfung gegen globalen Schlüssel
            if (unlock_credential == GLOBAL_UNLOCK_KEY) begin
                device_unlocked <= 1'b1;
                debug_enabled <= 1'b1;
            end

            // Probleme:
            // 1. Schlüssel mit Chip-Designer geteilt
            // 2. Schlüssel mit Foundry geteilt
            // 3. Schlüssel mit Testhaus geteilt
            // 4. Schlüssel mit OEM geteilt
            // 5. Jedes Leck kompromittiert ALLE Gerate
        end
    end

endmodule

// VERWUNDBAR: Fest einprogrammierte Entsperrungs-Anmeldedaten
module vulnerable_hardcoded_unlock (
    input wire clk,
    input wire reset_n,
    input wire [63:0] password,
    input wire unlock_request,
    output reg unlocked
);

    // VERWUNDBAR: Fest einprogrammierte Passworter über Organisation geteilt
    parameter PASSWORD_ENGINEERING = 64'h456E67696E656572;  // "Engineer"
    parameter PASSWORD_PRODUCTION = 64'h50726F64756374;     // "Product"
    parameter PASSWORD_DEBUG = 64'h4465627567313233;        // "Debug123"

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            unlocked <= 1'b0;
        end
        else if (unlock_request) begin
            // VERWUNDBAR: Jedes der geteilten Passworter entsperrt Gerat
            if (password == PASSWORD_ENGINEERING ||
                password == PASSWORD_PRODUCTION ||
                password == PASSWORD_DEBUG) begin
                unlocked <= 1'b1;
            end

            // Jeder der ein Passwort kennt kann jedes Gerat entsperren
        end
    end

endmodule
// VERWUNDBAR: Software mit geteilten Entsperrungs-Anmeldedaten

#include <stdint.h>
#include <string.h>

// VERWUNDBAR: Globaler Entsperrschlüssel in Firmware kompiliert
// Derselbe Schlüssel für alle Gerate dieses Herstellers
static const uint8_t global_unlock_key[16] = {
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
};

// VERWUNDBAR: Über Lieferkette geteilt
static const char* shared_passwords[] = {
    "DesignerAccess2024",   // Chip-Designer
    "FoundryDebug",         // Foundry
    "TestHouseUnlock",      // Testhaus
    "OEMService",           // OEM
    "FieldDebug123"         // Außendienst
};

bool vulnerable_check_unlock(const uint8_t* credential, size_t len) {
    // VERWUNDBAR: Prüfung gegen globalen Schlüssel
    if (len == 16 && memcmp(credential, global_unlock_key, 16) == 0) {
        return true;
    }

    // VERWUNDBAR: Prüfung gegen alle geteilten Passworter
    for (int i = 0; i < sizeof(shared_passwords)/sizeof(shared_passwords[0]); i++) {
        if (strcmp((const char*)credential, shared_passwords[i]) == 0) {
            return true;
        }
    }

    return false;
}

void vulnerable_unlock_device(const uint8_t* credential, size_t len) {
    if (vulnerable_check_unlock(credential, len)) {
        // VERWUNDBAR: Vollständige Entsperrung für jede gültige Anmeldedaten
        enable_jtag();
        enable_debug_uart();
        disable_secure_boot();
        enable_memory_dump();

        // Jede Partei mit beliebigen Anmeldedaten erhält vollen Zugang
    }
}

// VERWUNDBAR: Anmeldedaten-Weitergabe in der Lieferkette
typedef struct {
    char company_name[64];
    uint8_t unlock_credential[16];
    uint32_t access_level;
} supply_chain_credential_t;

supply_chain_credential_t vulnerable_supply_chain[] = {
    {"Chip Designer Co", {0x01, 0x23, ...}, ACCESS_FULL},
    {"Global Foundry",   {0x01, 0x23, ...}, ACCESS_FULL},  // Gleicher Schlüssel!
    {"Test Systems Inc", {0x01, 0x23, ...}, ACCESS_FULL},  // Gleicher Schlüssel!
    {"Acme OEM",         {0x01, 0x23, ...}, ACCESS_FULL},  // Gleicher Schlüssel!
};
// Alle Parteien teilen dieselben Anmeldedaten
// Leck von jeder Partei kompromittiert alle

Sichere Lösung

// SICHER: Geratespezifische Entsperrungs-Anmeldedaten

module secure_device_unlock (
    input wire clk,
    input wire reset_n,
    input wire [127:0] unlock_credential,
    input wire [127:0] challenge,
    input wire unlock_request,
    input wire [63:0] device_id,
    output reg device_unlocked,
    output reg debug_enabled,
    output reg unlock_failed
);

    // SICHER: Geratespezifischer Schlüssel abgeleitet aus Master + Gerate-ID
    // Master-Schlüssel in HSM gespeichert, nie direkt geteilt

    wire [127:0] device_specific_key;
    reg [127:0] expected_response;

    // Schlüsselableitung (vereinfacht - in der Praxis ordnungsgemäße KDF verwenden)
    // In realer Implementierung: HKDF(master_key, device_id)
    key_derivation_unit kdf (
        .device_id(device_id),
        .derived_key(device_specific_key)
    );

    // Challenge-Response-Authentifizierung
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            device_unlocked <= 1'b0;
            debug_enabled <= 1'b0;
            unlock_failed <= 1'b0;
        end
        else if (unlock_request) begin
            // SICHER: Challenge-Response mit geratespezifischem Schlüssel verifizieren
            expected_response <= compute_hmac(device_specific_key, challenge);

            if (unlock_credential == expected_response) begin
                device_unlocked <= 1'b1;
                debug_enabled <= 1'b1;
                unlock_failed <= 1'b0;
            end
            else begin
                unlock_failed <= 1'b1;
            end
        end
    end

endmodule

// SICHER: Gestufte Entsperrung mit verschiedenen Zugriffsebenen
module secure_tiered_unlock (
    input wire clk,
    input wire reset_n,
    input wire [127:0] credential,
    input wire [1:0] requested_level,
    input wire unlock_request,
    output reg [1:0] current_access_level,
    output reg unlock_granted
);

    // SICHER: Verschiedene Anmeldedaten für verschiedene Zugriffsebenen
    // Jede Ebene hat eindeutige, nicht geteilte Anmeldedaten

    parameter LEVEL_NONE = 2'b00;
    parameter LEVEL_BASIC = 2'b01;      // Grunddiagnose
    parameter LEVEL_ADVANCED = 2'b10;   // Erweitertes Debug
    parameter LEVEL_FULL = 2'b11;       // Volle Entsperrung (eingeschrankt)

    // Geratespezifische Anmeldedaten in OTP gespeichert
    reg [127:0] basic_credential;       // Aus Fuse
    reg [127:0] advanced_credential;    // Aus Fuse
    reg [127:0] full_credential;        // Aus sicherer Fuse

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            current_access_level <= LEVEL_NONE;
            unlock_granted <= 1'b0;
        end
        else if (unlock_request) begin
            unlock_granted <= 1'b0;

            case (requested_level)
                LEVEL_BASIC: begin
                    // SICHER: Grundebene - begrenzte Offenlegung
                    if (credential == basic_credential) begin
                        current_access_level <= LEVEL_BASIC;
                        unlock_granted <= 1'b1;
                    end
                end

                LEVEL_ADVANCED: begin
                    // SICHER: Erweiterte Ebene - eingeschranktere Weitergabe
                    if (credential == advanced_credential) begin
                        current_access_level <= LEVEL_ADVANCED;
                        unlock_granted <= 1'b1;
                    end
                end

                LEVEL_FULL: begin
                    // SICHER: Volle Ebene - nie extern geteilt
                    if (credential == full_credential) begin
                        current_access_level <= LEVEL_FULL;
                        unlock_granted <= 1'b1;
                    end
                end
            endcase
        end
    end

endmodule

// SICHER: Einmal-Entsperrungstoken
module secure_one_time_unlock (
    input wire clk,
    input wire reset_n,
    input wire [255:0] unlock_token,
    input wire unlock_request,
    output reg device_unlocked,
    output reg token_consumed
);

    // SICHER: Einmal-Token - können nicht wiederverwendet werden
    reg [255:0] token_hash_storage [0:15];
    reg [3:0] token_index;
    reg token_valid;

    // Prüfen ob Token mit ungenutztem Token übereinstimmt
    integer i;
    always @(*) begin
        token_valid = 1'b0;
        for (i = 0; i < 16; i = i + 1) begin
            if (token_hash_storage[i] == sha256(unlock_token) &&
                token_hash_storage[i] != 256'h0) begin
                token_valid = 1'b1;
                token_index = i;
            end
        end
    end

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            device_unlocked <= 1'b0;
            token_consumed <= 1'b0;
        end
        else if (unlock_request && token_valid) begin
            // SICHER: Token nach Verwendung verbrauchen
            token_hash_storage[token_index] <= 256'h0;
            device_unlocked <= 1'b1;
            token_consumed <= 1'b1;
        end
    end

endmodule
// SICHER: Software mit sicherer Verwaltung von Anmeldedaten

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

// SICHER: Keine fest einprogrammierten Anmeldedaten
// Alle Anmeldedaten aus geratespezifischen Geheimnissen abgeleitet

typedef struct {
    uint8_t device_id[16];
    uint8_t derived_key[32];
} device_credentials_t;

// SICHER: Geratespezifische Anmeldedaten aus Master + Gerate-ID ableiten
static bool derive_device_credential(const uint8_t* device_id,
                                     uint8_t* credential_out) {
    // In der Praxis: HSM leitet Schlüssel ab, Gerat speichert nur abgeleiteten Wert
    // Schlüsselableitung: HKDF(master_key, device_id || "unlock")

    uint8_t context[32];
    memcpy(context, device_id, 16);
    memcpy(context + 16, "unlock_context", 16);

    // Aus geratespezifischem Root-Schlüssel ableiten
    return hkdf_derive(get_device_root_key(), context, 32, credential_out);
}

// SICHER: Challenge-Response-Authentifizierung
typedef struct {
    uint8_t challenge[32];
    uint8_t response[32];
    uint32_t timestamp;
    uint32_t nonce;
} unlock_request_t;

bool secure_verify_unlock(const unlock_request_t* request) {
    uint8_t device_credential[32];
    uint8_t expected_response[32];

    // Geratespezifische Anmeldedaten abrufen
    if (!derive_device_credential(get_device_id(), device_credential)) {
        return false;
    }

    // SICHER: Zeitstempel ist aktuell verifizieren (Replay verhindern)
    if (!verify_timestamp(request->timestamp)) {
        log_security_event("Entsperrungs-Zeitstempel ungültig");
        return false;
    }

    // SICHER: Nonce wurde nicht verwendet verifizieren (Replay verhindern)
    if (is_nonce_used(request->nonce)) {
        log_security_event("Entsperrungs-Nonce-Replay erkannt");
        return false;
    }

    // Erwartete Antwort berechnen
    compute_hmac_sha256(device_credential, request->challenge, 32,
                        expected_response);

    // SICHER: Zeitkonstanter Vergleich
    if (!secure_compare(request->response, expected_response, 32)) {
        log_security_event("Entsperrungs-Anmeldedaten stimmen nicht überein");
        return false;
    }

    // Nonce als verwendet markieren
    mark_nonce_used(request->nonce);

    return true;
}

// SICHER: Gestufte Zugriffsebenen mit separaten Anmeldedaten
typedef enum {
    ACCESS_NONE = 0,
    ACCESS_BASIC = 1,      // Grunddiagnose - mit Außendienst geteilt
    ACCESS_ADVANCED = 2,   // Erweitertes Debug - begrenzte Weitergabe
    ACCESS_FULL = 3        // Voller Zugang - nie extern geteilt
} access_level_t;

typedef struct {
    access_level_t level;
    uint8_t credential[32];
    uint32_t permissions;
} access_tier_t;

static access_tier_t access_tiers[4];

void secure_unlock_device(access_level_t level, const uint8_t* credential) {
    // SICHER: Anmeldedaten nur für bestimmte Ebene verifizieren
    uint8_t expected[32];
    derive_level_credential(level, expected);

    if (!secure_compare(credential, expected, 32)) {
        log_security_event("Ungültige Anmeldedaten für Ebene %d", level);
        increment_failure_counter();
        return;
    }

    // SICHER: Nur Berechtigungen für diese Ebene gewahren
    switch (level) {
        case ACCESS_BASIC:
            // Begrenzter Zugang für Außendienst
            enable_basic_diagnostics();
            break;

        case ACCESS_ADVANCED:
            // Mehr Zugang für autorisierte Techniker
            enable_advanced_debug();
            break;

        case ACCESS_FULL:
            // Voller Zugang - nur interne Verwendung
            enable_jtag();
            enable_memory_dump();
            break;

        default:
            break;
    }
}

// SICHER: Nutzung von Anmeldedaten protokollieren
void log_credential_usage(access_level_t level, const char* requester) {
    audit_entry_t entry = {
        .timestamp = get_secure_time(),
        .access_level = level,
        .device_id = get_device_id(),
        .requester_hash = hash_string(requester),
        .success = true
    };

    write_audit_log(&entry);
}

CVE-Beispiele

Schwachstellen bei der Weitergabe von Anmeldedaten wurden in verschiedenen Lieferkettenszenarien gefunden, in denen über mehrere Parteien geteilte Entsperrungs-Anmeldedaten durchgesickert sind, was unbefugten Zugriff auf Debug-Schnittstellen für gesamte Produktlinien ermöglichte.


Verwandte CWEs

  • CWE-200: Offenlegung sensibler Informationen an unbefugten Akteur (ubergeordnet)
  • CWE-1195: Fertigungs- und Lebenszyklus-Management-Bedenken (Kategorie)
  • CWE-798: Verwendung fest einprogrammierter Anmeldedaten (verwandt)
  • CAPEC-560: Verwendung bekannter Domanen-Anmeldedaten (Angriffsmuster)

Referenzen

  1. MITRE Corporation. "CWE-1273: Device Unlock Credential Sharing." https://cwe.mitre.org/data/definitions/1273.html
  2. NIST. "Supply Chain Risk Management Practices"
  3. GlobalPlatform. "Device Trust Architecture"