Compare commits
No commits in common. "eea36ec2a391cd11d868a021a2db3806020358a1" and "60bc5012277c743f608b71f3d5be02c2cf5f4d38" have entirely different histories.
eea36ec2a3
...
60bc501227
1
.vscode/c_cpp_properties.json
vendored
1
.vscode/c_cpp_properties.json
vendored
@ -6,7 +6,6 @@
|
|||||||
"includePath": [
|
"includePath": [
|
||||||
"src",
|
"src",
|
||||||
"dependencies/BearSSL/inc",
|
"dependencies/BearSSL/inc",
|
||||||
"dependencies/BearSSL/src",
|
|
||||||
"dependencies/tlibc/include",
|
"dependencies/tlibc/include",
|
||||||
"${default}"
|
"${default}"
|
||||||
],
|
],
|
||||||
|
|||||||
2
dependencies/BearSSL
vendored
2
dependencies/BearSSL
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 3d9be2f60b7764e46836514bcd6e453abdfa864a
|
Subproject commit 3c040368f6791553610e362401db1efff4b4c5b8
|
||||||
2
dependencies/tlibc
vendored
2
dependencies/tlibc
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 0184d2e8c96d882b815eae05fa160a40e9f7faf2
|
Subproject commit 14ffede476b786d9e31006f4bac52289ff656158
|
||||||
@ -3,9 +3,9 @@
|
|||||||
void ServerConnection_close(ServerConnection* conn){
|
void ServerConnection_close(ServerConnection* conn){
|
||||||
if(conn == NULL)
|
if(conn == NULL)
|
||||||
return;
|
return;
|
||||||
|
socket_close(conn->system_socket);
|
||||||
|
socket_close(conn->content_socket);
|
||||||
RSA_destroyPublicKey(&conn->server_pk);
|
RSA_destroyPublicKey(&conn->server_pk);
|
||||||
socket_close(conn->system_socket.sock);
|
|
||||||
socket_close(conn->content_socket.sock);
|
|
||||||
free(conn->session_key.data);
|
free(conn->session_key.data);
|
||||||
free(conn);
|
free(conn);
|
||||||
}
|
}
|
||||||
@ -56,32 +56,21 @@ Result(ServerConnection*) ServerConnection_open(ClientCredential* client_credent
|
|||||||
|
|
||||||
conn->session_key = Array_alloc_size(__AES_SESSION_KEY_SIZE);
|
conn->session_key = Array_alloc_size(__AES_SESSION_KEY_SIZE);
|
||||||
br_hmac_drbg_context key_rng = { .vtable = &br_hmac_drbg_vtable };
|
br_hmac_drbg_context key_rng = { .vtable = &br_hmac_drbg_vtable };
|
||||||
rng_init_sha256_seedFromSystem(&key_rng.vtable);
|
rng_init_sha256_seedFromTime(&key_rng.vtable);
|
||||||
br_hmac_drbg_generate(&key_rng, conn->session_key.data, conn->session_key.size);
|
br_hmac_drbg_generate(&key_rng, conn->session_key.data, conn->session_key.size);
|
||||||
|
// TODO: add more entropy to the key to prevent easy key cracking when attacker knows the time when connection request was sent to a server
|
||||||
|
|
||||||
printf("connecting to server %s\n", server_link_cstr);
|
printf("connecting to server %s\n", server_link_cstr);
|
||||||
try(Socket initial_socket, i, socket_open_TCP());
|
try(conn->system_socket, i, socket_open_TCP());
|
||||||
try_void(socket_connect(initial_socket, conn->server_end));
|
try_void(socket_connect(conn->system_socket, conn->server_end));
|
||||||
//TODO: add log
|
|
||||||
EncryptorRSA_construct(&conn->rsa_enc, &conn->server_pk);
|
|
||||||
// ClientHandshake client_handshake;
|
|
||||||
// Array(u8) encrypted_buf = Array_alloc_size(EncryptorAES_calcDstSize(sizeof(client_handshake)));
|
|
||||||
// u32 encrypted_size = 0;
|
|
||||||
// EncryptorRSA_encrypt(&conn->rsa_enc, struct_castTo_Array(&client_handshake), encrypted_buf, &encrypted_size);
|
|
||||||
|
|
||||||
// send handshake and session key to server
|
// send session key to server
|
||||||
// request server info
|
// request server info
|
||||||
// show server info
|
// show server info
|
||||||
// save server info to user's db
|
// save server info to user's db
|
||||||
// request log in
|
// request log in
|
||||||
// if not registered, request registration and then log in
|
// if not registered, request registration and then log in
|
||||||
|
|
||||||
EncryptedSocket_construct(&conn->system_socket, initial_socket, conn->session_key);
|
|
||||||
|
|
||||||
try(Socket _s, i, socket_open_TCP());
|
|
||||||
//try_void(socket_connect(_s, conn->server_end????));
|
|
||||||
EncryptedSocket_construct(&conn->content_socket, _s, conn->session_key);
|
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
Return RESULT_VALUE(p, conn);
|
Return RESULT_VALUE(p, conn);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "network/socket.h"
|
||||||
#include "cryptography/cryptography.h"
|
#include "cryptography/cryptography.h"
|
||||||
#include "network/EncryptedSocket.h"
|
|
||||||
|
|
||||||
Result(void) client_run();
|
Result(void) client_run();
|
||||||
|
|
||||||
@ -16,11 +16,13 @@ void ClientCredential_free(ClientCredential* cred);
|
|||||||
|
|
||||||
typedef struct ServerConnection {
|
typedef struct ServerConnection {
|
||||||
EndpointIPv4 server_end;
|
EndpointIPv4 server_end;
|
||||||
|
Socket system_socket;
|
||||||
|
Socket content_socket;
|
||||||
br_rsa_public_key server_pk;
|
br_rsa_public_key server_pk;
|
||||||
EncryptorRSA rsa_enc;
|
EncryptorRSA rsa_enc;
|
||||||
Array(u8) session_key;
|
Array(u8) session_key;
|
||||||
EncryptedSocket system_socket;
|
EncryptorAES session_aes_enc;
|
||||||
EncryptedSocket content_socket;
|
DecryptorAES session_aes_dec;
|
||||||
} ServerConnection;
|
} ServerConnection;
|
||||||
|
|
||||||
Result(ServerConnection*) ServerConnection_open(ClientCredential* client_credential, cstr server_link_cstr);
|
Result(ServerConnection*) ServerConnection_open(ClientCredential* client_credential, cstr server_link_cstr);
|
||||||
|
|||||||
@ -1,62 +1,52 @@
|
|||||||
#include "cryptography.h"
|
#include "cryptography.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
// write data from src to array and increment array data pointer
|
//TODO: use AES CTR encryption instead of my own padding algorithm
|
||||||
static inline void __Array_writeNext(Array(u8)* dst, void* src, size_t size){
|
|
||||||
memcpy(dst->data, src, size);
|
|
||||||
dst->data = (u8*)dst->data + size;
|
|
||||||
dst->size -= size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read data from array to dst and increment array data pointer
|
|
||||||
static inline void __Array_readNext(void* dst, Array(u8)* src, size_t size){
|
|
||||||
memcpy(dst, src->data, size);
|
|
||||||
src->data = (u8*)src->data + size;
|
|
||||||
src->size -= size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EncryptorAES_construct(EncryptorAES* ptr, Array(u8) key){
|
void EncryptorAES_construct(EncryptorAES* ptr, Array(u8) key){
|
||||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||||
|
|
||||||
//TODO: use AES CTR encryption?
|
|
||||||
br_aes_ct64_cbcenc_init(&ptr->enc_ctx, key.data, key.size);
|
br_aes_ct64_cbcenc_init(&ptr->enc_ctx, key.data, key.size);
|
||||||
|
|
||||||
ptr->rng_ctx.vtable = &br_hmac_drbg_vtable;
|
ptr->rng_ctx.vtable = &br_hmac_drbg_vtable;
|
||||||
rng_init_sha256_seedFromSystem(&ptr->rng_ctx.vtable);
|
rng_init_sha256_seedFromTime(&ptr->rng_ctx.vtable);
|
||||||
|
|
||||||
|
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
||||||
|
memset(ptr->iv, 0, sizeof(ptr->iv));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncryptorAES_encrypt(EncryptorAES* ptr, Array(u8) src, Array(u8) dst){
|
void EncryptorAES_encrypt(EncryptorAES* ptr, Array(u8) src, Array(u8) dst){
|
||||||
assert(dst.size >= EncryptorAES_calcDstSize(src.size));
|
assert(dst.size >= EncryptorAES_calcDstSize(src.size));
|
||||||
|
|
||||||
// generate random initial vector
|
// write random bytes to the beginning of the buffer
|
||||||
br_hmac_drbg_generate(&ptr->rng_ctx, ptr->iv, __AES_IV_SIZE);
|
br_hmac_drbg_generate(&ptr->rng_ctx, ptr->buf, __AES_RANDOM_BYTES_N);
|
||||||
// write IV to the beginning of dst
|
const EncryptedBlockInfo block_info = { .padding_size = 16 - src.size % 16 };
|
||||||
__Array_writeNext(&dst, ptr->iv, __AES_IV_SIZE);
|
// write struct after random_bytes
|
||||||
|
memcpy((u8*)ptr->buf + __AES_RANDOM_BYTES_N, &block_info, sizeof(EncryptedBlockInfo));
|
||||||
const EncryptedBlockHeader header = { .padding_size = 16 - src.size % 16 };
|
// encrypt buffer
|
||||||
// write header to buffer
|
const u32 header_size = __AES_RANDOM_BYTES_N + sizeof(EncryptedBlockInfo);
|
||||||
memcpy(ptr->buf, &header, sizeof(header));
|
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv, ptr->buf, header_size);
|
||||||
// encrypt header
|
|
||||||
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv, ptr->buf, sizeof(header));
|
|
||||||
// write encrypted header to dst
|
// write encrypted header to dst
|
||||||
__Array_writeNext(&dst, ptr->buf, sizeof(header));
|
memcpy(dst.data, ptr->buf, header_size);
|
||||||
|
dst.data = (u8*)dst.data + header_size;
|
||||||
|
dst.size -= header_size;
|
||||||
|
|
||||||
// encrypt full EncryptorAES buffers
|
// write full blocks
|
||||||
while(src.size > __AES_BUFFER_SIZE){
|
while(src.size > __AES_BUFFER_SIZE){
|
||||||
__Array_readNext(ptr->buf, &src, __AES_BUFFER_SIZE);
|
memcpy(ptr->buf, src.data, __AES_BUFFER_SIZE);
|
||||||
|
src.data = (u8*)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);
|
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv, ptr->buf, __AES_BUFFER_SIZE);
|
||||||
__Array_writeNext(&dst, ptr->buf, __AES_BUFFER_SIZE);
|
memcpy(dst.data, ptr->buf, __AES_BUFFER_SIZE);
|
||||||
}
|
dst.data = (u8*)dst.data + __AES_BUFFER_SIZE;
|
||||||
|
dst.size -= __AES_BUFFER_SIZE;
|
||||||
// encrypt buffer with remaining data
|
|
||||||
if(src.size > 0){
|
|
||||||
memcpy(ptr->buf, src.data, src.size);
|
|
||||||
u32 src_size_padded = src.size + header.padding_size;
|
|
||||||
memset(ptr->buf + src.size, 0, header.padding_size);
|
|
||||||
br_aes_ct64_cbcenc_run(&ptr->enc_ctx, ptr->iv, ptr->buf, src_size_padded);
|
|
||||||
memcpy(dst.data, ptr->buf, src_size_padded);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write incomplete block
|
||||||
|
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, ptr->buf, src_size_padded);
|
||||||
|
memcpy(dst.data, ptr->buf, src_size_padded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,37 +54,41 @@ void DecryptorAES_construct(DecryptorAES* ptr, Array(u8) key){
|
|||||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||||
|
|
||||||
br_aes_ct64_cbcdec_init(&ptr->dec_ctx, key.data, key.size);
|
br_aes_ct64_cbcdec_init(&ptr->dec_ctx, key.data, key.size);
|
||||||
|
|
||||||
|
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
||||||
|
memset(ptr->iv, 0, sizeof(ptr->iv));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32* decrypted_size){
|
void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32* decrypted_size){
|
||||||
assert(src.size >= EncryptorAES_calcDstSize(0));
|
|
||||||
assert(src.size % 16 == 0 && "src must be array of 16-byte blocks");
|
|
||||||
assert(dst.size >= src.size);
|
assert(dst.size >= src.size);
|
||||||
|
|
||||||
// read IV from the beginning of src
|
// copy encrypted header from src to buffer
|
||||||
__Array_readNext(ptr->iv, &src, __AES_IV_SIZE);
|
const u32 header_size = __AES_RANDOM_BYTES_N + sizeof(EncryptedBlockInfo);
|
||||||
|
memcpy(ptr->buf, src.data, header_size);
|
||||||
|
src.data = (u8*)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, (u8*)ptr->buf + __AES_RANDOM_BYTES_N, sizeof(EncryptedBlockInfo));
|
||||||
|
*decrypted_size = src.size - block_info.padding_size;
|
||||||
|
|
||||||
EncryptedBlockHeader header;
|
// write full blocks
|
||||||
// read encrypted header from src
|
|
||||||
__Array_readNext(&header, &src, sizeof(header));
|
|
||||||
// decrypt header
|
|
||||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv, &header, sizeof(header));
|
|
||||||
// size of decrypted data without padding
|
|
||||||
*decrypted_size = src.size - header.padding_size;
|
|
||||||
const u32 src_size_padded = src.size;
|
|
||||||
src.size = *decrypted_size;
|
|
||||||
|
|
||||||
// decrypt full buffers
|
|
||||||
while(src.size > __AES_BUFFER_SIZE){
|
while(src.size > __AES_BUFFER_SIZE){
|
||||||
__Array_readNext(ptr->buf, &src, __AES_BUFFER_SIZE);
|
memcpy(ptr->buf, src.data, __AES_BUFFER_SIZE);
|
||||||
|
src.data = (u8*)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);
|
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv, ptr->buf, __AES_BUFFER_SIZE);
|
||||||
__Array_writeNext(&dst, ptr->buf, __AES_BUFFER_SIZE);
|
memcpy(dst.data, ptr->buf, __AES_BUFFER_SIZE);
|
||||||
|
dst.data = (u8*)dst.data + __AES_BUFFER_SIZE;
|
||||||
|
dst.size -= __AES_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrypt buffer with remaining data
|
// write incomplete block
|
||||||
if(src.size > 0){
|
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
||||||
memcpy(ptr->buf, src.data, src.size);
|
memcpy(ptr->buf, src.data, src.size);
|
||||||
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv, ptr->buf, src_size_padded);
|
u32 src_size_padded = src.size + block_info.padding_size;
|
||||||
memcpy(dst.data, ptr->buf, src.size);
|
br_aes_ct64_cbcdec_run(&ptr->dec_ctx, ptr->iv, ptr->buf, src_size_padded);
|
||||||
}
|
memcpy(dst.data, ptr->buf, src_size_padded);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ Result(void) RSA_generateKeyPairFromTime(u32 key_size,
|
|||||||
{
|
{
|
||||||
Deferral(8);
|
Deferral(8);
|
||||||
br_hmac_drbg_context time_based_rng = { .vtable = &br_hmac_drbg_vtable };
|
br_hmac_drbg_context time_based_rng = { .vtable = &br_hmac_drbg_vtable };
|
||||||
rng_init_sha256_seedFromSystem(&time_based_rng.vtable);
|
rng_init_sha256_seedFromTime(&time_based_rng.vtable);
|
||||||
try_void(RSA_generateKeyPair(key_size, sk, pk, &time_based_rng.vtable));
|
try_void(RSA_generateKeyPair(key_size, sk, pk, &time_based_rng.vtable));
|
||||||
Return RESULT_VOID;
|
Return RESULT_VOID;
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ Result(void) RSA_parsePrivateKey_base64(const str src, br_rsa_private_key* sk){
|
|||||||
void EncryptorRSA_construct(EncryptorRSA* ptr, const br_rsa_public_key* pk){
|
void EncryptorRSA_construct(EncryptorRSA* ptr, const br_rsa_public_key* pk){
|
||||||
ptr->pk = pk;
|
ptr->pk = pk;
|
||||||
ptr->rng.vtable = &br_hmac_drbg_vtable;
|
ptr->rng.vtable = &br_hmac_drbg_vtable;
|
||||||
rng_init_sha256_seedFromSystem(&ptr->rng.vtable);
|
rng_init_sha256_seedFromTime(&ptr->rng.vtable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncryptorRSA_encrypt(EncryptorRSA* ptr, Array(u8) src, Array(u8) dst, u32* encrypted_size){
|
void EncryptorRSA_encrypt(EncryptorRSA* ptr, Array(u8) src, Array(u8) dst, u32* encrypted_size){
|
||||||
|
|||||||
@ -24,16 +24,6 @@ void hash_password(Array(u8) password, u8* out_buffer, i32 iterations);
|
|||||||
// rng.c //
|
// rng.c //
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// @brief Initialize prng context with sha256 hashing algorithm
|
|
||||||
/// and seed from system-provided cryptographic random bytes source.
|
|
||||||
/// @param rng_vtable_ptr pointer to vtable field in prng context. The field must be initialized.
|
|
||||||
/// EXAMPLE:
|
|
||||||
/// ```
|
|
||||||
/// br_hmac_drbg_context rng_ctx = { .vtable = &br_hmac_drbg_vtable };
|
|
||||||
/// rng_init_sha256_seedFromTime(&rng_ctx.vtable);
|
|
||||||
/// ```
|
|
||||||
void rng_init_sha256_seedFromSystem(const br_prng_class** rng_vtable_ptr);
|
|
||||||
|
|
||||||
/// @brief Initialize prng context with sha256 hashing algorithm and seed from CLOCK_REALTIME.
|
/// @brief Initialize prng context with sha256 hashing algorithm and seed from CLOCK_REALTIME.
|
||||||
/// @param rng_vtable_ptr pointer to vtable field in prng context. The field must be initialized.
|
/// @param rng_vtable_ptr pointer to vtable field in prng context. The field must be initialized.
|
||||||
/// EXAMPLE:
|
/// EXAMPLE:
|
||||||
@ -51,20 +41,22 @@ void rng_init_sha256_seedFromTime(const br_prng_class** rng_vtable_ptr);
|
|||||||
#define __AES_SESSION_KEY_SIZE 32
|
#define __AES_SESSION_KEY_SIZE 32
|
||||||
#define __AES_DB_KEY_SIZE 32
|
#define __AES_DB_KEY_SIZE 32
|
||||||
|
|
||||||
typedef struct EncryptedBlockHeader {
|
typedef struct EncryptedBlockInfo {
|
||||||
u8 padding_size;
|
u8 padding_size;
|
||||||
} __attribute__((aligned(16))) EncryptedBlockHeader;
|
u32 _reserved;
|
||||||
|
u64 __reserved;
|
||||||
|
} __attribute__((aligned(16))) EncryptedBlockInfo;
|
||||||
|
|
||||||
// must be multiple of 16
|
|
||||||
#define __AES_IV_SIZE 16
|
|
||||||
// must be multiple of 16
|
// must be multiple of 16
|
||||||
#define __AES_BUFFER_SIZE 512
|
#define __AES_BUFFER_SIZE 512
|
||||||
|
// must be multiple of 16
|
||||||
|
#define __AES_RANDOM_BYTES_N 16
|
||||||
|
|
||||||
typedef struct EncryptorAES {
|
typedef struct EncryptorAES {
|
||||||
br_aes_ct64_cbcenc_keys enc_ctx;
|
br_aes_ct64_cbcenc_keys enc_ctx;
|
||||||
br_hmac_drbg_context rng_ctx;
|
br_hmac_drbg_context rng_ctx;
|
||||||
u8 iv[__AES_IV_SIZE];
|
|
||||||
u8 buf[__AES_BUFFER_SIZE];
|
u8 buf[__AES_BUFFER_SIZE];
|
||||||
|
u8 iv[16];
|
||||||
} EncryptorAES;
|
} EncryptorAES;
|
||||||
|
|
||||||
/// @param key Array<u8, 16 | 24 | 32>
|
/// @param key Array<u8, 16 | 24 | 32>
|
||||||
@ -75,20 +67,20 @@ void EncryptorAES_construct(EncryptorAES* ptr, Array(u8) key);
|
|||||||
/// @param dst array of size >= EncryptorAES_calcDstSize(src.size)
|
/// @param dst array of size >= EncryptorAES_calcDstSize(src.size)
|
||||||
void EncryptorAES_encrypt(EncryptorAES* ptr, Array(u8) src, Array(u8) dst);
|
void EncryptorAES_encrypt(EncryptorAES* ptr, Array(u8) src, Array(u8) dst);
|
||||||
|
|
||||||
#define EncryptorAES_calcDstSize(SRC_SIZE) (__AES_IV_SIZE + sizeof(EncryptedBlockHeader) + ALIGN_TO(SRC_SIZE, 16))
|
#define EncryptorAES_calcDstSize(SRC_SIZE) (ALIGN_TO(SRC_SIZE, 16) + __AES_RANDOM_BYTES_N + sizeof(EncryptedBlockInfo))
|
||||||
|
|
||||||
|
|
||||||
typedef struct DecryptorAES {
|
typedef struct DecryptorAES {
|
||||||
br_aes_ct64_cbcdec_keys dec_ctx;
|
br_aes_ct64_cbcdec_keys dec_ctx;
|
||||||
u8 iv[__AES_IV_SIZE];
|
|
||||||
u8 buf[__AES_BUFFER_SIZE];
|
u8 buf[__AES_BUFFER_SIZE];
|
||||||
|
u8 iv[16];
|
||||||
} DecryptorAES;
|
} DecryptorAES;
|
||||||
|
|
||||||
/// @param key Array<u8, 16 | 24 | 32>
|
/// @param key Array<u8, 16 | 24 | 32>
|
||||||
void DecryptorAES_construct(DecryptorAES* ptr, Array(u8) key);
|
void DecryptorAES_construct(DecryptorAES* ptr, Array(u8) key);
|
||||||
|
|
||||||
/// @brief Decrypts `src` and writes output to `dst`.
|
/// @brief Decrypts `src` and writes output to `dst`.
|
||||||
/// @param src array of size at least EncryptorAES_calcDstSize(0). Size must be multiple of 16.
|
/// @param src array of any size
|
||||||
/// @param dst array of size >= src.size
|
/// @param dst array of size >= src.size
|
||||||
/// @param decrypted_size size of original data without padding added by EncryptorAES_encrypt
|
/// @param decrypted_size size of original data without padding added by EncryptorAES_encrypt
|
||||||
void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32* decrypted_size);
|
void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32* decrypted_size);
|
||||||
|
|||||||
@ -1,18 +1,8 @@
|
|||||||
#include "cryptography.h"
|
#include "cryptography.h"
|
||||||
#include "tlibc/time.h"
|
#include "tlibc/time.h"
|
||||||
#include "assert.h"
|
|
||||||
|
|
||||||
void rng_init_sha256_seedFromTime(const br_prng_class** rng_vtable_ptr){
|
void rng_init_sha256_seedFromTime(const br_prng_class** rng_vtable_ptr){
|
||||||
nsec_t time_now = getTimeNsec();
|
nsec_t time_now = getTimeNsec();
|
||||||
const br_prng_class* rng_vtable = *rng_vtable_ptr;
|
const br_prng_class* rng_vtable = *rng_vtable_ptr;
|
||||||
rng_vtable->init(rng_vtable_ptr, &br_sha256_vtable, &time_now, sizeof(time_now));
|
rng_vtable->init(rng_vtable_ptr, &br_sha256_vtable, &time_now, sizeof(time_now));
|
||||||
}
|
}
|
||||||
|
|
||||||
void rng_init_sha256_seedFromSystem(const br_prng_class** rng_vtable_ptr){
|
|
||||||
br_prng_seeder seeder = br_prng_seeder_system(NULL);
|
|
||||||
assert(seeder != NULL && "Can't get system random seeder. Bearssl is compiled incorrectly.");
|
|
||||||
|
|
||||||
const br_prng_class* rng_vtable = *rng_vtable_ptr;
|
|
||||||
rng_vtable->init(rng_vtable_ptr, &br_sha256_vtable, NULL, 0);
|
|
||||||
seeder(rng_vtable_ptr);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -13,11 +13,6 @@ typedef enum ProgramMode {
|
|||||||
int main(const int argc, cstr const* argv){
|
int main(const int argc, cstr const* argv){
|
||||||
Deferral(32);
|
Deferral(32);
|
||||||
|
|
||||||
if(br_prng_seeder_system(NULL) == NULL){
|
|
||||||
printfe("Can't get system random seeder. Bearssl is compiled incorrectly.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgramMode mode = Client;
|
ProgramMode mode = Client;
|
||||||
cstr server_endpoint_cstr;
|
cstr server_endpoint_cstr;
|
||||||
u32 key_size = 0;
|
u32 key_size = 0;
|
||||||
|
|||||||
@ -1,49 +0,0 @@
|
|||||||
#include "EncryptedSocket.h"
|
|
||||||
|
|
||||||
void EncryptedSocket_construct(EncryptedSocket* ptr, Socket sock, Array(u8) aes_key)
|
|
||||||
{
|
|
||||||
ptr->sock = sock;
|
|
||||||
EncryptorAES_construct(&ptr->enc, aes_key);
|
|
||||||
DecryptorAES_construct(&ptr->dec, aes_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Result(void) EncryptedSocket_send(EncryptedSocket* ptr,
|
|
||||||
Array(u8) decrypted_buf, Array(u8) encrypted_buf)
|
|
||||||
{
|
|
||||||
Deferral(4);
|
|
||||||
EncryptorAES_encrypt(&ptr->enc, decrypted_buf, encrypted_buf);
|
|
||||||
try_void(socket_send(ptr->sock, encrypted_buf));
|
|
||||||
Return RESULT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(void) EncryptedSocket_sendto(EncryptedSocket* ptr,
|
|
||||||
Array(u8) decrypted_buf, Array(u8) encrypted_buf,
|
|
||||||
EndpointIPv4 remote_end)
|
|
||||||
{
|
|
||||||
Deferral(4);
|
|
||||||
EncryptorAES_encrypt(&ptr->enc, decrypted_buf, encrypted_buf);
|
|
||||||
try_void(socket_sendto(ptr->sock, encrypted_buf, remote_end));
|
|
||||||
Return RESULT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(i32) EncryptedSocket_recv(EncryptedSocket* ptr,
|
|
||||||
Array(u8) encrypted_buf, Array(u8) decrypted_buf)
|
|
||||||
{
|
|
||||||
Deferral(4);
|
|
||||||
try(i32 r, i, socket_recv(ptr->sock, encrypted_buf));
|
|
||||||
encrypted_buf.size = r;
|
|
||||||
DecryptorAES_decrypt(&ptr->dec, encrypted_buf, decrypted_buf, (u32*)&r);
|
|
||||||
Return RESULT_VALUE(i, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(i32) EncryptedSocket_recvfrom(EncryptedSocket* ptr,
|
|
||||||
Array(u8) encrypted_buf, Array(u8) decrypted_buf,
|
|
||||||
NULLABLE(EndpointIPv4*) remote_end)
|
|
||||||
{
|
|
||||||
Deferral(4);
|
|
||||||
try(i32 r, i, socket_recvfrom(ptr->sock, encrypted_buf, remote_end));
|
|
||||||
encrypted_buf.size = r;
|
|
||||||
DecryptorAES_decrypt(&ptr->dec, encrypted_buf, decrypted_buf, (u32*)&r);
|
|
||||||
Return RESULT_VALUE(i, r);
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "network/socket.h"
|
|
||||||
#include "cryptography/cryptography.h"
|
|
||||||
|
|
||||||
typedef struct EncryptedSocket {
|
|
||||||
Socket sock;
|
|
||||||
EncryptorAES enc;
|
|
||||||
DecryptorAES dec;
|
|
||||||
} EncryptedSocket;
|
|
||||||
|
|
||||||
void EncryptedSocket_construct(EncryptedSocket* ptr, Socket sock, Array(u8) aes_key);
|
|
||||||
|
|
||||||
Result(void) EncryptedSocket_send(EncryptedSocket* ptr,
|
|
||||||
Array(u8) decrypted_buf, Array(u8) encrypted_buf);
|
|
||||||
|
|
||||||
Result(void) EncryptedSocket_sendto(EncryptedSocket* ptr,
|
|
||||||
Array(u8) decrypted_buf, Array(u8) encrypted_buf,
|
|
||||||
EndpointIPv4 remote_end);
|
|
||||||
|
|
||||||
Result(i32) EncryptedSocket_recv(EncryptedSocket* ptr,
|
|
||||||
Array(u8) encrypted_buf, Array(u8) decrypted_buf);
|
|
||||||
|
|
||||||
Result(i32) EncryptedSocket_recvfrom(EncryptedSocket* ptr,
|
|
||||||
Array(u8) encrypted_buf, Array(u8) decrypted_buf,
|
|
||||||
NULLABLE(EndpointIPv4*) remote_end);
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
#include "server.h"
|
|
||||||
|
|
||||||
void ClientConnection_close(ClientConnection* conn){
|
|
||||||
if(conn == NULL)
|
|
||||||
return;
|
|
||||||
socket_close(conn->system_socket.sock);
|
|
||||||
socket_close(conn->content_socket.sock);
|
|
||||||
free(conn->session_key.data);
|
|
||||||
free(conn);
|
|
||||||
}
|
|
||||||
@ -2,12 +2,12 @@
|
|||||||
#include "db/idb.h"
|
#include "db/idb.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
static void* handle_connection(void* _args);
|
typedef struct AcceptedConnection {
|
||||||
|
Socket sock;
|
||||||
typedef struct ConnectionHandlerArgs {
|
|
||||||
Socket accepted_socket;
|
|
||||||
EndpointIPv4 client_end;
|
EndpointIPv4 client_end;
|
||||||
} ConnectionHandlerArgs;
|
} AcceptedConnection;
|
||||||
|
|
||||||
|
static void* handle_connection(void* _args);
|
||||||
|
|
||||||
Result(void) server_run(cstr server_endpoint_str){
|
Result(void) server_run(cstr server_endpoint_str){
|
||||||
Deferral(32);
|
Deferral(32);
|
||||||
@ -19,8 +19,8 @@ Result(void) server_run(cstr server_endpoint_str){
|
|||||||
try_void(socket_listen(main_socket, 512));
|
try_void(socket_listen(main_socket, 512));
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)malloc(sizeof(ConnectionHandlerArgs));
|
AcceptedConnection* args = malloc(sizeof(AcceptedConnection));
|
||||||
try(args->accepted_socket, i, socket_accept(main_socket, &args->client_end));
|
try(args->sock, i, socket_accept(main_socket, &args->client_end));
|
||||||
pthread_t conn_thread = {0};
|
pthread_t conn_thread = {0};
|
||||||
try_stderrcode(pthread_create(&conn_thread, NULL, handle_connection, args));
|
try_stderrcode(pthread_create(&conn_thread, NULL, handle_connection, args));
|
||||||
}
|
}
|
||||||
@ -30,11 +30,8 @@ Result(void) server_run(cstr server_endpoint_str){
|
|||||||
|
|
||||||
static void* handle_connection(void* _args){
|
static void* handle_connection(void* _args){
|
||||||
Deferral(64);
|
Deferral(64);
|
||||||
ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)_args;
|
AcceptedConnection* conn = (AcceptedConnection*)_args;
|
||||||
// TODO: receive handshake and session key
|
Defer(free(conn));
|
||||||
|
|
||||||
//ClientConnection conn;
|
|
||||||
|
|
||||||
|
|
||||||
Return NULL;
|
Return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "network/socket.h"
|
||||||
#include "cryptography/cryptography.h"
|
#include "cryptography/cryptography.h"
|
||||||
#include "network/EncryptedSocket.h"
|
|
||||||
|
|
||||||
Result(void) server_run(cstr server_endpoint_str);
|
Result(void) server_run(cstr server_endpoint_str);
|
||||||
|
|
||||||
typedef struct ClientConnection {
|
|
||||||
EndpointIPv4 client_end;
|
|
||||||
Array(u8) session_key;
|
|
||||||
EncryptedSocket system_socket;
|
|
||||||
EncryptedSocket content_socket;
|
|
||||||
} ClientConnection;
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user