Rating: 5.0

# Basics

> With all those CPU bugs I don't trust software anymore, so I came up with my custom TPM (trademark will be filed soon!). You can't break this, so don't even try.
>
> basics.2020.ctfcompetition.com 1337

This challenge gives us two files:

- `check.sv`, a SystemVerilog file that describes a `check` module with an `open_safe` output;
- `main.cpp`, which asks for a password, feeds it to the `check` module and prints the flag if `open_safe` is true.

We need to understand the conditions that will set `open_safe` to true, so let's take a closer look at `check.sv`.

```verilog
module check(
input clk,

input [6:0] data,
output wire open_safe
);
```

The `[6:0]` notation represents a 7 bit wide bus, with the least significant bit on the right (index 0) and the most significant bit on the left (index 6). The module receives 7 bits of input at a time, which corresponds to an ASCII character.

```verilog
reg [6:0] memory [7:0];
reg [2:0] idx = 0;
```

There are 8 `memory` registers, each one 7 bits wide, and a single `idx` register, 3 bits wide and initially set to 0.

```verilog
wire [55:0] magic = {
{memory[0], memory[5]},
{memory[6], memory[2]},
{memory[4], memory[3]},
{memory[7], memory[1]}
};

wire [55:0] kittens = { magic[9:0], magic[41:22], magic[21:10], magic[55:42] };
assign open_safe = kittens == 56'd3008192072309708;
```

Now comes some wire tangling. The `magic` wire reoders the `memory` registers and the `kittens` wire reorders the `magic` wire. `open_safe` will be true if the output of `kittens` is equal to the decimal number 3008192072309708, so we'll need to untangle this. We can already infer that our password is 8 characters wide, for a total of 7 × 8 = 56 bits.

```verilog
always_ff @(posedge clk) begin
memory[idx] <= data;
idx <= idx + 5;
end
```

At each clock cycle, the input data is saved to the `idx` index of `memory`. Notice, however, that `idx` is 3 bits wide and we're adding 5 a few times, so `idx` will overflow and its value will wrap around.

Let's use `abcdefgh` as our input to see how this module will behave at each clock cycle:

1. `idx` = 0; `memory[0] <= 'a'`; `idx <= idx + 5`;
2. `idx` = 5; `memory[5] <= 'b'`; `idx <= idx + 5`; (Overflow!)
3. `idx` = 2; `memory[2] <= 'c'`; `idx <= idx + 5`;
4. `idx` = 7; `memory[7] <= 'd'`; `idx <= idx + 5`; (Overflow!)
5. `idx` = 4; `memory[4] <= 'e'`; `idx <= idx + 5`; (Overflow!)
6. `idx` = 1; `memory[1] <= 'f'`; `idx <= idx + 5`;
7. `idx` = 6; `memory[6] <= 'g'`; `idx <= idx + 5`; (Overflow!)
8. `idx` = 3; `memory[3] <= 'h'`; `idx <= idx + 5`;

Therefore, from `memory[0]` to `memory[7]` we have `{a, f, c, h, e, b, g, d}`. The `magic` wire reorders those registers once again, which results in `{a, b, g, c, e, h, d, f}`.

We need `kittens` to be equal to 3008192072309708, which is 00001010101011111110111101001011111000101101101111001100 in binary (notice the left zeroes to have exactly 56 bits). The first 10 bits of `kittens` correspond to `magic[9:0]`, the next 20 bits correspond to `magic[41:22]` and so on. By rearranging those bits, we can find out what value we need `magic` to have:

```
kittens = { magic[9:0], magic[41:22], magic[21:10], magic[55:42] }
0000101010 | 10111111101111010010 | 111110001011 | 01101111001100

{ magic[55:42], magic[41:22], magic[21:10], magic[9:0] }
01101111001100 | 10111111101111010010 | 111110001011 | 0000101010
```

Now we know the value of `magic` should be 01101111001100101111111011110100101111100010110000101010. If we split this value into groups of 7 bits, we'll find the following ASCII characters: `7L_o%xX*`. We also know that if our input is `abcdefgh` the value of `magic` will be `{a, b, g, c, e, h, d, f}`, so if we want `magic` to be `7L_o%xX*` we can reverse the logic:

```
abgcehdf => abcdefgh
7L_o%xX* => 7LoX%*_x
```

By submitting `7LoX%*_x` as the password, we obtain our flag!

Flag: `CTF{W4sTh4tASan1tyCh3ck?}`

Original writeup (https://github.com/m4rt1n0/ctf-write-ups/tree/master/google-ctf-2020/hardware-basics).