mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-10-13 19:20:54 +02:00
Audit-clean C standard across all 5 cb challenges: fix 3 functions over 8 exec lines; rebuild bins; update CB-0x03 and CB-0x05 guides; verify all guides against new bins
This commit is contained in:
1 parent
4ade66738f
commit
23b9f628ef
51 files changed
+3744
-7904
No files matched your search
+118
-21
@@ -2,6 +2,9 @@
|
||||
//
|
||||
// Copyright (c) 2026 Kevin Thomas
|
||||
//
|
||||
// Author: Kevin Thomas
|
||||
// Email: kevin@mytechnotalent.com
|
||||
// GitHub: https://github.com/mytechnotalent
|
||||
// File: aes.c
|
||||
// Desc: Minimal AES-128-ECB block decryption for the CTF waypoint.
|
||||
// Created: 2026
|
||||
@@ -50,9 +53,26 @@ static const uint8_t rsbox[256] = {
|
||||
|
||||
static const uint8_t Rcon[11] = {0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36};
|
||||
|
||||
static uint8_t xtime(uint8_t x) { return (uint8_t)((x << 1) ^ (((x >> 7) & 1) * 0x1B)); }
|
||||
/**
|
||||
* @brief Multiply a byte by two in GF(2^8) (AES xtime operation).
|
||||
*
|
||||
* @param x Byte to multiply by the polynomial x.
|
||||
* @return uint8_t Doubled byte reduced modulo the AES polynomial.
|
||||
*/
|
||||
static uint8_t xtime(uint8_t x)
|
||||
{
|
||||
return (uint8_t)((x << 1) ^ (((x >> 7) & 1) * 0x1B));
|
||||
}
|
||||
|
||||
static uint8_t mul(uint8_t a, uint8_t b) {
|
||||
/**
|
||||
* @brief Multiply two bytes in GF(2^8) with the AES polynomial.
|
||||
*
|
||||
* @param a Multiplicand byte.
|
||||
* @param b Multiplier byte.
|
||||
* @return uint8_t Product byte reduced modulo the AES polynomial.
|
||||
*/
|
||||
static uint8_t mul(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint8_t p = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (b & 1) p ^= a;
|
||||
@@ -63,36 +83,101 @@ static uint8_t mul(uint8_t a, uint8_t b) {
|
||||
return p;
|
||||
}
|
||||
|
||||
static void key_expansion(const uint8_t *key, uint8_t *rk) {
|
||||
/**
|
||||
* @brief Rotate and substitute a schedule word, then apply Rcon.
|
||||
*
|
||||
* @param t Four-byte schedule word to transform in place.
|
||||
* @param i Round-key word index selecting the Rcon constant.
|
||||
* @return None.
|
||||
*/
|
||||
static void rot_sub_word(uint8_t *t, int i)
|
||||
{
|
||||
uint8_t tmp = t[0];
|
||||
t[0] = (uint8_t)(sbox[t[1]] ^ Rcon[i / 4]);
|
||||
t[1] = sbox[t[2]];
|
||||
t[2] = sbox[t[3]];
|
||||
t[3] = sbox[tmp];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XOR a schedule word into the next round-key word.
|
||||
*
|
||||
* @param i Round-key word index being generated.
|
||||
* @param t Transformed previous word bytes.
|
||||
* @param rk Round-key buffer holding 44 words.
|
||||
* @return None.
|
||||
*/
|
||||
static void xor_round_word(int i, const uint8_t *t, uint8_t *rk)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
rk[i * 4 + j] = rk[(i - 4) * 4 + j] ^ t[j];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Expand the 16-byte cipher key into the round-key schedule.
|
||||
*
|
||||
* @param key 16-byte AES-128 cipher key.
|
||||
* @param rk Output buffer for 176 bytes of round keys.
|
||||
* @return None.
|
||||
*/
|
||||
static void key_expansion(const uint8_t *key, uint8_t *rk)
|
||||
{
|
||||
memcpy(rk, key, 16);
|
||||
for (int i = 4; i < 44; i++) {
|
||||
uint8_t t[4];
|
||||
memcpy(t, &rk[(i - 1) * 4], 4);
|
||||
if (i % 4 == 0) {
|
||||
uint8_t tmp = t[0];
|
||||
t[0] = (uint8_t)(sbox[t[1]] ^ Rcon[i / 4]);
|
||||
t[1] = sbox[t[2]];
|
||||
t[2] = sbox[t[3]];
|
||||
t[3] = sbox[tmp];
|
||||
}
|
||||
for (int j = 0; j < 4; j++) rk[i * 4 + j] = rk[(i - 4) * 4 + j] ^ t[j];
|
||||
if (i % 4 == 0)
|
||||
rot_sub_word(t, i);
|
||||
xor_round_word(i, t, rk);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_round_key(uint8_t r, uint8_t *s, const uint8_t *rk) {
|
||||
/**
|
||||
* @brief XOR one 16-byte round key into the cipher state.
|
||||
*
|
||||
* @param r Round number selecting the round key.
|
||||
* @param s Sixteen-byte cipher state, updated in place.
|
||||
* @param rk Round-key schedule produced by key_expansion.
|
||||
* @return None.
|
||||
*/
|
||||
static void add_round_key(uint8_t r, uint8_t *s, const uint8_t *rk)
|
||||
{
|
||||
for (int i = 0; i < 16; i++) s[i] ^= rk[r * 16 + i];
|
||||
}
|
||||
|
||||
static void inv_sub_bytes(uint8_t *s) { for (int i = 0; i < 16; i++) s[i] = rsbox[s[i]]; }
|
||||
/**
|
||||
* @brief Apply the inverse S-box to every state byte.
|
||||
*
|
||||
* @param s Sixteen-byte cipher state, updated in place.
|
||||
* @return None.
|
||||
*/
|
||||
static void inv_sub_bytes(uint8_t *s)
|
||||
{
|
||||
for (int i = 0; i < 16; i++) s[i] = rsbox[s[i]];
|
||||
}
|
||||
|
||||
static void inv_shift_rows(uint8_t *s) {
|
||||
/**
|
||||
* @brief Cyclically shift state rows for inverse ShiftRows.
|
||||
*
|
||||
* @param s Sixteen-byte cipher state, updated in place.
|
||||
* @return None.
|
||||
*/
|
||||
static void inv_shift_rows(uint8_t *s)
|
||||
{
|
||||
uint8_t t;
|
||||
t = s[13]; s[13] = s[9]; s[9] = s[5]; s[5] = s[1]; s[1] = t;
|
||||
t = s[2]; s[2] = s[10]; s[10] = t; t = s[6]; s[6] = s[14]; s[14] = t;
|
||||
t = s[3]; s[3] = s[7]; s[7] = s[11]; s[11] = s[15]; s[15] = t;
|
||||
}
|
||||
|
||||
static void inv_mix_columns(uint8_t *s) {
|
||||
/**
|
||||
* @brief Mix each state column with the inverse MDS matrix.
|
||||
*
|
||||
* @param s Sixteen-byte cipher state, updated in place.
|
||||
* @return None.
|
||||
*/
|
||||
static void inv_mix_columns(uint8_t *s)
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint8_t a = s[i * 4], b = s[i * 4 + 1], c = s[i * 4 + 2], d = s[i * 4 + 3];
|
||||
s[i * 4] = (uint8_t)(mul(a, 14) ^ mul(b, 11) ^ mul(c, 13) ^ mul(d, 9));
|
||||
@@ -102,17 +187,29 @@ static void inv_mix_columns(uint8_t *s) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run AES decryption rounds nine through one on the state.
|
||||
*
|
||||
* @param s Sixteen-byte cipher state, updated in place.
|
||||
* @param rk Round-key schedule produced by key_expansion.
|
||||
* @return None.
|
||||
*/
|
||||
static void decrypt_rounds(uint8_t *s, const uint8_t *rk)
|
||||
{
|
||||
for (int r = 9; r > 0; r--) {
|
||||
inv_shift_rows(s);
|
||||
inv_sub_bytes(s);
|
||||
add_round_key(r, s, rk);
|
||||
inv_mix_columns(s);
|
||||
}
|
||||
}
|
||||
|
||||
void aes128_ecb_decrypt_block(const uint8_t in[16], const uint8_t key[16], uint8_t out[16]) {
|
||||
uint8_t rk[176];
|
||||
key_expansion(key, rk);
|
||||
memcpy(out, in, 16);
|
||||
add_round_key(10, out, rk);
|
||||
for (int r = 9; r > 0; r--) {
|
||||
inv_shift_rows(out);
|
||||
inv_sub_bytes(out);
|
||||
add_round_key(r, out, rk);
|
||||
inv_mix_columns(out);
|
||||
}
|
||||
decrypt_rounds(out, rk);
|
||||
inv_shift_rows(out);
|
||||
inv_sub_bytes(out);
|
||||
add_round_key(0, out, rk);
|
||||
|
||||
@@ -148,6 +148,13 @@ static bool process_gps_char(char ch, double *lat, double *lon)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read one GPS byte from the PIO FIFO and process it.
|
||||
*
|
||||
* @param lat Pointer to current latitude.
|
||||
* @param lon Pointer to current longitude.
|
||||
* @return bool True if a valid active 3D fix was parsed, false otherwise.
|
||||
*/
|
||||
static bool handle_gps_byte(double *lat, double *lon)
|
||||
{
|
||||
char ch = (char)(pio_sm_get(GPS_PIO, GPS_SM) >> 24);
|
||||
|
||||
@@ -40,12 +40,24 @@
|
||||
static uint8_t lcd_addr = 0x27;
|
||||
static bool lcd_ready = false;
|
||||
|
||||
/**
|
||||
* @brief Write one byte to the PCF8574 expander when the LCD is ready.
|
||||
*
|
||||
* @param d Byte to write to the expander.
|
||||
* @return None.
|
||||
*/
|
||||
static void pcf_write(uint8_t d)
|
||||
{
|
||||
if (lcd_ready)
|
||||
i2c_write_blocking(LCD_I2C_INST, lcd_addr, &d, 1, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pulse the enable line to latch a byte into the HD44780.
|
||||
*
|
||||
* @param d Byte value carrying data and control bits.
|
||||
* @return None.
|
||||
*/
|
||||
static void pcf_pulse(uint8_t d)
|
||||
{
|
||||
pcf_write(d | PIN_EN);
|
||||
@@ -54,6 +66,13 @@ static void pcf_pulse(uint8_t d)
|
||||
sleep_us(50);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write one 4-bit nibble with register select and backlight.
|
||||
*
|
||||
* @param n Nibble value carried in the low four bits.
|
||||
* @param mode Register select (0 command, 1 data).
|
||||
* @return None.
|
||||
*/
|
||||
static void lcd_write4(uint8_t n, uint8_t mode)
|
||||
{
|
||||
uint8_t d = (n & 0x0F) << 4;
|
||||
@@ -62,30 +81,62 @@ static void lcd_write4(uint8_t n, uint8_t mode)
|
||||
pcf_pulse(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send one byte to the HD44780 as two nibbles.
|
||||
*
|
||||
* @param v Byte value to send.
|
||||
* @param mode Register select (0 command, 1 data).
|
||||
* @return None.
|
||||
*/
|
||||
static void lcd_send(uint8_t v, uint8_t mode)
|
||||
{
|
||||
lcd_write4((v >> 4) & 0x0F, mode);
|
||||
lcd_write4(v & 0x0F, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the display and return the cursor home.
|
||||
*
|
||||
* @param void No parameters.
|
||||
* @return None.
|
||||
*/
|
||||
static void lcd_clear(void)
|
||||
{
|
||||
lcd_send(0x01, 0);
|
||||
sleep_ms(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Position the display cursor at a row and column.
|
||||
*
|
||||
* @param row Display row (0 or 1).
|
||||
* @param col Display column.
|
||||
* @return None.
|
||||
*/
|
||||
static void lcd_set_cursor(int row, int col)
|
||||
{
|
||||
uint8_t offset = (row == 0) ? 0x00 : 0x40;
|
||||
lcd_send(0x80 | (col + offset), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a NUL-terminated string to the display.
|
||||
*
|
||||
* @param s String to write at the current cursor position.
|
||||
* @return None.
|
||||
*/
|
||||
static void lcd_puts(const char *s)
|
||||
{
|
||||
while (*s)
|
||||
lcd_send((uint8_t)*s++, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run the HD44780 4-bit interface reset sequence.
|
||||
*
|
||||
* @param void No parameters.
|
||||
* @return None.
|
||||
*/
|
||||
static void lcd_reset_seq(void)
|
||||
{
|
||||
lcd_write4(0x03, 0); sleep_ms(5);
|
||||
@@ -94,6 +145,12 @@ static void lcd_reset_seq(void)
|
||||
lcd_write4(0x02, 0); sleep_us(150);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run the HD44780 display configuration sequence.
|
||||
*
|
||||
* @param void No parameters.
|
||||
* @return None.
|
||||
*/
|
||||
static void lcd_cfg_seq(void)
|
||||
{
|
||||
lcd_send(0x28, 0);
|
||||
@@ -102,6 +159,12 @@ static void lcd_cfg_seq(void)
|
||||
lcd_send(0x06, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Probe the I2C bus for a known LCD expander address.
|
||||
*
|
||||
* @param void No parameters.
|
||||
* @return bool True when a display answered, false otherwise.
|
||||
*/
|
||||
static bool detect_lcd(void)
|
||||
{
|
||||
uint8_t rx;
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @brief Drain readable LoRa UART bytes and echo printable ones.
|
||||
*
|
||||
* @param void No parameters.
|
||||
* @return None.
|
||||
*/
|
||||
static void drain_lora_rx(void)
|
||||
{
|
||||
while (uart_is_readable(LORA_UART)) {
|
||||
@@ -42,6 +48,12 @@ static void drain_lora_rx(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send one AT command and drain its reply.
|
||||
*
|
||||
* @param cmd NUL-terminated AT command string.
|
||||
* @return None.
|
||||
*/
|
||||
static void send_at_cmd(const char *cmd)
|
||||
{
|
||||
uart_write_blocking(LORA_UART, (const uint8_t *)cmd, strlen(cmd));
|
||||
@@ -49,6 +61,12 @@ static void send_at_cmd(const char *cmd)
|
||||
drain_lora_rx();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the RYLR998 radio parameters over AT commands.
|
||||
*
|
||||
* @param void No parameters.
|
||||
* @return None.
|
||||
*/
|
||||
static void configure_lora_rf(void)
|
||||
{
|
||||
sleep_ms(1500);
|
||||
|
||||
+53
-17
@@ -72,31 +72,67 @@ static bool update_position(double *cur_lat, double *cur_lon)
|
||||
return got_fix;
|
||||
}
|
||||
|
||||
static void step_mission(double *cur_lat, double *cur_lon)
|
||||
/**
|
||||
* @brief Update the fix-hold countdown from the latest poll result.
|
||||
*
|
||||
* @param fix True when an active 3D lock was parsed this tick.
|
||||
* @return bool True when a fix is current or still held.
|
||||
*/
|
||||
static bool track_fix(bool fix)
|
||||
{
|
||||
int siv = 0, cno = 0;
|
||||
static int hold = 0;
|
||||
bool fix = update_position(cur_lat, cur_lon);
|
||||
gps_get_stats(&siv, &cno);
|
||||
hold = fix ? 3 : ((hold > 0) ? (hold - 1) : 0);
|
||||
bool have = fix || (hold > 0);
|
||||
set_gnss_leds(have, siv);
|
||||
if (have) {
|
||||
lcd_show_coords(*cur_lat, *cur_lon);
|
||||
navigate_to_target(*cur_lat, *cur_lon);
|
||||
} else {
|
||||
lcd_show_gnss(siv, cno);
|
||||
propeller_stop();
|
||||
send_telemetry(*cur_lat, *cur_lon);
|
||||
}
|
||||
return fix || (hold > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Autonomous micro-UAV firmware execution loop.
|
||||
* @brief Execute guidance actions while a position fix is held.
|
||||
*
|
||||
* @param None.
|
||||
* @return int Standard exit code (never reached in embedded firmware).
|
||||
* @param cur_lat Pointer to current latitude.
|
||||
* @param cur_lon Pointer to current longitude.
|
||||
* @return None.
|
||||
*/
|
||||
static void run_guided(double *cur_lat, double *cur_lon)
|
||||
{
|
||||
lcd_show_coords(*cur_lat, *cur_lon);
|
||||
navigate_to_target(*cur_lat, *cur_lon);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute fallback actions while no position fix is held.
|
||||
*
|
||||
* @param siv Satellites in view.
|
||||
* @param cno Best carrier-to-noise density.
|
||||
* @param cur_lat Pointer to current latitude.
|
||||
* @param cur_lon Pointer to current longitude.
|
||||
* @return None.
|
||||
*/
|
||||
static void run_unguided(int siv, int cno, double *cur_lat, double *cur_lon)
|
||||
{
|
||||
lcd_show_gnss(siv, cno);
|
||||
propeller_stop();
|
||||
send_telemetry(*cur_lat, *cur_lon);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Advance the mission by one flight tick.
|
||||
*
|
||||
* @param cur_lat Pointer to current latitude.
|
||||
* @param cur_lon Pointer to current longitude.
|
||||
* @return None.
|
||||
*/
|
||||
static void step_mission(double *cur_lat, double *cur_lon)
|
||||
{
|
||||
bool have = track_fix(update_position(cur_lat, cur_lon));
|
||||
int siv = 0, cno = 0;
|
||||
gps_get_stats(&siv, &cno);
|
||||
set_gnss_leds(have, siv);
|
||||
if (have)
|
||||
run_guided(cur_lat, cur_lon);
|
||||
else
|
||||
run_unguided(siv, cno, cur_lat, cur_lon);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
double cur_lat = ORIGIN_LAT, cur_lon = ORIGIN_LON;
|
||||
|
||||
Reference in new issue
Block a user