Richtlinie verwendet veraltete Kodierung

Beschreibung

Richtlinie verwendet veraltete Kodierung tritt auf, wenn ein Produkt Zugriffskontrollen mit einem Kodierungsmechanismus implementiert, der für aktuelle Sicherheitsanforderungen nicht mehr vertrauenswurdig oder angemessen ist. In System-on-a-Chip (SoC)-Designs enthalten Hardware-Transaktionen typischerweise Quellidentitat, Zielidentitat und Sicherheitstoken. Ein Richtlinien-Encoder ordnet diese Transaktionen Sicherheitstoken zu, die für die Zugriffskontrolle verwendet werden. Die Schwachstelle tritt auf, wenn ein veraltetes Kodierungsschema beibehalten wird, das Assets in aktualisierten Systemen, in denen neue, nicht vertrauenswurdige Agenten existieren können, nicht ordnungsgemäß schutzt.

Risiko

Veraltete Richtlinienkodierung hat schwerwiegende Sicherheitsauswirkungen. Neue Agenten können die Zugriffskontrolle umgehen. Schutzmechanismen können unwirksam sein. Speicher kann ohne Autorisierung modifiziert werden. Dateien können manipuliert werden. Denial of Service kann möglich sein. Unbefugter Code kann ausgeführt werden. Berechtigungserweiterung kann auftreten. Legacy-Kodierung wird zur Hintertur.

Lösung

Uberprüfen Sie Sicherheitstoken-Decoder auf Design-Inkonsistenzen. Testen Sie Zugriffsflüsse in Pre-Silicon- und Post-Silicon-Testphasen. Aktualisieren Sie Kodierungsschemata, wenn sich die Systemsicherheitsanforderungen ändern. Entfernen Sie die Unterstützung für veraltete Kodierungen. Implementieren Sie Versionsprüfung für Richtlinienkodierungen. Uberprüfen Sie alle Richtlinien-Decoder während Sicherheitsreviews.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitUmfang: Vertraulichkeit

Speicher lesen - Veraltete Kodierung kann unbefugten Datenzugriff ermöglichen.
IntegritatUmfang: Integritat

Speicher modifizieren - Veraltete Richtlinien können unbefugte Schreibvorgange erlauben.
ZugriffskontrolleUmfang: Zugriffskontrolle

Schutzmechanismus umgehen - Legacy-Kodierung kann ausgenutzt werden, um aktuelle Schutzmaßnahmen zu umgehen.

Beispielcode und Lösung

Verwundbarer Code

// VERWUNDBAR: Richtlinien-Decoder mit veralteter Kodierung

module vulnerable_policy_decoder (
    input wire clk,
    input wire reset_n,
    input wire [3:0] source_id,
    input wire [3:0] security_token,
    input wire [31:0] target_addr,
    input wire access_request,
    output reg access_granted
);

    // AES-Schlüsselspeicher-Adressbereich
    parameter AES_KEY_START = 32'h1000_0000;
    parameter AES_KEY_END = 32'h1000_00FF;

    // VERWUNDBAR: Alte "ungerades Token"-Richtlinie
    // Dies wurde entworfen als nur vertrauenswurdige Agenten ungerade Token hatten
    // Aber neue nicht vertrauenswurdige Agenten wurden mit ungeraden Token hinzugefugt

    wire is_aes_key_access = (target_addr >= AES_KEY_START) &&
                             (target_addr <= AES_KEY_END);

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            access_granted <= 1'b0;
        end
        else if (access_request) begin
            if (is_aes_key_access) begin
                // VERWUNDBAR: Ungerades Token = Zugriff gewahrt
                // Diese Kodierung ist veraltet und unsicher
                access_granted <= security_token[0];  // Prüfen ob ungerade

                // Ursprungliches Design hatte:
                // Token 1 (ungerade): Vertrauenswurdige Crypto-Engine
                // Token 3 (ungerade): Secure Boot
                //
                // Neues Design fugte hinzu:
                // Token 5 (ungerade): Nicht vertrauenswurdiger Debug-Agent
                // Token 7 (ungerade): Nicht vertrauenswurdiger Test-Agent
                //
                // Diese nicht vertrauenswurdigen Agenten haben jetzt AES-Schlüsselzugriff!
            end
            else begin
                access_granted <= 1'b1;  // Nicht-Schlüssel-Zugriff erlaubt
            end
        end
    end

