diff --git a/platforms/common/include/px4_platform_common/crypto.h b/platforms/common/include/px4_platform_common/crypto.h new file mode 100644 index 0000000000..554b6d4891 --- /dev/null +++ b/platforms/common/include/px4_platform_common/crypto.h @@ -0,0 +1,219 @@ +/**************************************************************************** + * + * Copyright (c) 2021 Technology Innovation Institute. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#ifdef PX4_CRYPTO + +#include +#include + +#include +#include +#include +#include "crypto_backend_definitions.h" + +/* + * Crypto API interface class + */ + +class PX4Crypto +{ +public: + /* + * Constructor & destructor + */ + + PX4Crypto(); + ~PX4Crypto(); + + /* + * Class function for crypto api initialization, called only once at + * boot + */ + + static void px4_crypto_init(void); + + /* + * Open crypto API for a specific algorithm + * algorithm: The crypto algorithm to be used + * returns true on success, false on failure + */ + + bool open(px4_crypto_algorithm_t algorithm); + + /* + * Close the crypto API. Optional, it is also closed by destructing the + * interface object + */ + + void close(); + + /* + * Keystore access functions + */ + + /* + * Generate a single random key for symmetric-key encryption + * + * idx: the index in keystore where the key will be stored + * persistent: whether the key need to be stored persistently + * returns true on success, false on failure + */ + + bool generate_key(uint8_t idx, + bool persistent); + + /* + * Generate a key pair for asymmetric-key encryption + * + * algorithm: the key type + * key_size: size of the key in bytes + * private_idx: the private key will be stored in this index in the keystore + * public_idx: the public key will be stored in this index in the keystore + * persistent: whether the keys need to be stored persistently + * returns true on success, false on failure + */ + + bool generate_keypair(size_t key_size, + uint8_t private_idx, + uint8_t public_idx, + bool persistent); + + + /* + * Re-create or set nonce. + * + * A nonce or intialization vector value for the selected algortithm is + * automatically generated when the crypto session is opened. If needed, the + * nonce can be set by this function. + * If this is called with NULL pointer, a new nonce is automatically random + * generated + */ + + bool renew_nonce(const uint8_t *nonce, size_t nonce_size); + + + /* + * Get current crypto session nonce + * + * This function returns the current nonce for the session + * If the "nonce" is NULL, only nonse legth will be provided + * nonce: pointer to the buffer where the nonce will be written + * nonce_len: length of the current nonce vector for the session + * returns true on success, false on failure + */ + + bool get_nonce(uint8_t *nonce, + size_t *nonce_len); + + /* + * Store a key into keystore + * + * encryption_idx: The key index in keystore to be used in decrypting and + * authenticating the key before storing + * key: The pointer to the key + * key_idx: Index where the key will be stored in keystore + */ + + + bool set_key(uint8_t encryption_idx, + const uint8_t *key, + uint8_t key_idx); + + /* + * Get a key from keystore. Key can be encrypted + * + * key_idx: Index of the requested key in the keystore + * key: The provided buffer to the key. If NULL, the function only provides + * the length of the key. + * key_len: input: the size of the provided "key" buffer. + output: the actual size of the key + * encryption_key_idx: The key index in keystore to be used for encrypting + * returns true on success, false on failure + * + */ + + bool get_encrypted_key(uint8_t key_idx, + uint8_t *key, + size_t *key_len, + uint8_t encryption_key_idx); + + /* + * PX4 Crypto API functions + */ + + /* + * Verify signature + * + * key_index: public key index in keystore + * signature: pointer to the signature + * message: pointer to the data to be verified + * message_size: size of the message in bytes + */ + + bool signature_check(uint8_t key_index, + const uint8_t *signature, + const uint8_t *message, + size_t message_size); + + + /* + * Encrypt data. This always supports encryption in-place + * + * key_index: key index in keystore + * message: pointer to the message + * message_size: size of the message in bytes + * cipher: pointer to a buffer for encrypted data + * cipher_size: size of the buffer reserved for cipher and actual cipher length + * after the encryption + * returns true on success, false on failure + */ + + bool encrypt_data(uint8_t key_index, + const uint8_t *message, + size_t message_size, + uint8_t *cipher, + size_t *cipher_size); + + size_t get_min_blocksize(uint8_t key_idx); + +private: + crypto_session_handle_t _crypto_handle; + static px4_sem_t _lock; + static bool _initialized; + static void lock() { do {} while (px4_sem_wait(&PX4Crypto::_lock) != 0); } + static void unlock() { px4_sem_post(&PX4Crypto::_lock); } +}; + +#endif diff --git a/platforms/common/include/px4_random.h b/platforms/common/include/px4_random.h new file mode 100644 index 0000000000..816bee16f3 --- /dev/null +++ b/platforms/common/include/px4_random.h @@ -0,0 +1,47 @@ +/**************************************************************************** + * + * Copyright (c) 2021 Technology Innovation Institute. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include + +/* + * Random number generator provided by the operating system. This can be used + * by the crypto_arch if needed, or it can implement an own HW-specific rng + */ + +__BEGIN_DECLS +size_t px4_get_secure_random(uint8_t *out, + size_t outlen); +__END_DECLS diff --git a/platforms/nuttx/src/px4/common/CMakeLists.txt b/platforms/nuttx/src/px4/common/CMakeLists.txt index 6a87f19a10..9937178ebf 100644 --- a/platforms/nuttx/src/px4/common/CMakeLists.txt +++ b/platforms/nuttx/src/px4/common/CMakeLists.txt @@ -48,6 +48,7 @@ if(NOT PX4_BOARD MATCHES "io-v2") px4_manifest.cpp px4_mtd.cpp px4_24xxxx_mtd.c + px4_crypto.cpp ) target_link_libraries(px4_layer PRIVATE @@ -58,7 +59,7 @@ if(NOT PX4_BOARD MATCHES "io-v2") nuttx_sched px4_work_queue uORB - ) + ) else() add_library(px4_layer ${PX4_SOURCE_DIR}/platforms/common/empty.c) endif() @@ -66,3 +67,14 @@ add_dependencies(px4_layer prebuild_targets) add_subdirectory(gpio) add_subdirectory(srgbled) + +if (DEFINED PX4_CRYPTO) + add_library(px4_random nuttx_random.c) + add_dependencies(px4_random nuttx_context) + target_link_libraries(px4_random PRIVATE nuttx_crypto) + + target_link_libraries(px4_layer + PUBLIC + crypto_backend + ) +endif() diff --git a/platforms/nuttx/src/px4/common/nuttx_random.c b/platforms/nuttx/src/px4/common/nuttx_random.c new file mode 100644 index 0000000000..26c2df3b41 --- /dev/null +++ b/platforms/nuttx/src/px4/common/nuttx_random.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * + * Copyright (c) 2021 Technology Innovation Institute. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +#if defined(CONFIG_CRYPTO_RANDOM_POOL) +size_t px4_get_secure_random(uint8_t *out, + size_t outlen) +{ + /* TODO: can getrandom fail?? */ + arc4random_buf(out, outlen); + return outlen; +} +#else +#error CONFIG_CRYPTO_RANDOM_POOL has to be defined +#endif diff --git a/platforms/nuttx/src/px4/common/px4_crypto.cpp b/platforms/nuttx/src/px4/common/px4_crypto.cpp new file mode 100644 index 0000000000..6ae4e8f7ea --- /dev/null +++ b/platforms/nuttx/src/px4/common/px4_crypto.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** + * + * Copyright (c) 2021 Technology Innovation Institute. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#if defined(PX4_CRYPTO) + +#include +#include + +extern "C" { +#include +} + + +px4_sem_t PX4Crypto::_lock; +bool PX4Crypto::_initialized = false; + +void PX4Crypto::px4_crypto_init() +{ + if (PX4Crypto::_initialized) { + return; + } + + px4_sem_init(&PX4Crypto::_lock, 0, 1); + + // Initialize nuttx random pool, if it is being used by crypto +#ifdef CONFIG_CRYPTO_RANDOM_POOL + up_randompool_initialize(); +#endif + + // initialize keystore functionality + keystore_init(); + + // initialize actual crypto algoritms + crypto_init(); + + PX4Crypto::_initialized = true; +} + +PX4Crypto::PX4Crypto() +{ + // Initialize an empty handle + crypto_session_handle_init(&_crypto_handle); +} + +PX4Crypto::~PX4Crypto() +{ + close(); +} + +bool PX4Crypto::open(px4_crypto_algorithm_t algorithm) +{ + bool ret = false; + lock(); + + // HW specific crypto already open? Just close before proceeding + if (crypto_session_handle_valid(_crypto_handle)) { + crypto_close(&_crypto_handle); + } + + // Open the HW specific crypto handle + _crypto_handle = crypto_open(algorithm); + + if (crypto_session_handle_valid(_crypto_handle)) { + ret = true; + } + + unlock(); + + return ret; +} + +void PX4Crypto::close() +{ + if (!crypto_session_handle_valid(_crypto_handle)) { + return; + } + + lock(); + crypto_close(&_crypto_handle); + unlock(); +} + +bool PX4Crypto::encrypt_data(uint8_t key_index, + const uint8_t *message, + size_t message_size, + uint8_t *cipher, + size_t *cipher_size) +{ + return crypto_encrypt_data(_crypto_handle, key_index, message, message_size, cipher, cipher_size); +} + +bool PX4Crypto::generate_key(uint8_t idx, + bool persistent) +{ + return crypto_generate_key(_crypto_handle, idx, persistent); +} + + +bool PX4Crypto::get_nonce(uint8_t *nonce, + size_t *nonce_len) +{ + return crypto_get_nonce(_crypto_handle, nonce, nonce_len); +} + + +bool PX4Crypto::get_encrypted_key(uint8_t key_idx, + uint8_t *key, + size_t *key_len, + uint8_t encryption_key_idx) +{ + return crypto_get_encrypted_key(_crypto_handle, key_idx, key, key_len, encryption_key_idx); +} + +size_t PX4Crypto::get_min_blocksize(uint8_t key_idx) +{ + return crypto_get_min_blocksize(_crypto_handle, key_idx); +} + +#endif diff --git a/platforms/nuttx/src/px4/common/px4_init.cpp b/platforms/nuttx/src/px4/common/px4_init.cpp index ef0538bdb7..9105109519 100644 --- a/platforms/nuttx/src/px4/common/px4_init.cpp +++ b/platforms/nuttx/src/px4/common/px4_init.cpp @@ -52,6 +52,10 @@ # include #endif // CONFIG_I2C +#if defined(PX4_CRYPTO) +#include +#endif + int px4_platform_init() { @@ -70,6 +74,10 @@ int px4_platform_init() close(fd_buf); } +#if defined(PX4_CRYPTO) + PX4Crypto::px4_crypto_init(); +#endif + hrt_init(); param_init();