Improper Finite State Machines (FSMs) in Hardware Logic

Faulty finite state machines (FSMs) in the hardware logic allow an attacker to put the system in an undefined state, to cause a denial of service (DoS) or gain privileges on the victim's system.


Description

The functionality and security of the system heavily depend on the implementation of FSMs. FSMs can be used to indicate the current security state of the system. Lots of secure data operations and data transfers rely on the state reported by the FSM. Faulty FSM designs that do not account for all states, either through undefined states (left as don't cares) or through incorrect implementation, might lead an attacker to drive the system into an unstable state from which the system cannot recover without a reset, thus causing a DoS. Depending on what the FSM is used for, an attacker might also gain additional privileges to launch further attacks and compromise the security guarantees.

Demonstrations

The following examples help to illustrate the nature of this weakness and describe methods or techniques which can be used to mitigate the risk.

Note that the examples here are by no means exhaustive and any given weakness may have many subtle varieties, each of which may require different detection methods or runtime controls.

Example One

The Finite State Machine (FSM) shown in the "bad" code snippet below assigns the output ("out") based on the value of state, which is determined based on the user provided input ("user_input").

module fsm_1(out, user_input, clk, rst_n);
input [2:0] user_input;
input clk, rst_n;
output reg [2:0] out;
reg [1:0] state;
always @ (posedge clk or negedge rst_n )

  begin

    if (!rst_n)

      state = 3'h0;
    else
    case (user_input)
      3'h0:
      3'h1:
      3'h2:
      3'h3: state = 2'h3;
      3'h4: state = 2'h2;
      3'h5: state = 2'h1;

    endcase
  end
  out <= {1'h1, state};

endmodule

The case statement does not include a default to handle the scenario when the user provides inputs of 3'h6 and 3'h7. Those inputs push the system to an undefined state and might cause a crash (denial of service) or any other unanticipated outcome.

Adding a default statement to handle undefined inputs mitigates this issue. This is shown in the "Good" code snippet below. The default statement is in bold.

case (user_input)

  3'h0:
  3'h1:
  3'h2:
  3'h3: state = 2'h3;
  3'h4: state = 2'h2;
  3'h5: state = 2'h1;
  default: state = 2'h0;
endcase

See Also

Comprehensive Categorization: Poor Coding Practices

Weaknesses in this category are related to poor coding practices.

General Circuit and Logic Design Concerns

Weaknesses in this category are related to hardware-circuit design and logic (e.g., CMOS transistors, finite state machines, and registers) as well as issues related t...

Comprehensive CWE Dictionary

This view (slice) covers all the elements in CWE.

Weaknesses Introduced During Implementation

This view (slice) lists weaknesses that can be introduced during implementation.

Weaknesses Introduced During Design

This view (slice) lists weaknesses that can be introduced during design.


Common Weakness Enumeration content on this website is copyright of The MITRE Corporation unless otherwise specified. Use of the Common Weakness Enumeration and the associated references on this website are subject to the Terms of Use as specified by The MITRE Corporation.