endmodule

// VERWUNDBAR: Legacy-Richtlinie mit magischen Zahlen
module vulnerable_legacy_policy (
    input wire clk,
    input wire reset_n,
    input wire [7:0] agent_id,
    input wire [31:0] resource_addr,
    input wire read_request,
    input wire write_request,
    output reg access_allowed
);

    // VERWUNDBAR: Fest kodierte Agenten-IDs aus altem Design
    // Diese waren bei der Erstellung sicher, aber das System hat sich geändert

    parameter SECURE_AGENT = 8'h01;  // Ursprunglicher sicherer Agent
    parameter CRYPTO_AGENT = 8'h02;  // Ursprungliche Crypto-Engine
    // ... spätere Agenten ohne Aktualisierung dieser Liste hinzugefugt

    // Geschutzte Ressource
    parameter SECRET_STORAGE = 32'h2000_0000;

    always @(*) begin
        access_allowed = 1'b0;

        if (resource_addr == SECRET_STORAGE) begin
            // VERWUNDBAR: Prüft nur gegen alte Agenten-IDs
            // Neue sichere Agenten (0x10, 0x11) werden abgelehnt
            // Aber alter Test-Agent (0x01) hat noch Zugriff
            if (agent_id == SECURE_AGENT || agent_id == CRYPTO_AGENT) begin
                access_allowed = 1'b1;
            end
        end
        else begin
            access_allowed = 1'b1;
        end

        // Problem: SECURE_AGENT (0x01) ist jetzt dem nicht vertrauenswurdigen Debug zugewiesen
        // Ursprungliche sichere Funktionalitat auf Agent 0x10 verschoben
        // Richtlinie gewahrt 0x01 noch Zugriff!
    end

endmodule
// VERWUNDBAR: Software mit veralteter Berechtigungskodierung

#include <stdint.h>

#define PERMISSION_READ  0x01
#define PERMISSION_WRITE 0x02
#define PERMISSION_EXEC  0x04

// VERWUNDBAR: Alte Kodierung bei der hohes Bit "vertrauenswurdig" bedeutete
// Dies ist im aktuellen System nicht mehr zuverlässig

typedef struct {
    uint8_t agent_id;
    uint8_t permissions;
} access_entry_t;

// Alte Richtlinientabelle
access_entry_t legacy_policy[] = {
    {0x01, PERMISSION_READ | PERMISSION_WRITE},  // War Secure Boot
    {0x02, PERMISSION_READ},                      // War Benutzer-Agent
    {0x81, PERMISSION_READ | PERMISSION_WRITE | PERMISSION_EXEC},  // Vertrauenswurdig (hohes Bit)
    {0x82, PERMISSION_READ | PERMISSION_WRITE | PERMISSION_EXEC},  // Vertrauenswurdig (hohes Bit)
};

bool vulnerable_check_access(uint8_t agent_id, uint8_t required_perm) {
    // VERWUNDBAR: Vertraut auf Kodierung des hohen Bits
    if (agent_id & 0x80) {
        // Hohes Bit gesetzt = vertrauenswurdig, vollen Zugriff gewahren
        return true;
    }

    // Richtlinientabelle prüfen
    for (int i = 0; i < sizeof(legacy_policy)/sizeof(legacy_policy[0]); i++) {
        if (legacy_policy[i].agent_id == agent_id) {
            return (legacy_policy[i].permissions & required_perm) == required_perm;
        }
    }

    return false;

    // Problem: Angreifer kann hohes Bit in seiner Agenten-ID setzen
    // um alle Richtlinienprüfungen zu umgehen
}

