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 <jukkax@ssrc.tii.ae>
This commit is contained in:
Jukka Laitinen 2021-07-21 12:35:22 +03:00 committed by Beat Küng
parent 1687cab56c
commit 9a4ef709ca
6 changed files with 102 additions and 27 deletions

View File

@ -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;

View File

@ -45,10 +45,6 @@
#include <systemlib/hardfault_log.h>
#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

View File

@ -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
};

View File

@ -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);

View File

@ -374,6 +374,11 @@ private:
(ParamInt<px4::params::SDLOG_MISSION>) _param_sdlog_mission,
(ParamBool<px4::params::SDLOG_BOOT_BAT>) _param_sdlog_boot_bat,
(ParamBool<px4::params::SDLOG_UUID>) _param_sdlog_uuid
#if defined(PX4_CRYPTO)
, (ParamInt<px4::params::SDLOG_ALGORITHM>) _param_sdlog_crypto_algorithm,
(ParamInt<px4::params::SDLOG_KEY>) _param_sdlog_crypto_key,
(ParamInt<px4::params::SDLOG_EXCH_KEY>) _param_sdlog_crypto_exchange_key
#endif
)
};

View File

@ -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);