From 2616f7c58838e8f3bbc99a13025240c98aece966 Mon Sep 17 00:00:00 2001 From: consti10 Date: Fri, 11 Aug 2023 12:40:12 +0200 Subject: [PATCH] encryption add bind phrase feature --- .gitignore | 2 +- {example_keys => example_key}/README.md | 0 {example_keys => example_key}/generate.sh | 0 example_key/txrx.key | 1 + example_keys/drone.key | 2 - example_keys/gs.key | 1 - executables/example_hello.cpp | 3 +- executables/example_pollute.cpp | 2 +- executables/example_udp.cpp | 4 +- executables/injection_rate_test.cpp | 2 +- executables/test_txrx.cpp | 4 +- executables/unit_test.cpp | 21 ++-- executables/wfb_keygen.cpp | 4 +- latencyTesting/SimpleTestProgram/.gitignore | 2 +- src/Encryption.hpp | 109 +++++++++----------- src/WBTxRx.cpp | 18 ++-- src/WBTxRx.h | 9 +- 17 files changed, 82 insertions(+), 102 deletions(-) rename {example_keys => example_key}/README.md (100%) rename {example_keys => example_key}/generate.sh (100%) create mode 100644 example_key/txrx.key delete mode 100644 example_keys/drone.key delete mode 100644 example_keys/gs.key diff --git a/.gitignore b/.gitignore index b2be1072..8bec5f8a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,7 @@ wfb_tx unit_test benchmark gs.key -drone.key +key_1.key wfb_keygen udp_generator_validator socket_helper_test diff --git a/example_keys/README.md b/example_key/README.md similarity index 100% rename from example_keys/README.md rename to example_key/README.md diff --git a/example_keys/generate.sh b/example_key/generate.sh similarity index 100% rename from example_keys/generate.sh rename to example_key/generate.sh diff --git a/example_key/txrx.key b/example_key/txrx.key new file mode 100644 index 00000000..b279cbc5 --- /dev/null +++ b/example_key/txrx.key @@ -0,0 +1 @@ +üÑèÚOäéØ8x±-»Ÿøì%Ç>Kqy?³*a¸oMº ¬0ªâõËÉh|—pš –©U8Bë÷=º´ø¹ºíά­|õáÌÝÅX3̦';,Uû;À°Påx™:þÁ’û@Ćþó;˜oaP6™>àêHØŸÔL¶-“’ÞE \ No newline at end of file diff --git a/example_keys/drone.key b/example_keys/drone.key deleted file mode 100644 index 642ce8ff..00000000 --- a/example_keys/drone.key +++ /dev/null @@ -1,2 +0,0 @@ -•æ‰„ç;·õd© =˜€Ágo1‹HF°%¸¸Ý4Ab×·šÏA­ —"<ô/Ç°]‘ ‡7Ðr+9(.Ñ+/ - \ No newline at end of file diff --git a/example_keys/gs.key b/example_keys/gs.key deleted file mode 100644 index 33e90a8c..00000000 --- a/example_keys/gs.key +++ /dev/null @@ -1 +0,0 @@ -RË[¿Ó÷Ú­YmwìÈMæCÐ4~ÿ¸©ÁÚÌYåO‰:›ãt­ •Ç;;(Y aÍ0):z&2¡ÓÙr \ No newline at end of file diff --git a/executables/example_hello.cpp b/executables/example_hello.cpp index 1af230ec..b8f6afcb 100644 --- a/executables/example_hello.cpp +++ b/executables/example_hello.cpp @@ -58,8 +58,7 @@ int main(int argc, char *const *argv) { WBTxRx::WifiCard tmp_card{card,1}; cards.push_back(tmp_card); WBTxRx::Options options_txrx{}; - options_txrx.rtl8812au_rssi_fixup= true; - options_txrx.set_direction= true; + options_txrx.pcap_rx_set_direction = true; options_txrx.use_gnd_identifier=!is_air; if(advanced_debugging){ options_txrx.log_all_received_validated_packets= true; diff --git a/executables/example_pollute.cpp b/executables/example_pollute.cpp index 6a66c627..2530584c 100644 --- a/executables/example_pollute.cpp +++ b/executables/example_pollute.cpp @@ -45,7 +45,7 @@ int main(int argc, char *const *argv) { cards.push_back(tmp_card); WBTxRx::Options options_txrx{}; options_txrx.rtl8812au_rssi_fixup= true; - options_txrx.set_direction= true; + options_txrx.pcap_rx_set_direction = true; options_txrx.enable_non_openhd_mode= true; std::shared_ptr txrx=std::make_shared(cards,options_txrx); diff --git a/executables/example_udp.cpp b/executables/example_udp.cpp index a1bb9731..306eac43 100644 --- a/executables/example_udp.cpp +++ b/executables/example_udp.cpp @@ -75,8 +75,8 @@ int main(int argc, char *const *argv) { cards.push_back(tmp_card); WBTxRx::Options options_txrx{}; options_txrx.rtl8812au_rssi_fixup= true; - //options_txrx.set_direction= false; - options_txrx.set_direction= pcap_setdirection; + //options_txrx.pcap_rx_set_direction= false; + options_txrx.pcap_rx_set_direction = pcap_setdirection; options_txrx.log_all_received_validated_packets= false; std::shared_ptr txrx=std::make_shared(cards,options_txrx); diff --git a/executables/injection_rate_test.cpp b/executables/injection_rate_test.cpp index 3ccf1c23..60c60005 100644 --- a/executables/injection_rate_test.cpp +++ b/executables/injection_rate_test.cpp @@ -250,7 +250,7 @@ int main(int argc, char *const *argv) { cards.push_back(tmp_card); WBTxRx::Options options_txrx{}; options_txrx.rtl8812au_rssi_fixup= true; - //options_txrx.set_direction= false; + //options_txrx.pcap_rx_set_direction= false; options_txrx.log_all_received_validated_packets= false; std::shared_ptr txrx=std::make_shared(cards,options_txrx); diff --git a/executables/test_txrx.cpp b/executables/test_txrx.cpp index 9e9211e6..255a0505 100644 --- a/executables/test_txrx.cpp +++ b/executables/test_txrx.cpp @@ -34,8 +34,8 @@ int main(int argc, char *const *argv) { cards.push_back(tmp_card); WBTxRx::Options options_txrx{}; options_txrx.rtl8812au_rssi_fixup= true; - //options_txrx.set_direction= false; - options_txrx.set_direction= pcap_setdirection; + //options_txrx.pcap_rx_set_direction= false; + options_txrx.pcap_rx_set_direction = pcap_setdirection; options_txrx.log_all_received_validated_packets= true; std::shared_ptr txrx=std::make_shared(cards,options_txrx); diff --git a/executables/unit_test.cpp b/executables/unit_test.cpp index 89482f2e..cc832df7 100644 --- a/executables/unit_test.cpp +++ b/executables/unit_test.cpp @@ -110,23 +110,14 @@ static void test_fec_stream_random_bs_fs_overhead_dropped(){ // Test encryption+packet validation and packet validation only static void test_encrypt_decrypt_validate(const bool use_key_from_file,bool message_signing_only) { std::cout << "Using generated keypair (default seed otherwise):" << (use_key_from_file ? "y" : "n") << "\n"; - //const std::string filename_gs="gs.key"; - //const std::string filename_drone="drone.key"; - const std::string filename_gs="../example_keys/gs.key"; - const std::string filename_drone="../example_keys/drone.key"; - wb::KeyPair encKey{}; - wb::KeyPair decKey{}; + const std::string KEY_FILENAME="../example_key/txrx.key"; + wb::KeyPairTxRx keyPairTxRx{}; if(use_key_from_file){ - encKey=wb::read_keypair_from_file(filename_gs); - decKey=wb::read_keypair_from_file(filename_gs); + keyPairTxRx=wb::read_keypair_from_file(KEY_FILENAME); }else{ - /*encKey=wb::generate_keypair_deterministic(false); - decKey=wb::generate_keypair_deterministic(false);*/ const auto before=std::chrono::steady_clock::now(); - auto tmp=wb::generate_keypair_from_bind_phrase("openhd"); + keyPairTxRx=wb::generate_keypair_from_bind_phrase("openhd"); std::cout<<"Generating keypair from bind phrase took:"< sessionKeyNonce{}; // random data diff --git a/executables/wfb_keygen.cpp b/executables/wfb_keygen.cpp index d57ab86b..e1fc39d1 100644 --- a/executables/wfb_keygen.cpp +++ b/executables/wfb_keygen.cpp @@ -23,7 +23,7 @@ * Generates a new keypair and saves it to file for later use. */ int main(void) { - auto keypair=wb::generate_keypair(); + auto keypair= wb::generate_keypair_random(); //auto keypair=wb::generate_keypair_from_bind_phrase("openhd"); - return wb::write_to_file(keypair); + return wb::write_keypair_to_file(keypair,"txrx.key"); } diff --git a/latencyTesting/SimpleTestProgram/.gitignore b/latencyTesting/SimpleTestProgram/.gitignore index 1bb5e802..91ea6225 100644 --- a/latencyTesting/SimpleTestProgram/.gitignore +++ b/latencyTesting/SimpleTestProgram/.gitignore @@ -8,7 +8,7 @@ env/ _trial_temp/ test gs.key -drone.key +key_1.key wfb_keygen telemetry/conf/site.cfg telemetry/conf/local.cfg diff --git a/src/Encryption.hpp b/src/Encryption.hpp index 5083195b..54089ab9 100644 --- a/src/Encryption.hpp +++ b/src/Encryption.hpp @@ -26,47 +26,52 @@ static constexpr auto ENCRYPTION_ADDITIONAL_VALIDATION_DATA=crypto_aead_chacha20 namespace wb{ -// A wb key consists of a public and private key -struct KeyPair { +// A wb key consists of a public and secret key +struct Key { std::array public_key; std::array secret_key; }; +// A wb keypair are 2 keys, one for transmitting, one for receiving +// (Since both ground and air unit talk bidirectional) +// We use a different key for the down-link / uplink, respective struct KeyPairTxRx { - // NOTE: The key itself for drone exists of drone.secret and ground.public - KeyPair drone; - KeyPair ground; - // NOTE the air key consists of key1.sec and key2.pub and vice versa - KeyPair get_keypair_air(){ - return KeyPair{drone.secret_key,ground.public_key}; + Key key_1; + Key key_2; + Key get_tx_key(bool is_air){ + return is_air ? key_1 : key_2; } - KeyPair get_keypair_ground(){ - return KeyPair{ground.secret_key,drone.public_key}; + Key get_rx_key(bool is_air){ + return is_air ? key_2 : key_1; } }; // Generates a new keypair. Non-deterministic, 100% secure. -static KeyPairTxRx generate_keypair(){ +static KeyPairTxRx generate_keypair_random(){ KeyPairTxRx ret{}; - crypto_box_keypair(ret.drone.public_key.data(), ret.drone.secret_key.data()); - crypto_box_keypair(ret.ground.public_key.data(), ret.ground.secret_key.data()); + crypto_box_keypair(ret.key_1.public_key.data(), ret.key_1.secret_key.data()); + crypto_box_keypair(ret.key_2.public_key.data(), ret.key_2.secret_key.data()); return ret; } -static KeyPair generate_keypair_deterministic(bool is_air){ - KeyPair ret{}; + +// Obsolete +static Key generate_keypair_deterministic(bool is_air){ + Key ret{}; std::array seed1{0}; std::array seed2{1}; crypto_box_seed_keypair(ret.public_key.data(), ret.secret_key.data(),is_air ? seed1.data(): seed2.data()); return ret; } +// Salts generated once using https://www.random.org/cgi-bin/randbyte?nbytes=16&format=d +// We want deterministic seed from a pw, and are only interested in making it impossible to reverse the process (even though the salt is plain text) +static constexpr std::array OHD_SALT_AIR{192,189,216,102,56,153,154,92,228,26,49,209,157,7,128,207}; +static constexpr std::array OHD_SALT_GND{179,30,150,20,17,200,225,82,48,64,18,130,89,62,83,234}; +static constexpr auto OHD_DEFAULT_TX_RX_KEY_FILENAME="txrx.key"; + // See https://libsodium.gitbook.io/doc/password_hashing static std::array create_seed_from_password(const std::string& pw,bool use_salt_air){ - // Salts generated once using https://www.random.org/cgi-bin/randbyte?nbytes=16&format=d - // We want deterministic seed from a pw, and are only interested in making it impossible to reverse the process (even though the seed is known) - std::array salt_air{192,189,216,102,56,153,154,92,228,26,49,209,157,7,128,207}; - std::array salt_gnd{179,30,150,20,17,200,225,82,48,64,18,130,89,62,83,234}; - const auto salt = use_salt_air ? salt_air : salt_gnd; + const auto salt = use_salt_air ? OHD_SALT_AIR : OHD_SALT_GND; std::array key{}; if (crypto_pwhash(key.data(), key.size(), pw.c_str(), pw.length(), salt.data(), crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE, @@ -78,59 +83,47 @@ static std::array create_seed_from_password(con return key; } -static KeyPairTxRx generate_keypair_from_bind_phrase(const std::string& bind_phrase=""){ +// We always use the same bind phrase by default +static constexpr auto DEFAULT_BIND_PHRASE="openhd"; +static KeyPairTxRx generate_keypair_from_bind_phrase(const std::string& bind_phrase=DEFAULT_BIND_PHRASE){ const auto seed_air= create_seed_from_password(bind_phrase, true); const auto seed_gnd= create_seed_from_password(bind_phrase, false); KeyPairTxRx ret{}; - crypto_box_seed_keypair(ret.drone.public_key.data(), ret.drone.secret_key.data(),seed_air.data()); - crypto_box_seed_keypair(ret.ground.public_key.data(), ret.ground.secret_key.data(),seed_gnd.data()); + crypto_box_seed_keypair(ret.key_1.public_key.data(), ret.key_1.secret_key.data(),seed_air.data()); + crypto_box_seed_keypair(ret.key_2.public_key.data(), ret.key_2.secret_key.data(),seed_gnd.data()); return ret; } -static int write_keypair_to_file(const KeyPair& keypair,const std::string& filename){ +static int write_keypair_to_file(const KeyPairTxRx& keypair_txrx,const std::string& filename){ FILE *fp; if ((fp = fopen(filename.c_str(), "w")) == nullptr) { std::cerr<<"Unable to save "<info("Decryptor-New session detected"); session_key = new_session_key; return SESSION_VALID_NEW; } + // this is NOT an error, the same session key is sent multiple times ! return SESSION_VALID_NOT_NEW; } /** diff --git a/src/WBTxRx.cpp b/src/WBTxRx.cpp index 39c4ca59..ad9a4818 100644 --- a/src/WBTxRx.cpp +++ b/src/WBTxRx.cpp @@ -45,7 +45,7 @@ WBTxRx::WBTxRx(std::vector wifi_cards1,Options options1) pcapTxRx.rx=wifibroadcast::pcap_helper::open_pcap_rx(wifi_card.name); //pcapTxRx.tx=pcapTxRx.rx; pcapTxRx.tx=wifibroadcast::pcap_helper::open_pcap_tx(wifi_card.name); - if(m_options.set_direction){ + if(m_options.pcap_rx_set_direction){ const auto ret=pcap_setdirection(pcapTxRx.rx, PCAP_D_IN); m_console->debug("pcap_setdirection() returned {}",ret); } @@ -54,14 +54,14 @@ WBTxRx::WBTxRx(std::vector wifi_cards1,Options options1) m_receive_pollfds[i].fd = fd; m_receive_pollfds[i].events = POLLIN; } - wb::KeyPair keypair{}; - if(m_options.encryption_key.has_value()){ - keypair= wb::read_keypair_from_file(m_options.encryption_key.value()); + wb::KeyPairTxRx keypair{}; + if(m_options.secure_keypair.has_value()){ + keypair= m_options.secure_keypair.value(); }else{ - keypair=wb::generate_keypair_deterministic(true); + keypair=wb::generate_keypair_from_bind_phrase(); } - m_encryptor=std::make_unique(keypair); - m_decryptor=std::make_unique(keypair); + m_encryptor=std::make_unique(keypair.get_tx_key(!m_options.use_gnd_identifier)); + m_decryptor=std::make_unique(keypair.get_rx_key(!m_options.use_gnd_identifier)); m_encryptor->makeNewSessionKey(m_tx_sess_key_packet.sessionKeyNonce,m_tx_sess_key_packet.sessionKeyData); // next session key in delta ms if packets are being fed m_session_key_next_announce_ts = std::chrono::steady_clock::now(); @@ -750,6 +750,6 @@ void WBTxRx::recalculate_pollution_perc() { } std::string WBTxRx::options_to_string(const std::vector& wifi_cards,const WBTxRx::Options& options) { - return fmt::format("Id:{} Cards:{} KeyPair:{} ",options.use_gnd_identifier ? "Ground":"Air",StringHelper::string_vec_as_string(wifi_cards), - options.encryption_key.value_or("DEFAULT_SEED")); + return fmt::format("Id:{} Cards:{} Key:{} ",options.use_gnd_identifier ? "Ground":"Air",StringHelper::string_vec_as_string(wifi_cards), + options.secure_keypair.has_value() ? "Custom" : "Default(openhd)"); } diff --git a/src/WBTxRx.h b/src/WBTxRx.h index e31c324c..1afa1bee 100644 --- a/src/WBTxRx.h +++ b/src/WBTxRx.h @@ -53,11 +53,10 @@ class WBTxRx { public: struct Options{ - // file for encryptor - // make optional for ease of use - with no keypair given the default "seed" is used - std::optional encryption_key = std::nullopt; - // on the rx pcap fd, set direction PCAP_D_IN (aka only packets received by the card) - doesn't work on AR9271 - bool set_direction= true; + // Bidirectional, so we need 2 keys + std::optional secure_keypair=std::nullopt; + // on the rx pcap rx fd, set direction PCAP_D_IN (aka only packets received by the card) - doesn't work on AR9271 + bool pcap_rx_set_direction = true; // thy spam the console, but usefully for debugging // log all received packets (regardless where they are from) bool log_all_received_packets= false;