cryptography rework and beginning of tcp-chat-protocol
This commit is contained in:
122
src/cryptography/AES.h
Normal file
122
src/cryptography/AES.h
Normal file
@@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
#include "tlibc/collections/Array.h"
|
||||
#include "tlibc/errors.h"
|
||||
#include "bearssl_block.h"
|
||||
#include "cryptography.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// AES.c //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define AESBlockEncryptor_DEFAULT_CLASS (&br_aes_ct64_cbcenc_vtable)
|
||||
#define AESBlockDecryptor_DEFAULT_CLASS (&br_aes_ct64_cbcdec_vtable)
|
||||
#define AESStream_DEFAULT_CLASS (&br_aes_ct64_ctr_vtable)
|
||||
|
||||
|
||||
//TODO: use PKS#7 instead of this garbage
|
||||
typedef struct EncryptedBlockHeader {
|
||||
u8 padding_size;
|
||||
} __attribute__((aligned(16))) EncryptedBlockHeader;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// AESBlockEncryptor //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define __AES_BLOCK_IV_SIZE 16
|
||||
// must be multiple of 16
|
||||
#define __AES_BUFFER_SIZE 512
|
||||
|
||||
typedef struct AESBlockEncryptor {
|
||||
const br_block_cbcenc_class* enc_class;
|
||||
u8 enc_keys[sizeof(br_aes_ct64_cbcenc_keys)];
|
||||
u8 buf[__AES_BUFFER_SIZE];
|
||||
u8 iv[__AES_BLOCK_IV_SIZE];
|
||||
br_hmac_drbg_context rng_ctx;
|
||||
} AESBlockEncryptor;
|
||||
|
||||
/// @param key supported sizes: 16, 24, 32
|
||||
/// @param enc_class &br_aes_XXX_cbcenc_vtable
|
||||
void AESBlockEncryptor_construct(AESBlockEncryptor* ptr, Array(u8) key, const br_block_cbcenc_class* enc_class);
|
||||
|
||||
/// @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)
|
||||
/// @return size of encrypted data
|
||||
Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr, Array(u8) src, Array(u8) dst);
|
||||
|
||||
#define AESBlockEncryptor_calcDstSize(SRC_SIZE) (__AES_BLOCK_IV_SIZE + sizeof(EncryptedBlockHeader) + ALIGN_TO(SRC_SIZE, 16))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// AESBlockDecryptor //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct AESBlockDecryptor {
|
||||
const br_block_cbcdec_class* dec_class;
|
||||
u8 dec_keys[sizeof(br_aes_ct64_cbcdec_keys)];
|
||||
u8 buf[__AES_BUFFER_SIZE];
|
||||
u8 iv[__AES_BLOCK_IV_SIZE];
|
||||
} AESBlockDecryptor;
|
||||
|
||||
/// @param key supported sizes: 16, 24, 32
|
||||
/// @param dec_class &br_aes_XXX_cbcdec_vtable
|
||||
void AESBlockDecryptor_construct(AESBlockDecryptor* ptr, Array(u8) key, const br_block_cbcdec_class* dec_class);
|
||||
|
||||
/// @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
|
||||
/// @return size of decrypted data
|
||||
Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr, Array(u8) src, Array(u8) dst);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// AESStreamEncryptor //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define __AES_STREAM_IV_SIZE 12
|
||||
|
||||
typedef struct AESStreamEncryptor {
|
||||
const br_block_ctr_class* ctr_class;
|
||||
u8 ctr_keys[sizeof(br_aes_ct64_ctr_keys)];
|
||||
u8 buf[__AES_BUFFER_SIZE];
|
||||
u8 iv[__AES_STREAM_IV_SIZE];
|
||||
u32 block_counter;
|
||||
} AESStreamEncryptor;
|
||||
|
||||
/// @warning If you start from not first block in sequence (example: to continue a previously interrupted operation) set correct values for ptr->block_counter and ptr->iv or encryption/decryption will produce incorrect data.
|
||||
/// @param key supported sizes: 16, 24, 32
|
||||
/// @param dec_class &br_aes_XXX_ctr_vtable
|
||||
void AESStreamEncryptor_construct(AESStreamEncryptor* ptr, Array(u8) key, const br_block_ctr_class* ctr_class);
|
||||
|
||||
#define AESStreamEncryptor_calcDstSize(src_size) (src_size + __AES_BLOCK_IV_SIZE)
|
||||
|
||||
/// @brief If ptr->block_counter == 0, writes random IV to `dst`. After that writes encrypted data to dst.
|
||||
/// @param src array of any size
|
||||
/// @param dst array of size >= AESStreamEncryptor_calcDstSize(src.size)
|
||||
/// @return size of encrypted data
|
||||
Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr, Array(u8) src, Array(u8) dst);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// AESStreamDecryptor //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct AESStreamDecryptor {
|
||||
const br_block_ctr_class* ctr_class;
|
||||
u8 ctr_keys[sizeof(br_aes_ct64_ctr_keys)];
|
||||
u8 buf[__AES_BUFFER_SIZE];
|
||||
u8 iv[__AES_STREAM_IV_SIZE];
|
||||
u32 block_counter;
|
||||
} AESStreamDecryptor;
|
||||
|
||||
/// @warning If you start from not first block in sequence (example: to continue a previously interrupted operation) set correct values for ptr->block_counter and ptr->iv or encryption/decryption will produce incorrect data.
|
||||
/// @param key supported sizes: 16, 24, 32
|
||||
/// @param dec_class &br_aes_XXX_ctr_vtable
|
||||
void AESStreamDecryptor_construct(AESStreamDecryptor* ptr, Array(u8) key, const br_block_ctr_class* ctr_class);
|
||||
|
||||
/// @brief Reads IV from `src`, then decrypts data and writes it to dst
|
||||
/// @param src array of size at least AESStreamEncryptor_calcDstSize(0).
|
||||
/// @param dst array of size >= src.size
|
||||
/// @return size of decrypted data
|
||||
Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr, Array(u8) src, Array(u8) dst);
|
||||
|
||||
#define __AESStreamDecryptor_calcDstSize(src_size) (src_size - __AES_BLOCK_IV_SIZE)
|
||||
Reference in New Issue
Block a user