commit a44810a181c59657c0752f0c13725b08d81a1f62 Author: Timerix Date: Fri Jul 18 22:24:05 2025 +0300 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..498924c --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# build results +bin/ +obj/ + +# IDE files +.vs/ +.vshistory/ +.editorconfig +*.user +*.vcxproj.filters + +# other files +.old*/ +old/ +tmp/ +temp/ +*.tmp +*.temp +logs/ +log/ +*.log diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2d1c599 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "dependencies/BearSSL"] + path = dependencies/BearSSL + url = https://www.bearssl.org/git/BearSSL +[submodule "dependencies/tlibc"] + path = dependencies/tlibc + url = https://timerix.ddns.net/git/timerix/tlibc.git diff --git a/.vscode/.gitignore b/.vscode/.gitignore new file mode 100755 index 0000000..c3d3a20 --- /dev/null +++ b/.vscode/.gitignore @@ -0,0 +1 @@ +settings.json \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100755 index 0000000..7f0fd13 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,15 @@ +{ + "configurations": [ + { + "name": "all", + "defines": [], + "includePath": [ + "dependencies", + "src", + "${default}" + ], + "cStandard": "c99" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f25ba41 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,29 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "gdb_debug", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/bin/tcp-chat", + "windows": { "program": "${workspaceFolder}/bin/tcp-chat.exe" }, + "preLaunchTask": "build_exec_dbg", + "stopAtEntry": false, + "cwd": "${workspaceFolder}/bin", + "externalConsole": false, + "internalConsoleOptions": "neverOpen", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..17a453c --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,31 @@ + +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build_exec_dbg", + "detail": "build project with debug symbols", + "type": "cppbuild", + "command": "bash", + "args": [ + "-c", + "cbuild build_exec_dbg" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": ["$gcc"], + "group": { + "kind": "build" + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "shared", + "showReuseMessage": false, + "clear": true + } + } + ] + } \ No newline at end of file diff --git a/dependencies/BearSSL b/dependencies/BearSSL new file mode 160000 index 0000000..3c04036 --- /dev/null +++ b/dependencies/BearSSL @@ -0,0 +1 @@ +Subproject commit 3c040368f6791553610e362401db1efff4b4c5b8 diff --git a/dependencies/bearssl.config b/dependencies/bearssl.config new file mode 100644 index 0000000..51e2eed --- /dev/null +++ b/dependencies/bearssl.config @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +DEP_WORKING_DIR="dependencies/BearSSL" +DEP_PRE_BUILD_COMMAND="" +DEP_POST_BUILD_COMMAND="" +projconfig_path="../bearssl.project.config" +if [[ "$TASK" = *_dbg ]]; then + dep_build_target="build_static_lib_dbg" +else + dep_build_target="build_static_lib" +fi +DEP_BUILD_COMMAND="cbuild -c $projconfig_path $dep_build_target" +DEP_CLEAN_COMMAND="cbuild -c $projconfig_path clean" +DEP_DYNAMIC_OUT_FILES="" +DEP_STATIC_OUT_FILES="bin/libbearssl.a" +DEP_OTHER_OUT_FILES="" +PRESERVE_OUT_DIRECTORY_STRUCTURE=false diff --git a/dependencies/bearssl.project.config b/dependencies/bearssl.project.config new file mode 100644 index 0000000..c536c01 --- /dev/null +++ b/dependencies/bearssl.project.config @@ -0,0 +1,191 @@ +#!/usr/bin/env bash +CBUILD_VERSION=2.2.3 + +PROJECT="bearssl" +CMP_C="gcc" +CMP_CPP="g++" +STD_C="c11" +STD_CPP="c++11" +WARN_C="-Wno-unknown-pragmas" +# WARN_CPP="-Wall -Wextra" + +SRC_C="" +for d in codec int hash rand rsa symcipher; do + SRC_C+=" $(find src/$d -name '*.c')" +done +#SRC_CPP="$(find src -name '*.cpp')" + +# Directory with dependency configs. +# See cbuild/example_dependency_configs +DEPENDENCY_CONFIGS_DIR='..' +# List of dependency config files in DEPENDENCY_CONFIGS_DIR separated by space. +ENABLED_DEPENDENCIES='' + +# OBJDIR structure: +# ├── objects/ - Compiled object files. Cleans on each call of build task +# ├── static_libs/ - Symbolic links to static libraries used by linker. Cleans on each call of build task. +# ├── static_libs/ - Symbolic links to dynamic libraries used by linker. Cleans on each call of build task. +# └── profile/ - gcc *.gcda profiling info files +OBJDIR="obj" +OUTDIR="bin" +STATIC_LIB_FILE="lib$PROJECT.a" + +INCLUDE="-I./src -I./inc" + +# OS-specific options +case "$OS" in + WINDOWS) + EXEC_FILE="$PROJECT.exe" + SHARED_LIB_FILE="$PROJECT.dll" + LINKER_LIBS="" + ;; + LINUX) + EXEC_FILE="$PROJECT" + SHARED_LIB_FILE="$PROJECT.so" + LINKER_LIBS="" + ;; + *) + error "operating system $OS has no configuration variants" + ;; +esac + +# TASKS +case "$TASK" in + # creates executable using profiling info if it exists + build_exec) + # -flto applies more optimizations across object files + # -flto=auto is needed to multithreaded copilation + # -fuse-linker-plugin is required to use static libs with lto + # -fprofile-use enables compiler to use profiling info files to optimize executable + # -fprofile-prefix-path sets path where profiling info about objects are be saved + # -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + POST_TASK_SCRIPT= + ;; + # creates executable with debug info and no optimizations + build_exec_dbg) + C_ARGS="-O0 -g3" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + POST_TASK_SCRIPT= + ;; + # creates shared library + build_shared_lib) + C_ARGS="-O2 -fpic -flto -shared" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh + POST_TASK_SCRIPT= + ;; + # creates shared library with debug symbols and no optimizations + build_shared_lib_dbg) + C_ARGS="-O0 -g3 -fpic -shared" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh + POST_TASK_SCRIPT= + ;; + # creates static library + build_static_lib) + C_ARGS="-O2 -fpic -fdata-sections -ffunction-sections" + CPP_ARGS="$C_ARGS" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh + POST_TASK_SCRIPT= + ;; + # creates static library with debug symbols and no optimizations + build_static_lib_dbg) + C_ARGS="-O0 -g3" + CPP_ARGS="$C_ARGS" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh + POST_TASK_SCRIPT= + ;; + # executes $EXEC_FILE + exec) + TASK_SCRIPT=cbuild/default_tasks/exec.sh + ;; + # executes $EXEC_FILE with valgrind memory checker + valgrind) + VALGRIND_ARGS="-s --read-var-info=yes --track-origins=yes --fullpath-after=$(pwd)/ --leak-check=full --show-leak-kinds=all" + TASK_SCRIPT=cbuild/default_tasks/valgrind.sh + ;; + # generates profiling info + profile) + OUTDIR="$OUTDIR/profile" + # -flto applies more optimizations across object files + # -flto=auto is needed to multithreaded copilation + # -fuse-linker-plugin is required to use static libs with lto + # -pg adds code to executable, that generates file containing function call info (gmon.out) + # -fprofile-generate generates executable with profiling code + # -fprofile-prefix-path sets path where profiling info about objects will be saved + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/profile.sh + POST_TASK_SCRIPT= + ;; + # compiles program with -pg and runs it with gprof + # uses gprof2dot python script to generate function call tree (pip install gprof2dot) + # requires graphviz (https://www.graphviz.org/download/source/) + gprof) + OUTDIR="$OUTDIR/gprof" + # -pg adds code to executable, that generates file containing function call info (gmon.out) + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/gprof.sh + POST_TASK_SCRIPT= + ;; + # compiles program and runs it with callgrind (part of valgrind) + # uses gprof2dot python script to generate function call tree (pip install gprof2dot) + # requires graphviz (https://www.graphviz.org/download/source/) + # P.S. detailed results can be viewed in KCacheGrind + callgrind) + OUTDIR="$OUTDIR/callgrind" + # -pg adds code to executable, that generates file containing function call info (gmon.out) + C_ARGS="-O2 -flto=auto -fuse-linker-plugin" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/callgrind.sh + POST_TASK_SCRIPT= + ;; + # compiles executable with sanitizers and executes it to find errors and warnings + sanitize) + OUTDIR="$OUTDIR/sanitize" + C_ARGS="-O0 -g3 -fsanitize=undefined,address" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/exec.sh + POST_TASK_SCRIPT= + ;; + # rebuilds specified dependencies + # EXAMPLE: `cbuild rebuild_dependencies=libexample1,fonts` + # 'all' can be specified to rebuild all dependencies + rebuild_dependencies) + TASK_SCRIPT=cbuild/default_tasks/rebuild_dependencies.sh + ;; + # deletes generated files + clean) + TASK_SCRIPT=cbuild/default_tasks/clean.sh + ;; + # nothing to do + "" | no_task) + ;; + # unknown task + *) + error "task <$PROJECT/$TASK> not found" + ;; +esac diff --git a/dependencies/tlibc b/dependencies/tlibc new file mode 160000 index 0000000..921bada --- /dev/null +++ b/dependencies/tlibc @@ -0,0 +1 @@ +Subproject commit 921bada09a86f2364464f8ce9301048e5a8e5344 diff --git a/dependencies/tlibc.config b/dependencies/tlibc.config new file mode 100644 index 0000000..a7eb037 --- /dev/null +++ b/dependencies/tlibc.config @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +DEP_WORKING_DIR="dependencies/tlibc" +DEP_PRE_BUILD_COMMAND="" +DEP_POST_BUILD_COMMAND="" +if [[ "$TASK" = *_dbg ]]; then + dep_build_target="build_static_lib_dbg" +else + dep_build_target="build_static_lib" +fi +DEP_BUILD_COMMAND="cbuild $dep_build_target" +DEP_CLEAN_COMMAND="cbuild clean" +DEP_DYNAMIC_OUT_FILES="" +DEP_STATIC_OUT_FILES="bin/tlibc.a" +DEP_OTHER_OUT_FILES="" +PRESERVE_OUT_DIRECTORY_STRUCTURE=false diff --git a/project.config b/project.config new file mode 100644 index 0000000..5a09686 --- /dev/null +++ b/project.config @@ -0,0 +1,189 @@ +#!/usr/bin/env bash +CBUILD_VERSION=2.2.3 + +PROJECT="tcp-chat" +CMP_C="gcc" +CMP_CPP="g++" +STD_C="c99" +STD_CPP="c++11" +WARN_C="-Wall -Wextra -Wno-unused-parameter" +WARN_CPP="-Wall -Wextra -Wno-unused-parameter" +SRC_C="$(find src -name '*.c')" +#SRC_CPP="$(find src -name '*.cpp')" + +# Directory with dependency configs. +# See cbuild/example_dependency_configs +DEPENDENCY_CONFIGS_DIR='dependencies' +# List of dependency config files in DEPENDENCY_CONFIGS_DIR separated by space. +ENABLED_DEPENDENCIES='tlibc bearssl' + +# OBJDIR structure: +# ├── objects/ - Compiled object files. Cleans on each call of build task +# ├── static_libs/ - Symbolic links to static libraries used by linker. Cleans on each call of build task. +# ├── static_libs/ - Symbolic links to dynamic libraries used by linker. Cleans on each call of build task. +# └── profile/ - gcc *.gcda profiling info files +OBJDIR="obj" +OUTDIR="bin" +STATIC_LIB_FILE="lib$PROJECT.a" + +INCLUDE="-I./src -I./dependencies" + +# OS-specific options +case "$OS" in + WINDOWS) + EXEC_FILE="$PROJECT.exe" + SHARED_LIB_FILE="$PROJECT.dll" + INCLUDE="$INCLUDE " + LINKER_LIBS="-lpthread -lws2_32" + ;; + LINUX) + EXEC_FILE="$PROJECT" + SHARED_LIB_FILE="$PROJECT.so" + INCLUDE="$INCLUDE " + LINKER_LIBS="" + ;; + *) + error "operating system $OS has no configuration variants" + ;; +esac + +# TASKS +case "$TASK" in + # creates executable using profiling info if it exists + build_exec) + # -flto applies more optimizations across object files + # -flto=auto is needed to multithreaded copilation + # -fuse-linker-plugin is required to use static libs with lto + # -fprofile-use enables compiler to use profiling info files to optimize executable + # -fprofile-prefix-path sets path where profiling info about objects are be saved + # -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + POST_TASK_SCRIPT= + ;; + # creates executable with debug info and no optimizations + build_exec_dbg) + C_ARGS="-O0 -g3" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + POST_TASK_SCRIPT= + ;; + # creates shared library + build_shared_lib) + C_ARGS="-O2 -fpic -flto -shared" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh + POST_TASK_SCRIPT= + ;; + # creates shared library with debug symbols and no optimizations + build_shared_lib_dbg) + C_ARGS="-O0 -g3 -fpic -shared" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh + POST_TASK_SCRIPT= + ;; + # creates static library + build_static_lib) + C_ARGS="-O2 -fpic -fdata-sections -ffunction-sections" + CPP_ARGS="$C_ARGS" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh + POST_TASK_SCRIPT= + ;; + # creates static library with debug symbols and no optimizations + build_static_lib_dbg) + C_ARGS="-O0 -g3" + CPP_ARGS="$C_ARGS" + PRE_TASK_SCRIPT= + TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh + POST_TASK_SCRIPT= + ;; + # executes $EXEC_FILE + exec) + TASK_SCRIPT=cbuild/default_tasks/exec.sh + ;; + # executes $EXEC_FILE with valgrind memory checker + valgrind) + VALGRIND_ARGS="-s --read-var-info=yes --track-origins=yes --fullpath-after=$(pwd)/ --leak-check=full --show-leak-kinds=all" + TASK_SCRIPT=cbuild/default_tasks/valgrind.sh + ;; + # generates profiling info + profile) + OUTDIR="$OUTDIR/profile" + # -flto applies more optimizations across object files + # -flto=auto is needed to multithreaded copilation + # -fuse-linker-plugin is required to use static libs with lto + # -pg adds code to executable, that generates file containing function call info (gmon.out) + # -fprofile-generate generates executable with profiling code + # -fprofile-prefix-path sets path where profiling info about objects will be saved + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/profile.sh + POST_TASK_SCRIPT= + ;; + # compiles program with -pg and runs it with gprof + # uses gprof2dot python script to generate function call tree (pip install gprof2dot) + # requires graphviz (https://www.graphviz.org/download/source/) + gprof) + OUTDIR="$OUTDIR/gprof" + # -pg adds code to executable, that generates file containing function call info (gmon.out) + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/gprof.sh + POST_TASK_SCRIPT= + ;; + # compiles program and runs it with callgrind (part of valgrind) + # uses gprof2dot python script to generate function call tree (pip install gprof2dot) + # requires graphviz (https://www.graphviz.org/download/source/) + # P.S. detailed results can be viewed in KCacheGrind + callgrind) + OUTDIR="$OUTDIR/callgrind" + # -pg adds code to executable, that generates file containing function call info (gmon.out) + C_ARGS="-O2 -flto=auto -fuse-linker-plugin" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/callgrind.sh + POST_TASK_SCRIPT= + ;; + # compiles executable with sanitizers and executes it to find errors and warnings + sanitize) + OUTDIR="$OUTDIR/sanitize" + C_ARGS="-O0 -g3 -fsanitize=undefined,address" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/exec.sh + POST_TASK_SCRIPT= + ;; + # rebuilds specified dependencies + # EXAMPLE: `cbuild rebuild_dependencies=libexample1,fonts` + # 'all' can be specified to rebuild all dependencies + rebuild_dependencies) + TASK_SCRIPT=cbuild/default_tasks/rebuild_dependencies.sh + ;; + # deletes generated files + clean) + TASK_SCRIPT=cbuild/default_tasks/clean.sh + ;; + # nothing to do + "" | no_task) + ;; + # unknown task + *) + error "task <$PROJECT/$TASK> not found" + ;; +esac diff --git a/src/main.c b/src/main.c new file mode 100755 index 0000000..4875dfc --- /dev/null +++ b/src/main.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +char *print_hex_memory(u8 *p, u32 len) { + char tmp[3]; + u32 output_len = len*2+1; + char *output = (char*)malloc(output_len); + memset(output, 0, output_len); + for (u32 i=0; i < len; i++) { + sprintf(tmp, "%02x", p[i]); + strcat(output, tmp); + } + return output; +} + +int main(){ + const char key_raw[] = "abobus"; + const u32 key_raw_len = ARRAY_SIZE(key_raw)-1; + const char data[] = "0123456789_hii_"; // must be multiple of 16 + const u32 data_len = ARRAY_SIZE(data); + + u8 hash_buffer[br_sha256_SIZE]; + const u32 hash_buffer_len = ARRAY_SIZE(hash_buffer); + memset(hash_buffer, 0, hash_buffer_len); + memcpy(hash_buffer, key_raw, key_raw_len); + + br_sha256_context sha256_ctx; + br_sha256_init(&sha256_ctx); + + // hash multiple times + for(i32 i = 0; i < 8; i++){ + br_sha256_update(&sha256_ctx, hash_buffer, hash_buffer_len); + br_sha256_out(&sha256_ctx, hash_buffer); + printf("hash(i=%i) %s\n", i, print_hex_memory(hash_buffer, hash_buffer_len)); + } + + + u8 key_padded[32]; // must be 16 or 24 or 32 + const u32 key_padded_len = ARRAY_SIZE(key_padded); + memset(key_padded, 0, key_padded_len); + memcpy(key_padded, hash_buffer, key_padded_len); + + u8 buffer[512]; + const u32 buffer_len = ARRAY_SIZE(buffer); + memset(buffer, 0, buffer_len); + memcpy(buffer, data, data_len); + + br_aes_ct64_cbcenc_keys enc_ctx; + br_aes_ct64_cbcenc_init(&enc_ctx, key_padded, key_padded_len); + u8 iv[16]; + memset(iv, 0, ARRAY_SIZE(iv)); + br_aes_ct64_cbcenc_run(&enc_ctx, iv, buffer, buffer_len); + + printf("data encrypted\n"); + + br_aes_ct64_cbcdec_keys dec_ctx; + br_aes_ct64_cbcdec_init(&dec_ctx, key_padded, key_padded_len); + memset(iv, 0, ARRAY_SIZE(iv)); + br_aes_ct64_cbcdec_run(&dec_ctx, iv, buffer, buffer_len); + + printf("data decrypted\n"); + fwrite(buffer, 1, buffer_len, stdout); + return 0; +} \ No newline at end of file