Improper Physical Access Control

Description

Improper Physical Access Control occurs when a product restricts access to certain information but does not sufficiently protect against an unauthorized actor with physical access to these areas. Restricted-access product sections may become accessible when physical protections are inadequate. The robustness required depends on the product type. Proper selection, implementation, and manufacturing of physical protection mechanisms are critical for overall product security.

Risk

Inadequate physical protection has severe security implications. Debug interfaces may be accessible. Cryptographic keys may be extracted. Firmware may be modified. Hardware may be reverse engineered. Side-channel attacks become easier. Memory contents may be read. Security configurations may be altered. Tamper-evident measures may be bypassed. Counterfeit devices may be produced.

Solution

Incorporate anti-tampering measures that protect against or detect when the product has been tampered with. Protection requirements depend on acceptable risk levels. Establish methods to determine whether the protection mechanism is sufficient to prevent unauthorized access. Ensure that all protection mechanisms are fully activated at the time of manufacturing and distribution.

Common Consequences

ImpactDetails
ConfidentialityScope: Confidentiality

Read Memory - Physical access may allow extraction of sensitive data including cryptographic keys.
IntegrityScope: Integrity

Modify Memory - Physical access may allow modification of firmware or security configurations.
Access ControlScope: Access Control

Bypass Protection Mechanism - Physical protections bypassed may expose debug interfaces and other attack surfaces.

Example Code

Vulnerable Code

// Vulnerable: Debug interface without physical access protection

module vulnerable_debug_controller (
    input wire clk,
    input wire reset_n,
    // VULNERABLE: Debug signals directly exposed on pins
    input wire tck,      // JTAG clock - exposed on board
    input wire tms,      // JTAG mode select
    input wire tdi,      // JTAG data in
    output wire tdo,     // JTAG data out
    // Internal debug access
    output reg [31:0] debug_addr,
    output reg [31:0] debug_write_data,
    output reg debug_write,
    output reg debug_read,
    input wire [31:0] debug_read_data
);

    // VULNERABLE: JTAG always enabled
    // No fuse or secure boot check
    // Attacker with physical access can use JTAG

    reg [3:0] jtag_state;
    reg [31:0] shift_register;

    // JTAG state machine
    always @(posedge tck or negedge reset_n) begin
        if (!reset_n) begin
            jtag_state <= 4'h0;  // Test-Logic-Reset
        end
        else begin
            // Full JTAG implementation
            // VULNERABLE: No authentication required
            // VULNERABLE: No physical tamper detection
        end
    end

    // VULNERABLE: Debug gives full memory access
    always @(posedge clk) begin
        if (jtag_command_valid) begin
            // Attacker can read any memory
            debug_addr <= jtag_address;
            debug_read <= jtag_read_cmd;
            debug_write <= jtag_write_cmd;
            debug_write_data <= jtag_data;
        end
    end

endmodule

// Vulnerable: Key storage without physical protection
module vulnerable_key_storage (
    input wire clk,
    input wire reset_n,
    input wire [7:0] addr,
    output reg [31:0] read_data
);

    // VULNERABLE: Keys stored in plain SRAM
    // Physical probing can read contents
    reg [31:0] key_memory [0:255];

    // VULNERABLE: No tamper detection
    // VULNERABLE: No memory encryption
    // VULNERABLE: No active erasure on tamper

    always @(posedge clk) begin
        read_data <= key_memory[addr];
    end

endmodule
// Vulnerable: Software without physical tamper response

#include <stdint.h>

// VULNERABLE: Keys in unprotected memory
static uint8_t encryption_key[32] = {
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
    // ... more key bytes
};

void vulnerable_init(void) {
    // VULNERABLE: No check for tamper events
    // VULNERABLE: Debug interface not disabled

    // Load key from unprotected flash
    load_key_from_flash(encryption_key);

    // Start normal operation
    // Attacker with physical access can:
    // 1. Probe memory bus
    // 2. Use debug interface
    // 3. Modify flash contents
}

// VULNERABLE: No physical security checks
int vulnerable_authenticate(const char* password) {
    // Simple comparison - no anti-probing measures
    return (strcmp(password, stored_password) == 0);
}

Fixed Code

// Fixed: Debug interface with physical access protection

