From ed9a43ca460bea936b2720b42ce2fd49585c65b5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Jan 2016 13:49:06 +1100 Subject: [PATCH] GCS_MAVLink: support for mavlink2 signing operations --- libraries/GCS_MAVLink/GCS.h | 6 ++ libraries/GCS_MAVLink/GCS_Common.cpp | 3 + libraries/GCS_MAVLink/GCS_Signing.cpp | 98 +++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 libraries/GCS_MAVLink/GCS_Signing.cpp diff --git a/libraries/GCS_MAVLink/GCS.h b/libraries/GCS_MAVLink/GCS.h index fce5751b85..b30ae73171 100644 --- a/libraries/GCS_MAVLink/GCS.h +++ b/libraries/GCS_MAVLink/GCS.h @@ -309,6 +309,7 @@ private: static DataFlash_Class *dataflash_p; mavlink_signing_t signing; + static StorageAccess _signing_storage; // a vehicle can optionally snoop on messages for other systems static void (*msg_snoop)(const mavlink_message_t* msg); @@ -352,4 +353,9 @@ private: // return true if this channel has hardware flow control bool have_flow_control(void); + + void handle_setup_signing(const mavlink_message_t *msg); + bool signing_key_save(const struct SigningKey &key); + bool signing_key_load(struct SigningKey &key); + void load_signing_key(void); }; diff --git a/libraries/GCS_MAVLink/GCS_Common.cpp b/libraries/GCS_MAVLink/GCS_Common.cpp index 7bb0186205..ed60d3aaeb 100644 --- a/libraries/GCS_MAVLink/GCS_Common.cpp +++ b/libraries/GCS_MAVLink/GCS_Common.cpp @@ -109,6 +109,9 @@ GCS_MAVLINK::setup_uart(const AP_SerialManager& serial_manager, AP_SerialManager // and init the gcs instance init(uart, mav_chan); + + // load signing key + load_signing_key(); } /** diff --git a/libraries/GCS_MAVLink/GCS_Signing.cpp b/libraries/GCS_MAVLink/GCS_Signing.cpp new file mode 100644 index 0000000000..2f9aad62c5 --- /dev/null +++ b/libraries/GCS_MAVLink/GCS_Signing.cpp @@ -0,0 +1,98 @@ +// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- + +/* + Code for handling MAVLink2 signing + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "GCS.h" + +extern const AP_HAL::HAL& hal; + +// storage object +StorageAccess GCS_MAVLINK::_signing_storage(StorageManager::StorageKeys); + +// magic for versioning of the structure +#define SIGNING_KEY_MAGIC 0x3852fcd1 + +// structure stored in FRAM +struct SigningKey { + uint32_t magic; + uint64_t timestamp; + uint8_t secret_key[32]; +}; + +bool GCS_MAVLINK::signing_key_save(const struct SigningKey &key) +{ + if (_signing_storage.size() < sizeof(key)) { + return false; + } + return _signing_storage.write_block(0, &key, sizeof(key)); +} + +bool GCS_MAVLINK::signing_key_load(struct SigningKey &key) +{ + if (_signing_storage.size() < sizeof(key)) { + return false; + } + return _signing_storage.read_block(&key, 0, sizeof(key)); +} + +/* + handle a setup_signing message + */ +void GCS_MAVLINK::handle_setup_signing(const mavlink_message_t *msg) +{ + // decode + mavlink_setup_signing_t packet; + mavlink_msg_setup_signing_decode(msg, &packet); + + struct SigningKey key; + key.magic = SIGNING_KEY_MAGIC; + key.timestamp = packet.initial_timestamp; + memcpy(key.secret_key, packet.secret_key, 32); + + if (!signing_key_save(key)) { + hal.console->printf("Failed to save signing key"); + return; + } + + // activate it immediately + load_signing_key(); +} + + +/* + load signing key + */ +void GCS_MAVLINK::load_signing_key(void) +{ + struct SigningKey key; + if (!signing_key_load(key)) { + hal.console->printf("Failed to load signing key"); + return; + } + mavlink_status_t *status = mavlink_get_channel_status(chan); + if (status == NULL) { + hal.console->printf("Failed to load signing key - no status"); + return; + } + memcpy(signing.secret_key, key.secret_key, 32); + signing.link_id = (uint8_t)chan; + signing.timestamp = 1; + signing.flags = MAVLINK_SIGNING_FLAG_SIGN_OUTGOING; + + status->signing = &signing; +}