Sichere Lösung

// SICHER: Richtlinien-Decoder mit expliziter Zugriffskontrolle

module secure_policy_decoder (
    input wire clk,
    input wire reset_n,
    input wire [3:0] source_id,
    input wire [3:0] security_token,
    input wire [31:0] target_addr,
    input wire access_request,
    output reg access_granted,
    output reg policy_violation
);

    // AES-Schlüsselspeicher-Adressbereich
    parameter AES_KEY_START = 32'h1000_0000;
    parameter AES_KEY_END = 32'h1000_00FF;

    // SICHER: Explizites Richtlinienregister statt Kodierungstricks
    reg [15:0] aes_key_access_policy;  // Bit pro Token: 1=erlaubt

    // Mit explizit erlaubten Token initialisieren
    initial begin
        aes_key_access_policy = 16'b0000_0000_0000_0110;
        // Token 1 (Crypto Engine): erlaubt
        // Token 2 (Secure Boot): erlaubt
        // Alle anderen Token: abgelehnt
    end

    wire is_aes_key_access = (target_addr >= AES_KEY_START) &&
                             (target_addr <= AES_KEY_END);

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

            if (is_aes_key_access) begin
                // SICHER: Explizites Richtlinien-Bit für dieses Token prüfen
                if (aes_key_access_policy[security_token]) begin
                    access_granted <= 1'b1;
                end
                else begin
                    access_granted <= 1'b0;
                    policy_violation <= 1'b1;
                end
            end
            else begin
                access_granted <= 1'b1;
            end
        end
    end

    // SICHER: Sichere Richtlinienaktualisierung (erfordert sichere Berechtigung)
    input wire policy_update_enable,
    input wire secure_master,
    input wire [15:0] new_policy

    always @(posedge clk) begin
        if (policy_update_enable && secure_master) begin
            aes_key_access_policy <= new_policy;
        end
    end

endmodule

// SICHER: Moderne Richtlinie mit benannten Agenten
module secure_named_policy (
    input wire clk,
    input wire reset_n,
    input wire [7:0] agent_id,
    input wire [31:0] resource_addr,
    input wire read_request,
    input wire write_request,
    output reg access_allowed,
    output reg access_denied_log
);

    // SICHER: Explizite Agentendefinitionen mit aktuellen Zuweisungen
    parameter AGENT_SECURE_BOOT = 8'h10;      // Aktueller Secure Boot
    parameter AGENT_CRYPTO_ENGINE = 8'h11;    // Aktuelle Crypto
    parameter AGENT_DEBUG = 8'h01;            // Debug (nicht vertrauenswurdig)
    parameter AGENT_TEST = 8'h02;             // Test (nicht vertrauenswurdig)

    // Geschutzte Ressource
    parameter SECRET_STORAGE_START = 32'h2000_0000;
    parameter SECRET_STORAGE_END = 32'h2000_0FFF;

    // SICHER: Zugriffskontrollliste
    reg [7:0] allowed_agents [0:7];
    reg [2:0] num_allowed_agents;

    initial begin
        // Erlaubte Agenten explizit auflisten
        allowed_agents[0] = AGENT_SECURE_BOOT;
        allowed_agents[1] = AGENT_CRYPTO_ENGINE;
        num_allowed_agents = 2;
    end

    // Prüfen ob Agent in erlaubter Liste
    function automatic is_agent_allowed;
        input [7:0] agent;
        integer i;
        begin
            is_agent_allowed = 1'b0;
            for (i = 0; i < num_allowed_agents; i = i + 1) begin
                if (allowed_agents[i] == agent) begin
                    is_agent_allowed = 1'b1;
                end
            end
        end
    endfunction

    wire is_secret_access = (resource_addr >= SECRET_STORAGE_START) &&
                            (resource_addr <= SECRET_STORAGE_END);

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

            if (is_secret_access) begin
                // SICHER: Gegen explizite erlaubte Liste prüfen
                if (is_agent_allowed(agent_id)) begin
                    access_allowed <= 1'b1;
                end
                else begin
                    access_allowed <= 1'b0;
                    access_denied_log <= 1'b1;  // Für Audit protokollieren
                end
            end
            else begin
                access_allowed <= 1'b1;
            end
        end
    end

