| 779 | "0123456789+/"; |
| 780 | |
| 781 | class AESCipherTCP { |
| 782 | private: |
| 783 | std::vector<uint8_t> key; |
| 784 | AES_ctx ctx; |
| 785 | |
| 786 | std::vector<uint8_t> pad(const std::vector<uint8_t>& data) { |
| 787 | size_t pad_len = 16 - (data.size() % 16); |
| 788 | std::vector<uint8_t> padded = data; |
| 789 | padded.insert(padded.end(), pad_len, static_cast<uint8_t>(pad_len)); |
| 790 | return padded; |
| 791 | } |
| 792 | |
| 793 | std::vector<uint8_t> unpad(const std::vector<uint8_t>& data) { |
| 794 | if (data.empty()) return data; |
| 795 | uint8_t pad_len = data.back(); |
| 796 | if (pad_len > 16 || pad_len == 0) return data; |
| 797 | return std::vector<uint8_t>(data.begin(), data.end() - pad_len); |
| 798 | } |
| 799 | |
| 800 | public: |
| 801 | AESCipherTCP(const std::string& key_str) { |
| 802 | key = std::vector<uint8_t>(key_str.begin(), key_str.end()); |
| 803 | if (key.size() != 16 && key.size() != 24 && key.size() != 32) { |
| 804 | throw std::runtime_error("Key must be 16, 24, or 32 bytes long"); |
| 805 | } |
| 806 | AES_init_ctx(&ctx, key.data()); |
| 807 | } |
| 808 | |
| 809 | std::vector<uint8_t> encrypt(const std::string& raw) { |
| 810 | std::vector<uint8_t> data(raw.begin(), raw.end()); |
| 811 | data = pad(data); |
| 812 | std::vector<uint8_t> iv(16); |
| 813 | for (size_t i = 0; i < 16; ++i) iv[i] = rand() % 256; |
| 814 | std::vector<uint8_t> result = iv; |
| 815 | AES_ctx ctx_copy = ctx; |
| 816 | AES_ctx_set_iv(&ctx_copy, iv.data()); |
| 817 | AES_CBC_encrypt_buffer(&ctx_copy, data.data(), data.size()); |
| 818 | result.insert(result.end(), data.begin(), data.end()); |
| 819 | return result; |
| 820 | } |
| 821 | |
| 822 | std::string decrypt(const std::vector<uint8_t>& enc) { |
| 823 | if (enc.size() < 16) throw std::runtime_error("Invalid encrypted data"); |
| 824 | std::vector<uint8_t> iv(enc.begin(), enc.begin() + 16); |
| 825 | std::vector<uint8_t> data(enc.begin() + 16, enc.end()); |
| 826 | if (data.size() % 16 != 0) throw std::runtime_error("Invalid data length"); |
| 827 | AES_ctx ctx_copy = ctx; |
| 828 | AES_ctx_set_iv(&ctx_copy, iv.data()); |
| 829 | AES_CBC_decrypt_buffer(&ctx_copy, data.data(), data.size()); |
| 830 | data = unpad(data); |
| 831 | return std::string(data.begin(), data.end()); |
| 832 | } |
| 833 | }; |
| 834 | |
| 835 | void send_data(SOCKET sock, const std::vector<uint8_t>& data) { |
| 836 | uint32_t length = static_cast<uint32_t>(data.size()); |
nothing calls this directly
no outgoing calls
no test coverage detected