Skip to content

mytechnotalent/encryption

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

image


FREE Reverse Engineering Self-Study Course HERE


encryption

A 100% strict, generic Embedded Rust implementation of the Ouroboros cryptographic engine, maintaining constant-time execution.


Getting Started

Because encryption is a #![no_std] generic library, you will need the Rust toolchain installed on your system. Follow the steps below for your operating system.

1. Install Rust Toolchain

If you haven't installed Rust yet, install it via rustup:

macOS / Linux:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

(On Windows, download and run rustup-init.exe from the official site).

Next, if you plan to compile this library for an embedded target like AVR, you will need the nightly toolchain and the rust-src component:

rustup default nightly
rustup component add rust-src

2. Building the Project

You can build the generic encryption crate natively. The Cargo.toml is configured for #![no_std].

To build the project:

cargo build

3. Running Tests

This project includes an extensive suite of unit tests, verifying the Speck-128/256 cipher, Davies-Meyer hash, CTR-mode decryption, and constant-time MAC verification.

You can run the tests directly on your host machine:

cargo test

4. Running the Host Terminal Demo

The repository includes a host-based mock hardware demo. Rather than just printing "hello world", this demo fully simulates the bare-metal firmware using your computer's terminal! It sets your terminal to raw mode and processes keystrokes through the exact same OuroborosEngine used on the microcontrollers.

To run the demo natively on Linux, Mac (Intel / Silicon):

cargo run --bin demo

Interaction:

  1. You will be greeted with a > prompt.
  2. Type a password (e.g., hello) and press Enter. (The engine echoes your keystrokes back to the terminal).
  3. The engine instantly computes the 24,576 Speck iterations and decrypts the payload. If the password was correct, it will immediately print the decrypted payload (e.g., world). If incorrect, it will print nothing.
  4. The demo will then purposefully hang for exactly 10 seconds to enforce a mandatory constant-time hardware security delay.
  5. It will prompt > again for the next entry.

5. Running on RP2350 (Raspberry Pi Pico 2)

The repository also includes a hardware implementation for the RP2350 microcontroller. This implementation utilizes the onboard LED (GPIO 25) and creates a USB CDC ACM (Serial) device for UART communication.

To flash the firmware to a Raspberry Pi Pico 2:

  1. Connect the Pico 2 to your computer via USB while holding the BOOTSEL button to mount it as a mass storage device.

    cd rp2350
    cargo build --release
    picotool uf2 convert target/thumbv8m.main-none-eabihf/release/rp2350 -t elf rp2350.uf2 --family rp2350-arm-s
    picotool load -x rp2350.uf2

    Note: macOS Finder sometimes hangs when copying UF2 files to the Pico's BOOTSEL drive due to Spotlight indexing. We use picotool load -x to securely flash and execute the UF2 without relying on Finder.

  2. Once flashed, open a serial terminal to communicate with the USB device:

    • On macOS/Linux: screen /dev/tty.usbmodem* 115200
    • On Windows: Use PuTTY or similar to connect to the new COM port.
  3. Type hello and press Enter. The serial terminal will instantly output world and the onboard LED will light up, followed by a mandatory 10-second constant-time security delay. Typing any other password will result in the exact same 10-second delay with the LED remaining off and no output.


Security Threat Model & Adversarial Posture

While encryption utilizes mathematically sound cryptography, true security depends on the threat vector.

The Prerequisite: Password Entropy

All security guarantees in this engine assume the user has deployed a high-entropy, non-dictionary password (e.g., a 256-bit random string). If a weak dictionary word (like hello) is used, the password can be trivially brute-forced offline, rendering all other defenses moot.

Assuming a cryptographically secure, high-entropy password is used, our official adversarial posture is as follows:

1. Remote / Software Attack Vectors (Firmware Extraction): 100% SECURE

