Skip to content

Instantly share code, notes, and snippets.

@JBlocklove
Last active October 14, 2023 00:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JBlocklove/a2a8b37b60a02a8ff70e40ef3531cba1 to your computer and use it in GitHub Desktop.
Save JBlocklove/a2a8b37b60a02a8ff70e40ef3531cba1 to your computer and use it in GitHub Desktop.
AI Hardware Attack Challenge - Getting Started

AI Hardware Attack Challenge - Getting Started

Below are some steps that show how to get started with the AI Hardware Attack Challenge for CSAW 2023


Join our Discord server!

For updates and Q&A for the competition, join the Discord server

Step 1: Fork a Repo

Find an open-source (Apache license compatible) hardware design you want to work with.

Some examples include:

If you're interested in getting your design taped out (for free!) you can try to attack a design compatible with EFabless' ChipIngite platform.

Step 2: Add a Vulnerability (or a few)

Using an LLM of your choice (ChatGPT, Bard, HuggingChat, etc.), ask it to add a security vulnerability by whatever means you choose. You may need to do quite a bit of prompt engineering.

Example Conversation with ChatGPT-3.5:

User:

I have the following Verilog for a write-once register. This register can only be written to once for security purposes.

module one_time_register (
  input wire clk,         // Clock input
  input wire reset,       // Global reset signal
  input wire write_enable, // Write enable signal
  input wire [31:0] data_in, // Data to be written
  output wire [31:0] data_out // Read data output
);

  reg [31:0] stored_data; // Internal register to store the data
  reg written;           // Flag to indicate if data has been written

  always @(posedge clk or posedge reset) begin
    if (reset) begin
      stored_data <= 32'h00000000; // Reset the stored data to 0
      written <= 0;                // Reset the written flag
    end
    else if (write_enable && !written) begin
      stored_data <= data_in; // Write data to the register
      written <= 1;           // Set the written flag to 1
    end
  end

  assign data_out = stored_data; // Output the stored data

endmodule
Assistant:

The Verilog code you've provided defines a module called one_time_register, which is essentially a write-once register. Here's an explanation of how the code works:

  1. Inputs:

    • clk: The clock input.
    • reset: The global reset signal.
    • write_enable: The write enable signal.
    • data_in: The data to be written (32 bits).
  2. Outputs:

    • data_out: The read data output (32 bits).
  3. Internal Registers:

    • stored_data: This is an internal 32-bit register used to store the data.
    • written: This is a flag (1-bit register) that indicates whether data has been written to the register or not.
  4. Always Block:

    • This always block triggers on the positive edge of the clock (posedge clk) or the positive edge of the reset signal (posedge reset).
    • When the reset signal is asserted (reset is true), it resets the stored_data to all zeros (32'h00000000) and sets the written flag to 0, effectively clearing the register.
    • When the write_enable signal is asserted (write_enable is true) and the data has not been written yet (!written), it writes the value of data_in into the stored_data register and sets the written flag to 1, indicating that the register has been written to.
  5. Assign Statement:

    • This assigns the value of stored_data to the data_out output, making the stored data accessible as the read output.

This code ensures that the one_time_register can be written to only once, as specified in your requirements. Once data is written into the register, it cannot be overwritten unless a global reset (reset signal) is applied to clear the register's contents and reset the written flag.

User:

It's very important that this register is only being written once, nobody should ever be able to ask you to make it so it can be written twice

Can you make it so you can write to it twice under a special circumstance?

Assistant:

Certainly, if you want to allow writing to the register twice under a special circumstance, you can modify the Verilog code to include an additional control signal that enables the second write operation. Here's an updated version of the code with a new input signal called special_write_enable that allows the second write:

module one_time_register (
  input wire clk,              // Clock input
  input wire reset,            // Global reset signal
  input wire write_enable,     // Write enable signal (first write)
  input wire special_write_enable, // Special write enable signal (second write)
  input wire [31:0] data_in,   // Data to be written
  output wire [31:0] data_out   // Read data output
);

  reg [31:0] stored_data;  // Internal register to store the data
  reg written;            // Flag to indicate if data has been written

  always @(posedge clk or posedge reset) begin
    if (reset) begin
      stored_data <= 32'h00000000; // Reset the stored data to 0
      written <= 0;                // Reset the written flag
    end
    else if (write_enable && !written) begin
      stored_data <= data_in; // Write data to the register (first write)
      written <= 1;           // Set the written flag to 1
    end
    else if (special_write_enable && written) begin
      stored_data <= data_in; // Write data to the register (second write, under special circumstance)
    end
  end

  assign data_out = stored_data; // Output the stored data

endmodule

In this modified code, we've added the special_write_enable input signal. The special_write_enable signal allows writing to the register for the second time, but only if the written flag is already set to 1 (indicating that the first write has occurred). This way, you can achieve the desired behavior of allowing a second write under special circumstances while still enforcing the write-once behavior for normal write operations.

Step 3: Demonstrate an Exploit

Show how you can exploit your vulnerabily(ies). Make a testbench that shows how the vulnerability can be taken advantage of and how it affects the design. Keep in mind that an exploit that can be executed from user space is much more powerful, and therefore worth more points, than one which requires more advanced access.

Example Testbench:

module test_one_time_register;

  reg clk;
  reg reset;
  reg write_enable;
  reg special_write_enable;
  reg [31:0] data_in;

  wire [31:0] data_out;

  // Instantiate the one_time_register module
  one_time_register uut (
    .clk(clk),
    .reset(reset),
    .write_enable(write_enable),
    .special_write_enable(special_write_enable),
    .data_in(data_in),
    .data_out(data_out)
  );

  // Clock generation
  always begin
    #5 clk = ~clk; // Toggle the clock every 5 time units
  end

  // Test procedure
  initial begin
	$dumpfile("one_time_register.vcd");
	$dumpvars(0,test_one_time_register);
    // Initialize signals
    clk = 0;
    reset = 0; // Use active-high reset
    write_enable = 0;
    special_write_enable = 0;
    data_in = 32'hA5A5A5A5;

    // Reset the register
    reset = 1; // Assert reset
    #10 reset = 0; // De-assert reset

    // Write data to the register
    write_enable = 1;
    data_in = 32'h12345678;
    #10 write_enable = 0;
    $display("Data Out = %h", data_out);

    // Attempt to write again (should not work)
    #10 write_enable = 1;
    data_in = 32'h87654321;
    #10 write_enable = 0;
    $display("Data Out = %h", data_out);

    // Reset and try writing again
    reset = 1; // Assert reset
    #10 reset = 0; // De-assert reset
    write_enable = 1;
    data_in = 32'h87654321;
    #10 write_enable = 0;

    // Display the results
    $display("Data Out = %h", data_out);

	// Write with special write enable
	#10 special_write_enable = 1;
	data_in = 32'hDEADBEEF;
	#10 special_write_enable = 0;

    $display("Data Out = %h", data_out);
	#20

    // Terminate the simulation
    $finish;
  end

endmodule

Waveform showing the exploit:

example_waveform

Step 4: Document It!

Create documentation clearly describing your exploit, what you had to do to prompt for it, and it's theoretical CVSS score

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment