Inclusion of Undocumented Features or Chicken Bits

Description

Inclusion of Undocumented Features or Chicken Bits occurs when a device includes chicken bits or undocumented features that can create entry points for unauthorized actors. Devices often incorporate undocumented bits—colloquially called "chicken bits"—to disable functional security features for debugging and testing purposes. These mechanisms facilitate quick identification of faulty components or features that negatively impact performance. Similar vulnerabilities arise through implementation of undocumented features themselves. When these features remain in production devices, they can be discovered and exploited by attackers.

Risk

Undocumented features and chicken bits have severe security implications. Security features may be disableable through hidden bits. Debug access may be available in production. Backdoors may exist in hardware or firmware. Secure boot may be bypassable. Memory protection may be disableable. Encryption may be bypassable. Privilege escalation may be possible. Supply chain attacks may exploit hidden functionality.

Solution

The implementation of chicken bits in a released product is highly discouraged. If implemented, ensure they remain disabled in production devices. Document all device interfaces comprehensively. Remove or fuse-disable debug features before production. Conduct thorough security audits for undocumented functionality. Implement secure manufacturing processes. Test for undocumented feature discovery. Use hardware fuses to permanently disable debug features.

Common Consequences

ImpactDetails
Confidentiality, Integrity, Availability, Access ControlScope: All

Multiple impacts including memory modification, unauthorized reads, execution of unauthorized code, privilege escalation, identity assumption, and bypass of protection mechanisms.

Example Code

Vulnerable Code

// Vulnerable: Chicken bits to disable security features

module vulnerable_security_controller (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [7:0] register_addr,
    // Security features
    output reg secure_boot_enabled,
    output reg memory_encryption_enabled,
    output reg debug_locked,
    output reg access_control_enabled
);

    // VULNERABLE: Undocumented register at address 0xFF
    // Contains "chicken bits" to disable security
    reg [31:0] chicken_bits;

    // Normal security configuration
    reg [31:0] security_config;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            security_config <= 32'hFFFFFFFF;  // All security enabled
            chicken_bits <= 32'h0;
        end
        else if (write_enable) begin
            case (register_addr)
                8'h00: security_config <= write_data;
                // VULNERABLE: Undocumented address
                8'hFF: chicken_bits <= write_data;
            endcase
        end
    end

    // Security features can be disabled via chicken bits!
    always @(*) begin
        // Normal security setting AND NOT chicken bit override
        secure_boot_enabled = security_config[0] && !chicken_bits[0];
        memory_encryption_enabled = security_config[1] && !chicken_bits[1];
        debug_locked = security_config[2] && !chicken_bits[2];
        access_control_enabled = security_config[3] && !chicken_bits[3];
    end

    // Attack: Write 0xF to address 0xFF to disable all security

endmodule

// Vulnerable: Hidden UART debug interface
module vulnerable_hidden_debug (
    input wire clk,
    input wire reset_n,
    input wire uart_rx,
    output reg uart_tx,
    // Memory interface
    output reg [31:0] debug_addr,
    output reg [31:0] debug_wdata,
    output reg debug_write,
    output reg [31:0] debug_rdata
);

    reg [7:0] command_buffer [0:15];
    reg [3:0] cmd_index;

    // VULNERABLE: Undocumented UART commands
    parameter CMD_READ_MEM = 8'hA5;
    parameter CMD_WRITE_MEM = 8'h5A;
    parameter CMD_EXEC_CODE = 8'hE0;  // Execute arbitrary code!
    parameter CMD_DISABLE_SEC = 8'hD5;  // Disable security!

    always @(posedge clk) begin
        if (uart_byte_received) begin
            command_buffer[cmd_index] <= uart_data;
            cmd_index <= cmd_index + 1;

            // Process command when complete
            if (cmd_index == 5) begin
                case (command_buffer[0])
                    CMD_READ_MEM: begin
                        debug_addr <= {command_buffer[1], command_buffer[2],
                                      command_buffer[3], command_buffer[4]};
                        // Returns memory contents via UART
                    end
                    CMD_WRITE_MEM: begin
                        debug_addr <= {command_buffer[1], command_buffer[2],
                                      command_buffer[3], command_buffer[4]};
                        debug_wdata <= uart_data;
                        debug_write <= 1'b1;
                    end
                    CMD_DISABLE_SEC: begin
                        // VULNERABLE: Disables security without authentication!
                        security_disabled <= 1'b1;
                    end
                endcase
            end
        end
    end