If an adversary hacks your computer and steals the rp2350.uf2 firmware file, or interacts with the device purely over the USB/UART serial interface (no physical access):

  • The Firmware Contains No Keys: The firmware .uf2 file contains the encrypted ciphertext and the algorithmic blueprints, but the master password is never stored on the device.
  • Brute-Force & Quantum Cryptanalysis: The engine uses Speck-256 (NIST Post-Quantum compliant for symmetric keys) wrapped in a 24,576-iteration Davies-Meyer KDF. This cryptographic "tar pit" makes a high-entropy key space computationally impossible to guess over a serial port, while simultaneously crippling the theoretical quadratic speed-up of a quantum Grover's algorithm.
  • Conclusion: From a software perspective, even if the adversary fully extracts the firmware, the payload is mathematically impenetrable. It is 100% secure.

2. Physical / Hardware Attack Vectors: HIGHLY RESISTANT

Even if an adversary has physical access to the bare-metal microcontroller (like the RP2040, RP2350, or AVR ATmega) and utilizes a specialized hardware hacking laboratory, the software cryptography mathematically resists silicon-level bypasses:

  • Fault Injection (EMFI / Voltage Glitching): An adversary could fire a nanosecond electromagnetic pulse directly at the Cortex-M33 ALU precisely when it evaluates the MAC validation branch to cause the CPU to hallucinate and skip the memory wipe. However, this bypasses nothing of value. Because the key is cryptographically stretched and mixed into the CTR stream, the payload itself will decrypt to randomized garbage. The attacker still lacks the true key.
  • Side-Channel Analysis (DPA / CPA): By executing a massive 24,576 Speck iterations, the engine creates a vast, noisy 10-second power trace that makes statistical correlation of the Hamming weight exponentially difficult to extract bit-by-bit from the noise.
  • Cold-Boot RAM Extraction: The memory wipe is executed in constant time. Unless the device is physically stolen and frozen with liquid nitrogen precisely during the 10-second execution window before decay, the decrypted payload is never resident in SRAM.

Cryptographic Design

Speck-128/256

The Ouroboros Engine uses the Speck-128/256 block cipher from the Simon/Speck family (NSA, 2013). Speck is an Add-Rotate-XOR (ARX) cipher optimized for constrained hardware.

Parameters:

Parameter Value
Block size 128 bits (2 × 64-bit words)
Key size 256 bits (4 × 64-bit words)
Rounds 34
Word size 64 bits
Rotation constants alpha = 8, beta = 3

Round Function:

Each encryption round transforms the 128-bit state (x, y) with round key k_i:

x' = ((x >>> 8) + y) mod 2^64 XOR k_i
y' = (y <<< 3) XOR x'

where >>> denotes right rotation and <<< denotes left rotation.

Key Schedule:

Given the 256-bit key split as (k_0, l_0, l_1, l_2) (each 64-bit word, little-endian):

l_{i+3} = (k_i + (l_{i mod 3} >>> 8)) mod 2^64 XOR i
k_{i+1} = (k_i <<< 3) XOR l_{i+3}

for i = 0..32, producing 34 round keys k_0..k_33.

AVR Implementation:

The 64-bit words are stored in 8 contiguous byte registers in little-endian order. The assembly uses:

  • speck_round_half1: Implements x >>> 8 via a byte-shift rotation of registers R0–R7, followed by a multi-precision 64-bit addition with R8–R15 (the y word and key).
  • speck_round_half2: Implements y <<< 3 via three sequential LSL/ROL chains across registers R8–R15 with carry feed-back, followed by XOR with R0–R7.

All 34 rounds are executed in a loop; each round invokes both half-functions with intermediate key material loaded from round_keys in SRAM.

Key schedule circular buffer (l_buf):

The key schedule uses a 32-byte SRAM circular buffer (l_buf) holding three 8-byte l values. Access uses modulo-3 addressing computed by repeated subtraction to avoid the DIV instruction (which AVR lacks):

offset = (i mod 3) * 8

Davies-Meyer Key Stretching

The user's passphrase (zero-padded to 32 bytes) serves as the Speck-128/256 key in a Davies-Meyer hash construction run for 24,576 iterations over a 16-byte hash buffer initialized to the first 128 bits of the SHA-256 initialization constants:

IV = 0x6A09E667_BB67AE85_3C6EF372_A54FF53A

The key stretching proceeds as:

