From 9a4ef709cadea0486188e0a7a3cf2d3793776693 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Wed, 21 Jul 2021 12:35:22 +0300 Subject: [PATCH] Add parameters for configuring the logfile encryption SDLOG_ALGORITHM for selecting the crypto algorithm SDLOG_KEY for selecting the key in keystore to use with the algorithm. for symmetric algorithms which are currently supported, this is just a free slot to be used, the key is generated at logging start SDLOG_EXCH_KEY for selecting an RSA2048 key for encrypting the SDLOG_KEY Signed-off-by: Jukka Laitinen --- src/modules/logger/log_writer.h | 6 ++++ src/modules/logger/log_writer_file.cpp | 47 ++++++++++++-------------- src/modules/logger/log_writer_file.h | 12 +++++++ src/modules/logger/logger.cpp | 15 ++++++-- src/modules/logger/logger.h | 5 +++ src/modules/logger/params.c | 44 ++++++++++++++++++++++++ 6 files changed, 102 insertions(+), 27 deletions(-) diff --git a/src/modules/logger/log_writer.h b/src/modules/logger/log_writer.h index abac8a5d57..504d35b767 100644 --- a/src/modules/logger/log_writer.h +++ b/src/modules/logger/log_writer.h @@ -166,6 +166,12 @@ public: return false; } +#if defined(PX4_CRYPTO) + void set_encryption_parameters(px4_crypto_algorithm_t algorithm, uint8_t key_idx, uint8_t exchange_key_idx) + { + if (_log_writer_file) { _log_writer_file->set_encryption_parameters(algorithm, key_idx, exchange_key_idx); } + } +#endif private: LogWriterFile *_log_writer_file = nullptr; diff --git a/src/modules/logger/log_writer_file.cpp b/src/modules/logger/log_writer_file.cpp index 5a013cda74..915aa1962b 100644 --- a/src/modules/logger/log_writer_file.cpp +++ b/src/modules/logger/log_writer_file.cpp @@ -45,10 +45,6 @@ #include #endif /* __PX4_NUTTX */ -// TODO: how to define the key slots/product? -// this depends on the keystore as well -#define LOGGER_CRYPTO_KEY_IDX 2 - using namespace time_literals; @@ -89,8 +85,12 @@ LogWriterFile::~LogWriterFile() #if defined(PX4_CRYPTO) bool LogWriterFile::init_logfile_encryption(const char *filename) { - // open a crypto session // TODO: use a parameter for algorithm - if (!_crypto.open(CRYPTO_XCHACHA20)) { + if (_algorithm == CRYPTO_NONE) { + return true; + } + + // open a crypto session + if (!_crypto.open(_algorithm)) { return false; } @@ -99,9 +99,7 @@ bool LogWriterFile::init_logfile_encryption(const char *filename) // Generate a crypto key and store it to the keystore. - // TODO: use parameter for alogrithm? Or product specific macro? - // TODO: how to define key index to the keystore? Product macro? parameter? - if (!_crypto.generate_key(LOGGER_CRYPTO_KEY_IDX, false)) { + if (!_crypto.generate_key(_key_idx, false)) { PX4_ERR("Can't generate crypto key"); return false; } @@ -113,17 +111,15 @@ bool LogWriterFile::init_logfile_encryption(const char *filename) return false; } - // TODO: define the public key used for key exchange. Now hardcoded to 1 - /* Get the size of an encrypted key and nonce */ size_t key_size; size_t nonce_size; - if (!rsa_crypto.get_encrypted_key(LOGGER_CRYPTO_KEY_IDX, + if (!rsa_crypto.get_encrypted_key(_key_idx, NULL, &key_size, - 1) || + _exchange_key_idx) || !_crypto.get_nonce(NULL, &nonce_size) || key_size == 0) { rsa_crypto.close(); @@ -135,10 +131,10 @@ bool LogWriterFile::init_logfile_encryption(const char *filename) if (!key || !rsa_crypto.get_encrypted_key( - LOGGER_CRYPTO_KEY_IDX, + _key_idx, key, &key_size, - 1) || + _exchange_key_idx) || !_crypto.get_nonce( key + key_size, &nonce_size)) { PX4_ERR("Can't get & encrypt the key"); @@ -223,7 +219,6 @@ void LogWriterFile::start_log(LogType type, const char *filename) } #if PX4_CRYPTO - // TODO: use parameter to check if logfile crypto is enabled bool enc_init = init_logfile_encryption(filename); if (!enc_init) { @@ -391,17 +386,19 @@ void LogWriterFile::run() by the px4 crypto interfaces */ - // TODO: use parameter to check if logfile crypto is enabled size_t out = available; - _crypto.encrypt_data( - LOGGER_CRYPTO_KEY_IDX, // key - (uint8_t *)read_ptr, - available, - (uint8_t *)read_ptr, - &out); - if (out != available) { - PX4_ERR("Encryption output size mismatch, logfile corrupted"); + if (_algorithm != CRYPTO_NONE) { + _crypto.encrypt_data( + _key_idx, + (uint8_t *)read_ptr, + available, + (uint8_t *)read_ptr, + &out); + + if (out != available) { + PX4_ERR("Encryption output size mismatch, logfile corrupted"); + } } #endif diff --git a/src/modules/logger/log_writer_file.h b/src/modules/logger/log_writer_file.h index a042e639cf..01db3bdaaa 100644 --- a/src/modules/logger/log_writer_file.h +++ b/src/modules/logger/log_writer_file.h @@ -129,6 +129,15 @@ public: pthread_t thread_id() const { return _thread; } +#if defined(PX4_CRYPTO) + void set_encryption_parameters(px4_crypto_algorithm_t algorithm, uint8_t key_idx, uint8_t exchange_key_idx) + { + _algorithm = algorithm; + _key_idx = key_idx; + _exchange_key_idx = exchange_key_idx; + } +#endif + private: static void *run_helper(void *); @@ -205,6 +214,9 @@ private: bool init_logfile_encryption(const char *filename); PX4Crypto _crypto; int _min_blocksize; + px4_crypto_algorithm_t _algorithm; + uint8_t _key_idx; + uint8_t _exchange_key_idx; #endif }; diff --git a/src/modules/logger/logger.cpp b/src/modules/logger/logger.cpp index ff46364a06..047f5f56ea 100644 --- a/src/modules/logger/logger.cpp +++ b/src/modules/logger/logger.cpp @@ -1271,8 +1271,11 @@ int Logger::get_log_file_name(LogType type, char *file_name, size_t file_name_si const char *crypto_suffix = ""; #if defined(PX4_CRYPTO) - // TODO: use parameter to check if logfile crypto is enabled - crypto_suffix = "c"; + + if (_param_sdlog_crypto_algorithm.get() != 0) { + crypto_suffix = "c"; + } + #endif char *log_file_name = _file_name[(int)type].log_file_name; @@ -1376,9 +1379,17 @@ void Logger::start_log_file(LogType type) return; } +#if defined(PX4_CRYPTO) + _writer.set_encryption_parameters( + (px4_crypto_algorithm_t)_param_sdlog_crypto_algorithm.get(), + _param_sdlog_crypto_key.get(), + _param_sdlog_crypto_exchange_key.get()); +#endif + _writer.start_log_file(type, file_name); _writer.select_write_backend(LogWriter::BackendFile); _writer.set_need_reliable_transfer(true); + write_header(type); write_version(type); write_formats(type); diff --git a/src/modules/logger/logger.h b/src/modules/logger/logger.h index 5638fe82ce..34cab79899 100644 --- a/src/modules/logger/logger.h +++ b/src/modules/logger/logger.h @@ -374,6 +374,11 @@ private: (ParamInt) _param_sdlog_mission, (ParamBool) _param_sdlog_boot_bat, (ParamBool) _param_sdlog_uuid +#if defined(PX4_CRYPTO) + , (ParamInt) _param_sdlog_crypto_algorithm, + (ParamInt) _param_sdlog_crypto_key, + (ParamInt) _param_sdlog_crypto_exchange_key +#endif ) }; diff --git a/src/modules/logger/params.c b/src/modules/logger/params.c index 8220aa8fcf..81ce9e426d 100644 --- a/src/modules/logger/params.c +++ b/src/modules/logger/params.c @@ -173,3 +173,47 @@ PARAM_DEFINE_INT32(SDLOG_DIRS_MAX, 0); * @group SD Logging */ PARAM_DEFINE_INT32(SDLOG_UUID, 1); + +/** + * Logfile Encryption algorithm + * + * Selects the algorithm used for logfile encryption + * + * @value 0 Disabled + * @value 2 XChaCha20 + * @value 3 AES + * + * @group SD Logging + */ +PARAM_DEFINE_INT32(SDLOG_ALGORITHM, 2); + +/** + * Logfile Encryption key index + * + * Selects the key in keystore, used for encrypting the log. When using + * a symmetric encryption algorithm, the key is generated at logging start + * and kept stored in this index. For symmetric algorithms, the key is + * volatile and valid only for the duration of logging. The key is stored + * in encrypted format on the sdcard alongside the logfile, using an RSA2048 + * key defined by the SDLOG_EXCHANGE_KEY + * + * @min 0 + * @max 255 + * + * @group SD Logging + */ +PARAM_DEFINE_INT32(SDLOG_KEY, 2); + +/** + * Logfile Encryption key exchange key + * + * If the logfile is encrypted using a symmetric key algorithm, + * the used encryption key is generated at logging start and stored + * on the sdcard RSA2048 encrypted using this key. + * + * @min 0 + * @max 255 + * + * @group SD Logging + */ +PARAM_DEFINE_INT32(SDLOG_EXCH_KEY, 1);