diff --git a/generic_functions/generic_functions.cpp b/generic_functions/generic_functions.cpp index 2e85c25..187608d 100644 --- a/generic_functions/generic_functions.cpp +++ b/generic_functions/generic_functions.cpp @@ -9,7 +9,7 @@ void xor_iv(std::string &submessage, const std::string &init_vec) hexstr_to_uint8t(init_vec, init_vec_bin); hexstr_to_uint8t(submessage, submessage_bin); - for(int i = 0; i < 64; i++) + for(int i = 0; i < 32; i++) { submessage_bin[i] ^= init_vec_bin[i]; } diff --git a/main.cpp b/main.cpp index 1fa6ce8..19d200c 100644 --- a/main.cpp +++ b/main.cpp @@ -11,6 +11,7 @@ #include "meta/cfb.h" #include "meta/ofb.h" #include "meta/ctr.h" +#include "meta/gcm.h" int main() { @@ -20,15 +21,17 @@ int main() std::string message = "00112233445566778899aabbccddeeff"; std::string message_ll = "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"; + std::string auth_data = "00000000000000000000000000000000"; + std::string auth_tag{}; + AES aes(AES_key_length::AES_128); aes.generate_keys(key_128); - CBC<AES> aes_cbc(aes); - - std::cout << "META" << std::endl; + GCM<AES> aes_gcm(aes); + std::cout << message_ll << std::endl; - aes_cbc.encrypt(message_ll); + aes_gcm.encrypt(message_ll, auth_data, auth_tag); std::cout << message_ll << std::endl; - aes_cbc.decrypt(message_ll); + aes_gcm.decrypt(message_ll, auth_data, auth_tag); std::cout << message_ll << std::endl; return 0; diff --git a/meta/gcm.h b/meta/gcm.h new file mode 100644 index 0000000..68503fc --- /dev/null +++ b/meta/gcm.h @@ -0,0 +1,175 @@ +#include "../conversion/conversion.h" +#include "../random_gen/rng.h" +#include "../generic_functions/generic_functions.h" +#include <string> +#include <vector> + +template<typename AlgorithmType> +class GCM +{ +private: + AlgorithmType& alg; + RNG rng; + uint8_t iv_len = 16; + std::string iv; + +public: + GCM(AlgorithmType& alg) + :alg(alg) + { + iv = rng.generate_iv(iv_len); + }; + + void encrypt(std::string &message, std::string auth_data, std::string &auth_tag) + { + std::string init_vec = iv; + std::string counter = init_vec; + uint8_t counter_arr[16]; + std::vector<std::string> message_vec; + std::string message_len = std::to_string(message.size() * 8); + + split_message(message, message_vec); + + int j = 15; + + hexstr_to_uint8t(counter, counter_arr); + if(counter_arr[j] == 0xFF) + { + j--; + } + counter_arr[j]++; + uint8t_to_hexstr(counter, counter_arr, 16); + + for(size_t i = 0; i < message_vec.size(); i++) + { + if(i > 0) + { + init_vec = counter; + } + + alg.encrypt(init_vec); + xor_iv(message_vec[i], init_vec); + xor_iv(auth_data, message_vec[i]); + gf_multiplication(auth_data, iv); + + hexstr_to_uint8t(counter, counter_arr); + if(counter_arr[j] == 0xFF) + { + j--; + } + counter_arr[j]++; + uint8t_to_hexstr(counter, counter_arr, 16); + + for(size_t i = 0; i < message_vec.size(); i++) + { + message += message_vec[i]; + } + } + + xor_iv(auth_data, message_len); + + auth_tag = iv; + alg.encrypt(auth_tag); + xor_iv(auth_tag, auth_data); + + message = ""; + + for(size_t i = 0; i < message_vec.size(); i++) + { + message += message_vec[i]; + } + }; + + void decrypt(std::string &cipher, std::string auth_data, const std::string &auth_tag) + { + std::string init_vec = iv; + std::string counter = init_vec; + std::string auth_iv = iv; + uint8_t counter_arr[16]; + std::vector<std::string> cipher_vec; + std::string cipher_len = std::to_string(cipher.size() * 8); + + split_message(cipher, cipher_vec); + + int j = 15; + + hexstr_to_uint8t(counter, counter_arr); + if(counter_arr[j] == 0xFF) + { + j--; + } + counter_arr[j]++; + uint8t_to_hexstr(counter, counter_arr, 16); + + for(size_t i = 0; i < cipher_vec.size(); i++) + { + if(i > 0) + { + init_vec = counter; + } + + alg.encrypt(init_vec); + xor_iv(cipher_vec[i], init_vec); + xor_iv(auth_data, cipher_vec[i]); + gf_multiplication(auth_data, iv); + + hexstr_to_uint8t(counter, counter_arr); + if(counter_arr[j] == 0xFF) + { + j--; + } + counter_arr[j]++; + uint8t_to_hexstr(counter, counter_arr, 16); + } + + xor_iv(auth_data, cipher_len); + + alg.encrypt(auth_iv); + xor_iv(auth_iv, auth_data); + + cipher = ""; + + for(size_t i = 0; i < cipher_vec.size(); i++) + { + cipher += cipher_vec[i]; + } + + std::cout << auth_iv << std::endl; + std::cout << auth_tag << std::endl; + }; + + void gf_multiplication(std::string &auth_data, const std::string &hash_key) + { + uint8_t auth_data_bin[16]; + uint64_t auth_data_bin_expanded[2]; + uint8_t hash_key_bin[16]; + uint64_t hash_key_bin_expanded[2]; + + size_t auth_data_len = sizeof(auth_data_bin) / (2 * sizeof(*auth_data_bin)); + + hexstr_to_uint8t(hash_key, hash_key_bin); + hexstr_to_uint8t(auth_data, auth_data_bin); + uint8t_to_uint64t_arr(hash_key_bin, hash_key_bin_expanded, 2); + + uint8t_to_hexstr(auth_data, auth_data_bin, auth_data_len); + } + + void uint8t_to_uint64t_arr(uint8_t *uint8t_arr, uint64_t *uint64t_arr, const size_t &uint64t_arr_size) + { + int j = 0; + + for(size_t i = 0; i < uint64t_arr_size; i++) + { + uint64t_arr[i] = (((uint64_t)uint8t_arr[j] << 56) & 0xFF00000000000000) | + (((uint64_t)uint8t_arr[j + 1] << 48) & 0x00FF000000000000) | + (((uint64_t)uint8t_arr[j + 2] << 40) & 0x0000FF0000000000) | + (((uint64_t)uint8t_arr[j + 3] << 32) & 0x000000FF00000000) | + (((uint64_t)uint8t_arr[j + 4] << 24) & 0x00000000FF000000) | + (((uint64_t)uint8t_arr[j + 5] << 16) & 0x0000000000FF0000) | + (((uint64_t)uint8t_arr[j + 6] << 8) & 0x000000000000FF00) | + (((uint64_t)uint8t_arr[j + 7]) & 0x00000000000000FF); + + j += 8; + } + } +};