module secure_debug_controller (
    input wire clk,
    input wire reset_n,
    // Debug signals
    input wire tck,
    input wire tms,
    input wire tdi,
    output wire tdo,
    // Physical security inputs
    input wire tamper_detected,      // Physical tamper sensor
    input wire case_open,            // Enclosure open sensor
    input wire voltage_anomaly,      // Voltage glitch detection
    input wire debug_auth_fuse,      // Fuse: 1=debug requires auth
    input wire debug_disable_fuse,   // Fuse: 1=debug permanently disabled
    // Authentication
    input wire [127:0] debug_challenge,
    input wire [127:0] debug_response,
    input wire debug_auth_request,
    // Internal debug access
    output reg [31:0] debug_addr,
    output reg [31:0] debug_write_data,
    output reg debug_write,
    output reg debug_read,
    input wire [31:0] debug_read_data,
    // Status
    output reg tamper_lockout,
    output reg debug_enabled
);

    // FIXED: Debug state
    reg debug_authenticated;
    reg [3:0] auth_failures;

    // FIXED: Physical tamper response
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            tamper_lockout <= 1'b0;
            debug_enabled <= 1'b0;
            debug_authenticated <= 1'b0;
            auth_failures <= 4'h0;
        end
        else begin
            // FIXED: Immediate lockout on physical tamper
            if (tamper_detected || case_open || voltage_anomaly) begin
                tamper_lockout <= 1'b1;
                debug_enabled <= 1'b0;
                debug_authenticated <= 1'b0;
                // Trigger key erasure
            end

            // FIXED: Check debug disable fuse
            if (debug_disable_fuse) begin
                debug_enabled <= 1'b0;
            end
            // FIXED: Debug requires authentication if fuse set
            else if (debug_auth_fuse) begin
                if (debug_auth_request && !tamper_lockout) begin
                    if (verify_debug_auth(debug_challenge, debug_response)) begin
                        debug_authenticated <= 1'b1;
                        debug_enabled <= 1'b1;
                        auth_failures <= 4'h0;
                    end
                    else begin
                        auth_failures <= auth_failures + 1;
                        if (auth_failures >= 4'd10) begin
                            tamper_lockout <= 1'b1;  // Too many failures
                        end
                    end
                end
            end
        end
    end

    // FIXED: Debug access gated by authentication and tamper status
    wire debug_access_allowed = debug_enabled && debug_authenticated && !tamper_lockout;

    always @(posedge clk) begin
        if (debug_access_allowed && jtag_command_valid) begin
            debug_addr <= jtag_address;
            debug_read <= jtag_read_cmd;
            debug_write <= jtag_write_cmd;
            debug_write_data <= jtag_data;
        end
        else begin
            debug_read <= 1'b0;
            debug_write <= 1'b0;
        end
    end

endmodule

// Fixed: Key storage with physical protection
module secure_key_storage (
    input wire clk,
    input wire reset_n,
    input wire [7:0] addr,
    input wire tamper_detected,
    input wire case_open,
    output reg [31:0] read_data,
    output reg key_valid
);

    // FIXED: Encrypted key storage
    reg [31:0] encrypted_key_memory [0:255];
    reg [127:0] memory_encryption_key;

    // FIXED: Tamper response
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            key_valid <= 1'b1;
        end
        else if (tamper_detected || case_open) begin
            // FIXED: Zeroize all keys on tamper
            integer i;
            for (i = 0; i < 256; i = i + 1) begin
                encrypted_key_memory[i] <= 32'h0;
            end
            memory_encryption_key <= 128'h0;
            key_valid <= 1'b0;
        end
    end

    // FIXED: Return decrypted key only if no tamper
    always @(posedge clk) begin
        if (key_valid && !tamper_detected) begin
            read_data <= decrypt(encrypted_key_memory[addr], memory_encryption_key);
        end
        else begin
            read_data <= 32'h0;
        end
    end

endmodule

// Fixed: Active mesh tamper detection
module tamper_mesh (
    input wire clk,
    input wire reset_n,
    input wire [31:0] mesh_sense,  // Mesh wire continuity sensors
    output reg tamper_detected
);

    // FIXED: Active mesh monitoring
    reg [31:0] expected_pattern;
    reg [31:0] actual_pattern;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            tamper_detected <= 1'b0;
            expected_pattern <= 32'hA5A5A5A5;
        end
        else begin
            actual_pattern <= mesh_sense;

            // FIXED: Detect mesh wire cutting or probing
            if (actual_pattern != expected_pattern) begin
                tamper_detected <= 1'b1;
            end

            // Rotate pattern to detect sophisticated attacks
            expected_pattern <= {expected_pattern[30:0], expected_pattern[31]};
        end
    end

endmodule
// Fixed: Software with physical tamper response

#include <stdint.h>

// FIXED: Keys protected by secure element
// Not stored in main memory

void secure_init(void) {
    // FIXED: Check tamper status before any operations
    if (check_tamper_flags()) {
        enter_lockout_mode();
        return;
    }

    // FIXED: Verify boot integrity
    if (!verify_secure_boot()) {
        zeroize_all_keys();
        enter_lockout_mode();
        return;
    }

    // FIXED: Disable debug in production
    if (is_production_device()) {
        disable_debug_interface();
    }

    // FIXED: Enable tamper monitoring
    enable_tamper_sensors();
    register_tamper_interrupt(tamper_handler);

    // Normal operation
}

// FIXED: Tamper interrupt handler
void tamper_handler(void) {
    // Immediately zeroize all sensitive data
    zeroize_all_keys();
    zeroize_sensitive_memory();

    // Disable crypto operations
    disable_crypto_engine();

    // Log event (to protected storage)
    log_tamper_event();

    // Enter lockout - no recovery without factory reset
    enter_lockout_mode();
}

// FIXED: Anti-probing measures in authentication
int secure_authenticate(const char* password) {
    // Add random delay to prevent timing analysis
    random_delay();

    // Use constant-time comparison
    int result = constant_time_compare(password, stored_password);

    // Add noise to power consumption
    dummy_crypto_operation();

    return result;
}

// FIXED: Periodic tamper checks
void periodic_security_check(void) {
    // Check mesh integrity
    if (!verify_mesh_integrity()) {
        tamper_handler();
    }

    // Check voltage levels
    if (!verify_voltage_levels()) {
        tamper_handler();
    }

    // Verify memory integrity
    if (!verify_memory_checksums()) {
        tamper_handler();
    }
}

CVE Examples

Physical access vulnerabilities have been exploited in various devices including payment terminals, secure elements, and IoT devices where attackers used probing, fault injection, or debug interface access to extract secrets.


  • CWE-284: Improper Access Control (parent)
  • CWE-1243: Sensitive Non-Volatile Information Not Protected During Debug (child)
  • CWE-1191: On-Chip Debug/Test Interface With Improper Access Control (peer)
  • CAPEC-401: Physically Hacking Hardware (attack pattern)

References

  1. MITRE Corporation. "CWE-1263: Improper Physical Access Control." https://cwe.mitre.org/data/definitions/1263.html
  2. Common Criteria. "Physical Security Requirements"
  3. FIPS 140-3. "Security Requirements for Cryptographic Modules"