Improper Protection Against Voltage and Clock Glitches

Description

Improper Protection Against Voltage and Clock Glitches occurs when a device lacks appropriate circuitry or sensors to detect and mitigate voltage and clock glitches that could compromise sensitive information or software. Devices implementing security features like secure boot establish a chain of trust through signature verification before executing subsequent stages. Hardware and firmware work together to configure secure states via access control settings. However, without proper defenses, attackers can exploit fault-injection techniques—specifically voltage and clock glitches—to bypass these security measures.

Risk

Vulnerability to glitch attacks has severe security implications. Secure boot may be bypassable. Signature verification may be defeated. Access control decisions may be corrupted. Cryptographic operations may produce wrong results. Security state machines may skip states. Debug locks may be bypassed. Privilege escalation may be possible. Arbitrary code execution may be achieved.

Solution

Implement Tunable Replica Circuits (TRCs) or Razor flip-flops to detect timing violations. Deploy platform-level glitch detection sensors. Add redundancy to security-critical code sections. Implement double-checking of security decisions. Use error-detecting codes for critical data. Add voltage and clock monitors. Design security checks to be glitch-resistant. Consider hardware security modules for critical operations.

Common Consequences

ImpactDetails
Confidentiality, Integrity, Availability, Access ControlScope: All

Multiple impacts including privilege escalation, protection mechanism bypass, unauthorized memory access, and arbitrary code execution.

Example Code

Vulnerable Code

// Vulnerable: Single security check easily bypassed by glitch

bool verify_firmware_signature(const uint8_t* firmware, size_t size,
                                const uint8_t* signature) {
    // VULNERABLE: Single point of failure for glitch attack
    bool valid = crypto_verify_signature(firmware, size, signature, public_key);

    if (valid) {  // <-- GLITCH TARGET: Skip this check
        return true;
    } else {
        return false;
    }
}

void vulnerable_secure_boot(void) {
    load_firmware_to_memory();

    // VULNERABLE: Single signature check
    if (verify_firmware_signature(firmware, fw_size, fw_signature)) {
        // Attacker glitches here to skip verification
        execute_firmware();
    } else {
        halt_boot();
    }
}

// Vulnerable: Security decision based on single comparison
void vulnerable_password_check(const char* input) {
    // VULNERABLE: Single comparison, glitch can bypass
    if (strcmp(input, stored_password) == 0) {  // <-- GLITCH TARGET
        grant_access();
    } else {
        deny_access();
    }
}

// Vulnerable: Security flag easily corrupted
volatile bool security_enabled = true;

void vulnerable_security_gate(void) {
    // VULNERABLE: Single flag check
    if (security_enabled) {  // <-- GLITCH can corrupt this read
        enforce_security_policy();
    }
    // If glitch causes security_enabled to read as false, security bypassed
}
// Vulnerable: Security state machine without glitch protection

module vulnerable_secure_boot_fsm (
    input wire clk,
    input wire reset_n,
    input wire signature_valid,
    output reg boot_authorized,
    output reg [2:0] boot_state
);

    parameter IDLE = 3'h0;
    parameter VERIFY = 3'h1;
    parameter AUTHORIZED = 3'h2;
    parameter DENIED = 3'h3;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            boot_state <= IDLE;
            boot_authorized <= 1'b0;
        end
        else begin
            case (boot_state)
                IDLE: begin
                    boot_state <= VERIFY;
                end

                VERIFY: begin
                    // VULNERABLE: Single check, no redundancy
                    if (signature_valid) begin  // <-- GLITCH TARGET
                        boot_state <= AUTHORIZED;
                        boot_authorized <= 1'b1;
                    end else begin
                        boot_state <= DENIED;
                    end
                end

                AUTHORIZED: begin
                    // Boot proceeds
                end

                DENIED: begin
                    // Boot halted
                end
            endcase
        end
    end

endmodule

// Vulnerable: No voltage/clock glitch detection
module vulnerable_crypto_core (
    input wire clk,
    input wire reset_n,
    input wire [127:0] data_in,
    input wire [127:0] key,
    output reg [127:0] data_out
);

    // VULNERABLE: No glitch detection
    // Glitch during crypto operation can produce wrong/weak output

    always @(posedge clk) begin
        data_out <= aes_encrypt(data_in, key);
        // If clock glitched, encryption may be incomplete/wrong
    end

endmodule

Fixed Code

// Fixed: Redundant security checks resist glitch attacks

bool verify_firmware_signature_secure(const uint8_t* firmware, size_t size,
                                       const uint8_t* signature) {
    // FIXED: Multiple independent verification passes
    volatile bool valid1 = crypto_verify_signature(firmware, size, signature, public_key);

    // Add timing jitter to make glitch timing harder
    random_delay();

    volatile bool valid2 = crypto_verify_signature(firmware, size, signature, public_key);

    // Different verification method
    volatile bool valid3 = crypto_verify_signature_alt(firmware, size, signature, public_key);

    // FIXED: All three must agree
    if (valid1 && valid2 && valid3) {
        // Triple-check the decision
        if (valid1 == true && valid2 == true && valid3 == true) {
            return true;
        }
    }

    return false;
}

void secure_boot_with_redundancy(void) {
    load_firmware_to_memory();

    // FIXED: Multiple verification with different timing
    volatile int verify_count = 0;

    for (int i = 0; i < 3; i++) {
        random_delay();  // Variable timing

        if (verify_firmware_signature(firmware, fw_size, fw_signature)) {
            verify_count++;
        }
    }

    // FIXED: Require all verifications to pass
    if (verify_count == 3) {
        // Final check before execution
        if (verify_count == 3) {
            execute_firmware();
        }
    } else {
        halt_boot();
    }
}

// Fixed: Glitch-resistant comparison
bool secure_compare(const char* a, const char* b, size_t len) {
    volatile uint8_t result = 0;
    volatile uint8_t result2 = 0;

    // First pass
    for (size_t i = 0; i < len; i++) {
        result |= a[i] ^ b[i];
    }

    random_delay();

    // Second pass (different direction)
    for (size_t i = len; i > 0; i--) {
        result2 |= a[i-1] ^ b[i-1];
    }

    // Both must indicate match
    return (result == 0) && (result2 == 0) && (result == result2);
}

// Fixed: Security flag with redundancy
volatile bool security_enabled_1 = true;
volatile bool security_enabled_2 = true;
volatile uint32_t security_checksum = SECURITY_ENABLED_CHECKSUM;

void secure_security_gate(void) {
    // FIXED: Multiple flags and checksum
    bool flag1 = security_enabled_1;
    bool flag2 = security_enabled_2;
    bool checksum_valid = (security_checksum == SECURITY_ENABLED_CHECKSUM);

    // All three must agree
    if (flag1 && flag2 && checksum_valid) {
        if (flag1 == flag2) {
            enforce_security_policy();
        }
    } else {
        // Inconsistency detected - possible attack
        security_violation_handler();
    }
}
// Fixed: Security state machine with glitch detection

module secure_boot_fsm (
    input wire clk,
    input wire reset_n,
    input wire signature_valid,
    input wire voltage_glitch_detected,
    input wire clock_glitch_detected,
    output reg boot_authorized,
    output reg [2:0] boot_state,
    output reg security_violation
);

    parameter IDLE = 3'h0;
    parameter VERIFY_1 = 3'h1;
    parameter VERIFY_2 = 3'h2;
    parameter VERIFY_3 = 3'h3;
    parameter AUTHORIZED = 3'h4;
    parameter DENIED = 3'h5;

    reg [2:0] verify_count;
    reg [2:0] verify_pass_count;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            boot_state <= IDLE;
            boot_authorized <= 1'b0;
            security_violation <= 1'b0;
            verify_count <= 3'h0;
            verify_pass_count <= 3'h0;
        end
        // FIXED: Check for glitch attacks
        else if (voltage_glitch_detected || clock_glitch_detected) begin
            boot_state <= DENIED;
            security_violation <= 1'b1;
            boot_authorized <= 1'b0;
        end
        else begin
            case (boot_state)
                IDLE: begin
                    boot_state <= VERIFY_1;
                    verify_count <= 3'h0;
                    verify_pass_count <= 3'h0;
                end

                VERIFY_1: begin
                    // FIXED: First verification
                    if (signature_valid) verify_pass_count <= verify_pass_count + 1;
                    boot_state <= VERIFY_2;
                end

                VERIFY_2: begin
                    // FIXED: Second verification (different timing)
                    if (signature_valid) verify_pass_count <= verify_pass_count + 1;
                    boot_state <= VERIFY_3;
                end

                VERIFY_3: begin
                    // FIXED: Third verification
                    if (signature_valid) verify_pass_count <= verify_pass_count + 1;

                    // FIXED: All three verifications must pass
                    if (verify_pass_count == 3'd2 && signature_valid) begin
                        boot_state <= AUTHORIZED;
                        boot_authorized <= 1'b1;
                    end else begin
                        boot_state <= DENIED;
                    end
                end

                AUTHORIZED: begin
                    // Continue monitoring for glitches
                    if (voltage_glitch_detected || clock_glitch_detected) begin
                        boot_authorized <= 1'b0;
                        security_violation <= 1'b1;
                    end
                end

                DENIED: begin
                    boot_authorized <= 1'b0;
                end
            endcase
        end
    end

endmodule

// Fixed: Glitch detection circuitry
module glitch_detector (
    input wire clk,
    input wire reset_n,
    input wire voltage_sense,
    input wire clock_in,
    output reg voltage_glitch,
    output reg clock_glitch
);

    // Voltage glitch detection using window comparator
    reg [7:0] voltage_history;
    parameter VOLTAGE_MIN = 8'd100;
    parameter VOLTAGE_MAX = 8'd200;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            voltage_glitch <= 1'b0;
        end
        else begin
            // Detect voltage outside normal range
            if (voltage_sense < VOLTAGE_MIN || voltage_sense > VOLTAGE_MAX) begin
                voltage_glitch <= 1'b1;
            end
        end
    end

    // Clock glitch detection using Razor flip-flop concept
    reg clock_sample_1, clock_sample_2;
    reg clock_edge_count;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            clock_glitch <= 1'b0;
            clock_sample_1 <= 1'b0;
            clock_sample_2 <= 1'b0;
        end
        else begin
            clock_sample_1 <= clock_in;
            clock_sample_2 <= clock_sample_1;

            // Detect unexpected clock edges
            if (clock_sample_1 != clock_sample_2) begin
                clock_edge_count <= clock_edge_count + 1;
                if (clock_edge_count > expected_edges) begin
                    clock_glitch <= 1'b1;
                end
            end
        end
    end

endmodule

CVE Examples

  • CVE-2019-17391: Secure boot bypass via lack of anti-glitch protection
  • CVE-2021-33478: Boot shell access through impulse attacks
  • Plundervolt and CLKSCREW attacks exploiting DVFS interfaces

  • CWE-1384: Improper Handling of Physical or Environmental Conditions (parent)
  • CWE-1332: Improper Handling of Faults that Lead to Instruction Skips (peer)
  • CWE-1256: Privileged Access to Power Management Features (related)

References

  1. MITRE Corporation. "CWE-1247: Improper Protection Against Voltage and Clock Glitches." https://cwe.mitre.org/data/definitions/1247.html
  2. Plundervolt Attack Research
  3. CLKSCREW: Exploiting DVFS for Security Bypass