Semiconductor Defects in Hardware Logic with Security-Sensitive Implications
Description
Semiconductor Defects in Hardware Logic with Security-Sensitive Implications occurs when security-sensitive hardware modules contain semiconductor defects. Semiconductors can fail through various mechanisms including manufacturing/packaging defects and degradation from prolonged use or extreme conditions. Specific failure mechanisms include encapsulation failure, die-attach failure, wire-bond failure, bulk-silicon defects, oxide-layer faults, and aluminum-metal faults including electromigration and corrosion. These defects manifest as faults where chip-internal signals or registers remain stuck at 0 or 1 and fail to switch as expected.
Risk
Semiconductor defects in security hardware have severe implications. Access control logic may fail open. Security checks may be bypassed due to stuck signals. Cryptographic operations may produce wrong results. Authentication logic may malfunction. Security state machines may not function correctly. Protection mechanisms may fail silently. Denial of service may occur. Trust anchors may be compromised.
Solution
Implement post-manufacturing silicon testing using fault models like stuck-at-0 or stuck-at-1 to achieve good test coverage. Operate hardware within specifications to avoid accelerated degradation from extreme temperatures or voltage. Use redundant logic for security-critical functions. Implement runtime fault detection. Design for fail-secure behavior. Monitor security hardware health. Use burn-in testing to detect early failures.
Common Consequences
| Impact | Details |
|---|---|
| Availability, Access Control | Scope: Availability, Access Control DoS: Instability, Bypass Protection Mechanism - If faults occur in security-sensitive hardware modules, security objectives may be compromised, leading to denial of service or protection bypass. |
Example Code
Vulnerable Code
// Vulnerable: Firewall without defect detection
module vulnerable_noc_firewall (
input wire clk,
input wire reset_n,
input wire [31:0] source_id,
input wire [31:0] dest_addr,
input wire [3:0] access_type,
output reg access_allowed
);
// Access control rules
parameter SECURE_REGION_START = 32'h8000_0000;
parameter SECURE_REGION_END = 32'h8FFF_FFFF;
parameter TRUSTED_SOURCE_ID = 32'h0000_0001;
// VULNERABLE: No detection of stuck-at faults
wire is_secure_region = (dest_addr >= SECURE_REGION_START) &&
(dest_addr <= SECURE_REGION_END);
wire is_trusted_source = (source_id == TRUSTED_SOURCE_ID);
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
access_allowed <= 1'b0;
end
else begin
if (is_secure_region) begin
// VULNERABLE: If is_trusted_source stuck at 1, all access allowed
access_allowed <= is_trusted_source;
end else begin
access_allowed <= 1'b1;
end
end
end
// Manufacturing defect: is_trusted_source signal stuck at 1
// Result: All sources appear trusted, security bypassed
endmodule
// Vulnerable: Security comparator without fault detection
module vulnerable_key_comparator (
input wire clk,
input wire [127:0] input_key,
input wire [127:0] stored_key,
output reg key_match
);
// VULNERABLE: Single comparison, no defect detection
always @(posedge clk) begin
key_match <= (input_key == stored_key);
end
// Defect: If key_match signal stuck at 1, any key accepted
endmodule
// Vulnerable: Access control with no redundancy
module vulnerable_access_controller (
input wire clk,
input wire reset_n,
input wire request_access,
input wire [7:0] privilege_level,
input wire [7:0] required_level,
output reg access_granted
);
// VULNERABLE: Single privilege check
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
access_granted <= 1'b0;
end
else if (request_access) begin
// VULNERABLE: If privilege_level[7] stuck at 1, always max privilege
access_granted <= (privilege_level >= required_level);
end
end
endmodule
// Vulnerable: Firmware assuming correct hardware behavior
void vulnerable_security_check(void) {
// Reads from security hardware
uint32_t security_status = read_security_register();
// VULNERABLE: Assumes hardware is functioning correctly
// If register stuck at 0x00000001 (security OK), check always passes
if (security_status == SECURITY_OK) {
allow_operation();
} else {
deny_operation();
}
}
// Vulnerable: No health check of security hardware
void vulnerable_init(void) {
// Initialize security hardware
init_security_module();
// VULNERABLE: No verification that hardware is functioning correctly
// A stuck-at fault in the security module would go undetected
continue_boot();
}
Fixed Code
// Fixed: Firewall with defect detection
module secure_noc_firewall (
input wire clk,
input wire reset_n,
input wire [31:0] source_id,
input wire [31:0] dest_addr,
input wire [3:0] access_type,
output reg access_allowed,
output reg fault_detected
);
parameter SECURE_REGION_START = 32'h8000_0000;
parameter SECURE_REGION_END = 32'h8FFF_FFFF;
parameter TRUSTED_SOURCE_ID = 32'h0000_0001;
// FIXED: Redundant logic with different implementations
wire is_secure_region_a = (dest_addr >= SECURE_REGION_START) &&
(dest_addr <= SECURE_REGION_END);
wire is_secure_region_b = (dest_addr[31:28] == 4'h8); // Different check
wire is_trusted_source_a = (source_id == TRUSTED_SOURCE_ID);
wire is_trusted_source_b = (source_id[31:0] == 32'h0000_0001); // Explicit
// FIXED: Detect stuck-at faults through comparison
wire region_check_consistent = (is_secure_region_a == is_secure_region_b);
wire source_check_consistent = (is_trusted_source_a == is_trusted_source_b);
// FIXED: Built-in self-test pattern
reg [31:0] test_counter;
reg in_self_test;
wire test_pass;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
access_allowed <= 1'b0;
fault_detected <= 1'b0;
test_counter <= 32'h0;
in_self_test <= 1'b1;
end
else if (in_self_test) begin
// FIXED: Periodic self-test
test_counter <= test_counter + 1;
if (test_counter == 32'hFFFF) begin
in_self_test <= 1'b0;
// Verify test results
if (!test_pass) begin
fault_detected <= 1'b1;
end
end
end
else begin
// Check for inconsistencies (indicates fault)
if (!region_check_consistent || !source_check_consistent) begin
fault_detected <= 1'b1;
access_allowed <= 1'b0; // Fail secure
end
else if (is_secure_region_a) begin
// Both redundant checks must agree
access_allowed <= is_trusted_source_a && is_trusted_source_b;
end else begin
access_allowed <= 1'b1;
end
end
end
endmodule
// Fixed: Security comparator with fault detection
module secure_key_comparator (
input wire clk,
input wire reset_n,
input wire [127:0] input_key,
input wire [127:0] stored_key,
input wire compare_enable,
output reg key_match,
output reg fault_detected
);
// FIXED: Multiple comparison methods
wire match_method_a = (input_key == stored_key);
wire match_method_b = ((input_key ^ stored_key) == 128'h0);
// FIXED: XOR result for stuck-at detection
wire [127:0] xor_result = input_key ^ stored_key;
wire all_zero = (xor_result == 128'h0);
// Counter for detecting stuck signals
reg [7:0] match_history;
reg [7:0] mismatch_history;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
key_match <= 1'b0;
fault_detected <= 1'b0;
match_history <= 8'h0;
mismatch_history <= 8'h0;
end
else if (compare_enable) begin
// FIXED: Both methods must agree
if (match_method_a == match_method_b) begin
key_match <= match_method_a && all_zero;
end else begin
// Inconsistency = fault
fault_detected <= 1'b1;
key_match <= 1'b0;
end
// FIXED: Track history to detect stuck-at
if (match_method_a) begin
match_history <= {match_history[6:0], 1'b1};
end else begin
mismatch_history <= {mismatch_history[6:0], 1'b1};
end
// Detect if always matching (stuck at 1)
if (match_history == 8'hFF) begin
fault_detected <= 1'b1;
end
end
end
endmodule
// Fixed: Access controller with redundancy
module secure_access_controller (
input wire clk,
input wire reset_n,
input wire request_access,
input wire [7:0] privilege_level,
input wire [7:0] required_level,
input wire [7:0] privilege_level_shadow, // Redundant copy
output reg access_granted,
output reg fault_detected
);
// FIXED: Compare primary and shadow privilege levels
wire privilege_consistent = (privilege_level == privilege_level_shadow);
// FIXED: Two different comparison methods
wire check_a = (privilege_level >= required_level);
wire check_b = ((privilege_level - required_level) < 8'h80); // No underflow = pass
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
access_granted <= 1'b0;
fault_detected <= 1'b0;
end
else if (request_access) begin
// FIXED: Check for inconsistencies
if (!privilege_consistent) begin
fault_detected <= 1'b1;
access_granted <= 1'b0; // Fail secure
end
else if (check_a != check_b) begin
// Comparison methods disagree = fault
fault_detected <= 1'b1;
access_granted <= 1'b0;
end
else begin
access_granted <= check_a && check_b;
end
end
end
endmodule
// Fixed: Firmware with hardware health verification
void secure_security_check(void) {
// FIXED: Verify hardware is functioning before trusting it
if (!verify_security_hardware_health()) {
security_failure_handler();
return;
}
uint32_t security_status = read_security_register();
// FIXED: Read multiple times and compare
uint32_t status_2 = read_security_register();
uint32_t status_3 = read_security_register();
if (security_status != status_2 || status_2 != status_3) {
// Inconsistent reads = possible fault
security_failure_handler();
return;
}
if (security_status == SECURITY_OK) {
allow_operation();
} else {
deny_operation();
}
}
// Fixed: Hardware health verification
bool verify_security_hardware_health(void) {
// Run built-in self-test
if (!run_security_bist()) {
return false;
}
// Test with known patterns
write_test_register(TEST_PATTERN_A);
if (read_test_register() != TEST_PATTERN_A) {
return false; // Stuck-at fault detected
}
write_test_register(TEST_PATTERN_B);
if (read_test_register() != TEST_PATTERN_B) {
return false;
}
// Test all bits toggle
write_test_register(0x55555555);
if (read_test_register() != 0x55555555) {
return false;
}
write_test_register(0xAAAAAAAA);
if (read_test_register() != 0xAAAAAAAA) {
return false;
}
return true;
}
// Periodic health check during operation
void periodic_health_check(void) {
static uint32_t check_counter = 0;
check_counter++;
if (check_counter >= HEALTH_CHECK_INTERVAL) {
check_counter = 0;
if (!verify_security_hardware_health()) {
log_error("Security hardware fault detected!");
enter_safe_mode();
}
}
}
CVE Examples
Semiconductor defects in security hardware have been identified in various chips where manufacturing defects or aging caused security logic to malfunction.
Related CWEs
- CWE-693: Protection Mechanism Failure (parent)
- CWE-1195: Manufacturing and Life Cycle Management Concerns (category member)
- CWE-1206: Power, Clock, Thermal, and Reset Concerns (category member)
- CWE-1388: Physical Access Issues and Concerns (category member)
References
- MITRE Corporation. "CWE-1248: Semiconductor Defects in Hardware Logic with Security-Sensitive Implications." https://cwe.mitre.org/data/definitions/1248.html
- Bailey, Brian. "Why Chips Die."
- Lakshminarayan, V. "What Causes Semiconductor Devices to Fail"
- CAPEC-624: Hardware Fault Injection