Compare commits
No commits in common. "1e41ab49e5eeb1d83b48d123f346e4b8070b3c8b" and "2fb4657fed33c1f9660cd00314c5167a502ab9e5" have entirely different histories.
1e41ab49e5
...
2fb4657fed
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
@ -4,9 +4,8 @@
|
|||||||
"name": "all",
|
"name": "all",
|
||||||
"defines": [],
|
"defines": [],
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"src",
|
|
||||||
"dependencies",
|
"dependencies",
|
||||||
"dependencies/tlibc/include",
|
"src",
|
||||||
"${default}"
|
"${default}"
|
||||||
],
|
],
|
||||||
"cStandard": "c99"
|
"cStandard": "c99"
|
||||||
|
|||||||
2
dependencies/tlibc
vendored
2
dependencies/tlibc
vendored
@ -1 +1 @@
|
|||||||
Subproject commit ba7a81d205a7dfe49d64f0f9c6b8d97d693d5ec2
|
Subproject commit ebe6e58ef3b777a7e45f10b5552ca95bc96e8cc8
|
||||||
@ -26,7 +26,7 @@ OBJDIR="obj"
|
|||||||
OUTDIR="bin"
|
OUTDIR="bin"
|
||||||
STATIC_LIB_FILE="lib$PROJECT.a"
|
STATIC_LIB_FILE="lib$PROJECT.a"
|
||||||
|
|
||||||
INCLUDE="-I./src -I./dependencies -I./dependencies/tlibc/include"
|
INCLUDE="-I./src -I./dependencies"
|
||||||
|
|
||||||
# OS-specific options
|
# OS-specific options
|
||||||
case "$OS" in
|
case "$OS" in
|
||||||
|
|||||||
@ -1,7 +1,26 @@
|
|||||||
#include "cryptography.h"
|
#include "cryptography.h"
|
||||||
#include "BearSSL/inc/bearssl_block.h"
|
#include <BearSSL/inc/bearssl_block.h>
|
||||||
|
#include <BearSSL/inc/bearssl_hash.h>
|
||||||
|
#include <BearSSL/inc/bearssl_rand.h>
|
||||||
#include <assert.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);
|
||||||
|
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, hash_buffer.data);
|
||||||
|
|
||||||
|
return hash_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// size must be multiple of 16
|
// size must be multiple of 16
|
||||||
#define __AES_BUFFER_SIZE 256
|
#define __AES_BUFFER_SIZE 256
|
||||||
|
|
||||||
@ -42,14 +61,11 @@ void EncryptorAES_destroy(EncryptorAES* ptr){
|
|||||||
void EncryptorAES_encrypt(EncryptorAES* ptr, Array src, Array dst){
|
void EncryptorAES_encrypt(EncryptorAES* ptr, Array src, Array dst){
|
||||||
assert(dst.size >= EncryptorAES_calcDstSize(src.size));
|
assert(dst.size >= EncryptorAES_calcDstSize(src.size));
|
||||||
|
|
||||||
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
|
// emit EncryptedBlockInfo to beginning of result
|
||||||
memcpy(dst.data, ptr->buf.data, sizeof(EncryptedBlockInfo));
|
EncryptedBlockInfo block_info = { .padding_size = 16 - src.size % 16 };
|
||||||
dst.data += sizeof(EncryptedBlockInfo);
|
memcpy(dst.data, &block_info, sizeof(block_info));
|
||||||
dst.size -= sizeof(EncryptedBlockInfo);
|
dst.data += sizeof(block_info);
|
||||||
|
dst.size -= sizeof(block_info);
|
||||||
|
|
||||||
// write full blocks
|
// write full blocks
|
||||||
while(src.size > ptr->buf.size){
|
while(src.size > ptr->buf.size){
|
||||||
@ -98,11 +114,9 @@ void DecryptorAES_decrypt(DecryptorAES* ptr, Array src, Array dst, u32* decrypte
|
|||||||
|
|
||||||
// read EncryptedBlockInfo from beginning of data
|
// read EncryptedBlockInfo from beginning of data
|
||||||
EncryptedBlockInfo block_info;
|
EncryptedBlockInfo block_info;
|
||||||
memcpy(&block_info, src.data, sizeof(EncryptedBlockInfo));
|
memcpy(&block_info, src.data, sizeof(block_info));
|
||||||
src.data += sizeof(EncryptedBlockInfo);
|
src.data += sizeof(block_info);
|
||||||
src.size -= sizeof(EncryptedBlockInfo);
|
src.size -= sizeof(block_info);
|
||||||
// decrypt this struct
|
|
||||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv.data, &block_info, sizeof(EncryptedBlockInfo));
|
|
||||||
*decrypted_size = src.size - block_info.padding_size;
|
*decrypted_size = src.size - block_info.padding_size;
|
||||||
|
|
||||||
// write full blocks
|
// write full blocks
|
||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "tlibc/std.h"
|
#include <tlibc/include/std.h>
|
||||||
#include "tlibc/collections/Array.h"
|
#include <tlibc/include/collections/Array.h>
|
||||||
#include "tlibc/string/str.h"
|
#include <tlibc/include/string/str.h>
|
||||||
|
|
||||||
/// @brief hashes password multiple times using its own hash as salt
|
/// @brief hashes password multiple times using its own hash as salt
|
||||||
/// @param password some byte array
|
/// @param password some byte array
|
||||||
@ -1,18 +0,0 @@
|
|||||||
#include "cryptography.h"
|
|
||||||
#include "BearSSL/inc/bearssl_hash.h"
|
|
||||||
|
|
||||||
Array hash_password(str password, i32 iterations){
|
|
||||||
Array hash_buffer = Array_alloc(u8, br_sha256_SIZE);
|
|
||||||
Array_memset(&hash_buffer, 0);
|
|
||||||
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, hash_buffer.data);
|
|
||||||
|
|
||||||
return hash_buffer;
|
|
||||||
}
|
|
||||||
33
src/main.c
33
src/main.c
@ -1,13 +1,18 @@
|
|||||||
#include "cryptography/cryptography.h"
|
#include <cryptography.h>
|
||||||
#include "network/network.h"
|
#include <tlibc/include/string/StringBuilder.h>
|
||||||
#include "network/socket.h"
|
|
||||||
|
|
||||||
void test_aes(){
|
str hex_to_str(Array buf) {
|
||||||
|
StringBuilder sb = StringBuilder_alloc(buf.size * 2 + 1);
|
||||||
|
StringBuilder_append_memory(&sb, buf);
|
||||||
|
return StringBuilder_getStr(&sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
const str password = STR("abobus");
|
const str password = STR("abobus");
|
||||||
const Array data = str_castTo_Array(STR("0123456789_hii_"));
|
const Array data = str_castTo_Array(STR("0123456789_hii_"));
|
||||||
|
|
||||||
const Array key_hash = hash_password(password, 1e5);
|
const Array key_hash = hash_password(password, 1e5);
|
||||||
str hash_str = hex_to_str(key_hash, true);
|
str hash_str = hex_to_str(key_hash);
|
||||||
printf("password hash [%i] %s\n", key_hash.size, hash_str.data);
|
printf("password hash [%i] %s\n", key_hash.size, hash_str.data);
|
||||||
free(hash_str.data);
|
free(hash_str.data);
|
||||||
|
|
||||||
@ -19,8 +24,7 @@ void test_aes(){
|
|||||||
Array buffer = Array_alloc_size(EncryptorAES_calcDstSize(data.size));
|
Array buffer = Array_alloc_size(EncryptorAES_calcDstSize(data.size));
|
||||||
EncryptorAES_encrypt(encr, data, buffer);
|
EncryptorAES_encrypt(encr, data, buffer);
|
||||||
EncryptorAES_destroy(encr);
|
EncryptorAES_destroy(encr);
|
||||||
|
str encrypted_str = hex_to_str(buffer);
|
||||||
str encrypted_str = hex_to_str(buffer, true);
|
|
||||||
printf("data encrypted (hex): %s\n", encrypted_str.data);
|
printf("data encrypted (hex): %s\n", encrypted_str.data);
|
||||||
free(encrypted_str.data);
|
free(encrypted_str.data);
|
||||||
|
|
||||||
@ -28,22 +32,9 @@ void test_aes(){
|
|||||||
u32 decrypted_size = 0;
|
u32 decrypted_size = 0;
|
||||||
DecryptorAES_decrypt(decr, buffer, buffer, &decrypted_size);
|
DecryptorAES_decrypt(decr, buffer, buffer, &decrypted_size);
|
||||||
DecryptorAES_destroy(decr);
|
DecryptorAES_destroy(decr);
|
||||||
|
|
||||||
str decrypted_str = str_copy(str_construct(buffer.data, decrypted_size, false));
|
str decrypted_str = str_copy(str_construct(buffer.data, decrypted_size, false));
|
||||||
printf("data decrypted (utf8): %s\n", decrypted_str.data);
|
printf("data decrypted (utf8): %s\n", decrypted_str.data);
|
||||||
free(decrypted_str.data);
|
free(decrypted_str.data);
|
||||||
}
|
|
||||||
|
|
||||||
void test_server(){
|
|
||||||
try_fatal(_10, network_init(), );
|
|
||||||
try_fatal(main_socket, socket_open_TCP(), );
|
|
||||||
EndpointIPv4 server_end = EndpointIPv4_create(AddressIPv4_LOOPBACK, 24500);
|
|
||||||
try_fatal(_20, socket_bind(main_socket.v_i64, server_end), );
|
|
||||||
try_fatal(_30, socket_listen(main_socket.v_i64, 64), );
|
|
||||||
try_fatal(_100, network_deinit(), );
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
test_server();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1,28 +0,0 @@
|
|||||||
#include "endpoint.h"
|
|
||||||
#include "network.h"
|
|
||||||
|
|
||||||
struct sockaddr_in EndpointIPv4_toSockaddr(EndpointIPv4 end){
|
|
||||||
struct sockaddr_in saddr = {0};
|
|
||||||
saddr.sin_family = AF_INET;
|
|
||||||
saddr.sin_addr.s_addr = end.address.UintBigEndian;
|
|
||||||
/* transforms port number to big endian (network order) */
|
|
||||||
saddr.sin_port = htons(end.port);
|
|
||||||
return saddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
EndpointIPv4 EndpointIPv4_fromSockaddr(struct sockaddr_in saddr){
|
|
||||||
EndpointIPv4 end;
|
|
||||||
end.address = AddressIPv4_fromU32(saddr.sin_addr.s_addr);
|
|
||||||
/* transforms port number to little endian (normal order) */
|
|
||||||
end.port = ntohs(saddr.sin_port);
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddressIPv4 AddressIPv4_fromStr(cstr);
|
|
||||||
|
|
||||||
str AddressIPv4_toStr(AddressIPv4 address);
|
|
||||||
|
|
||||||
EndpointIPv4 EndpointIPv4_fromStr(cstr s);
|
|
||||||
|
|
||||||
str EndpointIPv4_toStr(EndpointIPv4 end);
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "tlibc/std.h"
|
|
||||||
#include "tlibc/string/str.h"
|
|
||||||
#include "network.h"
|
|
||||||
|
|
||||||
#define port_INVALID ((port)~0)
|
|
||||||
#define port_is_invalid(PORT) (PORT == port_INVALID)
|
|
||||||
|
|
||||||
|
|
||||||
typedef union AddressIPv4 {
|
|
||||||
u32 UintBigEndian;
|
|
||||||
u8 bytes[4];
|
|
||||||
} AddressIPv4;
|
|
||||||
|
|
||||||
#define AddressIPv4_ANY AddressIPv4_fromBytes(0,0,0,0)
|
|
||||||
#define AddressIPv4_LOOPBACK AddressIPv4_fromBytes(127,0,0,1)
|
|
||||||
#define AddressIPv4_INVALID AddressIPv4_fromBytes(255,255,255,255)
|
|
||||||
#define AddressIPv4_is_invalid(ADDR) (ADDR.UintBigEndian == (u32)~0)
|
|
||||||
|
|
||||||
#define AddressIPv4_fromBytes(A, B, C, D) ((AddressIPv4){.bytes={A,B,C,D}})
|
|
||||||
#define AddressIPv4_fromU32(N) ((AddressIPv4){.UintBigEndian=N})
|
|
||||||
AddressIPv4 AddressIPv4_fromStr(cstr);
|
|
||||||
str AddressIPv4_toStr(AddressIPv4 address);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct EndpointIPv4 {
|
|
||||||
AddressIPv4 address;
|
|
||||||
u16 port;
|
|
||||||
} EndpointIPv4;
|
|
||||||
|
|
||||||
#define EndpointIPv4_INVALID EndpointIPv4_create(AddressIPv4_INVALID, port_INVALID)
|
|
||||||
#define EndpointIPv4_is_invalid(ENDP) (AddressIPv4_is_invalid(ENDP.address) || port_is_invalid(ENDP.port))
|
|
||||||
|
|
||||||
#define EndpointIPv4_create(ADDR, PORT) ((EndpointIPv4){ADDR, PORT})
|
|
||||||
EndpointIPv4 EndpointIPv4_fromStr(cstr s);
|
|
||||||
str EndpointIPv4_toStr(EndpointIPv4 end);
|
|
||||||
|
|
||||||
struct sockaddr_in EndpointIPv4_toSockaddr(EndpointIPv4 end);
|
|
||||||
EndpointIPv4 EndpointIPv4_fromSockaddr(struct sockaddr_in saddr);
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
#include "network.h"
|
|
||||||
#include "network.h"
|
|
||||||
|
|
||||||
Result(void) network_init(){
|
|
||||||
#if _WIN32
|
|
||||||
// Initialize Winsock
|
|
||||||
WSADATA wsaData = {0};
|
|
||||||
int result = WSAStartup(MAKEWORD(2,2), &wsaData);
|
|
||||||
if (result != 0) {
|
|
||||||
return RESULT_ERROR(sprintf_malloc(64, "WSAStartup failed with error code 0x%X", result), true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return RESULT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(void) network_deinit(){
|
|
||||||
#if _WIN32
|
|
||||||
// Deinitialize Winsock
|
|
||||||
int result = WSACleanup();
|
|
||||||
if (result != 0) {
|
|
||||||
return RESULT_ERROR(sprintf_malloc(64, "WSACleanup failed with error code 0x%X", result), true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return RESULT_VOID;
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "tlibc/errors.h"
|
|
||||||
|
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
|
||||||
#define KN_USE_WINSOCK 1
|
|
||||||
#else
|
|
||||||
#define KN_USE_WINSOCK 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if KN_USE_WINSOCK
|
|
||||||
#include <winsock2.h>
|
|
||||||
#else
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Result(void) network_init();
|
|
||||||
Result(void) network_deinit();
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
#include "network.h"
|
|
||||||
#include "network.h"
|
|
||||||
#include "socket.h"
|
|
||||||
|
|
||||||
Result(Socket) socket_open_TCP(){
|
|
||||||
Socket s = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if(s == -1){
|
|
||||||
return RESULT_ERROR("can't create socket", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RESULT_VALUE(i64, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void socket_close(Socket s){
|
|
||||||
#if KN_USE_WINSOCK
|
|
||||||
closesocket(s);
|
|
||||||
#else
|
|
||||||
close(s);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(void) socket_shutdown(Socket s, SocketShutdownType direction){
|
|
||||||
if(shutdown(s, (int)direction) == -1)
|
|
||||||
return RESULT_ERROR("shutdown() failed", false);
|
|
||||||
return RESULT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(void) socket_bind(Socket s, EndpointIPv4 local_end){
|
|
||||||
struct sockaddr_in sockaddr = EndpointIPv4_toSockaddr(local_end);
|
|
||||||
if(bind(s, (void*)&sockaddr, sizeof(sockaddr)) != 0)
|
|
||||||
return RESULT_ERROR("bind() failed", false);
|
|
||||||
return RESULT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(void) socket_listen(Socket s, i32 backlog){
|
|
||||||
if(listen(s, backlog) != 0)
|
|
||||||
return RESULT_ERROR("listen() failed", false);
|
|
||||||
return RESULT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(Socket) socket_accept(Socket main_socket) {
|
|
||||||
struct sockaddr_in remote_addr = {0};
|
|
||||||
i32 sockaddr_size = sizeof(remote_addr);
|
|
||||||
Socket user_connection = accept(main_socket, (struct sockaddr*)&remote_addr, (void*)&sockaddr_size);
|
|
||||||
return RESULT_VALUE(i64, user_connection);
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "endpoint.h"
|
|
||||||
#include "tlibc/errors.h"
|
|
||||||
|
|
||||||
typedef enum SocketShutdownType {
|
|
||||||
SocketShutdownType_Receive = 0,
|
|
||||||
SocketShutdownType_Send = 1,
|
|
||||||
SocketShutdownType_Both = 2,
|
|
||||||
} SocketShutdownType;
|
|
||||||
|
|
||||||
typedef i64 Socket;
|
|
||||||
|
|
||||||
Result(Socket) socket_open_TCP();
|
|
||||||
void socket_close(Socket s);
|
|
||||||
Result(void) socket_shutdown(Socket s, SocketShutdownType direction);
|
|
||||||
Result(void) socket_bind(Socket s, EndpointIPv4 local_end);
|
|
||||||
Result(void) socket_listen(Socket s, i32 backlog);
|
|
||||||
Result(Socket) socket_accept(Socket main_socket);
|
|
||||||
Loading…
Reference in New Issue
Block a user