endmodule

// Vulnerable: Undocumented test mode
module vulnerable_test_mode (
    input wire clk,
    input wire reset_n,
    input wire [3:0] gpio_pins,
    output reg test_mode_active,
    output reg security_bypass
);

    // VULNERABLE: Secret GPIO sequence enables test mode
    parameter SECRET_SEQUENCE = 12'hA5A;
    reg [11:0] gpio_history;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            gpio_history <= 12'h0;
            test_mode_active <= 1'b0;
            security_bypass <= 1'b0;
        end
        else begin
            gpio_history <= {gpio_history[7:0], gpio_pins};

            // VULNERABLE: Secret sequence activates test mode
            if (gpio_history == SECRET_SEQUENCE) begin
                test_mode_active <= 1'b1;
                security_bypass <= 1'b1;  // All security disabled!
            end
        end
    end

endmodule
// Vulnerable: Firmware with undocumented features

// VULNERABLE: Hidden debug command interface
#define SECRET_DEBUG_PORT 0xDEAD
#define SECRET_COMMAND_KEY 0xCAFEBABE

struct hidden_command {
    uint32_t magic;      // Must be SECRET_COMMAND_KEY
    uint8_t command;
    uint32_t address;
    uint32_t data;
};

void process_network_packet(uint8_t* data, size_t len) {
    // Normal packet processing
    handle_normal_packet(data, len);

    // VULNERABLE: Check for hidden debug commands
    if (len >= sizeof(struct hidden_command)) {
        struct hidden_command* cmd = (struct hidden_command*)data;

        if (cmd->magic == SECRET_COMMAND_KEY) {
            // Undocumented debug commands - no authentication!
            switch (cmd->command) {
                case 0x01:  // Read memory
                    send_response(*(uint32_t*)cmd->address);
                    break;
                case 0x02:  // Write memory
                    *(uint32_t*)cmd->address = cmd->data;
                    break;
                case 0x03:  // Disable secure boot
                    disable_secure_boot_check = true;
                    break;
                case 0x04:  // Execute code
                    ((void(*)(void))cmd->address)();
                    break;
            }
        }
    }
}

// VULNERABLE: Chicken bit in configuration
#define SECURITY_CONFIG_REG 0x40001000
#define CHICKEN_BIT_DISABLE_ENCRYPTION (1 << 31)  // Undocumented!

void vulnerable_init(void) {
    // Someone might discover and set the chicken bit
    // Disables encryption entirely
}

Fixed Code

// Fixed: No chicken bits in production hardware