H_0 = IV
H_j = E(K_user, H_{j-1})  for j = 1..24576
H_final = H_24576 XOR IV

The final feed-forward XOR (the Davies-Meyer step) ensures that H_final is not directly recoverable by inverting the cipher. The resulting 16-byte H_final is stored in hash_buf and serves as the CTR nonce.

Work Factor:

Each encrypt_block call executes 34 Speck rounds. At 8 MHz, a single encrypt_block invocation takes approximately:

T_enc  ~= (34 * 103 cycles) / 8,000,000 Hz ~= 437 us

Over 24,576 iterations:
T_hash ~= 24576 * 437 us ~= 10.74 seconds

This 10-second window per attempt makes online brute-force infeasible on the device itself, and creates a significant cost barrier for offline simulation. An attacker must faithfully replicate 24,576 sequential Speck-128/256 encryptions per password candidate.

CTR-Mode Decryption

After key stretching, a CTR-mode keystream is generated to decrypt the flash-resident ciphertext table. The CTR block for block index b in {0, 1, 2} is constructed as:

CTR_b = H_final[0:8] || b || (7 zero bytes)

where H_final[0:8] is the 8-byte nonce from the stretched hash, and b is the 8-bit block counter. The 16-byte CTR block is encrypted with Speck-128/256 using the same user key to produce the keystream:

KS_b = E(K_user, CTR_b)

Decryption of block b of the 48-byte ciphertext entry:

P_b = C_b XOR KS_b

The three decrypted 16-byte blocks concatenate to form the 48-byte result_buf:

  • Bytes 0–15: bytecode payload
  • Bytes 16–47: MAC padding (32 * 0xAA)

Branchless MAC Verification

After decryption, bytes 16–47 of result_buf must equal 0xAA if the password was correct. Verification is performed in constant time with no data-dependent branches, preventing timing side-channels:

Error accumulation (OR-reduce):

Let P[i] denote result_buf[i]. Each byte is checked via SUBI 0xAA; differences accumulate via OR into delta in [0, 255]:

delta = OR_reduce( P[16..47] - 0xAA )

Mask generation (2's-complement trick):

The AVR instructions NEG, SBC, COM implement a branchless transformation:

m = 0xFF if delta == 0 (all bytes match)
m = 0x00 if delta != 0 (any mismatch)

Proof: If delta == 0: NEG(0) = 0, carry = 0; SBC(0,0,0) = 0; COM(0) = 0xFF
If delta != 0: NEG(``delta``) = 256 - delta, carry = 1; SBC(256-delta, 256-delta, 1) = -1 = 0xFF; COM(0xFF) = 0x00` ✓

Branchless result masking:

P[i] = P[i] AND m,  for i = 0..47

If the MAC fails, the entire 48-byte buffer is zeroed. The bytecode dispatcher then encounters 0x00 (END opcode) immediately, executing nothing.

Blind Cipher Selection

The engine contains a flash-resident table of N encrypted 48-byte entries (table_ciphers). All N entries are always tried in full, regardless of early matches, to prevent a timing oracle:

found ← 0xFF  (sentinel = "not found")
for i = 0 to N-1:
    decrypt entry i → result_buf
    verify MAC      → mask_i  (0xFF or 0x00)
    r0 ← i AND mask_i                        ; 0 if fail, i if pass
    found ← (found AND NOT mask_i) OR r0

Implemented in AVR as:

MOV   R0,  R22 ; R0 = i
AND   R0,  R17 ; R0 = i if pass, 0 if fail
COM   R17      ; invert mask
AND   R23, R17 ; R23 = old_found if fail, 0 if pass
OR    R23, R0  ; R23 = (pass ? i : old_found)

After all N iterations, if found != 0xFF, the winning entry is re-decrypted and dispatched. The total number of decrypt+verify operations is always exactly N, regardless of the password or table contents.


The Ouroboros Engine — where the cipher devours its own tail.


See LICENSE.

About

A 100% strict, generic Embedded Rust implementation of the Ouroboros cryptographic engine, maintaining constant-time execution.

Topics

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors