Erzeugung fehlerhafter Sicherheitstoken

Beschreibung

Erzeugung fehlerhafter Sicherheitstoken tritt auf, wenn ein System Sicherheitstoken implementiert, um erlaubte und nicht erlaubte Aktionen zu unterscheiden, diese Token jedoch fehlerhaft erzeugt. In System-on-Chip (SoC)-Designs unterscheiden und identifizieren Sicherheitstoken Aktionen verschiedener Agenten, die Aktionen wie "Lesen", "Schreiben", "Programmieren", "Zurücksetzen", "Abrufen" und "Berechnen" reprasentieren. Jeder Agent erhält ein eindeutiges Token basierend auf Vertrauensstufe oder Berechtigungen. Wenn Token fehlerhaft erzeugt werden, kann dasselbe Token verschiedenen Agenten zugewiesen oder verschiedene Token demselben Agenten zugewiesen werden, was das Sicherheitsmodell bricht.

Risiko

Fehlerhafte Sicherheitstoken-Erzeugung hat schwerwiegende Sicherheitsauswirkungen. Berechtigungserweiterung wird möglich. Unbefugter Zugriff kann gewahrt werden. Denial of Service kann auftreten. Mehrere Agenten können identische Token erhalten. Vertrauenswurdige und nicht vertrauenswurdige Agenten können verwechselt werden. Zugriffskontrolle wird vollständig umgangen. Geschutzte Ressourcen werden freigelegt. Die gesamte Sicherheitsarchitektur kann kompromittiert werden.

Lösung

Uberprüfen Sie die Token-Erzeugungslogik auf Design-Inkonsistenzen und häufige Schwachstellen während Sicherheitsreviews. Testen Sie Sicherheitstoken-Definitionen in Pre-Silicon- und Post-Silicon-Testphasen. Implementieren Sie Verifizierung der eindeutigen Token-Zuweisung. Stellen Sie sicher, dass die Token-Erzeugung deterministisch und reproduzierbar ist. Dokumentieren Sie alle Token-Zuweisungen und validieren Sie die Konsistenz. Verwenden Sie formale Verifikation für die Token-Erzeugungslogik.

Häufige Auswirkungen

AuswirkungDetails
ZugriffskontrolleUmfang: Zugriffskontrolle

Schutzmechanismus umgehen - Fehlerhafte Token erlauben unbefugte Aktionen.
VertraulichkeitUmfang: Vertraulichkeit

Speicher lesen - Unbefugte Agenten können Lesezugriff erlangen.
IntegritatUmfang: Integritat

Speicher modifizieren - Unbefugte Agenten können Schreibzugriff erlangen.
VerfügbarkeitUmfang: Verfügbarkeit

DoS - Konfligierende Token können Systemausfalle verursachen.

Beispielcode und Lösung

Verwundbarer Code

// VERWUNDBAR: Token-Erzeugung mit Konflikt

module vulnerable_token_generator (
    input wire clk,
    input wire reset_n,
    input wire [3:0] agent_id,
    input wire request_token,
    output reg [7:0] security_token,
    output reg token_valid
);

    // VERWUNDBAR: Fehlerhafte Token-Erzeugungslogik
    // Mehrere Agenten können dasselbe Token erhalten

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            security_token <= 8'h00;
            token_valid <= 1'b0;
        end
        else if (request_token) begin
            // VERWUNDBAR: Token basiert nur auf unteren 2 Bits der agent_id
            // Agenten 0, 4, 8, 12 erhalten alle dasselbe Token
            // Agenten 1, 5, 9, 13 erhalten alle dasselbe Token
            // usw.

            case (agent_id[1:0])
                2'b00: security_token <= 8'h01;  // Token 1
                2'b01: security_token <= 8'h02;  // Token 2
                2'b10: security_token <= 8'h03;  // Token 3
                2'b11: security_token <= 8'h04;  // Token 4
            endcase

            token_valid <= 1'b1;

            // Problem: Agent 0 (vertrauenswurdige CPU) erhält Token 1
            // Agent 4 (nicht vertrauenswurdiger DMA) erhält ebenfalls Token 1
            // Beide können auf dieselben geschützten Ressourcen zugreifen!
        end
    end

endmodule