module secure_security_controller (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [7:0] register_addr,
    input wire production_fuse,  // Blown in production
    // Security features - always enabled in production
    output wire secure_boot_enabled,
    output wire memory_encryption_enabled,
    output wire debug_locked,
    output wire access_control_enabled
);

    reg [31:0] security_config;

    `ifdef DEBUG_BUILD
        // Debug chicken bits - ONLY in debug builds
        reg [31:0] debug_override;
    `endif

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            security_config <= 32'hFFFFFFFF;
            `ifdef DEBUG_BUILD
                debug_override <= 32'h0;
            `endif
        end
        else if (write_enable) begin
            case (register_addr)
                8'h00: security_config <= write_data;
                `ifdef DEBUG_BUILD
                    8'hFF: if (!production_fuse) debug_override <= write_data;
                `endif
                // No chicken bits at 0xFF in production!
            endcase
        end
    end

    // Security features - no override in production
    `ifdef DEBUG_BUILD
        assign secure_boot_enabled = production_fuse ?
            security_config[0] : (security_config[0] && !debug_override[0]);
        // etc.
    `else
        // FIXED: Production build has no override capability
        assign secure_boot_enabled = security_config[0];
        assign memory_encryption_enabled = security_config[1];
        assign debug_locked = security_config[2];
        assign access_control_enabled = security_config[3];
    `endif

endmodule

// Fixed: Debug interface removed or properly secured
module secure_debug_interface (
    input wire clk,
    input wire reset_n,
    input wire debug_fuse_blown,  // Permanent disable
    input wire [255:0] debug_challenge,
    input wire [255:0] debug_response,
    input wire debug_auth_request,
    output reg debug_authenticated,
    output reg debug_enabled
);

    // Debug only available if:
    // 1. Fuse not blown (development only)
    // 2. Proper cryptographic authentication

    wire [255:0] expected_response;
    wire response_valid;

    crypto_auth auth (
        .challenge(debug_challenge),
        .response(debug_response),
        .valid(response_valid),
        .expected(expected_response)
    );

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            debug_authenticated <= 1'b0;
            debug_enabled <= 1'b0;
        end
        else if (debug_fuse_blown) begin
            // FIXED: Fuse permanently disables debug
            debug_enabled <= 1'b0;
            debug_authenticated <= 1'b0;
        end
        else if (debug_auth_request && response_valid) begin
            // FIXED: Cryptographic authentication required
            debug_authenticated <= 1'b1;
            debug_enabled <= 1'b1;
        end
    end

endmodule

// Fixed: All registers documented, no hidden addresses
module secure_register_bank (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [7:0] register_addr,
    output reg [31:0] read_data
);

    // All registers are documented
    reg [31:0] config_reg;      // 0x00 - Documented
    reg [31:0] status_reg;      // 0x04 - Documented
    reg [31:0] control_reg;     // 0x08 - Documented
    // No hidden registers!

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            config_reg <= 32'h0;
            status_reg <= 32'h0;
            control_reg <= 32'h0;
        end
        else if (write_enable) begin
            case (register_addr)
                8'h00: config_reg <= write_data;
                8'h04: status_reg <= write_data;
                8'h08: control_reg <= write_data;
                // FIXED: Unknown addresses ignored, no hidden functionality
                default: ; // Do nothing
            endcase
        end
    end

    always @(*) begin
        case (register_addr)
            8'h00: read_data = config_reg;
            8'h04: read_data = status_reg;
            8'h08: read_data = control_reg;
            default: read_data = 32'h0;  // Unknown returns zero
        endcase
    end

endmodule
// Fixed: No undocumented features in production firmware

// All commands documented, authenticated
typedef enum {
    CMD_STATUS = 0x01,
    CMD_CONFIG = 0x02,
    CMD_RESET = 0x03
    // No hidden commands!
} command_t;

void process_command(uint8_t cmd, void* data) {
    // All commands require authentication
    if (!is_authenticated()) {
        return;
    }

    switch (cmd) {
        case CMD_STATUS:
            send_status();
            break;
        case CMD_CONFIG:
            update_config(data);
            break;
        case CMD_RESET:
            system_reset();
            break;
        default:
            // FIXED: Unknown commands logged and rejected
            log_security_event("Unknown command: %02x", cmd);
            break;
    }
}

// Production verification
void verify_no_debug_features(void) {
    // Check debug fuses are blown
    if (!is_debug_fuse_blown()) {
        panic("Debug fuse not blown in production!");
    }

    // Verify no chicken bits exist
    // (This is a compile-time check via build system)
    #ifdef CHICKEN_BITS_ENABLED
        #error "Chicken bits must not be enabled in production!"
    #endif

    // Verify all register addresses return expected values
    for (uint32_t addr = 0; addr < 0x100; addr++) {
        if (!is_documented_address(addr)) {
            uint32_t value = read_register(addr);
            if (value != 0 && value != 0xFFFFFFFF) {
                panic("Undocumented register at 0x%02x has value!", addr);
            }
        }
    }
}

CVE Examples

  • Skorobogatov & Woods: "Breakthrough Silicon Scanning Discovers Backdoor in Military Chip"
  • Domas: "God Mode Unlocked: Hardware Backdoors in x86 CPUs"
  • Research on Siemens S7 silicon vulnerabilities

  • CWE-912: Hidden Functionality (parent)
  • CWE-1198: Privilege Separation and Access Control Issues (category member)
  • CWE-1371: ICS Supply Chain: Poorly Documented Features (category member)
  • CWE-1209: Failure to Disable Reserved Bits (related)

References

  1. MITRE Corporation. "CWE-1242: Inclusion of Undocumented Features or Chicken Bits." https://cwe.mitre.org/data/definitions/1242.html
  2. CAPEC-212: Functionality Misuse
  3. CAPEC-36: Using Unpublished Interfaces or Functionality