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

ImpactDetails
Confidentiality, Integrity, AvailabilityScope: All

Varies By Context - Impact depends on which parameters or registers have incorrect defaults. Security bypass, information disclosure, or privilege escalation possible.
Access ControlScope: 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.


  • 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

  1. MITRE Corporation. "CWE-1221: Incorrect Register Defaults or Module Parameters." https://cwe.mitre.org/data/definitions/1221.html
  2. Secure-by-Default Design Principles
  3. Hardware Security Configuration Guidelines