// VERWUNDBAR: AES-Schlüsselzugriff mit Token-Kollision
module vulnerable_aes_access (
    input wire clk,
    input wire reset_n,
    input wire [7:0] token,
    input wire [7:0] reg_addr,
    input wire read_request,
    output reg [31:0] read_data,
    output reg access_granted
);

    reg [127:0] aes_key;

    // Token-Zuweisungen (verwundbar):
    // Token 1 = Krypto-Controller (vertrauenswürdig) - sollte auf Schlüssel zugreifen
    // Token 1 = DMA-Controller (nicht vertrauenswürdig) - gleiches Token!

    parameter TRUSTED_CRYPTO = 8'h01;
    // VERWUNDBAR: Beide Agenten haben Token 0x01

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            access_granted <= 1'b0;
        end
        else if (read_request) begin
            if (reg_addr == 8'h00) begin  // AES-Schlüsselregister
                // VERWUNDBAR: Nur gegen Token-Wert prüfen
                if (token == TRUSTED_CRYPTO) begin
                    // Sowohl vertrauenswürdiger als auch nicht vertrauenswürdiger erhält Zugriff!
                    read_data <= aes_key[31:0];
                    access_granted <= 1'b1;
                end
                else begin
                    access_granted <= 1'b0;
                end
            end
        end
    end

endmodule
// VERWUNDBAR: Software-Token-Zuweisung mit Kollision

#include <stdint.h>

#define MAX_AGENTS 16

typedef struct {
    uint8_t agent_id;
    uint8_t security_token;
    const char* name;
} agent_info_t;

// VERWUNDBAR: Token-Zuweisungsfunktion
uint8_t vulnerable_generate_token(uint8_t agent_id) {
    // VERWUNDBAR: Verwendet nur untere 3 Bits
    // Agenten 0 und 8 erhalten dasselbe Token
    return (agent_id & 0x07) + 1;
}

// VERWUNDBAR: Token-Tabelle mit Kollisionen
agent_info_t vulnerable_agent_table[] = {
    {0, 1, "Secure CPU"},        // Token 1
    {1, 2, "Crypto Engine"},     // Token 2
    {2, 3, "Boot ROM"},          // Token 3
    {3, 4, "User App"},          // Token 4
    // ... später hinzugefugt
    {8, 1, "DMA Controller"},    // VERWUNDBAR: Gleiches Token wie Secure CPU!
    {9, 2, "Debug Agent"},       // VERWUNDBAR: Gleiches Token wie Crypto Engine!
};

bool vulnerable_check_access(uint8_t token, uint32_t resource) {
    // Prüft nur Token-Wert, nicht Agenten-Identitat
    if (resource == RESOURCE_AES_KEY) {
        return (token == 1 || token == 2);  // Token 1 und 2 erlaubt
    }
    return false;

    // Problem: DMA (Token 1) und Debug (Token 2) können auf AES-Schlüssel zugreifen!
}

Sichere Lösung

// SICHER: Eindeutige Token-Erzeugung

module secure_token_generator (
    input wire clk,
    input wire reset_n,
    input wire [3:0] agent_id,
    input wire request_token,
    output reg [7:0] security_token,
    output reg token_valid,
    output reg token_conflict
);

    // Token-Zuweisungstabelle (verifiziert eindeutig)
    reg [7:0] token_table [0:15];

    // Zugewiesene Token verfolgen
    reg [255:0] token_assigned;

    // Eindeutige Token initialisieren
    initial begin
        // Jeder Agent erhält eindeutiges Token
        token_table[0]  = 8'h01;  // Secure CPU
        token_table[1]  = 8'h02;  // Crypto Engine
        token_table[2]  = 8'h03;  // Boot ROM
        token_table[3]  = 8'h04;  // Benutzeranwendung
        token_table[4]  = 8'h10;  // DMA Controller (anders!)
        token_table[5]  = 8'h20;  // Debug Agent (anders!)
        token_table[6]  = 8'h30;  // Test-Schnittstelle
        token_table[7]  = 8'h40;  // Externer Host
        token_table[8]  = 8'h50;  // GPU
        token_table[9]  = 8'h60;  // DSP
        token_table[10] = 8'h70;  // Netzwerk-Controller
        token_table[11] = 8'h80;  // Speicher-Controller
        token_table[12] = 8'h90;  // USB-Controller
        token_table[13] = 8'hA0;  // Audio-Controller
        token_table[14] = 8'hB0;  // Video-Controller
        token_table[15] = 8'hC0;  // Reserviert

        token_assigned = 256'h0;
    end

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            security_token <= 8'h00;
            token_valid <= 1'b0;
            token_conflict <= 1'b0;
        end
        else if (request_token) begin
            token_conflict <= 1'b0;

            // SICHER: Vollständige agent_id für Lookup verwenden
            security_token <= token_table[agent_id];

            // SICHER: Keine Token-Kollision verifizieren
            if (token_assigned[token_table[agent_id]]) begin
                // Token bereits einem anderen Agenten zugewiesen!
                token_conflict <= 1'b1;
                token_valid <= 1'b0;
            end
            else begin
                token_assigned[token_table[agent_id]] <= 1'b1;
                token_valid <= 1'b1;
            end
        end
    end

endmodule

// SICHER: AES-Zugriff mit verifizierten Token
module secure_aes_access (
    input wire clk,
    input wire reset_n,
    input wire [3:0] agent_id,
    input wire [7:0] token,
    input wire [7:0] reg_addr,
    input wire read_request,
    output reg [31:0] read_data,
    output reg access_granted,
    output reg token_mismatch
);

    reg [127:0] aes_key;

    // Erwartete Token-Tabelle
    reg [7:0] expected_token [0:15];

    // Zugriffsrichtlinie für AES-Schlüssel
    reg [15:0] aes_access_policy;

    initial begin
        // Erwartete Token setzen (müssen mit Token-Generator übereinstimmen)
        expected_token[0]  = 8'h01;  // Secure CPU
        expected_token[1]  = 8'h02;  // Crypto Engine
        expected_token[4]  = 8'h10;  // DMA-Controller
        expected_token[5]  = 8'h20;  // Debug-Agent

        // Nur Agenten 0 und 1 können auf AES-Schlüssel zugreifen
        aes_access_policy = 16'b0000_0000_0000_0011;
    end

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            access_granted <= 1'b0;
            token_mismatch <= 1'b0;
        end
        else if (read_request) begin
            token_mismatch <= 1'b0;
            access_granted <= 1'b0;

            // SICHER: Verifizieren dass Token für Agenten erwartet wird
            if (token != expected_token[agent_id]) begin
                // Token stimmt nicht mit Agent überein - mögliches Spoofing
                token_mismatch <= 1'b1;
            end
            else if (reg_addr == 8'h00) begin  // AES-Schlüsselregister
                // SICHER: Agentenberechtigung prüfen, nicht nur Token
                if (aes_access_policy[agent_id]) begin
                    read_data <= aes_key[31:0];
                    access_granted <= 1'b1;
                end
            end
        end
    end

endmodule

// SICHER: Token-Verifizierungsmodul
module token_verification (
    input wire clk,
    input wire reset_n,
    input wire verify_enable,
    output reg verification_passed,
    output reg [3:0] conflict_agent_a,
    output reg [3:0] conflict_agent_b
);

    reg [7:0] token_table [0:15];
    integer i, j;
    reg conflict_found;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            verification_passed <= 1'b0;
            conflict_found <= 1'b0;
        end
        else if (verify_enable) begin
            conflict_found <= 1'b0;

            // SICHER: Alle Token-Paare auf Eindeutigkeit prüfen
            for (i = 0; i < 15; i = i + 1) begin
                for (j = i + 1; j < 16; j = j + 1) begin
                    if (token_table[i] == token_table[j]) begin
                        conflict_found <= 1'b1;
                        conflict_agent_a <= i[3:0];
                        conflict_agent_b <= j[3:0];
                    end
                end
            end

            verification_passed <= !conflict_found;
        end
    end

endmodule
// SICHER: Software-Token-Erzeugung mit Eindeutigkeitsverifizierung

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

#define MAX_AGENTS 16
#define INVALID_TOKEN 0x00

// SICHER: Verifizierte eindeutige Token-Tabelle
static const secure_agent_info_t secure_agent_table[] = {
    {0,  0x01, "Secure CPU",       true},
    {1,  0x02, "Crypto Engine",    true},
    {2,  0x03, "Boot ROM",         true},
    {3,  0x04, "Benutzeranwendung", false},
    {4,  0x10, "DMA Controller",   false},  // SICHER: Eindeutiges Token
    {5,  0x20, "Debug Agent",      false},  // SICHER: Eindeutiges Token
    {6,  0x30, "Test-Schnittstelle", false},
    {7,  0x40, "Externer Host",    false},
    {8,  0x50, "GPU",              false},  // SICHER: Eindeutiges Token
    {9,  0x60, "DSP",              false},  // SICHER: Eindeutiges Token
    {10, 0x70, "Netzwerk",         false},
    {11, 0x80, "Speicher",         false},
    {12, 0x90, "USB",              false},
    {13, 0xA0, "Audio",            false},
    {14, 0xB0, "Video",            false},
    {15, 0xC0, "Reserviert",       false},
};

// SICHER: Token-Eindeutigkeit beim Start verifizieren
bool verify_token_uniqueness(void) {
    uint8_t token_count[256] = {0};

    for (int i = 0; i < MAX_AGENTS; i++) {
        uint8_t token = secure_agent_table[i].security_token;

        if (token == INVALID_TOKEN) {
            log_error("Agent %d hat ungültiges Token", i);
            return false;
        }

        if (token_count[token] > 0) {
            log_error("Token-Kollision: Token 0x%02X mehrfach zugewiesen", token);
            return false;
        }

        token_count[token]++;
    }

    log_info("Token-Eindeutigkeit für alle %d Agenten verifiziert", MAX_AGENTS);
    return true;
}

// SICHER: Token für Agenten mit Validierung abrufen
uint8_t secure_get_token(uint8_t agent_id) {
    if (agent_id >= MAX_AGENTS) {
        return INVALID_TOKEN;
    }

    return secure_agent_table[agent_id].security_token;
}

// SICHER: Verifizieren dass Token zum beanspruchten Agenten gehört
bool verify_token_ownership(uint8_t agent_id, uint8_t presented_token) {
    if (agent_id >= MAX_AGENTS) {
        return false;
    }

    return (secure_agent_table[agent_id].security_token == presented_token);
}

// SICHER: Zugriffsprüfung mit Agenten- und Token-Verifizierung
bool secure_check_access(uint8_t agent_id, uint8_t token, uint32_t resource) {
    // Token-Zugehörigkeit zum Agenten verifizieren
    if (!verify_token_ownership(agent_id, token)) {
        log_security_event("Token-Nichtübereinstimmung für Agent %d", agent_id);
        return false;
    }

    // Ressourcenzugriff basierend auf Agenten-Identitat prüfen (nicht nur Token)
    if (resource == RESOURCE_AES_KEY) {
        // Nur vertrauenswurdige Agenten können auf AES-Schlüssel zugreifen
        return secure_agent_table[agent_id].is_trusted;
    }

    return false;
}

CVE-Beispiele

Schwachstellen bei der Token-Erzeugung wurden in verschiedenen SoC-Designs gefunden, bei denen mehreren Agenten falschlicherweise dasselbe Sicherheitstoken zugewiesen wurde, wodurch nicht vertrauenswurdige Komponenten auf geschützte Ressourcen zugreifen könnten.


Verwandte CWEs

  • CWE-284: Unzureichende Zugriffskontrolle (ubergeordnet)
  • CWE-1294: Unsicherer Sicherheitsidentifikator-Mechanismus (ubergeordnet)
  • CWE-1259: Unsachgemäße Einschränkung der Sicherheitstoken-Zuweisung (verwandt)
  • CAPEC-121: Nicht-Produktionsschnittstellen ausnutzen (Angriffsmuster)
  • CAPEC-633: Token-Imitation (Angriffsmuster)
  • CAPEC-681: Ausnutzung fehlerhaft kontrollierter Hardware-Sicherheitsidentifikatoren (Angriffsmuster)

Referenzen

  1. MITRE Corporation. "CWE-1270: Generation of Incorrect Security Tokens." https://cwe.mitre.org/data/definitions/1270.html
  2. ARM. "AMBA AXI Security Extensions"
  3. RISC-V. "World-Guard Security Specification"