System-on-Chip (SoC) mit Komponenten ohne eindeutige Identifikation und Authentifizierung
Beschreibung
System-on-Chip (SoC) mit Komponenten ohne eindeutige Identifikation und Authentifizierung tritt auf, wenn ein SoC Komponenten ohne eindeutige Kennungen oder ohne Authentifizierungsfähigkeiten enthält. Wenn Komponenten nicht eindeutig identifiziert werden, können Angreifer sie fälschen. Wenn der Zugriff auf begrenzte oder sensible Ressourcen erfolgt, müssen Transaktionen authentifiziert werden, um Spoofing zu verhindern. Ohne ordnungsgemäße Identifikation und Authentifizierung können nicht vertrauenswürdige Agenten vertrauenswürdige Komponenten imitieren.
Risiko
Fehlende Komponentenidentifikation schafft schwerwiegende Sicherheitsauswirkungen. Nicht vertrauenswürdige Agenten können vertrauenswürdige Agenten imitieren. Zugriffskontrolle kann umgangen werden. Sensible Ressourcen können kompromittiert werden. Transaktionsursprung kann nicht verifiziert werden. Denial-of-Service-Angriffe werden möglich. Privilegieneskalation kann auftreten. Böswillige Komponenten können als vertrauenswürdig erscheinen.
Lösung
Implementieren Sie eine eindeutige Identifizierung für jede SoC-Komponente. Erfordern Sie Authentifizierung für den Zugriff auf sensible Ressourcen. Implementieren Sie kryptografische Transaktionsauthentifizierung. Verwenden Sie sichere Identitätszuweisung, die nicht modifiziert werden kann. Implementieren Sie Transaktionssignaturen. Überprüfen Sie die Komponentenidentität an Ressourcenschnittstellen. Verhindern Sie ID-Spoofing durch Hardware-Durchsetzung.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Autorisierung | Bereich: Autorisierung Identität annehmen - Angreifer können sich als vertrauenswürdige Komponenten ausgeben. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle Schutzmechanismus umgehen - Authentifizierungskontrollen können umgangen werden. |
| Integrität | Bereich: Integrität Speicher modifizieren - Unautorisierte Speichermodifikation durch gefälschte Transaktionen. |
Beispielcode und Lösung
Verwundbarer Code
// Verwundbar: SoC-Interconnect ohne Komponentenidentifikation
module vulnerable_soc_interconnect (
input wire clk,
input wire reset_n,
// Master-Schnittstellen - keine Identifikation
input wire [31:0] master0_addr,
input wire [31:0] master0_data,
input wire master0_valid,
input wire [31:0] master1_addr,
input wire [31:0] master1_data,
input wire master1_valid,
// Slave-Schnittstellen
output reg [31:0] slave_addr,
output reg [31:0] slave_data,
output reg slave_valid
);
// VERWUNDBAR: Keine Möglichkeit zu identifizieren, welcher Master die Transaktion initiiert hat
// Alle Master erscheinen den Slaves identisch
// Keine Zugriffskontrolle basierend auf Quelle möglich
always @(posedge clk) begin
if (master0_valid) begin
// Master 0 könnte nicht vertrauenswürdig sein, aber wir können es nicht erkennen
slave_addr <= master0_addr;
slave_data <= master0_data;
slave_valid <= 1'b1;
end
else if (master1_valid) begin
// Master 1 könnte andere Vertrauensstufe haben
// Aber kein Identifikator zur Unterscheidung
slave_addr <= master1_addr;
slave_data <= master1_data;
slave_valid <= 1'b1;
end
end
endmodule
// Verwundbar: Sicherheitscontroller ohne Quellidentifikation
module vulnerable_security_controller (
input wire clk,
input wire [31:0] request_addr,
input wire [31:0] request_data,
input wire request_valid,
// Kein Quell-ID-Eingang!
output reg access_granted
);
// Sicherer Speicherbereich
parameter SECURE_START = 32'h8000_0000;
parameter SECURE_END = 32'h8FFF_FFFF;
always @(posedge clk) begin
if (request_valid) begin
// VERWUNDBAR: Kann nicht feststellen ob Anforderer autorisiert ist
// Muss Zugriff für alle oder niemanden gewähren
if (request_addr >= SECURE_START && request_addr <= SECURE_END) begin
// Sollte Quell-ID prüfen, aber es gibt keine
access_granted <= 1'b1; // Gezwungen, allen zu erlauben!
end else begin
access_granted <= 1'b1;
end
end
end
endmodule
// Verwundbar: IP-Block mit fälschbarem Software-Identifikator
module vulnerable_ip_block (
input wire clk,
input wire [7:0] configured_id, // Software-konfigurierbar - kann gefälscht werden!
output reg [7:0] transaction_source_id
);
// VERWUNDBAR: ID kann durch Software geändert werden
// Bösartige Software kann andere Komponenten imitieren
always @(posedge clk) begin
transaction_source_id <= configured_id;
end
endmodule
// Verwundbar: SoC-Firmware ohne Komponentenidentifikation
// Keine Komponenten-ID in Transaktionsstruktur
struct transaction {
uint32_t address;
uint32_t data;
uint8_t read_write;
// Fehlt: source_id, dest_id
};
// Kann keine Zugriffskontrolle ohne IDs durchsetzen
bool check_access(struct transaction* tx) {
// VERWUNDBAR: Keine Möglichkeit zu wissen, wer die Anfrage stellt
// Muss für alle gleich erlauben oder verweigern
if (is_secure_region(tx->address)) {
// Sollte prüfen: ist Anforderer autorisiert?
// Aber wir wissen nicht, wer der Anforderer ist!
return true; // Gezwungen zu erlauben
}
return true;
}
// Routing ohne Quellidentifikation
void route_transaction(struct transaction* tx) {
// VERWUNDBAR: Kein Audit-Trail wer was gesendet hat
// Keine Möglichkeit, komponentenspezifische Richtlinien zu implementieren
uint32_t dest = get_destination(tx->address);
send_to_slave(dest, tx);
// Kann nicht protokollieren: "Komponente X hat auf Adresse Y zugegriffen"
// Kann nur protokollieren: "Jemand hat auf Adresse Y zugegriffen"
}
Sichere Lösung
// Sicher: SoC-Interconnect mit Hardware-Komponentenidentifikatoren
module secure_soc_interconnect (
input wire clk,
input wire reset_n,
// Master-Schnittstellen MIT Hardware-IDs
input wire [31:0] master0_addr,
input wire [31:0] master0_data,
input wire master0_valid,
input wire [7:0] master0_hw_id, // Festverdrahtet, unveränderlich
input wire [31:0] master1_addr,
input wire [31:0] master1_data,
input wire master1_valid,
input wire [7:0] master1_hw_id, // Festverdrahtet, unveränderlich
// Slave-Schnittstellen mit Quellverfolgung
output reg [31:0] slave_addr,
output reg [31:0] slave_data,
output reg [7:0] slave_source_id, // Identifiziert Anforderer
output reg slave_valid
);
// Komponenten-ID-Definitionen (zur Entwurfszeit festverdrahtet)
parameter CPU_SECURE_ID = 8'h01;
parameter CPU_NONSECURE_ID = 8'h02;
parameter DMA_ID = 8'h03;
parameter GPU_ID = 8'h04;
// Zugriffskontrollmatrix
wire master0_access_granted;
wire master1_access_granted;
access_control_checker checker0 (
.source_id(master0_hw_id),
.dest_addr(master0_addr),
.access_granted(master0_access_granted)
);
access_control_checker checker1 (
.source_id(master1_hw_id),
.dest_addr(master1_addr),
.access_granted(master1_access_granted)
);
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
slave_valid <= 1'b0;
end
else if (master0_valid && master0_access_granted) begin
slave_addr <= master0_addr;
slave_data <= master0_data;
slave_source_id <= master0_hw_id; // Quelle verfolgen
slave_valid <= 1'b1;
end
else if (master1_valid && master1_access_granted) begin
slave_addr <= master1_addr;
slave_data <= master1_data;
slave_source_id <= master1_hw_id; // Quelle verfolgen
slave_valid <= 1'b1;
end
else begin
slave_valid <= 1'b0;
end
end
endmodule
// Sicher: Sicherheitscontroller mit Quellidentifikation
module secure_security_controller (
input wire clk,
input wire reset_n,
input wire [31:0] request_addr,
input wire [31:0] request_data,
input wire [7:0] source_id, // Hardware-Komponenten-ID
input wire request_valid,
output reg access_granted,
output reg security_violation
);
// Sicherheitsbereiche und Richtlinien
parameter SECURE_START = 32'h8000_0000;
parameter SECURE_END = 32'h8FFF_FFFF;
// Vertrauenswürdige Komponenten-IDs (festverdrahtet)
parameter CPU_SECURE_ID = 8'h01;
parameter CRYPTO_ENGINE_ID = 8'h05;
// Prüfen ob Quelle für sicheren Bereich autorisiert ist
function is_trusted_source;
input [7:0] id;
begin
is_trusted_source = (id == CPU_SECURE_ID) ||
(id == CRYPTO_ENGINE_ID);
end
endfunction
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
access_granted <= 1'b0;
security_violation <= 1'b0;
end
else if (request_valid) begin
if (request_addr >= SECURE_START && request_addr <= SECURE_END) begin
// Sicherer Bereich - Quell-ID prüfen
if (is_trusted_source(source_id)) begin
access_granted <= 1'b1;
security_violation <= 1'b0;
end else begin
access_granted <= 1'b0;
security_violation <= 1'b1; // Verletzung protokollieren
end
end else begin
// Nicht-sicherer Bereich - erlauben
access_granted <= 1'b1;
security_violation <= 1'b0;
end
end
end
endmodule
// Sicher: IP-Block mit unveränderlichem Hardware-Identifikator
module secure_ip_block #(
parameter [7:0] HARDWARE_ID = 8'h00 // Zur Synthesezeit festgelegt
) (
input wire clk,
output wire [7:0] transaction_source_id
);
// ID ist festverdrahtet - kann nicht durch Software geändert werden
assign transaction_source_id = HARDWARE_ID;
// Jeden Änderungsversuch verhindern
// Die ID ist ein Parameter, kein Register
endmodule
// Sicher: System-Instanziierung mit eindeutigen IDs
module soc_top (
input wire clk,
input wire reset_n
);
// Jede Komponente hat eine eindeutige, festverdrahtete ID
secure_ip_block #(.HARDWARE_ID(8'h01)) cpu_secure (...);
secure_ip_block #(.HARDWARE_ID(8'h02)) cpu_nonsecure (...);
secure_ip_block #(.HARDWARE_ID(8'h03)) dma_controller (...);
secure_ip_block #(.HARDWARE_ID(8'h04)) gpu (...);
secure_ip_block #(.HARDWARE_ID(8'h05)) crypto_engine (...);
// IDs können nach der Synthese nicht dupliziert oder geändert werden
endmodule
// Sicher: SoC-Firmware mit Komponentenidentifikation
// Transaktionsstruktur mit Komponenten-IDs
struct secure_transaction {
uint32_t address;
uint32_t data;
uint8_t read_write;
uint8_t source_id; // Hardware-Komponenten-ID
uint8_t dest_id; // Zielkomponenten-ID
uint8_t security_level; // Transaktionssicherheitsstufe
};
// Komponenten-ID-Definitionen (entsprechen Hardware)
#define CPU_SECURE_ID 0x01
#define CPU_NONSECURE_ID 0x02
#define DMA_ID 0x03
#define GPU_ID 0x04
#define CRYPTO_ID 0x05
// Zugriffskontroll-Richtlinientabelle
struct access_policy {
uint8_t source_id;
uint32_t region_start;
uint32_t region_end;
bool read_allowed;
bool write_allowed;
};
static const struct access_policy policies[] = {
// Sichere CPU kann auf alles zugreifen
{CPU_SECURE_ID, 0x00000000, 0xFFFFFFFF, true, true},
// Nicht-sichere CPU kann nicht auf sicheren Bereich zugreifen
{CPU_NONSECURE_ID, 0x00000000, 0x7FFFFFFF, true, true},
{CPU_NONSECURE_ID, 0x80000000, 0x8FFFFFFF, false, false},
{CPU_NONSECURE_ID, 0x90000000, 0xFFFFFFFF, true, true},
// DMA hat eingeschränkten Zugriff
{DMA_ID, 0x00000000, 0x7FFFFFFF, true, true},
{DMA_ID, 0x80000000, 0xFFFFFFFF, false, false},
// Krypto-Engine kann auf sicheren Bereich zugreifen
{CRYPTO_ID, 0x80000000, 0x8FFFFFFF, true, true},
};
// Zugriff basierend auf Komponenten-ID prüfen
bool check_access(struct secure_transaction* tx) {
for (int i = 0; i < ARRAY_SIZE(policies); i++) {
if (policies[i].source_id == tx->source_id &&
tx->address >= policies[i].region_start &&
tx->address <= policies[i].region_end) {
if (tx->read_write == READ) {
return policies[i].read_allowed;
} else {
return policies[i].write_allowed;
}
}
}
// Standardmäßig verweigern
return false;
}
// Audit-Protokollierung mit Komponentenidentifikation
void log_transaction(struct secure_transaction* tx, bool granted) {
audit_log("Komponente 0x%02X %s Adresse 0x%08X: %s",
tx->source_id,
tx->read_write == READ ? "liest" : "schreibt",
tx->address,
granted ? "GEWÄHRT" : "VERWEIGERT");
}
Ausgenutzt in der Praxis
On-Chip-Bus-Spoofing-Angriffe auf Smartphones (2019)
Forscher demonstrierten, dass böswillige Peripheriegeräte auf Smartphone-SoCs vertrauenswürdige Komponenten imitieren könnten, um auf sensible Daten wie kryptografische Schlüssel und Biometrie zuzugreifen.
Tools zum Testen und Ausnutzen
-
ChipWhisperer — Hardware-Sicherheits-Testplattform.
-
Protokollanalysatoren für On-Chip-Busse (AMBA, AXI).
CVE-Beispiele
- CVE-2020-10713 — Boot-Komponenten-Authentifizierungsumgehung.
Referenzen
-
MITRE Corporation. "CWE-1192: System-on-Chip (SoC) Using Components without Unique, Immutable Identifiers." https://cwe.mitre.org/data/definitions/1192.html
-
ARM. "TrustZone Technology" - Komponentenisolation.
-
AMBA AXI-Protokoll - Transaktionssicherheit.