Compare commits
2 Commits
7cd7535eb0
...
664ff91e63
| Author | SHA1 | Date | |
|---|---|---|---|
| 664ff91e63 | |||
| e0646139e3 |
2
.vscode/c_cpp_properties.json
vendored
2
.vscode/c_cpp_properties.json
vendored
@ -5,7 +5,7 @@
|
||||
"defines": [],
|
||||
"includePath": [
|
||||
"src",
|
||||
"dependencies",
|
||||
"dependencies/BearSSL/inc",
|
||||
"dependencies/tlibc/include",
|
||||
"${default}"
|
||||
],
|
||||
|
||||
27
dependencies/bearssl.project.config
vendored
27
dependencies/bearssl.project.config
vendored
@ -9,10 +9,7 @@ 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_C="$(find src -name '*.c')"
|
||||
#SRC_CPP="$(find src -name '*.cpp')"
|
||||
|
||||
# Directory with dependency configs.
|
||||
@ -38,11 +35,13 @@ case "$OS" in
|
||||
EXEC_FILE="$PROJECT.exe"
|
||||
SHARED_LIB_FILE="$PROJECT.dll"
|
||||
LINKER_LIBS=""
|
||||
DEFINE=""
|
||||
;;
|
||||
LINUX)
|
||||
EXEC_FILE="$PROJECT"
|
||||
SHARED_LIB_FILE="$PROJECT.so"
|
||||
LINKER_LIBS=""
|
||||
DEFINE="-DBR_USE_GETENTROPY=0"
|
||||
;;
|
||||
*)
|
||||
error "operating system $OS has no configuration variants"
|
||||
@ -59,7 +58,7 @@ case "$TASK" in
|
||||
# -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"
|
||||
C_ARGS="$DEFINE -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=
|
||||
@ -68,7 +67,7 @@ case "$TASK" in
|
||||
;;
|
||||
# creates executable with debug info and no optimizations
|
||||
build_exec_dbg)
|
||||
C_ARGS="-O0 -g3"
|
||||
C_ARGS="$DEFINE -O0 -g3"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||
PRE_TASK_SCRIPT=
|
||||
@ -77,7 +76,7 @@ case "$TASK" in
|
||||
;;
|
||||
# creates shared library
|
||||
build_shared_lib)
|
||||
C_ARGS="-O2 -fpic -flto -shared"
|
||||
C_ARGS="$DEFINE -O2 -fpic -flto -shared"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE"
|
||||
PRE_TASK_SCRIPT=
|
||||
@ -86,7 +85,7 @@ case "$TASK" in
|
||||
;;
|
||||
# creates shared library with debug symbols and no optimizations
|
||||
build_shared_lib_dbg)
|
||||
C_ARGS="-O0 -g3 -fpic -shared"
|
||||
C_ARGS="$DEFINE -O0 -g3 -fpic -shared"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE"
|
||||
PRE_TASK_SCRIPT=
|
||||
@ -95,7 +94,7 @@ case "$TASK" in
|
||||
;;
|
||||
# creates static library
|
||||
build_static_lib)
|
||||
C_ARGS="-O2 -fpic -fdata-sections -ffunction-sections"
|
||||
C_ARGS="$DEFINE -O2 -fpic -fdata-sections -ffunction-sections"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
PRE_TASK_SCRIPT=
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
||||
@ -103,7 +102,7 @@ case "$TASK" in
|
||||
;;
|
||||
# creates static library with debug symbols and no optimizations
|
||||
build_static_lib_dbg)
|
||||
C_ARGS="-O0 -g3"
|
||||
C_ARGS="$DEFINE -O0 -g3"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
PRE_TASK_SCRIPT=
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
||||
@ -127,7 +126,7 @@ case "$TASK" in
|
||||
# -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"
|
||||
C_ARGS="$DEFINE -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
|
||||
@ -140,7 +139,7 @@ case "$TASK" in
|
||||
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"
|
||||
C_ARGS="$DEFINE -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
|
||||
@ -154,7 +153,7 @@ case "$TASK" in
|
||||
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"
|
||||
C_ARGS="$DEFINE -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
|
||||
@ -164,7 +163,7 @@ case "$TASK" in
|
||||
# compiles executable with sanitizers and executes it to find errors and warnings
|
||||
sanitize)
|
||||
OUTDIR="$OUTDIR/sanitize"
|
||||
C_ARGS="-O0 -g3 -fsanitize=undefined,address"
|
||||
C_ARGS="$DEFINE -O0 -g3 -fsanitize=undefined,address"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||
|
||||
@ -26,7 +26,7 @@ OBJDIR="obj"
|
||||
OUTDIR="bin"
|
||||
STATIC_LIB_FILE="lib$PROJECT.a"
|
||||
|
||||
INCLUDE="-I./src -I./dependencies -I./dependencies/tlibc/include"
|
||||
INCLUDE="-I./src -I./dependencies/BearSSL/inc -I./dependencies/tlibc/include"
|
||||
|
||||
# OS-specific options
|
||||
case "$OS" in
|
||||
|
||||
@ -1,125 +1,95 @@
|
||||
#include "cryptography.h"
|
||||
#include "BearSSL/inc/bearssl_block.h"
|
||||
#include <assert.h>
|
||||
#include "tlibc/time.h"
|
||||
|
||||
// size must be multiple of 16
|
||||
#define __AES_BUFFER_SIZE 256
|
||||
|
||||
typedef struct EncryptorAES {
|
||||
br_aes_ct64_cbcenc_keys enc_ctx;
|
||||
Array buf;
|
||||
Array iv;
|
||||
} EncryptorAES;
|
||||
|
||||
typedef struct DecryptorAES {
|
||||
br_aes_ct64_cbcdec_keys dec_ctx;
|
||||
Array buf;
|
||||
Array iv;
|
||||
} DecryptorAES;
|
||||
|
||||
EncryptorAES* EncryptorAES_create(Array key){
|
||||
void EncryptorAES_create(EncryptorAES* ptr, Array key){
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
|
||||
EncryptorAES* ptr = (EncryptorAES*)malloc(sizeof(EncryptorAES));
|
||||
br_aes_ct64_cbcenc_init(&ptr->enc_ctx, key.data, key.size);
|
||||
|
||||
// size must be multiple of 16
|
||||
ptr->buf = Array_alloc(u8, __AES_BUFFER_SIZE);
|
||||
Array_memset(&ptr->buf, 0);
|
||||
// uses CLOCK_REALTIME to seed rng
|
||||
nsec_t time_now = getTimeNsec();
|
||||
br_hmac_drbg_init(&ptr->rng_ctx, &br_sha256_vtable, &time_now, sizeof(time_now));
|
||||
|
||||
// size of one SHA block (16 bytes)
|
||||
ptr->iv = Array_alloc(u8, 16);
|
||||
Array_memset(&ptr->iv, 0);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void EncryptorAES_destroy(EncryptorAES* ptr){
|
||||
free(ptr->buf.data);
|
||||
free(ptr->iv.data);
|
||||
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
||||
memset(ptr->iv, 0, sizeof(ptr->iv));
|
||||
}
|
||||
|
||||
void EncryptorAES_encrypt(EncryptorAES* ptr, Array src, Array dst){
|
||||
assert(dst.size >= EncryptorAES_calcDstSize(src.size));
|
||||
|
||||
// write random bytes to the beginning of the buffer
|
||||
br_hmac_drbg_generate(&ptr->rng_ctx, ptr->buf, __AES_RANDOM_BYTES_N);
|
||||
const EncryptedBlockInfo block_info = { .padding_size = 16 - src.size % 16 };
|
||||
memcpy(ptr->buf.data, &block_info, sizeof(EncryptedBlockInfo));
|
||||
// encrypt this struct
|
||||
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv.data, ptr->buf.data, sizeof(EncryptedBlockInfo));
|
||||
// emit EncryptedBlockInfo to beginning of result
|
||||
memcpy(dst.data, ptr->buf.data, sizeof(EncryptedBlockInfo));
|
||||
dst.data += sizeof(EncryptedBlockInfo);
|
||||
dst.size -= sizeof(EncryptedBlockInfo);
|
||||
|
||||
// write struct after random_bytes
|
||||
memcpy((u8*)ptr->buf + __AES_RANDOM_BYTES_N, &block_info, sizeof(EncryptedBlockInfo));
|
||||
// encrypt buffer
|
||||
const u32 header_size = __AES_RANDOM_BYTES_N + sizeof(EncryptedBlockInfo);
|
||||
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv, ptr->buf, header_size);
|
||||
// write encrypted header to dst
|
||||
memcpy(dst.data, ptr->buf, header_size);
|
||||
dst.data += header_size;
|
||||
dst.size -= header_size;
|
||||
|
||||
// write full blocks
|
||||
while(src.size > ptr->buf.size){
|
||||
memcpy(ptr->buf.data, src.data, ptr->buf.size);
|
||||
src.data += ptr->buf.size;
|
||||
src.size -= ptr->buf.size;
|
||||
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv.data, ptr->buf.data, ptr->buf.size);
|
||||
memcpy(dst.data, ptr->buf.data, ptr->buf.size);
|
||||
dst.data += ptr->buf.size;
|
||||
dst.size -= ptr->buf.size;
|
||||
while(src.size > __AES_BUFFER_SIZE){
|
||||
memcpy(ptr->buf, src.data, __AES_BUFFER_SIZE);
|
||||
src.data += __AES_BUFFER_SIZE;
|
||||
src.size -= __AES_BUFFER_SIZE;
|
||||
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv, ptr->buf, __AES_BUFFER_SIZE);
|
||||
memcpy(dst.data, ptr->buf, __AES_BUFFER_SIZE);
|
||||
dst.data += __AES_BUFFER_SIZE;
|
||||
dst.size -= __AES_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// write incomplete block
|
||||
Array_memset(&ptr->buf, 0);
|
||||
memcpy(ptr->buf.data, src.data, src.size);
|
||||
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
||||
memcpy(ptr->buf, src.data, src.size);
|
||||
u32 src_size_padded = src.size + block_info.padding_size;
|
||||
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv.data, ptr->buf.data, src_size_padded);
|
||||
memcpy(dst.data, ptr->buf.data, src_size_padded);
|
||||
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv, ptr->buf, src_size_padded);
|
||||
memcpy(dst.data, ptr->buf, src_size_padded);
|
||||
}
|
||||
|
||||
|
||||
DecryptorAES* DecryptorAES_create(Array key){
|
||||
void DecryptorAES_create(DecryptorAES* ptr, Array key){
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
|
||||
DecryptorAES* ptr = (DecryptorAES*)malloc(sizeof(DecryptorAES));
|
||||
br_aes_ct64_cbcdec_init(&ptr->dec_ctx, key.data, key.size);
|
||||
|
||||
// size must be multiple of 16
|
||||
ptr->buf = Array_alloc(u8, __AES_BUFFER_SIZE);
|
||||
Array_memset(&ptr->buf, 0);
|
||||
|
||||
// size of one SHA block (16 bytes)
|
||||
ptr->iv = Array_alloc(u8, 16);
|
||||
Array_memset(&ptr->iv, 0);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void DecryptorAES_destroy(DecryptorAES* ptr){
|
||||
free(ptr->buf.data);
|
||||
free(ptr->iv.data);
|
||||
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
||||
memset(ptr->iv, 0, sizeof(ptr->iv));
|
||||
}
|
||||
|
||||
void DecryptorAES_decrypt(DecryptorAES* ptr, Array src, Array dst, u32* decrypted_size){
|
||||
assert(dst.size >= src.size);
|
||||
|
||||
// read EncryptedBlockInfo from beginning of data
|
||||
// copy encrypted header from src to buffer
|
||||
const u32 header_size = __AES_RANDOM_BYTES_N + sizeof(EncryptedBlockInfo);
|
||||
memcpy(ptr->buf, src.data, header_size);
|
||||
src.data += header_size;
|
||||
src.size -= header_size;
|
||||
// decrypt buffer
|
||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv, &ptr->buf, header_size);
|
||||
// read EncryptedBlockInfo from buffer
|
||||
EncryptedBlockInfo block_info;
|
||||
memcpy(&block_info, src.data, sizeof(EncryptedBlockInfo));
|
||||
src.data += sizeof(EncryptedBlockInfo);
|
||||
src.size -= sizeof(EncryptedBlockInfo);
|
||||
// decrypt this struct
|
||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv.data, &block_info, sizeof(EncryptedBlockInfo));
|
||||
memcpy(&block_info, (u8*)ptr->buf + __AES_RANDOM_BYTES_N, sizeof(EncryptedBlockInfo));
|
||||
*decrypted_size = src.size - block_info.padding_size;
|
||||
|
||||
// write full blocks
|
||||
while(src.size > ptr->buf.size){
|
||||
memcpy(ptr->buf.data, src.data, ptr->buf.size);
|
||||
src.data += ptr->buf.size;
|
||||
src.size -= ptr->buf.size;
|
||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv.data, ptr->buf.data, ptr->buf.size);
|
||||
memcpy(dst.data, ptr->buf.data, ptr->buf.size);
|
||||
dst.data += ptr->buf.size;
|
||||
dst.size -= ptr->buf.size;
|
||||
while(src.size > __AES_BUFFER_SIZE){
|
||||
memcpy(ptr->buf, src.data, __AES_BUFFER_SIZE);
|
||||
src.data += __AES_BUFFER_SIZE;
|
||||
src.size -= __AES_BUFFER_SIZE;
|
||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv, ptr->buf, __AES_BUFFER_SIZE);
|
||||
memcpy(dst.data, ptr->buf, __AES_BUFFER_SIZE);
|
||||
dst.data += __AES_BUFFER_SIZE;
|
||||
dst.size -= __AES_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// write incomplete block
|
||||
Array_memset(&ptr->buf, 0);
|
||||
memcpy(ptr->buf.data, src.data, src.size);
|
||||
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
||||
memcpy(ptr->buf, src.data, src.size);
|
||||
u32 src_size_padded = src.size + block_info.padding_size;
|
||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv.data, ptr->buf.data, src_size_padded);
|
||||
memcpy(dst.data, ptr->buf.data, src_size_padded);
|
||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv, ptr->buf, src_size_padded);
|
||||
memcpy(dst.data, ptr->buf, src_size_padded);
|
||||
}
|
||||
|
||||
@ -2,40 +2,54 @@
|
||||
#include "tlibc/std.h"
|
||||
#include "tlibc/collections/Array.h"
|
||||
#include "tlibc/string/str.h"
|
||||
#include "bearssl_block.h"
|
||||
#include "bearssl_rand.h"
|
||||
|
||||
/// @brief hashes password multiple times using its own hash as salt
|
||||
/// @param password some byte array
|
||||
/// @param out_buffer u8[hash_password_out_size]
|
||||
/// @param iterations number of iterations
|
||||
/// @return Array<u8, 32>
|
||||
Array hash_password(str password, i32 iterations);
|
||||
void hash_password(str password, u8* out_buffer, i32 iterations);
|
||||
#define hash_password_out_size 32
|
||||
|
||||
|
||||
typedef struct EncryptedBlockInfo {
|
||||
u32 padding_size;
|
||||
u8 padding_size;
|
||||
u32 _reserved;
|
||||
u64 __reserved;
|
||||
} EncryptedBlockInfo;
|
||||
} __attribute__((aligned(16))) EncryptedBlockInfo;
|
||||
|
||||
typedef struct EncryptorAES EncryptorAES;
|
||||
// must be multiple of 16
|
||||
#define __AES_BUFFER_SIZE 512
|
||||
// must be multiple of 16
|
||||
#define __AES_RANDOM_BYTES_N 16
|
||||
|
||||
typedef struct EncryptorAES {
|
||||
br_aes_ct64_cbcenc_keys enc_ctx;
|
||||
br_hmac_drbg_context rng_ctx;
|
||||
u8 buf[__AES_BUFFER_SIZE];
|
||||
u8 iv[16];
|
||||
} EncryptorAES;
|
||||
|
||||
/// @param key Array<u8, 16 | 24 | 32>
|
||||
EncryptorAES* EncryptorAES_create(Array key);
|
||||
|
||||
void EncryptorAES_destroy(EncryptorAES* ptr);
|
||||
void EncryptorAES_create(EncryptorAES* ptr, Array key);
|
||||
|
||||
/// @brief Encrypts `src` and writes output to `dst`.
|
||||
/// @param src array of any size
|
||||
/// @param dst array of size >= EncryptorAES_calcDstSize(src.size)
|
||||
void EncryptorAES_encrypt(EncryptorAES* ptr, Array src, Array dst);
|
||||
|
||||
#define EncryptorAES_calcDstSize(SRC_SIZE) (ALIGN_TO(SRC_SIZE, 16) + sizeof(EncryptedBlockInfo))
|
||||
#define EncryptorAES_calcDstSize(SRC_SIZE) (ALIGN_TO(SRC_SIZE, 16) + __AES_RANDOM_BYTES_N + sizeof(EncryptedBlockInfo))
|
||||
|
||||
typedef struct DecryptorAES DecryptorAES;
|
||||
|
||||
typedef struct DecryptorAES {
|
||||
br_aes_ct64_cbcdec_keys dec_ctx;
|
||||
u8 buf[__AES_BUFFER_SIZE];
|
||||
u8 iv[16];
|
||||
} DecryptorAES;
|
||||
|
||||
/// @param key Array<u8, 16 | 24 | 32>
|
||||
DecryptorAES* DecryptorAES_create(Array key);
|
||||
|
||||
void DecryptorAES_destroy(DecryptorAES* ptr);
|
||||
void DecryptorAES_create(DecryptorAES* ptr, Array key);
|
||||
|
||||
/// @brief Decrypts `src` and writes output to `dst`.
|
||||
/// @param src array of any size
|
||||
|
||||
@ -1,18 +1,17 @@
|
||||
#include "cryptography.h"
|
||||
#include "BearSSL/inc/bearssl_hash.h"
|
||||
#include "bearssl_hash.h"
|
||||
#include "assert.h"
|
||||
|
||||
Array hash_password(str password, i32 iterations){
|
||||
Array hash_buffer = Array_alloc(u8, br_sha256_SIZE);
|
||||
Array_memset(&hash_buffer, 0);
|
||||
void hash_password(str password, u8* out_buffer, i32 iterations){
|
||||
assert(hash_password_out_size == br_sha256_SIZE);;
|
||||
memset(out_buffer, 0, br_sha256_SIZE);
|
||||
br_sha256_context sha256_ctx;
|
||||
br_sha256_init(&sha256_ctx);
|
||||
|
||||
for(i32 i = 0; i < iterations; i++){
|
||||
br_sha256_update(&sha256_ctx, password.data, password.size);
|
||||
br_sha256_out(&sha256_ctx, hash_buffer.data);
|
||||
br_sha256_update(&sha256_ctx, hash_buffer.data, hash_buffer.size);
|
||||
br_sha256_out(&sha256_ctx, out_buffer);
|
||||
br_sha256_update(&sha256_ctx, out_buffer, hash_password_out_size);
|
||||
}
|
||||
br_sha256_out(&sha256_ctx, hash_buffer.data);
|
||||
|
||||
return hash_buffer;
|
||||
br_sha256_out(&sha256_ctx, out_buffer);
|
||||
}
|
||||
|
||||
98
src/main.c
98
src/main.c
@ -1,49 +1,51 @@
|
||||
#include "cryptography/cryptography.h"
|
||||
#include "network/network.h"
|
||||
#include "network/socket.h"
|
||||
#include <pthread.h>
|
||||
#include "tlibc/time.h"
|
||||
#include "errno.h"
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
Result(void) test_aes(){
|
||||
const str password = STR("abobus");
|
||||
const Array data = str_castTo_Array(STR("0123456789_hii_"));
|
||||
|
||||
const Array key_hash = hash_password(password, 1e5);
|
||||
str hash_str = hex_to_str(key_hash, true);
|
||||
printf("password hash [%i] %s\n", key_hash.size, hash_str.data);
|
||||
free(hash_str.data);
|
||||
|
||||
u8 hash_buffer[hash_password_out_size];
|
||||
// SHA256 accepts keys with size 16, 24 or 32
|
||||
const u32 key_size = 32;
|
||||
const Array key = Array_construct_size(key_hash.data, key_size);
|
||||
assert(key_size <= hash_password_out_size);
|
||||
const Array key = Array_construct_size(hash_buffer, key_size);
|
||||
hash_password(password, hash_buffer, 1e5);
|
||||
str hash_str = hex_to_str(key, true);
|
||||
printf("key [%i] %s\n", key.size, hash_str.data);
|
||||
free(hash_str.data);
|
||||
|
||||
EncryptorAES* encr = EncryptorAES_create(key);
|
||||
EncryptorAES encr;
|
||||
EncryptorAES_create(&encr, key);
|
||||
Array buffer = Array_alloc_size(EncryptorAES_calcDstSize(data.size));
|
||||
EncryptorAES_encrypt(encr, data, buffer);
|
||||
EncryptorAES_destroy(encr);
|
||||
EncryptorAES_encrypt(&encr, data, buffer);
|
||||
|
||||
str encrypted_str = hex_to_str(buffer, true);
|
||||
printf("data encrypted (hex): %s\n", encrypted_str.data);
|
||||
free(encrypted_str.data);
|
||||
|
||||
DecryptorAES* decr = DecryptorAES_create(key);
|
||||
DecryptorAES decr;
|
||||
DecryptorAES_create(&decr, key);
|
||||
u32 decrypted_size = 0;
|
||||
DecryptorAES_decrypt(decr, buffer, buffer, &decrypted_size);
|
||||
DecryptorAES_destroy(decr);
|
||||
DecryptorAES_decrypt(&decr, buffer, buffer, &decrypted_size);
|
||||
|
||||
str decrypted_str = str_copy(str_construct(buffer.data, decrypted_size, false));
|
||||
printf("data decrypted (utf8): %s\n", decrypted_str.data);
|
||||
free(decrypted_str.data);
|
||||
|
||||
free(buffer.data);
|
||||
return RESULT_VOID;
|
||||
}
|
||||
|
||||
|
||||
static pthread_mutex_t stdout_mutex = {0};
|
||||
|
||||
// thread-safe print
|
||||
/// thread-safe print
|
||||
#define printf_safe(ARGS...) {\
|
||||
pthread_mutex_lock(&stdout_mutex);\
|
||||
printf(ARGS);\
|
||||
@ -51,6 +53,28 @@ static pthread_mutex_t stdout_mutex = {0};
|
||||
pthread_mutex_unlock(&stdout_mutex);\
|
||||
}
|
||||
|
||||
/// removes blank characters from line end
|
||||
void line_trim(str* line, bool set_zero_at_end){
|
||||
bool stop = false;
|
||||
while(line->size > 0 && !stop)
|
||||
{
|
||||
char last_char = line->data[line->size - 1];
|
||||
switch(last_char){
|
||||
case '\0': case '\r': case '\n':
|
||||
case '\t': case ' ':
|
||||
line->size--;
|
||||
break;
|
||||
default:
|
||||
stop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(set_zero_at_end){
|
||||
line->data[line->size] = '\0';
|
||||
line->isZeroTerminated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void* test_server(void* data){
|
||||
printf_safe("[server]: opening main socket\n");
|
||||
try_fatal(main_socket, socket_open_TCP(), );
|
||||
@ -66,29 +90,17 @@ void* test_server(void* data){
|
||||
while(true){
|
||||
try_fatal(read_n,
|
||||
socket_recv(client_conn.i, buf),
|
||||
socket_close(client_conn.i));
|
||||
{
|
||||
socket_close(client_conn.i);
|
||||
socket_close(main_socket.i);
|
||||
});
|
||||
if(read_n.i == 0){
|
||||
sleepMsec(20);
|
||||
continue;
|
||||
}
|
||||
char* data_s = (char*)buf.data;
|
||||
char last_char;
|
||||
bool stop = false;
|
||||
while(read_n.i > 0 && !stop)
|
||||
{
|
||||
last_char = data_s[read_n.i - 1];
|
||||
switch(last_char){
|
||||
case '\0': case '\r': case '\n':
|
||||
case '\t': case ' ':
|
||||
read_n.i--;
|
||||
break;
|
||||
default:
|
||||
stop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data_s[read_n.i] = '\0';
|
||||
printf_safe("[server]: got '%s'\n", data_s);
|
||||
str message = str_construct(buf.data, read_n.u, false);
|
||||
line_trim(&message, true);
|
||||
printf_safe("[server]: received '%s'\n", message.data);
|
||||
}
|
||||
socket_close(client_conn.i);
|
||||
printf_safe("[server]: client socket closed\n");
|
||||
@ -106,15 +118,19 @@ void* test_client(void* data){
|
||||
socket_connect(client_socket.i, server_end),
|
||||
socket_close(client_socket.i));
|
||||
Array buf = Array_alloc(u8, 1024);
|
||||
i32 read_n;
|
||||
printf_safe("[client]: reading stdin\n");
|
||||
while(fgets(buf.data, buf.size, stdin) != NULL){
|
||||
read_n = strlen(buf.data) + 1;
|
||||
str line = str_construct(buf.data, strlen(buf.data), true);
|
||||
line_trim(&line, true);
|
||||
if(str_equals(line, STR("/q"))){
|
||||
printf_safe("[client]: quit\n");
|
||||
break;
|
||||
}
|
||||
try_fatal(_50,
|
||||
socket_send(client_socket.i, Array_construct_size(buf.data, read_n)),
|
||||
socket_send(client_socket.i, str_castTo_Array(line)),
|
||||
socket_close(client_socket.i));
|
||||
}
|
||||
printf_safe("[client]: stdin end\n");
|
||||
printf_safe("[client]: closing connection\n");
|
||||
socket_close(client_socket.i);
|
||||
return NULL;
|
||||
}
|
||||
@ -141,8 +157,8 @@ Result(void) test_network(){
|
||||
|
||||
int main(){
|
||||
try_fatal(_10, network_init(), );
|
||||
// try_fatal(_20, test_aes(), );
|
||||
try_fatal(_30, test_network(), );
|
||||
try_fatal(_20, test_aes(), );
|
||||
// try_fatal(_30, test_network(), );
|
||||
try_fatal(_100, network_deinit(), );
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user