Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_CheckFirmware/AP_CheckFirmware.h
Views: 1798
/*1support checking board ID and firmware CRC in the bootloader2*/3#pragma once45#include <AP_HAL/AP_HAL_Boards.h>6#include <AP_OpenDroneID/AP_OpenDroneID_config.h>7#include <AP_HAL/AP_HAL.h>8#include <GCS_MAVLink/GCS_config.h>9#if HAL_GCS_ENABLED10#include <GCS_MAVLink/GCS_MAVLink.h>11#endif1213#ifndef AP_CHECK_FIRMWARE_ENABLED14#define AP_CHECK_FIRMWARE_ENABLED AP_OPENDRONEID_ENABLED15#endif1617#if AP_CHECK_FIRMWARE_ENABLED1819enum class check_fw_result_t : uint8_t {20CHECK_FW_OK = 0,21FAIL_REASON_NO_APP_SIG = 10,22FAIL_REASON_BAD_LENGTH_APP = 11,23FAIL_REASON_BAD_BOARD_ID = 12,24FAIL_REASON_BAD_CRC = 13,25FAIL_REASON_IN_UPDATE = 14,26FAIL_REASON_WATCHDOG = 15,27FAIL_REASON_BAD_LENGTH_DESCRIPTOR = 16,28FAIL_REASON_BAD_FIRMWARE_SIGNATURE = 17,29FAIL_REASON_VERIFICATION = 18,30};3132#ifndef FW_MAJOR33#define APP_FW_MAJOR 034#define APP_FW_MINOR 035#else36#define APP_FW_MAJOR FW_MAJOR37#define APP_FW_MINOR FW_MINOR38#endif3940#if CONFIG_HAL_BOARD == HAL_BOARD_SITL && !defined(APJ_BOARD_ID)41// this allows for sitl_periph to build42#define APJ_BOARD_ID 043#endif4445/*46the app_descriptor stored in flash in the main firmware and is used47by the bootloader to confirm that the firmware is not corrupt and is48suitable for this board. The build dependent values in this structure49are filled in by set_app_descriptor() in the waf build5051Note that we need to define both structures to make it possible to52boot a signed firmware using a bootloader setup for unsigned53*/5455#define AP_APP_DESCRIPTOR_SIGNATURE_SIGNED { 0x41, 0xa3, 0xe5, 0xf2, 0x65, 0x69, 0x92, 0x07 }56#define AP_APP_DESCRIPTOR_SIGNATURE_UNSIGNED { 0x40, 0xa2, 0xe4, 0xf1, 0x64, 0x68, 0x91, 0x06 }5758struct app_descriptor_unsigned {59uint8_t sig[8];60// crc1 is the crc32 from firmware start to start of image_crc161uint32_t image_crc1;62// crc2 is the crc32 from the start of version_major to the end of the firmware63uint32_t image_crc2;64// total size of firmware image in bytes65uint32_t image_size;66uint32_t git_hash;6768// software version number69uint8_t version_major;70uint8_t version_minor;71// APJ_BOARD_ID (hardware version). This is also used in CAN NodeInfo72// with high byte in HardwareVersion.major and low byte in HardwareVersion.minor73uint16_t board_id;74uint8_t reserved[8];75};7677struct app_descriptor_signed {78uint8_t sig[8];79// crc1 is the crc32 from firmware start to start of image_crc180uint32_t image_crc1;81// crc2 is the crc32 from the start of version_major to the end of the firmware82uint32_t image_crc2;83// total size of firmware image in bytes84uint32_t image_size;85uint32_t git_hash;8687// firmware signature88uint32_t signature_length;89uint8_t signature[72];9091// software version number92uint8_t version_major;93uint8_t version_minor;94// APJ_BOARD_ID (hardware version). This is also used in CAN NodeInfo95// with high byte in HardwareVersion.major and low byte in HardwareVersion.minor96uint16_t board_id;97uint8_t reserved[8];98};99100#if AP_SIGNED_FIRMWARE101typedef struct app_descriptor_signed app_descriptor_t;102#else103typedef struct app_descriptor_unsigned app_descriptor_t;104#endif105106#define APP_DESCRIPTOR_UNSIGNED_TOTAL_LENGTH 36107#define APP_DESCRIPTOR_SIGNED_TOTAL_LENGTH (APP_DESCRIPTOR_UNSIGNED_TOTAL_LENGTH+72+4)108109static_assert(sizeof(app_descriptor_unsigned) == APP_DESCRIPTOR_UNSIGNED_TOTAL_LENGTH, "app_descriptor_unsigned incorrect length");110static_assert(sizeof(app_descriptor_signed) == APP_DESCRIPTOR_SIGNED_TOTAL_LENGTH, "app_descriptor_signed incorrect length");111112#if AP_SIGNED_FIRMWARE113114#define AP_PUBLIC_KEY_LEN 32115#define AP_PUBLIC_KEY_MAX_KEYS 10116#define AP_PUBLIC_KEY_SIGNATURE {0x4e, 0xcf, 0x4e, 0xa5, 0xa6, 0xb6, 0xf7, 0x29}117118struct PACKED ap_secure_data {119uint8_t sig[8] = AP_PUBLIC_KEY_SIGNATURE;120struct PACKED {121uint8_t key[AP_PUBLIC_KEY_LEN] = {};122} public_key[AP_PUBLIC_KEY_MAX_KEYS];123};124#endif125126#ifdef HAL_BOOTLOADER_BUILD127check_fw_result_t check_good_firmware(void);128const app_descriptor_t *get_app_descriptor(void);129#else130void check_firmware_print(void);131132class AP_CheckFirmware {133public:134#if HAL_GCS_ENABLED135// handle a message from the GCS. This is static as we don't have an AP_CheckFirmware object136static void handle_msg(mavlink_channel_t chan, const mavlink_message_t &msg);137static void handle_secure_command(mavlink_channel_t chan, const mavlink_secure_command_t &pkt);138static bool check_signature(const mavlink_secure_command_t &pkt);139#endif140static const struct ap_secure_data *find_public_keys(void);141142/*143in memory structure representing the current bootloader. It has two144data regions to cope with persistent data at the end of the145bootloader sector146*/147struct bl_data {148uint32_t length1;149uint8_t *data1;150uint32_t offset2;151uint32_t length2;152uint8_t *data2;153154// destructor155~bl_data(void) {156delete[] data1;157delete[] data2;158}159};160static struct bl_data *read_bootloader(void);161static bool write_bootloader(const struct bl_data *bld);162static bool set_public_keys(uint8_t key_idx, uint8_t num_keys, const uint8_t *key_data);163static bool all_zero_keys(const struct ap_secure_data *sec_data);164static bool check_signed_bootloader(const uint8_t *fw, uint32_t fw_size);165166private:167#if HAL_GCS_ENABLED168static uint8_t session_key[8];169#endif170};171172#endif // HAL_BOOTLOADER_BUILD173174#endif // AP_CHECK_FIRMWARE_ENABLED175176177