Incorrect Register Defaults or Module Parameters
Description
Incorrect Register Defaults or Module Parameters occurs when hardware design parameters or register default values are incorrectly set during design. System-on-Chip (SoC) hardware designs have IP modules with parameters and registers storing data or controlling operations. These parameters and default values are initially set during design. If security-critical parameters or defaults are set incorrectly—either due to implementation mistakes or specifications that don't account for all system states—the hardware may be exploited. Parameters and defaults should be safe during both normal operation and debug modes.
Risk
Incorrect register defaults have severe security implications. Debug interfaces may be enabled by default. Security features may be disabled initially. Access controls may default to permissive states. Cryptographic functions may use weak default keys. Protection mechanisms may not activate automatically. Boot security may be bypassed through defaults. Privilege levels may default to elevated states. Memory regions may default to unprotected.
Solution
Ensure all security-critical parameters default to the most secure state. Verify defaults enforce security during both normal and debug modes. Document all security-relevant default values. Implement secure-by-default design principles. Review default values during security audits. Test that defaults cannot be exploited before firmware initialization. Use hardware to enforce secure defaults that cannot be overridden. Consider using fuses for permanent security defaults. Implement defense in depth with multiple default protections.
Common Consequences
| Impact | Details |
|---|---|
| Confidentiality, Integrity, Availability | Scope: All Varies By Context - Impact depends on which parameters or registers have incorrect defaults. Security bypass, information disclosure, or privilege escalation possible. |
| Access Control | Scope: Access Control Bypass Protection Mechanism - Incorrect defaults may leave protection mechanisms disabled. |
Example Code
Vulnerable Code
// Vulnerable: Security features disabled by default
module vulnerable_security_controller #(
// VULNERABLE: Debug enabled by default
parameter DEBUG_ENABLED = 1,
// VULNERABLE: Security checks disabled by default
parameter SECURITY_CHECK_ENABLED = 0,
// VULNERABLE: Permissive access control default
parameter DEFAULT_ACCESS_LEVEL = 3'b111 // Full access
) (
input wire clk,
input wire reset_n,
input wire [31:0] access_request,
output reg access_granted
);
reg debug_mode;
reg security_enabled;
reg [2:0] access_level;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
// Defaults are insecure!
debug_mode <= DEBUG_ENABLED; // Debug ON by default
security_enabled <= SECURITY_CHECK_ENABLED; // Security OFF
access_level <= DEFAULT_ACCESS_LEVEL; // Full access
end
end
// Security checks may be bypassed due to defaults
always @(*) begin
if (debug_mode || !security_enabled) begin
access_granted = 1'b1; // Always grant access
end else begin
access_granted = check_access(access_request, access_level);
end
end
endmodule
// Vulnerable: Crypto module with weak default key
module vulnerable_crypto_engine #(
// VULNERABLE: Default key is all zeros
parameter [127:0] DEFAULT_KEY = 128'h0
) (
input wire clk,
input wire reset_n,
input wire [127:0] plaintext,
input wire [127:0] key_input,
input wire key_valid,
output reg [127:0] ciphertext
);
reg [127:0] encryption_key;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
// VULNERABLE: Weak default key
encryption_key <= DEFAULT_KEY; // All zeros!
end
else if (key_valid) begin
encryption_key <= key_input;
end
end
// If firmware doesn't set key, weak default is used
always @(posedge clk) begin
ciphertext <= encrypt_aes(plaintext, encryption_key);
end
endmodule
// Vulnerable: Memory protection with permissive defaults
module vulnerable_memory_controller (
input wire clk,
input wire reset_n,
input wire [31:0] address,
input wire read_enable,
input wire write_enable,
output reg [31:0] data_out,
output reg access_error
);
// Protection configuration
reg [31:0] protected_region_start;
reg [31:0] protected_region_end;
reg protection_enabled;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
// VULNERABLE: Protection disabled by default
protection_enabled <= 1'b0;
// VULNERABLE: No region protected by default
protected_region_start <= 32'hFFFFFFFF;
protected_region_end <= 32'h00000000;
end
end
// All memory accessible until firmware enables protection
endmodule
// Vulnerable: Firmware relying on insecure hardware defaults
void vulnerable_init(void) {
// Assumes hardware defaults are secure - they may not be!
// Hardware debug is ON by default
// Attacker can exploit before this runs
// Eventually disable debug...
disable_debug_interface(); // Too late if attacker acted first
// Eventually enable security...
enable_security_checks(); // Security was off during boot!
}
// Vulnerable: Not setting cryptographic key
void vulnerable_crypto_init(void) {
// VULNERABLE: Assumes default key is secure
// Hardware has all-zero default key!
// Start encrypting with default (weak) key
start_encryption();
}
Fixed Code
// Fixed: Security features enabled by default
module secure_security_controller #(
// Debug disabled by default
parameter DEBUG_ENABLED = 0,
// Security checks enabled by default
parameter SECURITY_CHECK_ENABLED = 1,
// Restrictive access control default
parameter DEFAULT_ACCESS_LEVEL = 3'b000 // No access
) (
input wire clk,
input wire reset_n,
input wire [31:0] access_request,
input wire privileged_mode,
output reg access_granted
);
reg debug_mode;
reg security_enabled;
reg [2:0] access_level;
reg initialized;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
// Secure defaults
debug_mode <= DEBUG_ENABLED; // Debug OFF
security_enabled <= SECURITY_CHECK_ENABLED; // Security ON
access_level <= DEFAULT_ACCESS_LEVEL; // Minimal access
initialized <= 1'b0;
end
else begin
// Track initialization
if (configure_complete) begin
initialized <= 1'b1;
end
end
end
// Security enforced even before initialization
always @(*) begin
if (!initialized) begin
// Before init: very restrictive
access_granted = privileged_mode; // Only privileged boot code
end
else if (security_enabled) begin
access_granted = check_access(access_request, access_level);
end
else begin
// Security disabled requires explicit privileged action
access_granted = 1'b1;
end
end
endmodule
// Fixed: Crypto module with secure default handling
module secure_crypto_engine (
input wire clk,
input wire reset_n,
input wire [127:0] plaintext,
input wire [127:0] key_input,
input wire key_valid,
output reg [127:0] ciphertext,
output reg key_set,
output reg crypto_ready
);
reg [127:0] encryption_key;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
// No default key - must be explicitly set
encryption_key <= 128'h0;
key_set <= 1'b0;
crypto_ready <= 1'b0;
end
else if (key_valid) begin
// Key must be explicitly provided
encryption_key <= key_input;
key_set <= 1'b1;
crypto_ready <= 1'b1;
end
end
// Only encrypt if key has been properly set
always @(posedge clk) begin
if (crypto_ready && key_set) begin
ciphertext <= encrypt_aes(plaintext, encryption_key);
end else begin
// Output zeros if not ready - don't use weak default
ciphertext <= 128'h0;
end
end
endmodule
// Fixed: Memory protection enabled by default
module secure_memory_controller (
input wire clk,
input wire reset_n,
input wire [31:0] address,
input wire read_enable,
input wire write_enable,
input wire privileged_mode,
output reg [31:0] data_out,
output reg access_error
);
// Protection configuration
reg [31:0] protected_region_start;
reg [31:0] protected_region_end;
reg protection_enabled;
reg configuration_locked;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
// SECURE: Protection enabled by default
protection_enabled <= 1'b1;
// SECURE: All memory protected by default
protected_region_start <= 32'h00000000;
protected_region_end <= 32'hFFFFFFFF;
configuration_locked <= 1'b0;
end
end
// Access control active from boot
always @(*) begin
if (protection_enabled) begin
if (address >= protected_region_start &&
address <= protected_region_end) begin
// Protected region - require privilege
access_error = !privileged_mode;
end else begin
access_error = 1'b0;
end
end else begin
access_error = 1'b0;
end
end
endmodule
// Fixed: System-level secure defaults
module secure_soc_defaults #(
// All security features ON by default
parameter SECURE_BOOT_ENABLED = 1,
parameter MEMORY_ENCRYPTION_ENABLED = 1,
parameter DEBUG_DISABLED = 1,
parameter JTAG_LOCKED = 1,
parameter DMA_PROTECTION_ENABLED = 1
) (
input wire clk,
input wire reset_n,
output wire secure_boot_active,
output wire memory_encrypted,
output wire debug_locked,
output wire jtag_disabled,
output wire dma_protected
);
// Secure defaults applied at synthesis time
assign secure_boot_active = SECURE_BOOT_ENABLED;
assign memory_encrypted = MEMORY_ENCRYPTION_ENABLED;
assign debug_locked = DEBUG_DISABLED;
assign jtag_disabled = JTAG_LOCKED;
assign dma_protected = DMA_PROTECTION_ENABLED;
// These cannot be changed without hardware modification
endmodule
// Fixed: Firmware with explicit security initialization
void secure_init(void) {
// Verify secure defaults are in place
if (is_debug_enabled()) {
panic("Security violation: Debug enabled at boot!");
}
if (!is_security_check_enabled()) {
panic("Security violation: Security checks disabled!");
}
// Hardware defaults are secure, but verify anyway
verify_secure_defaults();
// Continue with normal initialization
complete_secure_boot();
}
// Fixed: Explicit key initialization required
void secure_crypto_init(void) {
// Generate or retrieve secure key
uint8_t key[16];
if (!get_secure_key(key, sizeof(key))) {
panic("Failed to obtain encryption key");
}
// Explicitly set key before any encryption
if (!crypto_set_key(key, sizeof(key))) {
panic("Failed to set encryption key");
}
// Verify key was set
if (!crypto_is_ready()) {
panic("Crypto engine not ready after key set");
}
// Clear key from stack
secure_memzero(key, sizeof(key));
// Now safe to use encryption
}
// Verification function
bool verify_secure_defaults(void) {
bool secure = true;
// Check all security-critical defaults
if (read_register(DEBUG_CONTROL) & DEBUG_ENABLE_BIT) {
log_error("Debug enabled - should be disabled by default");
secure = false;
}
if (!(read_register(SECURITY_CONTROL) & SECURITY_ENABLE_BIT)) {
log_error("Security disabled - should be enabled by default");
secure = false;
}
if (read_register(ACCESS_CONTROL) != MINIMAL_ACCESS_DEFAULT) {
log_error("Access control not at minimal default");
secure = false;
}
return secure;
}
CVE Examples
Incorrect default vulnerabilities have been found in various SoC designs where security features were disabled by default or used weak default configurations.
Related CWEs
- CWE-1188: Insecure Default Initialization of Resource (related)
- CWE-453: Insecure Default Variable Initialization (related)
- CWE-1199: General Circuit and Logic Design Concerns (category member)
References
- MITRE Corporation. "CWE-1221: Incorrect Register Defaults or Module Parameters." https://cwe.mitre.org/data/definitions/1221.html
- Secure-by-Default Design Principles
- Hardware Security Configuration Guidelines