implemented EncryptedSocketTCP_recvStruct and EncryptedSocketTCP_recvRSA

This commit is contained in:
2025-11-08 18:21:47 +05:00
parent ee522ac401
commit 2db37bb902
12 changed files with 267 additions and 153 deletions

View File

@@ -4,18 +4,23 @@
// write data from src to array and increment array data pointer
static inline void __Array_writeNext(Array(u8)* dst, u8* src, size_t size){
memcpy(dst->data, src, size);
*dst = Array_sliceAfter(*dst, size);
*dst = Array_sliceFrom(*dst, size);
}
// read data from array to dst and increment array data pointer
static inline void __Array_readNext(u8* dst, Array(u8)* src, size_t size){
memcpy(dst, src->data, size);
*src = Array_sliceAfter(*src, size);
*src = Array_sliceFrom(*src, size);
}
//////////////////////////////////////////////////////////////////////////////
// AESBlockEncryptor //
//////////////////////////////////////////////////////////////////////////////
void AESBlockEncryptor_construct(AESBlockEncryptor* ptr, Array(u8) key, const br_block_cbcenc_class* enc_class){
void AESBlockEncryptor_construct(AESBlockEncryptor* ptr,
Array(u8) key, const br_block_cbcenc_class* enc_class)
{
assert(key.size == 16 || key.size == 24 || key.size == 32);
ptr->enc_class = enc_class;
@@ -25,7 +30,15 @@ void AESBlockEncryptor_construct(AESBlockEncryptor* ptr, Array(u8) key, const br
rng_init_sha256_seedFromSystem(&ptr->rng_ctx.vtable);
}
Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr, Array(u8) src, Array(u8) dst){
void AESBlockEncryptor_changeKey(AESBlockEncryptor* ptr, Array(u8) key)
{
assert(key.size == 16 || key.size == 24 || key.size == 32);
ptr->enc_class->init((void*)ptr->enc_keys, key.data, key.size);
}
Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr,
Array(u8) src, Array(u8) dst)
{
Deferral(4);
u32 encrypted_size = AESBlockEncryptor_calcDstSize(src.size);
try_assert(dst.size >= encrypted_size);
@@ -67,15 +80,28 @@ Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr, Array(u8) src, Arr
}
//////////////////////////////////////////////////////////////////////////////
// AESBlockDecryptor //
//////////////////////////////////////////////////////////////////////////////
void AESBlockDecryptor_construct(AESBlockDecryptor* ptr, Array(u8) key, const br_block_cbcdec_class* dec_class){
void AESBlockDecryptor_construct(AESBlockDecryptor* ptr,
Array(u8) key, const br_block_cbcdec_class* dec_class)
{
assert(key.size == 16 || key.size == 24 || key.size == 32);
ptr->dec_class = dec_class;
ptr->dec_class->init((void*)ptr->dec_keys, key.data, key.size);
}
Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr, Array(u8) src, Array(u8) dst){
void AESBlockDecryptor_changeKey(AESBlockDecryptor* ptr, Array(u8) key)
{
assert(key.size == 16 || key.size == 24 || key.size == 32);
ptr->dec_class->init((void*)ptr->dec_keys, key.data, key.size);
}
Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr,
Array(u8) src, Array(u8) dst)
{
Deferral(4);
try_assert(src.size >= AESBlockEncryptor_calcDstSize(0));
try_assert(src.size % 16 == 0 && "src must be array of 16-byte blocks");
@@ -116,8 +142,13 @@ Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr, Array(u8) src, Arr
}
//////////////////////////////////////////////////////////////////////////////
// AESStreamEncryptor //
//////////////////////////////////////////////////////////////////////////////
void AESStreamEncryptor_construct(AESStreamEncryptor* ptr, Array(u8) key, const br_block_ctr_class* ctr_class){
void AESStreamEncryptor_construct(AESStreamEncryptor* ptr,
Array(u8) key, const br_block_ctr_class* ctr_class)
{
assert(key.size == 16 || key.size == 24 || key.size == 32);
ptr->ctr_class = ctr_class;
@@ -131,7 +162,15 @@ void AESStreamEncryptor_construct(AESStreamEncryptor* ptr, Array(u8) key, const
ptr->block_counter = 0;
}
Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr, Array(u8) src, Array(u8) dst){
void AESStreamEncryptor_changeKey(AESStreamEncryptor* ptr, Array(u8) key)
{
assert(key.size == 16 || key.size == 24 || key.size == 32);
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.size);
}
Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr,
Array(u8) src, Array(u8) dst)
{
Deferral(4);
u32 encrypted_size = AESStreamEncryptor_calcDstSize(src.size);
try_assert(dst.size >= encrypted_size);
@@ -164,8 +203,13 @@ Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr, Array(u8) src, A
}
//////////////////////////////////////////////////////////////////////////////
// AESStreamDecryptor //
//////////////////////////////////////////////////////////////////////////////
void AESStreamDecryptor_construct(AESStreamDecryptor* ptr, Array(u8) key, const br_block_ctr_class* ctr_class){
void AESStreamDecryptor_construct(AESStreamDecryptor* ptr,
Array(u8) key, const br_block_ctr_class* ctr_class)
{
assert(key.size == 16 || key.size == 24 || key.size == 32);
ptr->ctr_class = ctr_class;
@@ -174,7 +218,15 @@ void AESStreamDecryptor_construct(AESStreamDecryptor* ptr, Array(u8) key, const
ptr->block_counter = 0;
}
Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr, Array(u8) src, Array(u8) dst){
void AESStreamDecryptor_changeKey(AESStreamDecryptor* ptr, Array(u8) key)
{
assert(key.size == 16 || key.size == 24 || key.size == 32);
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.size);
}
Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr,
Array(u8) src, Array(u8) dst)
{
Deferral(4);
// if it is the beginning of the stream, read IV

View File

@@ -40,6 +40,9 @@ typedef struct AESBlockEncryptor {
/// @param enc_class &br_aes_XXX_cbcenc_vtable
void AESBlockEncryptor_construct(AESBlockEncryptor* ptr, Array(u8) key, const br_block_cbcenc_class* enc_class);
/// @param key supported sizes: 16, 24, 32
void AESBlockEncryptor_changeKey(AESBlockEncryptor* ptr, Array(u8) key);
/// @brief Encrypts a complete message. For part-by-part encryption use AESStreamEncryptor.
/// @param src array of any size
/// @param dst array of size >= AESBlockEncryptor_calcDstSize(src.size)
@@ -63,6 +66,9 @@ typedef struct AESBlockDecryptor {
/// @param dec_class &br_aes_XXX_cbcdec_vtable
void AESBlockDecryptor_construct(AESBlockDecryptor* ptr, Array(u8) key, const br_block_cbcdec_class* dec_class);
/// @param key supported sizes: 16, 24, 32
void AESBlockDecryptor_changeKey(AESBlockDecryptor* ptr, Array(u8) key);
/// @brief Decrypts a complete message. For part-by-part decryption use AESStreamEncryptor.
/// @param src array of size at least AESBlockEncryptor_calcDstSize(0). Size must be multiple of 16.
/// @param dst array of size >= src.size
@@ -88,6 +94,9 @@ typedef struct AESStreamEncryptor {
/// @param dec_class &br_aes_XXX_ctr_vtable
void AESStreamEncryptor_construct(AESStreamEncryptor* ptr, Array(u8) key, const br_block_ctr_class* ctr_class);
/// @param key supported sizes: 16, 24, 32
void AESStreamEncryptor_changeKey(AESStreamEncryptor* ptr, Array(u8) key);
/// use this only at the beginning of the stream
#define AESStreamEncryptor_calcDstSize(src_size) (src_size + __AES_STREAM_IV_SIZE)
@@ -114,6 +123,9 @@ typedef struct AESStreamDecryptor {
/// @param dec_class &br_aes_XXX_ctr_vtable
void AESStreamDecryptor_construct(AESStreamDecryptor* ptr, Array(u8) key, const br_block_ctr_class* ctr_class);
/// @param key supported sizes: 16, 24, 32
void AESStreamDecryptor_changeKey(AESStreamDecryptor* ptr, Array(u8) key);
/// @brief Reads IV from `src`, then decrypts data and writes it to dst
/// @param src array of any size
/// @param dst array of size >= src.size

View File

@@ -175,6 +175,11 @@ Result(void) RSA_parsePrivateKey_base64(cstr src, br_rsa_private_key* sk){
Return RESULT_VOID;
}
//////////////////////////////////////////////////////////////////////////////
// RSAEncryptor //
//////////////////////////////////////////////////////////////////////////////
void RSAEncryptor_construct(RSAEncryptor* ptr, const br_rsa_public_key* pk){
ptr->pk = pk;
ptr->rng.vtable = &br_hmac_drbg_vtable;
@@ -185,11 +190,11 @@ Result(u32) RSAEncryptor_encrypt(RSAEncryptor* ptr, Array(u8) src, Array(u8) dst
u32 key_size_bytes = ptr->pk->nlen;
const u32 max_src_size = RSAEncryptor_calcMaxSrcSize(key_size_bytes * 8, 256);
if(src.size > max_src_size){
return RESULT_ERROR_FMT("src.size (%u) must be <= %u (use RSAEncryptor_calcMaxSrcSize)",
return RESULT_ERROR_FMT("src.size (%u) must be <= RSAEncryptor_calcMaxSrcSize() (%u)",
src.size, max_src_size);
}
if(dst.size < key_size_bytes){
return RESULT_ERROR_FMT("dst.size (%u) must be >= %u (key length in bytes)",
return RESULT_ERROR_FMT("dst.size (%u) must be >= key length in bytes (%u)",
dst.size, key_size_bytes);
}
size_t sz = br_rsa_i31_oaep_encrypt(
@@ -206,30 +211,27 @@ Result(u32) RSAEncryptor_encrypt(RSAEncryptor* ptr, Array(u8) src, Array(u8) dst
}
//////////////////////////////////////////////////////////////////////////////
// RSADecryptor //
//////////////////////////////////////////////////////////////////////////////
void RSADecryptor_construct(RSADecryptor* ptr, const br_rsa_private_key* sk){
ptr->sk = sk;
}
Result(u32) RSADecryptor_decrypt(RSADecryptor* ptr, Array(u8) src, Array(u8) dst){
Result(u32) RSADecryptor_decrypt(RSADecryptor* ptr, Array(u8) buffer){
u32 key_size_bits = ptr->sk->n_bitlen;
if(src.size != key_size_bits/8){
return RESULT_ERROR_FMT("src.size (%u) must be == %u (key length in bytes)",
src.size, key_size_bits/8);
if(buffer.size != key_size_bits/8){
return RESULT_ERROR_FMT("buffer.size (%u) must be == key length in bytes (%u)",
buffer.size, key_size_bits/8);
}
const u32 max_src_size = RSAEncryptor_calcMaxSrcSize(key_size_bits, 256);
if(dst.size < max_src_size){
return RESULT_ERROR_FMT("dst.size (%u) must be >= %u (use RSAEncryptor_calcMaxSrcSize)",
dst.size, max_src_size);
}
memcpy(dst.data, src.data, src.size);
size_t sz = src.size;
size_t sz = buffer.size;
size_t r = br_rsa_i31_oaep_decrypt(
&br_sha256_vtable,
NULL, 0,
ptr->sk,
dst.data, &sz);
buffer.data, &sz);
if(r == 0){
return RESULT_ERROR("RSA encryption failed", false);

View File

@@ -58,6 +58,7 @@ str RSA_serializePublicKey_base64(const br_rsa_public_key* sk);
/// @param sk out public key. WARNING: .p is allocated on heap
Result(void) RSA_parsePublicKey_base64(cstr src, br_rsa_public_key* sk);
//////////////////////////////////////////////////////////////////////////////
// RSAEncryptor //
//////////////////////////////////////////////////////////////////////////////
@@ -90,6 +91,7 @@ https://crypto.stackexchange.com/a/42100
/// @return size of encrypted data
Result(u32) RSAEncryptor_encrypt(RSAEncryptor* ptr, Array(u8) src, Array(u8) dst);
//////////////////////////////////////////////////////////////////////////////
// RSADecryptor //
//////////////////////////////////////////////////////////////////////////////
@@ -102,6 +104,5 @@ typedef struct RSADecryptor {
void RSADecryptor_construct(RSADecryptor* ptr, const br_rsa_private_key* sk);
/// @param src buffer with size == key size in bytes
/// @param dst buffer with size >= `RSAEncryptor_calcMaxSrcSize(key_size_bits, 256)`
/// @return size of decrypted data
Result(u32) RSADecryptor_decrypt(RSADecryptor* ptr, Array(u8) src, Array(u8) dst);
Result(u32) RSADecryptor_decrypt(RSADecryptor* ptr, Array(u8) buffer);