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
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Umfang: Vertraulichkeit Speicher lesen - Kompromittierte Anmeldedaten ermöglichen unbefugten Speicherzugriff. |
| Integritat | Umfang: Integritat Dateien ändern - Angreifer können Geratekonfiguration und Firmware ändern. |
| Zugriffskontrolle | Umfang: Zugriffskontrolle Schutzmechanismus umgehen - Debug-Zugriff umgeht Sicherheitskontrollen. |
| Autorisierung | Umfang: 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
- MITRE Corporation. "CWE-1273: Device Unlock Credential Sharing." https://cwe.mitre.org/data/definitions/1273.html
- NIST. "Supply Chain Risk Management Practices"
- GlobalPlatform. "Device Trust Architecture"