mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-09 14:18:00 +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"]
|
||||
path = sw/ext/hacl-c
|
||||
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 apt-get update -q
|
||||
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:
|
||||
- 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
|
||||
|
||||
+13
-1
@@ -70,6 +70,7 @@ MODULES_H=$(AC_GENERATED)/modules.h
|
||||
MODULES_DIR=$(PAPARAZZI_HOME)/conf/modules/
|
||||
AUTOPILOT_DIR=$(AC_GENERATED)/
|
||||
AIRCRAFT_MD5=$(AIRCRAFT_CONF_DIR)/aircraft.md5
|
||||
GENERATE_KEYS ?= 0
|
||||
|
||||
UNAME = $(shell uname -s)
|
||||
ifeq ("$(UNAME)","Darwin")
|
||||
@@ -176,6 +177,17 @@ else
|
||||
$(Q)cd $(PAPARAZZI_SRC) ; ./sw/tools/find_vpaths.py $(CXX) $(TMP_LIST) $(PAPARAZZI_SRC) >> $(SRCS_LIST)
|
||||
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)
|
||||
ifneq ($(PAPARAZZI_QT_GEN),)
|
||||
$(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)
|
||||
|
||||
$(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)
|
||||
@echo GENERATE $@ from $(AIRFRAME_XML)
|
||||
$(eval $@_TMP := $(shell $(MKTEMP)))
|
||||
|
||||
@@ -26,6 +26,7 @@ Aggie Air ARK
|
||||
<module name="radio_control" type="spektrum"/>
|
||||
</target>
|
||||
|
||||
<!-- hitl currently not supported for secure link comms
|
||||
<target name="hitl" board="pc">
|
||||
<module name="fdm" type="jsbsim"/>
|
||||
<module name="imu" type="nps"/>
|
||||
@@ -35,13 +36,14 @@ Aggie Air ARK
|
||||
<configure name="AP_DEV" value="/dev/ttyUSB2"/>
|
||||
<configure name="AP_BAUD" value="B921600"/>
|
||||
</target>
|
||||
-->
|
||||
|
||||
<module name="motor_mixing"/>
|
||||
<module name="actuators" type="pwm">
|
||||
<define name="SERVO_HZ" value="160"/>
|
||||
</module>
|
||||
|
||||
<module name="telemetry" type="transparent">
|
||||
<module name="telemetry" type="transparent_gec">
|
||||
<configure name="MODEM_PORT" value="UART3"/>
|
||||
<configure name="MODEM_BAUD" value="B57600"/>
|
||||
</module>
|
||||
@@ -56,7 +58,7 @@ Aggie Air ARK
|
||||
|
||||
<modules>
|
||||
<module name="sys_mon"/>
|
||||
<module name="rng"/>
|
||||
<!--module name="rng"/-->
|
||||
<module name="copilot"/>
|
||||
<module name="extra_dl">
|
||||
<!-- in order to use uart1 without chibios we need to remap the peripheral-->
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
telemetry="telemetry/AGGIEAIR/aggieair_rotorcraft.xml"
|
||||
flight_plan="flight_plans/rotorcraft_basic_geofence.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"
|
||||
/>
|
||||
<aircraft
|
||||
|
||||
@@ -13,6 +13,16 @@
|
||||
<program name="Data Link" command="sw/ground_segment/tmtc/link">
|
||||
<arg flag="-d" constant="/dev/ttyUSB0"/>
|
||||
</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="GCS" 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
|
||||
</description>
|
||||
</doc>
|
||||
<makefile target="!fbw|sim|nps|hitl">
|
||||
<makefile target="!fbw|sim">
|
||||
<file name="Hacl_Chacha20Poly1305.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="AEAD_Poly1305_64.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_Ed25519.c" dir="../ext/hacl-c"/>
|
||||
<file name="Hacl_SHA2_512.c" dir="../ext/hacl-c"/>
|
||||
<define name="KRML_NOUINT128"/>
|
||||
<raw>
|
||||
# to not use 128 bit arithmetic
|
||||
ap.CFLAGS += -DKRML_NOUINT128
|
||||
# tell Makefile.ac to generate keys
|
||||
GENERATE_KEYS = 1
|
||||
</raw>
|
||||
</makefile>
|
||||
</module>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<header>
|
||||
<file name="rng.h" dir="mcu_periph"/>
|
||||
</header>
|
||||
<makefile target="ap|fbw">
|
||||
<makefile target="!fbw|sim">
|
||||
<define name="USE_RNG"/>
|
||||
<file_arch name="rng_arch.c" dir="mcu_periph"/>
|
||||
</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="ATTITUDE" period="1.0"/>
|
||||
<message name="SECURE_LINK_STATUS" period="1.0"/>
|
||||
</mode>
|
||||
|
||||
<mode name="ppm">
|
||||
@@ -174,6 +175,7 @@
|
||||
<message name="ROTORCRAFT_FP" period="0.1"/>
|
||||
<message name="ATTITUDE" period="0.1"/>
|
||||
<message name="VECTORNAV_INFO" period="0.1"/>
|
||||
<message name="SECURE_LINK_STATUS" period="1.0"/>
|
||||
</mode>
|
||||
</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 */
|
||||
#define DatalinkFillDlBuffer(_buf, _len) { \
|
||||
uint8_t _i = 0; \
|
||||
uint16_t _i = 0; \
|
||||
for (_i = 0; _i < _len; _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
|
||||
|
||||
|
||||
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_submodules:
|
||||
@@ -67,6 +67,8 @@ luftboot_flash: luftboot.build
|
||||
|
||||
hacl-c: hacl-c.update
|
||||
|
||||
key_generator: key_generator.update
|
||||
|
||||
chibios: chibios.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