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
| Impact | Details |
|---|---|
| Confidentiality | Scope: Confidentiality Read Memory - Physical access may allow extraction of sensitive data including cryptographic keys. |
| Integrity | Scope: Integrity Modify Memory - Physical access may allow modification of firmware or security configurations. |
| Access Control | Scope: 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.
Related CWEs
- 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
- MITRE Corporation. "CWE-1263: Improper Physical Access Control." https://cwe.mitre.org/data/definitions/1263.html
- Common Criteria. "Physical Security Requirements"
- FIPS 140-3. "Security Requirements for Cryptographic Modules"