mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-09 22:49:53 +08:00
galois embedded crypto module and secure transport (#2205)
* Added RNG for NPS, cleaned up telemetry config files * Added Rust submodules * Added simple status message * Updated gec transport and key exchange * Update pprzink * Compilation fix for Travis
This commit is contained in:
committed by
Gautier Hattenberger
parent
90c2c33b02
commit
d66fc0c3b7
@@ -31,3 +31,9 @@
|
|||||||
[submodule "sw/ext/hacl-c"]
|
[submodule "sw/ext/hacl-c"]
|
||||||
path = sw/ext/hacl-c
|
path = sw/ext/hacl-c
|
||||||
url = https://github.com/paparazzi/hacl-c.git
|
url = https://github.com/paparazzi/hacl-c.git
|
||||||
|
[submodule "sw/ext/rustlink"]
|
||||||
|
path = sw/ext/rustlink
|
||||||
|
url = https://github.com/paparazzi/rustlink.git
|
||||||
|
[submodule "sw/ext/key_generator"]
|
||||||
|
path = sw/ext/key_generator
|
||||||
|
url = https://github.com/paparazzi/key_generator.git
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ before_install:
|
|||||||
- sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa -y
|
- sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa -y
|
||||||
- sudo apt-get update -q
|
- sudo apt-get update -q
|
||||||
install:
|
install:
|
||||||
- sudo apt-get install -y --force-yes paparazzi-dev paparazzi-jsbsim gcc-arm-embedded gcc-arm-linux-gnueabi libipc-run-perl cmake
|
- sudo apt-get install -y --force-yes paparazzi-dev paparazzi-jsbsim gcc-arm-embedded gcc-arm-linux-gnueabi libipc-run-perl rustc cargo
|
||||||
script:
|
script:
|
||||||
- arm-none-eabi-gcc --version
|
- arm-none-eabi-gcc --version
|
||||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then if [ "${TRAVIS_EVENT_TYPE}" == "cron" ]; then make test_all_confs; else make test; fi; fi
|
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then if [ "${TRAVIS_EVENT_TYPE}" == "cron" ]; then make test_all_confs; else make test; fi; fi
|
||||||
|
|||||||
+13
-1
@@ -70,6 +70,7 @@ MODULES_H=$(AC_GENERATED)/modules.h
|
|||||||
MODULES_DIR=$(PAPARAZZI_HOME)/conf/modules/
|
MODULES_DIR=$(PAPARAZZI_HOME)/conf/modules/
|
||||||
AUTOPILOT_DIR=$(AC_GENERATED)/
|
AUTOPILOT_DIR=$(AC_GENERATED)/
|
||||||
AIRCRAFT_MD5=$(AIRCRAFT_CONF_DIR)/aircraft.md5
|
AIRCRAFT_MD5=$(AIRCRAFT_CONF_DIR)/aircraft.md5
|
||||||
|
GENERATE_KEYS ?= 0
|
||||||
|
|
||||||
UNAME = $(shell uname -s)
|
UNAME = $(shell uname -s)
|
||||||
ifeq ("$(UNAME)","Darwin")
|
ifeq ("$(UNAME)","Darwin")
|
||||||
@@ -176,6 +177,17 @@ else
|
|||||||
$(Q)cd $(PAPARAZZI_SRC) ; ./sw/tools/find_vpaths.py $(CXX) $(TMP_LIST) $(PAPARAZZI_SRC) >> $(SRCS_LIST)
|
$(Q)cd $(PAPARAZZI_SRC) ; ./sw/tools/find_vpaths.py $(CXX) $(TMP_LIST) $(PAPARAZZI_SRC) >> $(SRCS_LIST)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
CARGO=$(shell which cargo)
|
||||||
|
generate_keys:
|
||||||
|
ifeq ($(GENERATE_KEYS),1)
|
||||||
|
ifneq ($(CARGO),)
|
||||||
|
@echo GENERATE KEYS
|
||||||
|
$(Q)cargo run --manifest-path $(PAPARAZZI_SRC)/sw/ext/key_generator/Cargo.toml --release $(AC_GENERATED)
|
||||||
|
else
|
||||||
|
@echo "Error: Cargo (Rust) is not found, keys are not generated. Please install cargo."
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
qt_project : $(SRCS_LIST)
|
qt_project : $(SRCS_LIST)
|
||||||
ifneq ($(PAPARAZZI_QT_GEN),)
|
ifneq ($(PAPARAZZI_QT_GEN),)
|
||||||
$(Q)./sw/tools/qt_project.py $(AIRCRAFT) $(CONF_XML) $(SRCS_LIST)
|
$(Q)./sw/tools/qt_project.py $(AIRCRAFT) $(CONF_XML) $(SRCS_LIST)
|
||||||
@@ -187,7 +199,7 @@ flight_plan_ac_h : $(FLIGHT_PLAN_H) $(FLIGHT_PLAN_XML)
|
|||||||
|
|
||||||
makefile_ac: $(MAKEFILE_AC)
|
makefile_ac: $(MAKEFILE_AC)
|
||||||
|
|
||||||
$(AIRFRAME_H) : $(CONF)/$(AIRFRAME_XML) $(CONF_XML) $(AIRCRAFT_MD5)
|
$(AIRFRAME_H) : $(CONF)/$(AIRFRAME_XML) $(CONF_XML) $(AIRCRAFT_MD5) generate_keys
|
||||||
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
|
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
|
||||||
@echo GENERATE $@ from $(AIRFRAME_XML)
|
@echo GENERATE $@ from $(AIRFRAME_XML)
|
||||||
$(eval $@_TMP := $(shell $(MKTEMP)))
|
$(eval $@_TMP := $(shell $(MKTEMP)))
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ Aggie Air ARK
|
|||||||
<module name="radio_control" type="spektrum"/>
|
<module name="radio_control" type="spektrum"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
<!-- hitl currently not supported for secure link comms
|
||||||
<target name="hitl" board="pc">
|
<target name="hitl" board="pc">
|
||||||
<module name="fdm" type="jsbsim"/>
|
<module name="fdm" type="jsbsim"/>
|
||||||
<module name="imu" type="nps"/>
|
<module name="imu" type="nps"/>
|
||||||
@@ -35,13 +36,14 @@ Aggie Air ARK
|
|||||||
<configure name="AP_DEV" value="/dev/ttyUSB2"/>
|
<configure name="AP_DEV" value="/dev/ttyUSB2"/>
|
||||||
<configure name="AP_BAUD" value="B921600"/>
|
<configure name="AP_BAUD" value="B921600"/>
|
||||||
</target>
|
</target>
|
||||||
|
-->
|
||||||
|
|
||||||
<module name="motor_mixing"/>
|
<module name="motor_mixing"/>
|
||||||
<module name="actuators" type="pwm">
|
<module name="actuators" type="pwm">
|
||||||
<define name="SERVO_HZ" value="160"/>
|
<define name="SERVO_HZ" value="160"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
<module name="telemetry" type="transparent">
|
<module name="telemetry" type="transparent_gec">
|
||||||
<configure name="MODEM_PORT" value="UART3"/>
|
<configure name="MODEM_PORT" value="UART3"/>
|
||||||
<configure name="MODEM_BAUD" value="B57600"/>
|
<configure name="MODEM_BAUD" value="B57600"/>
|
||||||
</module>
|
</module>
|
||||||
@@ -56,7 +58,7 @@ Aggie Air ARK
|
|||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module name="sys_mon"/>
|
<module name="sys_mon"/>
|
||||||
<module name="rng"/>
|
<!--module name="rng"/-->
|
||||||
<module name="copilot"/>
|
<module name="copilot"/>
|
||||||
<module name="extra_dl">
|
<module name="extra_dl">
|
||||||
<!-- in order to use uart1 without chibios we need to remap the peripheral-->
|
<!-- in order to use uart1 without chibios we need to remap the peripheral-->
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
telemetry="telemetry/AGGIEAIR/aggieair_rotorcraft.xml"
|
telemetry="telemetry/AGGIEAIR/aggieair_rotorcraft.xml"
|
||||||
flight_plan="flight_plans/rotorcraft_basic_geofence.xml"
|
flight_plan="flight_plans/rotorcraft_basic_geofence.xml"
|
||||||
settings="settings/rotorcraft_basic.xml settings/nps.xml"
|
settings="settings/rotorcraft_basic.xml settings/nps.xml"
|
||||||
settings_modules="modules/battery_monitor.xml modules/gps.xml modules/stabilization_float_euler.xml modules/nav_basic_rotorcraft.xml modules/guidance_rotorcraft.xml modules/imu_common.xml"
|
settings_modules="modules/battery_monitor.xml modules/gps.xml modules/stabilization_float_euler.xml modules/nav_basic_rotorcraft.xml modules/guidance_rotorcraft.xml"
|
||||||
gui_color="#ffff954c0000"
|
gui_color="#ffff954c0000"
|
||||||
/>
|
/>
|
||||||
<aircraft
|
<aircraft
|
||||||
|
|||||||
@@ -13,6 +13,16 @@
|
|||||||
<program name="Data Link" command="sw/ground_segment/tmtc/link">
|
<program name="Data Link" command="sw/ground_segment/tmtc/link">
|
||||||
<arg flag="-d" constant="/dev/ttyUSB0"/>
|
<arg flag="-d" constant="/dev/ttyUSB0"/>
|
||||||
</program>
|
</program>
|
||||||
|
<program name="RustLink" command="sw/ext/rustlink/link">
|
||||||
|
<arg flag="-d" constant="/dev/ttyUSB0"/>
|
||||||
|
<arg flag="-a" constant="@AC_ID"/>
|
||||||
|
</program>
|
||||||
|
<program name="Secure Link" command="sw/ext/rustlink/link">
|
||||||
|
<arg flag="-d" constant="/dev/ttyUSB0"/>
|
||||||
|
<arg flag="-a" constant="@AC_ID"/>
|
||||||
|
<arg flag="-n" constant="@ACIRCRAFT"/>
|
||||||
|
<arg flag="-c" />
|
||||||
|
</program>
|
||||||
<program name="Link Combiner" command="sw/ground_segment/python/redundant_link/link_combiner.py"/>
|
<program name="Link Combiner" command="sw/ground_segment/python/redundant_link/link_combiner.py"/>
|
||||||
<program name="GCS" command="sw/ground_segment/cockpit/gcs"/>
|
<program name="GCS" command="sw/ground_segment/cockpit/gcs"/>
|
||||||
<program name="Flight Plan Editor" command="sw/ground_segment/cockpit/gcs">
|
<program name="Flight Plan Editor" command="sw/ground_segment/cockpit/gcs">
|
||||||
|
|||||||
@@ -7,18 +7,20 @@
|
|||||||
see https://github.com/mitls/hacl-star for details
|
see https://github.com/mitls/hacl-star for details
|
||||||
</description>
|
</description>
|
||||||
</doc>
|
</doc>
|
||||||
<makefile target="!fbw|sim|nps|hitl">
|
<makefile target="!fbw|sim">
|
||||||
<file name="Hacl_Chacha20Poly1305.c" dir="../ext/hacl-c"/>
|
<file name="Hacl_Chacha20Poly1305.c" dir="../ext/hacl-c"/>
|
||||||
<file name="kremlib.c" dir="../ext/hacl-c"/>
|
<file name="kremlib.c" dir="../ext/hacl-c"/>
|
||||||
|
<file name="FStar.c" dir="../ext/hacl-c"/>
|
||||||
<file name="Hacl_Policies.c" dir="../ext/hacl-c"/>
|
<file name="Hacl_Policies.c" dir="../ext/hacl-c"/>
|
||||||
<file name="AEAD_Poly1305_64.c" dir="../ext/hacl-c"/>
|
<file name="AEAD_Poly1305_64.c" dir="../ext/hacl-c"/>
|
||||||
<file name="Hacl_Chacha20.c" dir="../ext/hacl-c"/>
|
<file name="Hacl_Chacha20.c" dir="../ext/hacl-c"/>
|
||||||
<file name="Hacl_Curve25519.c" dir="../ext/hacl-c"/>
|
<file name="Hacl_Curve25519.c" dir="../ext/hacl-c"/>
|
||||||
<file name="Hacl_Ed25519.c" dir="../ext/hacl-c"/>
|
<file name="Hacl_Ed25519.c" dir="../ext/hacl-c"/>
|
||||||
<file name="Hacl_SHA2_512.c" dir="../ext/hacl-c"/>
|
<file name="Hacl_SHA2_512.c" dir="../ext/hacl-c"/>
|
||||||
|
<define name="KRML_NOUINT128"/>
|
||||||
<raw>
|
<raw>
|
||||||
# to not use 128 bit arithmetic
|
# tell Makefile.ac to generate keys
|
||||||
ap.CFLAGS += -DKRML_NOUINT128
|
GENERATE_KEYS = 1
|
||||||
</raw>
|
</raw>
|
||||||
</makefile>
|
</makefile>
|
||||||
</module>
|
</module>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<header>
|
<header>
|
||||||
<file name="rng.h" dir="mcu_periph"/>
|
<file name="rng.h" dir="mcu_periph"/>
|
||||||
</header>
|
</header>
|
||||||
<makefile target="ap|fbw">
|
<makefile target="!fbw|sim">
|
||||||
<define name="USE_RNG"/>
|
<define name="USE_RNG"/>
|
||||||
<file_arch name="rng_arch.c" dir="mcu_periph"/>
|
<file_arch name="rng_arch.c" dir="mcu_periph"/>
|
||||||
</makefile>
|
</makefile>
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE module SYSTEM "module.dtd">
|
||||||
|
|
||||||
|
<module name="telemetry_nps_secure" dir="datalink" task="datalink">
|
||||||
|
<doc>
|
||||||
|
<description>
|
||||||
|
Telemetry module for NPS simulation
|
||||||
|
Common parts of comms, not to be used as a stadalone module. Instead, this module
|
||||||
|
is autoloaded where appropriate.
|
||||||
|
</description>
|
||||||
|
<configure name="MODEM_DEV" value="UDPx" description="UDP port used for communication"/>
|
||||||
|
<configure name="MODEM_HOST" value="192.168.1.255" description="IP address of the ground station (can be a broadcast address)"/>
|
||||||
|
<configure name="MODEM_PORT_OUT" value="4242" description="output UDP port"/>
|
||||||
|
<configure name="MODEM_PORT_IN" value="4243" description="input UDP port"/>
|
||||||
|
<configure name="MODEM_BROADCAST" value="TRUE|FALSE" description="UDP socket in broadcast mode"/>
|
||||||
|
</doc>
|
||||||
|
|
||||||
|
<makefile target="nps|hitl">
|
||||||
|
<configure name="MODEM_DEV" default="UDP0" case="upper|lower"/>
|
||||||
|
<configure name="MODEM_PORT_OUT" default="4242"/>
|
||||||
|
<configure name="MODEM_PORT_IN" default="4243"/>
|
||||||
|
<configure name="MODEM_BROADCAST" default="TRUE"/>
|
||||||
|
<define name="USE_$(MODEM_DEV_UPPER)"/>
|
||||||
|
<define name="$(MODEM_DEV_UPPER)_HOST" value="$(MODEM_HOST)"/>
|
||||||
|
<define name="$(MODEM_DEV_UPPER)_PORT_OUT" value="$(MODEM_PORT_OUT)"/>
|
||||||
|
<define name="$(MODEM_DEV_UPPER)_PORT_IN" value="$(MODEM_PORT_IN)"/>
|
||||||
|
<define name="$(MODEM_DEV_UPPER)_BROADCAST" value="$(MODEM_BROADCAST)"/>
|
||||||
|
<define name="DOWNLINK_DEVICE" value="$(MODEM_DEV_LOWER)"/>
|
||||||
|
<define name="PPRZ_UART" value="$(MODEM_DEV_LOWER)"/>
|
||||||
|
<raw>
|
||||||
|
include $(CFG_SHARED)/udp.makefile
|
||||||
|
</raw>
|
||||||
|
</makefile>
|
||||||
|
<makefile target="nps|hitl" firmware="fixedwing">
|
||||||
|
<file name="fixedwing_datalink.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
<file name="ap_downlink.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
<file name="fbw_downlink.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
</makefile>
|
||||||
|
<makefile target="nps|hitl" firmware="rotorcraft">
|
||||||
|
<file name="rotorcraft_datalink.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
<file name="rotorcraft_telemetry.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
</makefile>
|
||||||
|
</module>
|
||||||
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<!DOCTYPE module SYSTEM "module.dtd">
|
||||||
|
|
||||||
|
<module name="telemetry_secure_common" dir="datalink" task="datalink">
|
||||||
|
<doc>
|
||||||
|
<description>
|
||||||
|
Telemetry using secure PPRZ protocol - common parts
|
||||||
|
</description>
|
||||||
|
<configure name="MODEM_PORT" value="UARTx" description="UART where the modem is connected to (UART1, UART2, etc)"/>
|
||||||
|
<configure name="MODEM_BAUD" value="B57600" description="UART baud rate"/>
|
||||||
|
</doc>
|
||||||
|
|
||||||
|
<autoload name="telemetry" type="nps_secure"/>
|
||||||
|
<autoload name="telemetry" type="sim"/>
|
||||||
|
|
||||||
|
<makefile target="!fbw|sim|nps|hitl">
|
||||||
|
<configure name="MODEM_PORT" case="upper|lower"/>
|
||||||
|
<define name="USE_$(MODEM_PORT_UPPER)"/>
|
||||||
|
<define name="$(MODEM_PORT_UPPER)_BAUD" value="$(MODEM_BAUD)"/>
|
||||||
|
<define name="DOWNLINK"/>
|
||||||
|
<define name="PERIODIC_TELEMETRY"/>
|
||||||
|
<define name="DOWNLINK_DEVICE" value="$(MODEM_PORT_LOWER)"/>
|
||||||
|
<define name="PPRZ_UART" value="$(MODEM_PORT_LOWER)"/>
|
||||||
|
</makefile>
|
||||||
|
|
||||||
|
<makefile target="!fbw|sim">
|
||||||
|
<define name="DOWNLINK"/>
|
||||||
|
<define name="PERIODIC_TELEMETRY"/>
|
||||||
|
<define name="DATALINK" value="PPRZ"/>
|
||||||
|
<file name="downlink.c" dir="subsystems/datalink"/>
|
||||||
|
<file name="datalink.c" dir="subsystems/datalink"/>
|
||||||
|
<file name="telemetry.c" dir="subsystems/datalink"/>
|
||||||
|
<file name="pprz_transport.c" dir="pprzlink/src"/>
|
||||||
|
</makefile>
|
||||||
|
<makefile target="ap" firmware="fixedwing">
|
||||||
|
<file name="fixedwing_datalink.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
<file name="ap_downlink.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
</makefile>
|
||||||
|
<makefile target="ap|fbw" firmware="fixedwing">
|
||||||
|
<file name="fbw_downlink.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
</makefile>
|
||||||
|
<makefile target="ap" firmware="rotorcraft">
|
||||||
|
<file name="rotorcraft_datalink.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
<file name="rotorcraft_telemetry.c" dir="$(SRC_FIRMWARE)"/>
|
||||||
|
</makefile>
|
||||||
|
</module>
|
||||||
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE module SYSTEM "module.dtd">
|
||||||
|
|
||||||
|
<module name="telemetry_transparent_gec" dir="datalink" task="datalink">
|
||||||
|
<doc>
|
||||||
|
<description>
|
||||||
|
Galois Embedded Crypto over transparent datalink
|
||||||
|
</description>
|
||||||
|
</doc>
|
||||||
|
|
||||||
|
<autoload name="telemetry" type="secure_common"/>
|
||||||
|
<autoload name="rng"/>
|
||||||
|
<autoload name="haclc"/>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<file name="gec_dl.h"/>
|
||||||
|
</header>
|
||||||
|
<init fun="gec_dl_init()"/>
|
||||||
|
<event fun="gec_dl_event()"/>
|
||||||
|
|
||||||
|
<makefile target="!fbw|sim">
|
||||||
|
<define name="DOWNLINK_TRANSPORT" value="gec_tp"/>
|
||||||
|
<file name="gec_dl.c"/>
|
||||||
|
<file name="gec.c" dir="modules/datalink/gec"/>
|
||||||
|
</makefile>
|
||||||
|
|
||||||
|
</module>
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
<message name="GPS_LLA" period="1.0"/>
|
<message name="GPS_LLA" period="1.0"/>
|
||||||
<message name="ATTITUDE" period="1.0"/>
|
<message name="ATTITUDE" period="1.0"/>
|
||||||
|
<message name="SECURE_LINK_STATUS" period="1.0"/>
|
||||||
</mode>
|
</mode>
|
||||||
|
|
||||||
<mode name="ppm">
|
<mode name="ppm">
|
||||||
@@ -174,6 +175,7 @@
|
|||||||
<message name="ROTORCRAFT_FP" period="0.1"/>
|
<message name="ROTORCRAFT_FP" period="0.1"/>
|
||||||
<message name="ATTITUDE" period="0.1"/>
|
<message name="ATTITUDE" period="0.1"/>
|
||||||
<message name="VECTORNAV_INFO" period="0.1"/>
|
<message name="VECTORNAV_INFO" period="0.1"/>
|
||||||
|
<message name="SECURE_LINK_STATUS" period="1.0"/>
|
||||||
</mode>
|
</mode>
|
||||||
</process>
|
</process>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Michal Podhradsky <mpodhradsky@galois.com>
|
||||||
|
*
|
||||||
|
* This file is part of Paparazzi.
|
||||||
|
*
|
||||||
|
* Paparazzi 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 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file rng_arch.c
|
||||||
|
* \brief arch specific Random Number Generator API
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "mcu_periph/rng.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void rng_init(void) {}
|
||||||
|
|
||||||
|
void rng_deinit(void) {}
|
||||||
|
|
||||||
|
// Return true only if we got a new number
|
||||||
|
// that is different from the previous one
|
||||||
|
bool rng_get(uint32_t *rand_nr)
|
||||||
|
{
|
||||||
|
int fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
printf("Cannot open /dev/urandom\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t len = sizeof(uint32_t);
|
||||||
|
uint8_t res = read(fd, rand_nr, len);
|
||||||
|
if (res != len) {
|
||||||
|
printf("Error on reading, expected %u bytes, got %u bytes\n",
|
||||||
|
len, res);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until we get a new number that is different
|
||||||
|
// from the previous one. We can wait forever here if
|
||||||
|
// the clocks are not setup properly.
|
||||||
|
uint32_t rng_wait_and_get(void) {
|
||||||
|
uint32_t tmp = 0;
|
||||||
|
while (!rng_get(&tmp)) {};
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Michal Podhradsky <mpodhradsky@galois.com>
|
||||||
|
*
|
||||||
|
* This file is part of paparazzi.
|
||||||
|
*
|
||||||
|
* paparazzi 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 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* paparazzi 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 paparazzi; see the file COPYING. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file datalink/gec/gec.c
|
||||||
|
*
|
||||||
|
* Galois embedded crypto iplementation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "modules/datalink/gec/gec.h"
|
||||||
|
|
||||||
|
void gec_sts_init(struct gec_sts_ctx * sts)
|
||||||
|
{
|
||||||
|
clear_sts(sts);
|
||||||
|
|
||||||
|
uint8_t theirPublicKey[PPRZ_KEY_LEN] = GCS_PUBLIC;
|
||||||
|
memcpy(&sts->theirPublicKey, theirPublicKey, PPRZ_KEY_LEN);
|
||||||
|
|
||||||
|
uint8_t myPublicKey[PPRZ_KEY_LEN] = UAV_PUBLIC;
|
||||||
|
memcpy(&sts->myPrivateKey.pub, myPublicKey, PPRZ_KEY_LEN);
|
||||||
|
|
||||||
|
uint8_t myPrivateKey[PPRZ_KEY_LEN] = UAV_PRIVATE;
|
||||||
|
memcpy(&sts->myPrivateKey.priv, myPrivateKey, PPRZ_KEY_LEN);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_sts(struct gec_sts_ctx * sts)
|
||||||
|
{
|
||||||
|
memset(&sts->theirPublicKeyEphemeral, 0, sizeof(struct gec_pubkey));
|
||||||
|
memset(&sts->myPrivateKeyEphemeral, 0, sizeof(struct gec_privkey));
|
||||||
|
memset(&sts->theirSymmetricKey, 0, sizeof(struct gec_sym_key));
|
||||||
|
memset(&sts->mySymmetricKey, 0, sizeof(struct gec_sym_key));
|
||||||
|
sts->protocol_stage = WAIT_MSG1;
|
||||||
|
sts->party = RESPONDER;
|
||||||
|
sts->last_error = ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate private and public key pairs for future use.
|
||||||
|
*/
|
||||||
|
void generate_ephemeral_keys(struct gec_privkey *sk)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < (PPRZ_KEY_LEN / sizeof(uint32_t)); i++) {
|
||||||
|
uint32_t tmp = rng_wait_and_get();
|
||||||
|
sk->priv[i] = (uint8_t) tmp;
|
||||||
|
sk->priv[i + 1] = (uint8_t) (tmp >> 8);
|
||||||
|
sk->priv[i + 2] = (uint8_t) (tmp >> 16);
|
||||||
|
sk->priv[i + 3] = (uint8_t) (tmp >> 24);
|
||||||
|
}
|
||||||
|
uint8_t basepoint[32] = {0};
|
||||||
|
basepoint[0] = 9; // default basepoint
|
||||||
|
Hacl_Curve25519_crypto_scalarmult(sk->pub, sk->priv, basepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive key material for both sender and receiver
|
||||||
|
*/
|
||||||
|
void derive_key_material(struct gec_sts_ctx *ctx, uint8_t* z) {
|
||||||
|
uint8_t tmp[PPRZ_KEY_LEN*2] = {0};
|
||||||
|
uint8_t input[PPRZ_KEY_LEN+1] = {0};
|
||||||
|
|
||||||
|
// Ka|| Sa = kdf(z,0)
|
||||||
|
memcpy(input, z, PPRZ_KEY_LEN);
|
||||||
|
input[PPRZ_KEY_LEN] = 0;
|
||||||
|
Hacl_SHA2_512_hash(tmp, input, sizeof(input));
|
||||||
|
memcpy(ctx->theirSymmetricKey.key, tmp, PPRZ_KEY_LEN); // K_a
|
||||||
|
memcpy(ctx->theirSymmetricKey.nonce, &tmp[PPRZ_KEY_LEN], PPRZ_NONCE_LEN); // S_a
|
||||||
|
|
||||||
|
// Kb|| Sb = kdf(z,1)
|
||||||
|
input[PPRZ_KEY_LEN] = 1;
|
||||||
|
Hacl_SHA2_512_hash(tmp, input, sizeof(input));
|
||||||
|
memcpy(ctx->mySymmetricKey.key, tmp, PPRZ_KEY_LEN); // K_b
|
||||||
|
memcpy(ctx->mySymmetricKey.nonce, &tmp[PPRZ_KEY_LEN], PPRZ_NONCE_LEN); // S_b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypt a message, no AAD for now
|
||||||
|
* if res == 0 everything OK
|
||||||
|
*/
|
||||||
|
uint32_t gec_decrypt(struct gec_sym_key *k, uint8_t *plaintext, uint8_t *ciphertext, uint8_t len, uint8_t *mac){
|
||||||
|
uint32_t res = Hacl_Chacha20Poly1305_aead_decrypt(plaintext,
|
||||||
|
ciphertext,
|
||||||
|
len,
|
||||||
|
mac,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
k->key,
|
||||||
|
k->nonce);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt a message, no AAD for now
|
||||||
|
* if res == 0 everything OK
|
||||||
|
*/
|
||||||
|
uint32_t gec_encrypt(struct gec_sym_key *k, uint8_t *ciphertext, uint8_t *plaintext, uint8_t len, uint8_t *mac) {
|
||||||
|
uint32_t res = Hacl_Chacha20Poly1305_aead_encrypt(ciphertext, // ciphertext
|
||||||
|
mac, // mac
|
||||||
|
plaintext, // plaintext
|
||||||
|
len, // plaintext len
|
||||||
|
NULL, // aad
|
||||||
|
0, // aad len
|
||||||
|
k->key, // key
|
||||||
|
k->nonce); // nonce
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Michal Podhradsky <mpodhradsky@galois.com>
|
||||||
|
*
|
||||||
|
* This file is part of paparazzi.
|
||||||
|
*
|
||||||
|
* paparazzi 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 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* paparazzi 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 paparazzi; see the file COPYING. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file datalink/gec/gec.h
|
||||||
|
*
|
||||||
|
* Galois embedded crypto iplementation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef SPPRZ_GEC_H
|
||||||
|
#define SPPRZ_GEC_H
|
||||||
|
|
||||||
|
#include "std.h"
|
||||||
|
#include "mcu_periph/rng.h"
|
||||||
|
#include "generated/keys_uav.h"
|
||||||
|
#include "../ext/hacl-c/Hacl_Ed25519.h"
|
||||||
|
#include "../ext/hacl-c/Hacl_Curve25519.h"
|
||||||
|
#include "../ext/hacl-c/Hacl_SHA2_512.h"
|
||||||
|
#include "../ext/hacl-c/Hacl_Chacha20Poly1305.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define PPRZ_SIGN_LEN 64
|
||||||
|
#define PPRZ_KEY_LEN 32
|
||||||
|
#define PPRZ_NONCE_LEN 12
|
||||||
|
#define PPRZ_MAC_LEN 16
|
||||||
|
|
||||||
|
typedef unsigned char ed25519_signature[64];
|
||||||
|
|
||||||
|
struct gec_privkey
|
||||||
|
{
|
||||||
|
uint8_t priv[PPRZ_KEY_LEN];
|
||||||
|
uint8_t pub[PPRZ_KEY_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gec_pubkey
|
||||||
|
{
|
||||||
|
uint8_t pub[PPRZ_KEY_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gec_sym_key
|
||||||
|
{
|
||||||
|
uint8_t key[PPRZ_KEY_LEN];
|
||||||
|
uint8_t nonce[PPRZ_NONCE_LEN];
|
||||||
|
uint32_t ctr;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
INIT, WAIT_MSG1, WAIT_MSG2, WAIT_MSG3, CRYPTO_OK,
|
||||||
|
} stage_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
INITIATOR, RESPONDER, CLIENT, INVALID_PARTY
|
||||||
|
} party_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
P_AE, P_BE, SIG,
|
||||||
|
} gec_sts_msg_type_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ERROR_NONE,
|
||||||
|
// RESPONDER ERRORS
|
||||||
|
MSG1_TIMEOUT_ERROR,
|
||||||
|
MSG1_ENCRYPT_ERROR,
|
||||||
|
MSG3_TIMEOUT_ERROR,
|
||||||
|
MSG3_DECRYPT_ERROR,
|
||||||
|
MSG3_SIGNVERIFY_ERROR,
|
||||||
|
// INITIATOR ERRORS
|
||||||
|
MSG2_TIMEOUT_ERROR,
|
||||||
|
MSG2_DECRYPT_ERROR,
|
||||||
|
MSG2_SIGNVERIFY_ERROR,
|
||||||
|
MSG3_ENCRYPT_ERROR,
|
||||||
|
// BOTH PARTIES
|
||||||
|
UNEXPECTED_MSG_TYPE_ERROR,
|
||||||
|
UNEXPECTED_STS_STAGE_ERROR,
|
||||||
|
UNEXPECTED_MSG_ERROR
|
||||||
|
} sts_error_t;
|
||||||
|
|
||||||
|
// Intermediate data structure containing information relating to the stage of
|
||||||
|
// the STS protocol.
|
||||||
|
struct gec_sts_ctx
|
||||||
|
{
|
||||||
|
struct gec_pubkey theirPublicKey;
|
||||||
|
struct gec_privkey myPrivateKey;
|
||||||
|
struct gec_pubkey theirPublicKeyEphemeral;
|
||||||
|
struct gec_privkey myPrivateKeyEphemeral;
|
||||||
|
struct gec_sym_key theirSymmetricKey;
|
||||||
|
struct gec_sym_key mySymmetricKey;
|
||||||
|
stage_t protocol_stage;
|
||||||
|
party_t party;
|
||||||
|
sts_error_t last_error;
|
||||||
|
uint32_t counter_err;
|
||||||
|
uint32_t encrypt_err;
|
||||||
|
uint32_t decrypt_err;
|
||||||
|
};
|
||||||
|
|
||||||
|
void gec_sts_init(struct gec_sts_ctx * sts);
|
||||||
|
|
||||||
|
void clear_sts(struct gec_sts_ctx * sts);
|
||||||
|
|
||||||
|
void generate_ephemeral_keys(struct gec_privkey *sk);
|
||||||
|
|
||||||
|
void derive_key_material(struct gec_sts_ctx *sts, uint8_t* z);
|
||||||
|
|
||||||
|
uint32_t gec_encrypt(struct gec_sym_key *k, uint8_t *ciphertext,
|
||||||
|
uint8_t *plaintext, uint8_t len, uint8_t *mac);
|
||||||
|
uint32_t gec_decrypt(struct gec_sym_key *k, uint8_t *plaintext,
|
||||||
|
uint8_t *ciphertext, uint8_t len, uint8_t *mac);
|
||||||
|
|
||||||
|
#endif /* SPPRZ_GEC_H */
|
||||||
@@ -0,0 +1,372 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Michal Podhradsky <michal.podhradsky@aggiemail.usu.edu>
|
||||||
|
*
|
||||||
|
* This file is part of paparazzi.
|
||||||
|
*
|
||||||
|
* paparazzi 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 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* paparazzi 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 paparazzi; see the file COPYING. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file modules/datalink/spprz_dl.c
|
||||||
|
* \brief Datalink using Galois Embedded Crypto
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gec_dl.h"
|
||||||
|
#include "modules/datalink/gec/gec.h"
|
||||||
|
#include "subsystems/datalink/datalink.h"
|
||||||
|
#include "pprzlink/messages.h"
|
||||||
|
#include <string.h> // for memset()
|
||||||
|
|
||||||
|
#if PPRZLINK_DEFAULT_VER != 2
|
||||||
|
#error "Secure link is only for Pprzlink v 2.0"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct gec_transport gec_tp;
|
||||||
|
|
||||||
|
#if PERIODIC_TELEMETRY
|
||||||
|
#include "subsystems/datalink/telemetry.h"
|
||||||
|
|
||||||
|
static void send_secure_link_info(struct transport_tx *trans, struct link_device *dev)
|
||||||
|
{
|
||||||
|
pprz_msg_send_SECURE_LINK_STATUS(trans, dev, AC_ID,
|
||||||
|
(uint8_t*)&gec_tp.sts.protocol_stage,
|
||||||
|
(uint8_t*)&gec_tp.sts.last_error,
|
||||||
|
&gec_tp.sts.counter_err,
|
||||||
|
&gec_tp.sts.decrypt_err,
|
||||||
|
&gec_tp.sts.encrypt_err);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static struct gec_transport * get_trans(struct pprzlink_msg *msg)
|
||||||
|
{
|
||||||
|
return (struct gec_transport *)(msg->trans->impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void insert_byte(struct gec_transport *t, const uint8_t byte) {
|
||||||
|
t->tx_msg[t->tx_msg_idx] = byte;
|
||||||
|
t->tx_msg_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void put_bytes(struct pprzlink_msg *msg,
|
||||||
|
long fd __attribute__((unused)),
|
||||||
|
enum TransportDataType type __attribute__((unused)),
|
||||||
|
enum TransportDataFormat format __attribute__((unused)),
|
||||||
|
const void *bytes, uint16_t len)
|
||||||
|
{
|
||||||
|
const uint8_t *b = (const uint8_t *) bytes;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
insert_byte(get_trans(msg), b[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void put_named_byte(struct pprzlink_msg *msg,
|
||||||
|
long fd __attribute__((unused)),
|
||||||
|
enum TransportDataType type __attribute__((unused)),
|
||||||
|
enum TransportDataFormat format __attribute__((unused)),
|
||||||
|
uint8_t byte, const char *name __attribute__((unused)))
|
||||||
|
{
|
||||||
|
insert_byte(get_trans(msg), byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
static uint8_t size_of(struct pprzlink_msg *msg, uint8_t len)
|
||||||
|
{
|
||||||
|
// message length: payload + crypto overhead
|
||||||
|
return len + get_trans(msg)->pprz_tp.trans_tx.size_of(msg, len);
|
||||||
|
// + ???; TODO depends on crypto header size
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
static void start_message(struct pprzlink_msg *msg,
|
||||||
|
long fd __attribute__((unused)),
|
||||||
|
uint8_t payload_len)
|
||||||
|
{
|
||||||
|
PPRZ_MUTEX_LOCK(get_trans(msg)->mtx_tx); // lock mutex
|
||||||
|
memset(get_trans(msg)->tx_msg, _FD, TRANSPORT_PAYLOAD_LEN); // erase message data
|
||||||
|
get_trans(msg)->tx_msg_idx = 0; // reset index
|
||||||
|
// TODO add crypto header to buffer if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
static void end_message(struct pprzlink_msg *msg, long fd)
|
||||||
|
{
|
||||||
|
// TODO apply crypto on buffer here, or a part of it
|
||||||
|
|
||||||
|
// if valid
|
||||||
|
// encapsulated encrypted data with pprz
|
||||||
|
get_trans(msg)->pprz_tp.trans_tx.start_message(msg, fd, get_trans(msg)->tx_msg_idx);
|
||||||
|
for (int i = 0; i < get_trans(msg)->tx_msg_idx; i++) {
|
||||||
|
// add byte one by one for now
|
||||||
|
get_trans(msg)->pprz_tp.trans_tx.put_bytes(msg, _FD, DL_TYPE_UINT8, DL_FORMAT_SCALAR,
|
||||||
|
&(get_trans(msg)->tx_msg[i]), 1);
|
||||||
|
// TODO: replace with one put_bytes() call
|
||||||
|
}
|
||||||
|
get_trans(msg)->pprz_tp.trans_tx.end_message(msg, fd);
|
||||||
|
|
||||||
|
// unlock mutex
|
||||||
|
PPRZ_MUTEX_UNLOCK(get_trans(msg)->mtx_tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
static void overrun(struct pprzlink_msg *msg)
|
||||||
|
{
|
||||||
|
get_trans(msg)->pprz_tp.trans_tx.overrun(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void count_bytes(struct pprzlink_msg *msg, uint8_t bytes)
|
||||||
|
{
|
||||||
|
get_trans(msg)->pprz_tp.trans_tx.count_bytes(msg, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_available_space(struct pprzlink_msg *msg, long *fd, uint16_t bytes)
|
||||||
|
{
|
||||||
|
return get_trans(msg)->pprz_tp.trans_tx.check_available_space(msg, fd, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Init pprz transport structure
|
||||||
|
static void gec_transport_init(struct gec_transport *t)
|
||||||
|
{
|
||||||
|
t->trans_rx.msg_received = false;
|
||||||
|
t->trans_tx.size_of = (size_of_t) size_of;
|
||||||
|
t->trans_tx.check_available_space = (check_available_space_t) check_available_space;
|
||||||
|
t->trans_tx.put_bytes = (put_bytes_t) put_bytes;
|
||||||
|
t->trans_tx.put_named_byte = (put_named_byte_t) put_named_byte;
|
||||||
|
t->trans_tx.start_message = (start_message_t) start_message;
|
||||||
|
t->trans_tx.end_message = (end_message_t) end_message;
|
||||||
|
t->trans_tx.overrun = (overrun_t) overrun;
|
||||||
|
t->trans_tx.count_bytes = (count_bytes_t) count_bytes;
|
||||||
|
t->trans_tx.impl = (void *)(t);
|
||||||
|
PPRZ_MUTEX_INIT(t->mtx_tx); // init mutex, check if correct pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void gec_process_sts_msg(struct link_device *dev, struct gec_transport *trans, uint8_t *buf)
|
||||||
|
{
|
||||||
|
uint8_t sender_id = SenderIdOfPprzMsg(buf);
|
||||||
|
uint8_t msg_id = IdOfPprzMsg(buf);
|
||||||
|
|
||||||
|
if (sender_id != 0) {
|
||||||
|
// process only messages from GCS
|
||||||
|
// log an error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t msg_type = DL_KEY_EXCHANGE_GCS_msg_type(buf);
|
||||||
|
|
||||||
|
switch (msg_id) {
|
||||||
|
case DL_KEY_EXCHANGE_GCS:
|
||||||
|
switch (trans->sts.protocol_stage) {
|
||||||
|
case WAIT_MSG1:
|
||||||
|
if (msg_type == P_AE) {
|
||||||
|
respond_sts(dev, trans, buf);
|
||||||
|
} else {
|
||||||
|
// log an error
|
||||||
|
trans->sts.last_error = UNEXPECTED_MSG_TYPE_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WAIT_MSG3:
|
||||||
|
if (msg_type == SIG) {
|
||||||
|
finish_sts(dev, trans, buf);
|
||||||
|
} else {
|
||||||
|
// log an error
|
||||||
|
trans->sts.last_error = UNEXPECTED_MSG_TYPE_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// INIT, WAIT_MSG2, CRYPTO_OK
|
||||||
|
// do nothing or log an error
|
||||||
|
trans->sts.last_error = UNEXPECTED_STS_STAGE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// process only KEY_EXCHANGE for now
|
||||||
|
// log an error
|
||||||
|
trans->sts.last_error = UNEXPECTED_MSG_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void gec_dl_init(void)
|
||||||
|
{
|
||||||
|
// init pprz transport
|
||||||
|
pprz_transport_init(&gec_tp.pprz_tp);
|
||||||
|
|
||||||
|
// init crypto transport
|
||||||
|
gec_transport_init(&gec_tp);
|
||||||
|
|
||||||
|
// initialize keys
|
||||||
|
gec_sts_init(&gec_tp.sts);
|
||||||
|
|
||||||
|
#if PERIODIC_TELEMETRY
|
||||||
|
register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_SECURE_LINK_STATUS, send_secure_link_info);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void gec_dl_event(void)
|
||||||
|
{
|
||||||
|
pprz_check_and_parse(&DOWNLINK_DEVICE.device, &gec_tp.pprz_tp, gec_tp.trans_rx.payload,
|
||||||
|
(bool*) &gec_tp.trans_rx.msg_received);
|
||||||
|
if (gec_tp.trans_rx.msg_received) {
|
||||||
|
if (gec_tp.sts.protocol_stage != CRYPTO_OK) {
|
||||||
|
// message is in plaintext, treat is as such
|
||||||
|
// TODO: check for decryption
|
||||||
|
// don't pass through
|
||||||
|
gec_process_sts_msg(&DOWNLINK_DEVICE.device, &gec_tp, gec_tp.trans_rx.payload);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// attempt decryption, pass data if all good
|
||||||
|
// process decrypted message if needed
|
||||||
|
// store in dl_buffer (see macro in datalink.h)
|
||||||
|
DatalinkFillDlBuffer(gec_tp.trans_rx.payload, TRANSPORT_PAYLOAD_LEN);
|
||||||
|
|
||||||
|
// pass to datalink
|
||||||
|
DlCheckAndParse(&DOWNLINK_DEVICE.device, &gec_tp.trans_tx, dl_buffer, &dl_msg_available);
|
||||||
|
}
|
||||||
|
// reset flag
|
||||||
|
gec_tp.trans_rx.msg_received = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message1 = [ Pae (32 bytes) ]
|
||||||
|
* 2. B generates ephemeral curve25519 key pair (Pbe, Qbe).
|
||||||
|
* 3. B computes the shared secret: z = scalar_multiplication(Qbe, Pae)
|
||||||
|
* 4. B uses the key derivation function kdf(z,1) to compute Kb || Sb,
|
||||||
|
* kdf(z,0) to compute Ka || Sa, and kdf(z,2) to compute Kclient || Sclient.
|
||||||
|
* 5. B computes the ed25519 signature: sig = signQb(Pbe || Pae)
|
||||||
|
* 6. B computes and sends the message Pbe || Ekey=Kb,IV=Sb||zero(sig)
|
||||||
|
*
|
||||||
|
* Sends: message2 = [ Pbe (32 bytes) | Encrypted Signature (64 bytes) ] + MAC (16bytes)
|
||||||
|
*/
|
||||||
|
void respond_sts(struct link_device *dev, struct gec_transport *trans, uint8_t *buf) {
|
||||||
|
// TODO: check message length
|
||||||
|
|
||||||
|
// copy P_ae over
|
||||||
|
memcpy(trans->sts.theirPublicKeyEphemeral.pub, DL_KEY_EXCHANGE_GCS_msg_data(buf), sizeof(struct gec_pubkey));
|
||||||
|
|
||||||
|
// 2. B generates ephemeral curve25519 key pair (Pbe, Qbe).
|
||||||
|
generate_ephemeral_keys(&trans->sts.myPrivateKeyEphemeral);
|
||||||
|
|
||||||
|
// 3. B computes the shared secret: z = scalar_multiplication(Qbe, Pae)
|
||||||
|
uint8_t z[32] = {0};
|
||||||
|
Hacl_Curve25519_crypto_scalarmult(z, trans->sts.myPrivateKeyEphemeral.priv, trans->sts.theirPublicKeyEphemeral.pub);
|
||||||
|
|
||||||
|
// 4. B uses the key derivation function kdf(z,1) to compute Kb || Sb,
|
||||||
|
// kdf(z,0) to compute Ka || Sa, and kdf(z,2) to compute Kclient || Sclient.
|
||||||
|
derive_key_material(&trans->sts, z);
|
||||||
|
|
||||||
|
// 5. B computes the ed25519 signature: sig = signQb(Pbe || Pae)
|
||||||
|
uint8_t sig[PPRZ_SIGN_LEN] = {0};
|
||||||
|
uint8_t pbe_concat_p_ae[PPRZ_KEY_LEN*2] = {0};
|
||||||
|
memcpy(pbe_concat_p_ae, trans->sts.myPrivateKeyEphemeral.pub, PPRZ_KEY_LEN);
|
||||||
|
memcpy(&pbe_concat_p_ae[PPRZ_KEY_LEN], trans->sts.theirPublicKeyEphemeral.pub, PPRZ_KEY_LEN);
|
||||||
|
Hacl_Ed25519_sign(sig, trans->sts.myPrivateKey.priv, pbe_concat_p_ae, PPRZ_KEY_LEN*2);
|
||||||
|
|
||||||
|
// 6. B computes and sends the message Pbe || Ekey=Kb,IV=Sb||zero(sig)
|
||||||
|
uint8_t msg_data[PPRZ_KEY_LEN + PPRZ_SIGN_LEN + PPRZ_MAC_LEN] = {0};
|
||||||
|
memcpy(msg_data, &trans->sts.myPrivateKeyEphemeral.pub, PPRZ_KEY_LEN);
|
||||||
|
if (gec_encrypt(&trans->sts.mySymmetricKey, &msg_data[PPRZ_KEY_LEN], sig, PPRZ_SIGN_LEN, &msg_data[PPRZ_KEY_LEN + PPRZ_SIGN_LEN])) {
|
||||||
|
// log error here and return
|
||||||
|
trans->sts.last_error = MSG1_ENCRYPT_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// all good, send message and increment status
|
||||||
|
uint8_t msg_type = P_BE;
|
||||||
|
uint8_t nb_msg_data = PPRZ_KEY_LEN + PPRZ_SIGN_LEN + PPRZ_MAC_LEN;
|
||||||
|
|
||||||
|
|
||||||
|
pprz_msg_send_KEY_EXCHANGE_UAV(&trans->trans_tx, dev, AC_ID, &msg_type, nb_msg_data, msg_data);
|
||||||
|
|
||||||
|
// update protocol stage
|
||||||
|
trans->sts.protocol_stage = WAIT_MSG3;
|
||||||
|
// TODO: add timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalize STS exchange
|
||||||
|
*
|
||||||
|
* message3 = [ Encrypted Signature (64 bytes) ] + MAC(16 bytes) = Ekey=Ka,IV=Sa||zero(sig)
|
||||||
|
* where sig = signQa(Pae || Pbe)
|
||||||
|
* 13. B decrypts the message and verifies the signature.
|
||||||
|
*/
|
||||||
|
void finish_sts(struct link_device *dev __attribute__((__unused__)),
|
||||||
|
struct gec_transport *trans,
|
||||||
|
uint8_t *buf){
|
||||||
|
// TODO: check message length
|
||||||
|
|
||||||
|
// decrypt
|
||||||
|
uint8_t sign[PPRZ_SIGN_LEN] = {0};
|
||||||
|
if (gec_decrypt(&trans->sts.theirSymmetricKey, sign, DL_KEY_EXCHANGE_GCS_msg_data(buf),
|
||||||
|
PPRZ_SIGN_LEN, DL_KEY_EXCHANGE_GCS_msg_data(buf)+PPRZ_SIGN_LEN)) {
|
||||||
|
// log error and return
|
||||||
|
// MSG3 decrypt error
|
||||||
|
trans->sts.last_error = MSG3_DECRYPT_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify
|
||||||
|
uint8_t pbe_concat_p_ae[PPRZ_KEY_LEN*2] = {0};
|
||||||
|
memcpy(pbe_concat_p_ae, trans->sts.myPrivateKeyEphemeral.pub, PPRZ_KEY_LEN);
|
||||||
|
memcpy(&pbe_concat_p_ae[PPRZ_KEY_LEN], trans->sts.theirPublicKeyEphemeral.pub, PPRZ_KEY_LEN);
|
||||||
|
// returns true if verified properly
|
||||||
|
if (!Hacl_Ed25519_verify(trans->sts.theirPublicKey.pub, pbe_concat_p_ae, PPRZ_SIGN_LEN, sign)) {
|
||||||
|
// log error and return
|
||||||
|
// MSG3 sign verify error
|
||||||
|
trans->sts.last_error = MSG3_SIGNVERIFY_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// update the transport
|
||||||
|
// tx key => my symm key
|
||||||
|
memcpy(trans->tx_key, sts.mySymmetricKey.key, PPRZ_KEY_LEN);
|
||||||
|
// tx nonce (12 bytes, first 4 bytes will be overwritten by the counter)
|
||||||
|
memcpy(trans->tx_nonce, sts.mySymmetricKey.nonce, PPRZ_NONCE_LEN);
|
||||||
|
|
||||||
|
// rx key => their symm key
|
||||||
|
memcpy(trans->rx_key, sts.theirSymmetricKey.key, PPRZ_KEY_LEN);
|
||||||
|
// rx nonce (12 bytes, first 4 bytes will be overwritten by the counter)
|
||||||
|
memcpy(trans->rx_nonce, sts.theirSymmetricKey.nonce, PPRZ_NONCE_LEN);
|
||||||
|
*/
|
||||||
|
// if everything went OK, proceed to CRYPTO_OK status
|
||||||
|
trans->sts.protocol_stage = CRYPTO_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Michal Podhradsky <michal.podhradsky@aggiemail.usu.edu>
|
||||||
|
*
|
||||||
|
* This file is part of paparazzi.
|
||||||
|
*
|
||||||
|
* paparazzi 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 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* paparazzi 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 paparazzi; see the file COPYING. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file modules/datalink/gec_dl.h
|
||||||
|
* \brief Datalink using Galois Embedded Crypto
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GEC_DL_H
|
||||||
|
#define GEC_DL_H
|
||||||
|
|
||||||
|
#include "pprzlink/pprzlink_transport.h"
|
||||||
|
#include "pprzlink/pprz_transport.h"
|
||||||
|
#include "modules/datalink/gec/gec.h"
|
||||||
|
#include "pprz_mutex.h"
|
||||||
|
|
||||||
|
#include "mcu_periph/uart.h"
|
||||||
|
#if USE_USB_SERIAL
|
||||||
|
#include "mcu_periph/usb_serial.h"
|
||||||
|
#endif
|
||||||
|
#if USE_UDP
|
||||||
|
#include "mcu_periph/udp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct gec_transport {
|
||||||
|
// pprz encapsulation layer
|
||||||
|
struct pprz_transport pprz_tp;
|
||||||
|
|
||||||
|
// generic reception interface
|
||||||
|
struct transport_rx trans_rx;
|
||||||
|
|
||||||
|
// generic transmission interface
|
||||||
|
struct transport_tx trans_tx;
|
||||||
|
// buffered tx message
|
||||||
|
uint8_t tx_msg[TRANSPORT_PAYLOAD_LEN];
|
||||||
|
volatile uint8_t tx_msg_idx;
|
||||||
|
|
||||||
|
// ecnryption primitives
|
||||||
|
struct gec_sts_ctx sts;
|
||||||
|
|
||||||
|
PPRZ_MUTEX(mtx_tx); // optional mutex
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** PPRZ transport structure */
|
||||||
|
extern struct gec_transport gec_tp;
|
||||||
|
|
||||||
|
/** Init function */
|
||||||
|
extern void gec_dl_init(void);
|
||||||
|
|
||||||
|
/** Datalink Event */
|
||||||
|
extern void gec_dl_event(void);
|
||||||
|
|
||||||
|
/** Parsing a frame data and copy the payload to the datalink buffer */
|
||||||
|
void gec_check_and_parse(struct link_device *dev, struct gec_transport *trans,
|
||||||
|
uint8_t *buf, bool *msg_available);
|
||||||
|
|
||||||
|
void gec_process_sts_msg(struct link_device *dev, struct gec_transport *trans, uint8_t *buf);
|
||||||
|
|
||||||
|
void respond_sts(struct link_device *dev, struct gec_transport *trans, uint8_t *buf);
|
||||||
|
|
||||||
|
void finish_sts(struct link_device *dev, struct gec_transport *trans, uint8_t *buf);
|
||||||
|
|
||||||
|
#endif /* GEC_DL_H */
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 Michal Podhradsky <michal.podhradsky@aggiemail.usu.edu>
|
|
||||||
*
|
|
||||||
* This file is part of paparazzi.
|
|
||||||
*
|
|
||||||
* paparazzi 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 2, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* paparazzi 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 paparazzi; see the file COPYING. If not, see
|
|
||||||
* <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file modules/datalink/spprz_dl.c
|
|
||||||
* \brief Datalink using secure PPRZ protocol
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "modules/datalink/spprz_dl.h"
|
|
||||||
#include "subsystems/datalink/datalink.h"
|
|
||||||
|
|
||||||
struct spprz_transport spprz_tp;
|
|
||||||
|
|
||||||
void spprz_dl_init(void)
|
|
||||||
{
|
|
||||||
spprz_transport_init(&spprz_tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void spprz_dl_event(void)
|
|
||||||
{
|
|
||||||
spprz_check_and_parse(&DOWNLINK_DEVICE.device, &spprz_tp, dl_buffer, &dl_msg_available);
|
|
||||||
DlCheckAndParse(&DOWNLINK_DEVICE.device, &spprz_tp.trans_tx, dl_buffer, &dl_msg_available);
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 Michal Podhradsky <michal.podhradsky@aggiemail.usu.edu>
|
|
||||||
*
|
|
||||||
* This file is part of paparazzi.
|
|
||||||
*
|
|
||||||
* paparazzi 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 2, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* paparazzi 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 paparazzi; see the file COPYING. If not, see
|
|
||||||
* <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file modules/datalink/spprz_dl.h
|
|
||||||
* \brief Datalink using secure PPRZ protocol
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SPPRZ_DL_H
|
|
||||||
#define SPPRZ_DL_H
|
|
||||||
|
|
||||||
#include "pprzlink/secure_pprz_transport.h"
|
|
||||||
|
|
||||||
#include "mcu_periph/uart.h"
|
|
||||||
#if USE_USB_SERIAL
|
|
||||||
#include "mcu_periph/usb_serial.h"
|
|
||||||
#endif
|
|
||||||
#if USE_UDP
|
|
||||||
#include "mcu_periph/udp.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** PPRZ transport structure */
|
|
||||||
extern struct spprz_transport spprz_tp;
|
|
||||||
|
|
||||||
/** Init function */
|
|
||||||
extern void spprz_dl_init(void);
|
|
||||||
|
|
||||||
/** Datalink Event */
|
|
||||||
extern void spprz_dl_event(void);
|
|
||||||
|
|
||||||
#endif /* SPPRZ_DL_H */
|
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ EXTERN bool datalink_enabled;
|
|||||||
|
|
||||||
/** Convenience macro to fill dl_buffer */
|
/** Convenience macro to fill dl_buffer */
|
||||||
#define DatalinkFillDlBuffer(_buf, _len) { \
|
#define DatalinkFillDlBuffer(_buf, _len) { \
|
||||||
uint8_t _i = 0; \
|
uint16_t _i = 0; \
|
||||||
for (_i = 0; _i < _len; _i++) { \
|
for (_i = 0; _i < _len; _i++) { \
|
||||||
dl_buffer[_i] = _buf[_i]; \
|
dl_buffer[_i] = _buf[_i]; \
|
||||||
} \
|
} \
|
||||||
|
|||||||
+3
-1
@@ -33,7 +33,7 @@ EXT_DIR=$(PAPARAZZI_SRC)/sw/ext
|
|||||||
include $(PAPARAZZI_SRC)/conf/Makefile.arm-embedded-toolchain
|
include $(PAPARAZZI_SRC)/conf/Makefile.arm-embedded-toolchain
|
||||||
|
|
||||||
|
|
||||||
all: libopencm3 luftboot chibios fatfs libsbp mavlink TRICAL hacl-c
|
all: libopencm3 luftboot chibios fatfs libsbp mavlink TRICAL hacl-c key_generator
|
||||||
|
|
||||||
# update (and init if needed) all submodules
|
# update (and init if needed) all submodules
|
||||||
update_submodules:
|
update_submodules:
|
||||||
@@ -67,6 +67,8 @@ luftboot_flash: luftboot.build
|
|||||||
|
|
||||||
hacl-c: hacl-c.update
|
hacl-c: hacl-c.update
|
||||||
|
|
||||||
|
key_generator: key_generator.update
|
||||||
|
|
||||||
chibios: chibios.update
|
chibios: chibios.update
|
||||||
|
|
||||||
TRICAL: TRICAL.update
|
TRICAL: TRICAL.update
|
||||||
|
|||||||
Submodule
+1
Submodule sw/ext/key_generator added at fa85320305
+1
-1
Submodule sw/ext/pprzlink updated: a41a07156f...e4a4bf3d5c
Submodule
+1
Submodule sw/ext/rustlink added at 1e70ae72d4
Reference in New Issue
Block a user