feat: implement encryption

This commit is contained in:
2026-05-14 16:22:52 +02:00
parent caf67b6e74
commit a0aed7e93b
12 changed files with 336 additions and 37 deletions

3
.gitmodules vendored
View File

@@ -1,3 +1,6 @@
[submodule "tinyriscv"] [submodule "tinyriscv"]
path = tinyriscv path = tinyriscv
url = ssh://git@ssh.git.xn--k-0fa.se:222/sas2026/tinyriscv.git url = ssh://git@ssh.git.xn--k-0fa.se:222/sas2026/tinyriscv.git
[submodule "tiny-AES-c"]
path = tiny-AES-c
url = git@github.com:kokke/tiny-AES-c.git

View File

@@ -16,10 +16,14 @@ HOST_LDFLAGS ?= -Wl,-s
EMU_SRC_FILES := $(wildcard src/emulated/*.c) EMU_SRC_FILES := $(wildcard src/emulated/*.c)
EMU_OBJ_FILES := $(EMU_SRC_FILES:src/emulated/%.c=build/%.riscv.o) EMU_OBJ_FILES := $(EMU_SRC_FILES:src/emulated/%.c=build/%.riscv.o)
EMU_OBJ := build/emulated.riscv.elf EMU_OBJ := build/emulated.riscv.elf
EMU_OBJ_LICENSE := build/license
GENERATED := build/include/generated.h GENERATED := build/include/generated.h
HOST_SRC := src/main.c src/elf.c HOST_SRC_EXTRA := src/elf.c src/hwinfo.c src/util.c tiny-AES-c/aes.c
HOST_SRC := src/main.c $(HOST_SRC_EXTRA)
HOST_SRC_ENCRYPTOR := src/encryptor.c $(HOST_SRC_EXTRA)
HOST_INCLUDE := -I src -I tinyriscv/src -I tiny-AES-c
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
HOST_EXE := build/main.exe HOST_EXE := build/main.exe
@@ -27,6 +31,13 @@ else
HOST_EXE := build/main HOST_EXE := build/main
endif endif
ifeq ($(OS),Windows_NT)
HOST_EXE_ENCRYPTOR := build/encryptor.exe
else
HOST_EXE_ENCRYPTOR := build/encryptor
endif
# Disassembly # Disassembly
RISCV_OBJDUMP ?= $(patsubst %-gcc,%-objdump,$(RISCV_CC)) RISCV_OBJDUMP ?= $(patsubst %-gcc,%-objdump,$(RISCV_CC))
_DISAS_TARGETS := $(filter disas-%,$(MAKECMDGOALS)) _DISAS_TARGETS := $(filter disas-%,$(MAKECMDGOALS))
@@ -36,18 +47,29 @@ _DISAS_FILES := $(if $(_DISAS_TARGETS),$(filter %.elf %.o,$(MAKECMDGOALS)))
.PHONY: all emulated-riscv host clean disas-risc .PHONY: all emulated-riscv host clean disas-risc
all: $(HOST_EXE) $(EMU_OBJ) all: $(HOST_EXE) $(EMU_OBJ_LICENSE) $(HOST_EXE_ENCRYPTOR)
emulated-riscv: $(EMU_OBJ) emulated-riscv: $(EMU_OBJ_LICENSE)
host: $(HOST_EXE) host: $(HOST_EXE) $(HOST_EXE_ENCRYPTOR)
$(HOST_EXE): $(HOST_SRC) tinyriscv/src/tinyriscv.h src/config.h src/elf.h | build $(HOST_EXE): $(HOST_SRC) | build
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -I src -I tinyriscv/src $(HOST_SRC) -o $@ $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_INCLUDE) $(HOST_SRC) -o $@
build/%.riscv.o: src/emulated/%.c $(GENERATED) | build $(HOST_EXE_ENCRYPTOR): $(HOST_SRC_ENCRYPTOR) | build
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_INCLUDE) $(HOST_SRC_ENCRYPTOR) -o $@
build/%.riscv.o: src/emulated/%.c $(GENERATED) $(HOST_EXE_ENCRYPTOR) | build
$(RISCV_CC) $(RISCV_ARCH_FLAGS) -I $(dir $(GENERATED)) -I src/emulated -c $< -o $@ $(RISCV_CC) $(RISCV_ARCH_FLAGS) -I $(dir $(GENERATED)) -I src/emulated -c $< -o $@
EMU_OBJ_LICENSE_IF_EXISTS := $(wildcard $(EMU_OBJ_LICENSE))
$(EMU_OBJ_LICENSE): $(EMU_OBJ) | build
ifneq ($(EMU_OBJ_LICENSE_IF_EXISTS),)
rm $(EMU_OBJ_LICENSE_IF_EXISTS)
endif
$(HOST_EXE_ENCRYPTOR) $(EMU_OBJ) $@
$(EMU_OBJ): $(EMU_OBJ_FILES) | build $(EMU_OBJ): $(EMU_OBJ_FILES) | build
$(RISCV_CC) $(RISCV_ARCH_FLAGS) -nostdlib -Wl,-e,entry -Wl,-Ttext=0 -Wl,--emit-relocs $(EMU_OBJ_FILES) -o $@ $(RISCV_CC) $(RISCV_ARCH_FLAGS) -nostdlib -Wl,-e,entry -Wl,-Ttext=0 -Wl,--emit-relocs $(EMU_OBJ_FILES) -o $@

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#define EMU_MEM_SIZE 16384u #define EMU_MEM_SIZE 16384u
#define EMU_PROGRAM_PATH "build/emulated.riscv.elf" #define EMU_PROGRAM_PATH "build/license"
#define EMU_ENTRY_SYMBOL "entry" #define EMU_ENTRY_SYMBOL "entry"
#define STACK_SIZE 1024 #define STACK_SIZE 1024

View File

@@ -8,45 +8,41 @@
#include <stdlib.h> #include <stdlib.h>
static int read_file_bytes(const char* path, uint8_t** out_buf, size_t* out_size) { static int read_file_bytes(FILE* f, uint8_t** out_buf, size_t* out_size) {
FILE* f = fopen(path, "rb");
if (!f) { if (!f) {
fprintf(stderr, "Failed to open object file: %s (%s)\n", path, strerror(errno)); fprintf(stderr, "Failed to open object file: (%s)\n", strerror(errno));
return LOAD_ERR_OPEN; return LOAD_ERR_OPEN;
} }
rewind(f);
if (fseek(f, 0, SEEK_END) != 0) { if (fseek(f, 0, SEEK_END) != 0) {
fclose(f); fprintf(stderr, "Failed to seek object file\n");
fprintf(stderr, "Failed to seek object file: %s\n", path);
return LOAD_ERR_SMALL_FILE; return LOAD_ERR_SMALL_FILE;
} }
long file_size = ftell(f); long file_size = ftell(f);
if (file_size < 0) { if (file_size < 0) {
fclose(f); fprintf(stderr, "Failed to read object file size\n");
fprintf(stderr, "Failed to read object file size: %s\n", path);
return LOAD_ERR_SMALL_FILE; return LOAD_ERR_SMALL_FILE;
} }
if (fseek(f, 0, SEEK_SET) != 0) { if (fseek(f, 0, SEEK_SET) != 0) {
fclose(f); fprintf(stderr, "Failed to rewind object file\n");
fprintf(stderr, "Failed to rewind object file: %s\n", path);
return LOAD_ERR_SMALL_FILE; return LOAD_ERR_SMALL_FILE;
} }
uint8_t* file_buf = (uint8_t*)malloc((size_t)file_size); uint8_t* file_buf = (uint8_t*)malloc((size_t)file_size);
if (!file_buf) { if (!file_buf) {
fclose(f);
fprintf(stderr, "Failed to allocate %ld bytes for object file\n", file_size); fprintf(stderr, "Failed to allocate %ld bytes for object file\n", file_size);
return LOAD_ERR_OOM; return LOAD_ERR_OOM;
} }
size_t read_count = fread(file_buf, 1, (size_t)file_size, f); size_t read_count = fread(file_buf, 1, (size_t)file_size, f);
fclose(f);
if (read_count != (size_t)file_size) { if (read_count != (size_t)file_size) {
free(file_buf); free(file_buf);
fprintf(stderr, "Object file too small or unreadable: %s\n", path); fprintf(stderr, "Object file too small or unreadable\n");
return LOAD_ERR_SMALL_FILE; return LOAD_ERR_SMALL_FILE;
} }
@@ -267,29 +263,29 @@ static int apply_relocations(const uint8_t* file_buf, size_t bytes, uint8_t* mem
return LOAD_OK; return LOAD_OK;
} }
int load_elf_object_sections(const char* path, uint8_t* memory, uint32_t mem_size) { int load_elf_object_sections(FILE* f, uint8_t* memory, uint32_t mem_size) {
uint8_t* file_buf = NULL; uint8_t* file_buf = NULL;
size_t bytes = 0u; size_t bytes = 0u;
int file_status = read_file_bytes(path, &file_buf, &bytes); int file_status = read_file_bytes(f, &file_buf, &bytes);
if (file_status != LOAD_OK) { if (file_status != LOAD_OK) {
return file_status; return file_status;
} }
if (bytes < 52u) { if (bytes < 52u) {
fprintf(stderr, "Object file too small or unreadable: %s\n", path); fprintf(stderr, "Object file too small or unreadable\n");
free(file_buf); free(file_buf);
return LOAD_ERR_SMALL_FILE; return LOAD_ERR_SMALL_FILE;
} }
if (file_buf[0] != ELF_MAGIC_0 || file_buf[1] != ELF_MAGIC_1 if (file_buf[0] != ELF_MAGIC_0 || file_buf[1] != ELF_MAGIC_1
|| file_buf[2] != ELF_MAGIC_2 || file_buf[3] != ELF_MAGIC_3) { || file_buf[2] != ELF_MAGIC_2 || file_buf[3] != ELF_MAGIC_3) {
fprintf(stderr, "Not an ELF file: %s\n", path); fprintf(stderr, "Not an ELF file\n");
free(file_buf); free(file_buf);
return LOAD_ERR_NOT_ELF; return LOAD_ERR_NOT_ELF;
} }
if (file_buf[4] != ELFCLASS32 || file_buf[5] != ELFDATA2LSB) { if (file_buf[4] != ELFCLASS32 || file_buf[5] != ELFDATA2LSB) {
fprintf(stderr, "Unsupported ELF format in %s (need 32-bit little-endian)\n", path); fprintf(stderr, "Unsupported ELF format (need 32-bit little-endian)\n");
free(file_buf); free(file_buf);
return LOAD_ERR_UNSUPPORTED_FORMAT; return LOAD_ERR_UNSUPPORTED_FORMAT;
} }
@@ -299,13 +295,13 @@ int load_elf_object_sections(const char* path, uint8_t* memory, uint32_t mem_siz
uint16_t e_shnum = read_u16_le(file_buf + 48); uint16_t e_shnum = read_u16_le(file_buf + 48);
if (e_shoff >= bytes || e_shentsize == 0u) { if (e_shoff >= bytes || e_shentsize == 0u) {
fprintf(stderr, "Invalid section header table in %s\n", path); fprintf(stderr, "Invalid section header table\n");
free(file_buf); free(file_buf);
return LOAD_ERR_INVALID_SHT; return LOAD_ERR_INVALID_SHT;
} }
if ((uint32_t)e_shoff + (uint32_t)e_shentsize * (uint32_t)e_shnum > bytes) { if ((uint32_t)e_shoff + (uint32_t)e_shentsize * (uint32_t)e_shnum > bytes) {
fprintf(stderr, "Section headers out of file bounds in %s\n", path); fprintf(stderr, "Section headers out of file bounds\n");
free(file_buf); free(file_buf);
return LOAD_ERR_SHT_OUT_OF_BOUNDS; return LOAD_ERR_SHT_OUT_OF_BOUNDS;
} }
@@ -389,11 +385,11 @@ int load_elf_object_sections(const char* path, uint8_t* memory, uint32_t mem_siz
return reloc_status; return reloc_status;
} }
int resolve_elf_symbol_memory_offset(const char* path, const char* symbol_name, int resolve_elf_symbol_memory_offset(FILE* f, const char* symbol_name,
uint32_t mem_size, uint32_t* out_offset) { uint32_t mem_size, uint32_t* out_offset) {
uint8_t* file_buf = NULL; uint8_t* file_buf = NULL;
size_t bytes = 0u; size_t bytes = 0u;
int file_status = read_file_bytes(path, &file_buf, &bytes); int file_status = read_file_bytes(f, &file_buf, &bytes);
if (file_status != LOAD_OK) { if (file_status != LOAD_OK) {
return file_status; return file_status;
} }

View File

@@ -24,6 +24,7 @@
#define R_RISCV_RELAX 51u #define R_RISCV_RELAX 51u
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
enum { enum {
LOAD_OK = 1, LOAD_OK = 1,
@@ -48,7 +49,7 @@ enum {
uint16_t read_u16_le(const uint8_t* data); uint16_t read_u16_le(const uint8_t* data);
uint32_t read_u32_le(const uint8_t* data); uint32_t read_u32_le(const uint8_t* data);
uint32_t align_up(uint32_t value, uint32_t align); uint32_t align_up(uint32_t value, uint32_t align);
int load_elf_object_sections(const char* path, uint8_t* memory, uint32_t mem_size); int load_elf_object_sections(FILE* f, uint8_t* memory, uint32_t mem_size);
int resolve_elf_symbol_memory_offset(const char* path, const char* symbol_name, int resolve_elf_symbol_memory_offset(FILE* f, const char* symbol_name,
uint32_t mem_size, uint32_t* out_offset); uint32_t mem_size, uint32_t* out_offset);

61
src/encryptor.c Normal file
View File

@@ -0,0 +1,61 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <aes.h>
#include "hwinfo.h"
#include "util.h"
int main(int argc, char** argv) {
if (argc != 3) {
return 1;
}
char* input = argv[1];
char* output = argv[2];
hw_info_t hwinfo = {0};
if(get_hw_info(&hwinfo) != 0){
return 1;
}
uint8_t* key = hwinfo_to_key(hwinfo);
if(key == NULL) {
return 1;
}
fprintf(stderr, "HWINFO: %s\n", hw_info_flatten(hwinfo));
fprintf(stderr, "Key: ");
for (int i = 0; i < 16; i++)
fprintf(stderr, "%02X", key[i]);
fprintf(stderr, "\n");
struct AES_ctx ctx;
uint8_t nonce[16] = {0};
FILE* license = fopen(input, "rb");
long data_start = ftell(license);
fseek(license, 0, SEEK_END);
int license_size = ftell(license) - data_start;
fseek(license, data_start, SEEK_SET);
uint8_t* buf = malloc(license_size);
fread(buf, 1, license_size, license);
AES_init_ctx(&ctx, key);
AES_init_ctx_iv(&ctx, key, nonce);
AES_CTR_xcrypt_buffer(&ctx, buf, license_size);
FILE* encrypted_license = fopen(output, "wb+");
fwrite(&nonce, 1, sizeof(nonce), encrypted_license);
fwrite(buf, 1, license_size, encrypted_license);
fclose(license);
fclose(encrypted_license);
fprintf(stderr, "Wrote encrypted license file to %s\n", output);
return 0;
}

77
src/hwinfo.c Normal file
View File

@@ -0,0 +1,77 @@
#include "hwinfo.h"
#include <stdlib.h>
char* hw_info_flatten(hw_info_t hwinfo) {
int bufsize = strlen(hwinfo.vendor_id) +
strlen(hwinfo.model_name) +
strlen(hwinfo.os_version) +
strlen(hwinfo.mem_total) +
1;
char* hw_info_flat = malloc(bufsize);
if(hw_info_flat == NULL) {
return NULL;
}
memset(hw_info_flat, 0, bufsize);
strcat(hw_info_flat, hwinfo.vendor_id);
strcat(hw_info_flat, hwinfo.model_name);
strcat(hw_info_flat, hwinfo.os_version);
strcat(hw_info_flat, hwinfo.mem_total);
return hw_info_flat;
}
void read_cpu_info(FILE* file, hw_info_t* hwinfo) {
char line[256];
while(fgets(line, sizeof(line), file)) {
if (strncmp(line, "vendor_id", 9) == 0) {
hwinfo->vendor_id = strdup(strchr(line, ':') + 2);
hwinfo->vendor_id[strcspn(hwinfo->vendor_id, "\r\n")] = 0; // Remove newline
} else if (strncmp(line, "model name", 10) == 0) {
hwinfo->model_name = strdup(strchr(line, ':') + 2);
hwinfo->model_name[strcspn(hwinfo->model_name, "\r\n")] = 0; // Remove newline
}
}
}
void read_os_version(FILE* file, hw_info_t* hwinfo) {
char line[256];
if(!fgets(line, sizeof(line), file)){
return;
}
hwinfo->os_version = strdup(strchr(strchr(line, ' ') + 1, ' ') + 1);
hwinfo->os_version[strcspn(hwinfo->os_version, " \r\n")] = 0;
}
void read_mem_info(FILE* file, hw_info_t* hwinfo) {
char line[256];
while(fgets(line, sizeof(line), file)) {
if(strncmp(line, "MemTotal", 8) == 0) {
hwinfo->mem_total = strchr(line, ':') + 1;
hwinfo->mem_total = strdup(hwinfo->mem_total + strspn(hwinfo->mem_total, " "));
*strrchr(hwinfo->mem_total, ' ') = 0;
}
}
}
int get_hw_info(hw_info_t* hwinfo) {
FILE* f_cpuinfo = fopen("/proc/cpuinfo", "rb");
FILE* f_osversion = fopen("/proc/version", "rb");
FILE* f_meminfo = fopen("/proc/meminfo", "rb");
if(!f_cpuinfo || !f_osversion || !f_meminfo) {
return 1;
}
read_cpu_info(f_cpuinfo, hwinfo);
read_os_version(f_osversion, hwinfo);
read_mem_info(f_meminfo, hwinfo);
return 0;
}

19
src/hwinfo.h Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#include <stdio.h>
#include <string.h>
typedef struct HWInfo {
char* vendor_id;
char* model_name;
char* os_version;
char* mem_total;
} hw_info_t;
char* hw_info_flatten(hw_info_t hwinfo);
void read_cpu_info(FILE* file, hw_info_t* hwinfo);
void read_os_version(FILE* file, hw_info_t* hwinfo);
void read_mem_info(FILE* file, hw_info_t* hwinfo);
int get_hw_info(hw_info_t* hwinfo);

View File

@@ -1,18 +1,78 @@
#define TINYRISCV_M #define TINYRISCV_M
#include "tinyriscv.h"
#include "elf.h" #include "elf.h"
#include "hwinfo.h"
#include "util.h"
#include "aes.h"
#include "tinyriscv.h"
#include "config.h" #include "config.h"
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#define MAX_STEPS 1024u #define MAX_STEPS 1024u
int main(){ int main(){
hw_info_t hwinfo = {0};
if(get_hw_info(&hwinfo) != 0){
return 1;
}
uint8_t* key = hwinfo_to_key(hwinfo);
if(key == NULL) {
return 1;
}
fprintf(stderr, "HWINFO: %s\n", hw_info_flatten(hwinfo));
fprintf(stderr, "Key: ");
for (int i = 0; i < 16; i++)
fprintf(stderr, "%02X", key[i]);
fprintf(stderr, "\n");
struct AES_ctx ctx;
uint8_t nonce[16] = {0};
FILE* license = fopen(EMU_PROGRAM_PATH, "rb");
fread(nonce, 16, 1, license);
long data_start = ftell(license);
fseek(license, 0, SEEK_END);
int license_size = ftell(license) - data_start;
fseek(license, data_start, SEEK_SET);
uint8_t* buf = malloc(license_size);
fread(buf, 1, license_size, license);
// void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
// void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
// void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
AES_init_ctx(&ctx, key);
AES_init_ctx_iv(&ctx, key, nonce);
AES_CTR_xcrypt_buffer(&ctx, buf, license_size);
FILE* decrypted_license = tmpfile();
fwrite(buf, 1, license_size, decrypted_license);
rewind(decrypted_license);
char begin[8] = {0};
char expected[] = {0x7F, 'E', 'L', 'F', 1, 1, 1, 0};
fread(begin, 1, sizeof(begin), decrypted_license);
if(memcmp(begin, expected, sizeof(begin)) != 0) {
// This happens when decryption fails
printf("You are not authorized to use this software!\n");
return 1;
}
const int maxninput = 255; const int maxninput = 255;
printf("Please enter the flag: "); printf("Please enter the flag: ");
fflush(stdout); fflush(stdout);
@@ -34,9 +94,9 @@ int main(){
memcpy(memory + SECTION_USERDATA + 1, userinput, real_len); memcpy(memory + SECTION_USERDATA + 1, userinput, real_len);
// Load elf, keep 512 bytes as safe buffer // Load elf, keep 512 bytes as safe buffer
int load_status = load_elf_object_sections(EMU_PROGRAM_PATH, memory, cpu.mem_size - SIZE_USERDATA); int load_status = load_elf_object_sections(decrypted_license, memory, cpu.mem_size - SIZE_USERDATA);
if (load_status != LOAD_OK) { if (load_status != LOAD_OK) {
fprintf(stderr, "ELF load failed with code %d for '%s'\n", load_status, EMU_PROGRAM_PATH); fprintf(stderr, "ELF load failed with code %d for decrypted license\n", load_status);
fflush(stderr); fflush(stderr);
printf("ELF load failed with code %d\n", load_status); printf("ELF load failed with code %d\n", load_status);
fflush(stdout); fflush(stdout);
@@ -45,7 +105,7 @@ int main(){
uint32_t entry_offset = 0u; uint32_t entry_offset = 0u;
int symbol_status = resolve_elf_symbol_memory_offset( int symbol_status = resolve_elf_symbol_memory_offset(
EMU_PROGRAM_PATH, EMU_ENTRY_SYMBOL, cpu.mem_size, &entry_offset); decrypted_license, EMU_ENTRY_SYMBOL, cpu.mem_size, &entry_offset);
if (symbol_status != LOAD_OK) { if (symbol_status != LOAD_OK) {
fprintf(stderr, "Entry symbol '%s' resolve failed with code %d for '%s'\n", fprintf(stderr, "Entry symbol '%s' resolve failed with code %d for '%s'\n",
EMU_ENTRY_SYMBOL, symbol_status, EMU_PROGRAM_PATH); EMU_ENTRY_SYMBOL, symbol_status, EMU_PROGRAM_PATH);
@@ -72,9 +132,9 @@ int main(){
uint32_t result = (uint32_t)cpu.x[10]; uint32_t result = (uint32_t)cpu.x[10];
if(result == 1) { if(result == 1) {
printf("Congrats! That's the flag!"); printf("Congrats! That's the flag!\n");
} else { } else {
printf("Nope, sorry, that's incorrect!"); printf("Nope, sorry, that's incorrect!\n");
} }
return 0; return 0;

44
src/util.c Normal file
View File

@@ -0,0 +1,44 @@
#include "util.h"
#include <stdlib.h>
/*
We do the following algorithm twice
algorithm fnv-1a is
hash := FNV_offset_basis
for each byte_of_data to be hashed do
hash := hash XOR byte_of_data
hash := hash × FNV_prime
return hash
*/
void dual_fnv_hash(char* input, uint8_t key[16]) {
uint64_t lower = 0xcbf29ce484222325;
uint64_t upper = 0xcbf29ce484222325 + 0xC0010FF5E7; // add a made-up constant
while(*input != 0) {
lower = (lower ^ *input) * FNV_PRIME;
upper = (upper ^ *input) * FNV_PRIME;
input += 1;
}
memcpy(key, &lower, 8);
memcpy(key + 8, &upper, 8);
}
uint8_t* hwinfo_to_key(hw_info_t hwinfo) {
char* hw_info_flat = hw_info_flatten(hwinfo);
if (hw_info_flat == NULL){
return NULL;
}
uint8_t* key = malloc(16);
dual_fnv_hash(hw_info_flat, key);
return key;
}

15
src/util.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include "hwinfo.h"
#include <stdint.h>
#define FNV_PRIME 0x00000100000001b3
// Generate an aes key by hashing the input
// This hash is not safe in any way
// But it is fast and easy to implement!
// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
void dual_fnv_hash(char* input, uint8_t key[16]);
uint8_t* hwinfo_to_key(hw_info_t hwinfo);

1
tiny-AES-c Submodule

Submodule tiny-AES-c added at 23856752fb