Hardware Child Block Incorrectly Connected to Parent System

Description

Hardware Child Block Incorrectly Connected to Parent System occurs when signals between a hardware IP component and the parent system design are incorrectly connected causing security risks. Hardware IP components require proper communication with parent systems for correct functionality. Incorrect connections, while potentially avoiding functional problems, can introduce security vulnerabilities. For example, when a reset input connects to a debug mode reset instead of a system-wide hard reset, compromising data integrity, or when security level signals are grounded instead of properly connected.

Risk

Incorrect signal connections have severe security implications. Security levels may be incorrectly assigned. Debug signals may be improperly routed. Reset behavior may be compromised. Interrupts may be lost or misdirected. Access control may be bypassed. Privilege separation may fail. Information may leak across security domains. System security assumptions may be violated.

Solution

Use system-level verification to ensure that components are correctly connected and that design security requirements are not violated due to interactions between various IP blocks. Review integration code for signal connection errors. Implement formal verification of security-critical signal paths. Document expected connections and verify against implementation. Test security functionality after integration.

Common Consequences

ImpactDetails
ConfidentialityScope: Confidentiality

Read Memory - Incorrect connections may expose sensitive data.
IntegrityScope: Integrity

Modify Memory - Security controls may be bypassed.
AvailabilityScope: Availability

DoS - System may malfunction due to incorrect signaling.
Access ControlScope: Access Control

Bypass Protection Mechanism - Security level signals may be compromised.

Example Code

Vulnerable Code

// Vulnerable: TrustZone security level grounded instead of connected

module vulnerable_system_integration (
    input wire clk,
    input wire reset_n,
    // AXI master interface from CPU
    input wire [31:0] cpu_awaddr,
    input wire cpu_awvalid,
    input wire cpu_awprot_secure,  // CPU security level signal
    output wire cpu_awready,
    // AXI slave interface to memory
    output wire [31:0] mem_awaddr,
    output wire mem_awvalid,
    output wire mem_awprot_secure,  // Memory security level
    input wire mem_awready
);

    // VULNERABLE: Security level signal grounded to 0 (secure)
    // instead of connected to CPU output

    axi_interconnect interconnect_inst (
        .clk(clk),
        .reset_n(reset_n),
        // Master interface
        .s_awaddr(cpu_awaddr),
        .s_awvalid(cpu_awvalid),
        // VULNERABLE: Grounded to secure level instead of connected
        .s_awprot_secure(1'b0),  // Should be: cpu_awprot_secure
        .s_awready(cpu_awready),
        // Slave interface
        .m_awaddr(mem_awaddr),
        .m_awvalid(mem_awvalid),
        .m_awprot_secure(mem_awprot_secure),
        .m_awready(mem_awready)
    );

    // Problem: All transactions appear as "secure"
    // Non-secure world can access secure memory!

endmodule

// Vulnerable: Interrupt signals not connected
module vulnerable_csr_integration (
    input wire clk,
    input wire reset_n,
    // CSR interface
    input wire [7:0] csr_addr,
    input wire [31:0] csr_write_data,
    input wire csr_write,
    output wire [31:0] csr_read_data,
    // Interrupt signals (should be connected)
    output wire tamper_interrupt,
    output wire error_interrupt,
    output wire overflow_interrupt
);

    // CSR register file instance
    csr_register_file csr_inst (
        .clk(clk),
        .reset_n(reset_n),
        .addr(csr_addr),
        .write_data(csr_write_data),
        .write_enable(csr_write),
        .read_data(csr_read_data),
        // VULNERABLE: Interrupt ports left unconnected
        .tamper_int(),       // Should be: tamper_interrupt
        .error_int(),        // Should be: error_interrupt
        .overflow_int()      // Should be: overflow_interrupt
    );

    // VULNERABLE: Interrupts are lost
    // System never notified of security events!
    // Tamper attempts go undetected

endmodule

// Vulnerable: Reset signal incorrectly connected
module vulnerable_reset_connection (
    input wire clk,
    input wire system_hard_reset_n,
    input wire debug_soft_reset_n,
    // Security subsystem
    output wire security_reset_n
);

    // Security subsystem needs hard reset to clear sensitive state
    security_controller sec_ctrl (
        .clk(clk),
        // VULNERABLE: Connected to debug reset instead of hard reset
        .reset_n(debug_soft_reset_n),  // Should be: system_hard_reset_n
        .security_reset_n(security_reset_n)
    );

    // Problem: Debug reset doesn't clear security state
    // Sensitive data persists across debug resets
    // Attacker can use debug reset to preserve access

endmodule
// Vulnerable: Software misconfiguration mirroring hardware issues

#include <stdint.h>

// VULNERABLE: Wrong register address definitions
// Copy-paste error from different chip version

#define SECURITY_CTRL_BASE  0x40001000  // Wrong! Should be 0x40002000
#define CRYPTO_ENGINE_BASE  0x40002000  // Wrong! Should be 0x40003000

typedef struct {
    volatile uint32_t ctrl;
    volatile uint32_t status;
    volatile uint32_t key[8];
} crypto_regs_t;

void vulnerable_crypto_init(void) {
    // VULNERABLE: Accessing wrong peripheral due to address error
    crypto_regs_t* crypto = (crypto_regs_t*)CRYPTO_ENGINE_BASE;

    // Actually writing to different peripheral!
    crypto->ctrl = 0x01;  // Enable crypto (but wrong address)

    // Problem: Security controller at 0x40002000 is modified
    // Crypto engine at 0x40003000 is not configured
    // Security may be disabled instead of enabling crypto!
}

// VULNERABLE: Interrupt handler connected to wrong interrupt
void vulnerable_interrupt_setup(void) {
    // Connect tamper handler to wrong interrupt number
    register_interrupt_handler(
        IRQ_TIMER,  // VULNERABLE: Should be IRQ_TAMPER
        tamper_handler
    );

    // Timer interrupts trigger tamper handler
    // Tamper events never handled!
}

Fixed Code

// Fixed: TrustZone security level properly connected

module secure_system_integration (
    input wire clk,
    input wire reset_n,
    // AXI master interface from CPU
    input wire [31:0] cpu_awaddr,
    input wire cpu_awvalid,
    input wire cpu_awprot_secure,
    output wire cpu_awready,
    // AXI slave interface to memory
    output wire [31:0] mem_awaddr,
    output wire mem_awvalid,
    output wire mem_awprot_secure,
    input wire mem_awready,
    // Debug/verification outputs
    output wire security_mismatch
);

    // FIXED: Security level signal properly connected
    wire internal_security_level;

    axi_interconnect interconnect_inst (
        .clk(clk),
        .reset_n(reset_n),
        // Master interface
        .s_awaddr(cpu_awaddr),
        .s_awvalid(cpu_awvalid),
        // FIXED: Properly connected to CPU output
        .s_awprot_secure(cpu_awprot_secure),
        .s_awready(cpu_awready),
        // Slave interface
        .m_awaddr(mem_awaddr),
        .m_awvalid(mem_awvalid),
        .m_awprot_secure(mem_awprot_secure),
        .m_awready(mem_awready),
        // FIXED: Internal signal for verification
        .security_level_internal(internal_security_level)
    );

    // FIXED: Verify security signal propagation
    assign security_mismatch = (cpu_awprot_secure != internal_security_level);

endmodule

// Fixed: Interrupt signals properly connected
module secure_csr_integration (
    input wire clk,
    input wire reset_n,
    // CSR interface
    input wire [7:0] csr_addr,
    input wire [31:0] csr_write_data,
    input wire csr_write,
    output wire [31:0] csr_read_data,
    // Interrupt signals - properly declared and connected
    output wire tamper_interrupt,
    output wire error_interrupt,
    output wire overflow_interrupt,
    // Combined interrupt for system
    output wire system_interrupt
);

    // Internal interrupt signals
    wire int_tamper;
    wire int_error;
    wire int_overflow;

    // CSR register file instance
    csr_register_file csr_inst (
        .clk(clk),
        .reset_n(reset_n),
        .addr(csr_addr),
        .write_data(csr_write_data),
        .write_enable(csr_write),
        .read_data(csr_read_data),
        // FIXED: All interrupt ports properly connected
        .tamper_int(int_tamper),
        .error_int(int_error),
        .overflow_int(int_overflow)
    );

    // FIXED: Connect to outputs
    assign tamper_interrupt = int_tamper;
    assign error_interrupt = int_error;
    assign overflow_interrupt = int_overflow;

    // FIXED: Combined interrupt for system-level handling
    assign system_interrupt = int_tamper | int_error | int_overflow;

endmodule

// Fixed: Reset signal correctly connected
module secure_reset_connection (
    input wire clk,
    input wire system_hard_reset_n,
    input wire debug_soft_reset_n,
    // Security subsystem
    output wire security_reset_n
);

    // FIXED: Security subsystem connected to correct reset
    security_controller sec_ctrl (
        .clk(clk),
        // FIXED: Connected to hard reset
        .reset_n(system_hard_reset_n),
        .security_reset_n(security_reset_n)
    );

    // Security state properly cleared on system reset

endmodule

// Fixed: Connection verification module
module connection_verifier (
    input wire clk,
    input wire reset_n,
    // Signals to verify
    input wire [31:0] expected_security_level,
    input wire [31:0] actual_security_level,
    input wire expected_interrupt,
    input wire actual_interrupt,
    input wire expected_reset,
    input wire actual_reset,
    // Verification outputs
    output reg connection_error,
    output reg [7:0] error_code
);

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            connection_error <= 1'b0;
            error_code <= 8'h00;
        end
        else begin
            connection_error <= 1'b0;

            // FIXED: Verify security level connection
            if (expected_security_level != actual_security_level) begin
                connection_error <= 1'b1;
                error_code <= 8'h01;  // Security level mismatch
            end

            // FIXED: Verify interrupt connection
            if (expected_interrupt != actual_interrupt) begin
                connection_error <= 1'b1;
                error_code <= 8'h02;  // Interrupt connection error
            end

            // FIXED: Verify reset connection
            if (expected_reset != actual_reset) begin
                connection_error <= 1'b1;
                error_code <= 8'h03;  // Reset connection error
            end
        end
    end

endmodule

// Fixed: Formal verification assertions
module formal_connection_check (
    input wire clk,
    input wire cpu_secure,
    input wire interconnect_secure,
    input wire memory_secure
);

    // FIXED: Formal assertions to verify connections
    `ifdef FORMAL
        // Security level must propagate correctly
        always @(posedge clk) begin
            assert(cpu_secure == interconnect_secure);
            assert(interconnect_secure == memory_secure);
        end

        // Cover property to ensure security transitions
        cover property (@(posedge clk) cpu_secure == 1'b1);
        cover property (@(posedge clk) cpu_secure == 1'b0);
    `endif

endmodule
// Fixed: Software with verified register addresses

#include <stdint.h>
#include <stdbool.h>

// FIXED: Verified register addresses from datasheet
#define SECURITY_CTRL_BASE  0x40002000  // Verified
#define CRYPTO_ENGINE_BASE  0x40003000  // Verified
#define INTERRUPT_CTRL_BASE 0x40004000  // Verified

// FIXED: Signature bytes for peripheral identification
#define CRYPTO_ENGINE_ID    0x43525950  // "CRYP"
#define SECURITY_CTRL_ID    0x53454355  // "SECU"

typedef struct {
    volatile uint32_t id;       // Peripheral ID register
    volatile uint32_t ctrl;
    volatile uint32_t status;
    volatile uint32_t key[8];
} crypto_regs_t;

// FIXED: Verify peripheral before use
bool verify_peripheral(volatile uint32_t* base, uint32_t expected_id) {
    return (*base == expected_id);
}

bool secure_crypto_init(void) {
    crypto_regs_t* crypto = (crypto_regs_t*)CRYPTO_ENGINE_BASE;

    // FIXED: Verify we're accessing the correct peripheral
    if (!verify_peripheral(&crypto->id, CRYPTO_ENGINE_ID)) {
        log_error("Crypto engine not found at expected address");
        return false;
    }

    // Now safe to configure
    crypto->ctrl = 0x01;  // Enable crypto
    return true;
}

// FIXED: Correct interrupt setup with verification
typedef struct {
    int irq_number;
    const char* name;
    void (*handler)(void);
} interrupt_mapping_t;

static const interrupt_mapping_t interrupt_table[] = {
    {IRQ_TAMPER,   "Tamper",   tamper_handler},
    {IRQ_ERROR,    "Error",    error_handler},
    {IRQ_OVERFLOW, "Overflow", overflow_handler},
    {IRQ_TIMER,    "Timer",    timer_handler},
};

bool secure_interrupt_setup(void) {
    // FIXED: Register handlers from verified table
    for (int i = 0; i < sizeof(interrupt_table)/sizeof(interrupt_table[0]); i++) {
        if (!register_interrupt_handler(
                interrupt_table[i].irq_number,
                interrupt_table[i].handler)) {
            log_error("Failed to register %s interrupt",
                      interrupt_table[i].name);
            return false;
        }
    }

    // FIXED: Verify all security interrupts are registered
    if (!verify_interrupt_registered(IRQ_TAMPER)) {
        log_error("Tamper interrupt not registered");
        return false;
    }

    return true;
}

// FIXED: Self-test for peripheral connections
bool test_peripheral_connections(void) {
    bool all_passed = true;

    // Test crypto engine
    if (!verify_peripheral(
            (volatile uint32_t*)CRYPTO_ENGINE_BASE,
            CRYPTO_ENGINE_ID)) {
        log_error("Crypto engine connection failed");
        all_passed = false;
    }

    // Test security controller
    if (!verify_peripheral(
            (volatile uint32_t*)SECURITY_CTRL_BASE,
            SECURITY_CTRL_ID)) {
        log_error("Security controller connection failed");
        all_passed = false;
    }

    // Test interrupts by triggering and verifying
    if (!test_interrupt_path(IRQ_TAMPER)) {
        log_error("Tamper interrupt path failed");
        all_passed = false;
    }

    return all_passed;
}

CVE Examples

Hardware integration vulnerabilities have been found in various SoC designs where security-critical signals were incorrectly connected, leading to privilege escalation or bypass of security controls.


  • CWE-284: Improper Access Control (parent)
  • CWE-1197: Integration Issues (category)
  • CWE-1396: Access Control (comprehensive category)
  • CWE-1254: Incorrect Comparison Logic Granularity (related)

References

  1. MITRE Corporation. "CWE-1276: Hardware Child Block Incorrectly Connected to Parent System." https://cwe.mitre.org/data/definitions/1276.html
  2. ARM. "AMBA Integration Guidelines"
  3. Synopsys. "IP Integration Best Practices"