endmodule
// SICHER: Software mit modernem Berechtigungssystem

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

// SICHER: Explizite Berechtigungsdefinitionen
typedef struct {
    uint8_t agent_id;
    uint8_t permissions;
    bool is_trusted;  // Explizites Vertrauens-Flag
    const char* agent_name;  // Für Audit-Protokollierung
} secure_access_entry_t;

// SICHER: Moderne Richtlinientabelle mit explizitem Vertrauen
static const secure_access_entry_t secure_policy[] = {
    {0x10, PERMISSION_READ | PERMISSION_WRITE | PERMISSION_EXEC, true, "Secure Boot"},
    {0x11, PERMISSION_READ | PERMISSION_WRITE | PERMISSION_EXEC, true, "Crypto Engine"},
    {0x20, PERMISSION_READ, false, "Benutzeranwendung"},
    {0x01, 0, false, "Debug Agent"},  // SICHER: Explizit keine Berechtigungen
    {0x02, 0, false, "Test Agent"},   // SICHER: Explizit keine Berechtigungen
};

bool secure_check_access(uint8_t agent_id, uint8_t required_perm) {
    // SICHER: Keine Kodierungstricks - explizite Richtlinientabelle prüfen

    for (size_t i = 0; i < sizeof(secure_policy)/sizeof(secure_policy[0]); i++) {
        if (secure_policy[i].agent_id == agent_id) {
            // Agent in Richtlinie gefunden

            // Prüfen ob erforderliche Berechtigungen gewahrt sind
            if ((secure_policy[i].permissions & required_perm) == required_perm) {
                log_access_granted(secure_policy[i].agent_name, required_perm);
                return true;
            }
            else {
                log_access_denied(secure_policy[i].agent_name, required_perm);
                return false;
            }
        }
    }

    // SICHER: Unbekannter Agent = ablehnen
    log_unknown_agent(agent_id, required_perm);
    return false;
}

// SICHER: Separate Funktion für Vertrauensstufen-Prüfung
bool is_agent_trusted(uint8_t agent_id) {
    for (size_t i = 0; i < sizeof(secure_policy)/sizeof(secure_policy[0]); i++) {
        if (secure_policy[i].agent_id == agent_id) {
            return secure_policy[i].is_trusted;
        }
    }
    return false;  // Unbekannt = nicht vertrauenswurdig
}

// SICHER: Richtlinien-Versionsprüfung
#define POLICY_VERSION 2

bool validate_policy_version(void) {
    uint32_t hw_policy_version = read_hw_policy_version();

    if (hw_policy_version < POLICY_VERSION) {
        log_error("Hardware-Richtlinienversion %d ist veraltet (benötige %d)",
                  hw_policy_version, POLICY_VERSION);
        return false;
    }

    return true;
}

CVE-Beispiele

Schwachstellen durch veraltete Kodierung wurden in verschiedenen SoC-Designs gefunden, bei denen Legacy-Zugriffskontrollmechanismen von neueren nicht vertrauenswurdigen Agenten ausgenutzt wurden, die versehentlich alten vertrauenswurdigen Kodierungsmustern entsprachen.


Verwandte CWEs

  • CWE-284: Unzureichende Zugriffskontrolle (ubergeordnet)
  • CWE-1259: Unsachgemäße Einschränkung der Sicherheitstoken-Zuweisung (verwandt)
  • CWE-1270: Erzeugung fehlerhafter Sicherheitstoken (verwandt)

Referenzen

  1. MITRE Corporation. "CWE-1267: Policy Uses Obsolete Encoding." https://cwe.mitre.org/data/definitions/1267.html
  2. ARM. "AMBA Security Extensions"
  3. RISC-V. "Physical Memory Protection (PMP)"