Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# include yamcs_serial_frontend folder
!/yamcs_serial_frontend

# include sdls-nos folder
!/sdls-nos

!/images
# exclude everything *in* images folder
/images/*
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ Features:
* forwards data from connected clients to each other

When a stream of CCSDS telemetry is available from a TCP client only, this client and ```yamcs``` can both connect to the ```tcp-server-bridge``` and ```yamcs``` will be able to receive this data.

## sdls-nos
Configuration used for testing the SDLS implementation of Yamcs with [NOS3](https://github.com/nasa/nos3/).
See sdls-nos/README.md for more information.
4 changes: 4 additions & 0 deletions sdls-nos/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target
.project
.settings
.classpath
53 changes: 53 additions & 0 deletions sdls-nos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# yamcs-nos3
YAMCS for NOS3

This example lets you test TM decryption and TC encryption with the NOS3 simulator in a virtual machine: https://github.com/nasa/nos3/
You can run it in the same way as [examples in the main Yamcs repository](https://github.com/yamcs/yamcs/tree/master/examples).

Tests were done with NOS3 commit `1e34337bdf8aa6bfb5adb4f68974be4e8de0eee0` (the latest `dev` commit at the time of testing), and Yamcs commit `e27592ab43f3e41c20c527e4541b25beb8f35e10`.

The key used for encryption/decryption in Yamcs has been extracted from NOS3 source code.

## Setup
Check out the correct revision in NOS3, as specified above, along with its submodules.

Apply the [patch](./nos3-yamcs.patch) to prepare NOS3 for integration with the new Yamcs version.
The patch fixes some errors in the code that prevented compilation, and updates configuration.

Start the NOS3 virtual machine following their instructions.
In the virtualbox machine settings, allow forwarding UDP ports 8010 and 8011.

In `cfg/sims/nos3-simulator.xml`, update `simulator/generic_radio_sim/hardware-model/connection/gsw` IP to docker bridge IP of the machine in virtualbox (in tests, it was 172.17.0.1).

Build and launch NOS3.

Connect the radio simulator to the bridge network:

```sh
docker network connect bridge sc_1_radio_sim
```

In both the virtualbox machine and the docker container `sc_1_radio_sim`, install the packages: socat, iproute2.


To forward telemetry to Yamcs outside of virtualbox:
- in the virtualbox guest machine, run `socat udp-listen:8011,bind=172.17.0.1,reuseaddr,fork udp:10.0.2.2:8011` (IP address may differ -- 172.17.0.1 is the docker bridge IP of the virtualbox machine, 10.0.2.2 is the IP of the host machine outside of virtualbox)
- the data flow is: data from sc_1_radio_sim goes to port 8011 on docker host IP, socat sends that to the virtualbox host IP, Yamcs on the outside host gets the data.


To forward telecommands from Yamcs outside of virtualbox to the flight software:
- in the virtualbox guest, forward to docker: `socat udp-listen:8010,reuseaddr,fork udp:172.17.0.2:8010` (172.17.0.2 is the docker bridge IP of sc_1_radio_sim)
- in sc_1_radio_sim, forward to correct port: `socat udp-listen:8010,bind=172.17.0.2,reuseaddr,fork udp:172.19.0.21:8010` (first is bridge IP of sc_1_radio_sim, second is nos3 network IP of sc_1_radio_sim)
- the data flow is: data from Yamcs goes to port 8010 of virtualbox guest. Socat in virtualbox guest forwards it to port 8010 of bridge interface of sc_1_radio_sim. Socat in sc_1_radio_sim forwards it from the bridge interface to the nos3 network interface. Flight software receives it via the nos3 network.

## Tests
To test telemetry:
1. In the Yamcs instance outside of the virtual machine, switch to the links view, and observe radio-in has no activity
2. In the Yamcs instance in the virtual machine, run the command `/CFS/CMD/TO_ENABLE_OUTPUT`
3. In the Yamcs instance outside of the virtual machine, observe that the radio-in link has activity. See that there are no errors in the Yamcs logs.

To test telecommands:
1. In the Yamcs instance in the virtual machine, import the NOS3 sample display, and open it.
2. On the sample display, observe that the counters do not change, and that the field says DISABLED.
3. In the Yamcs instance outside of the virtual machine, run the command `/SAMPLE/CMD/SAMPLE_ENABLE_CC`
4. In the Yamcs instance in the virtual machine, observe that the counters are now increasing and that the field says ENABLED.
130 changes: 130 additions & 0 deletions sdls-nos/nos3-yamcs.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
diff --git a/cfg/nos3_defs/toolchain-i386-linux-gnu.cmake b/cfg/nos3_defs/toolchain-i386-linux-gnu.cmake
index b254cc7..e58a643 100644
--- a/cfg/nos3_defs/toolchain-i386-linux-gnu.cmake
+++ b/cfg/nos3_defs/toolchain-i386-linux-gnu.cmake
@@ -30,5 +30,5 @@ SET(CMAKE_C_FLAGS_INIT "-m32" CACHE STRING "C Flags required by platform")
add_definitions(-DBYTE_ORDER_LE)
add_definitions(-D_LINUX_OS_)

-set(CI_TRANSPORT udp)
-set(TO_TRANSPORT udp)
+set(CI_TRANSPORT udp_tf)
+set(TO_TRANSPORT udp_tf)
diff --git a/cfg/sims/nos3-simulator.xml b/cfg/sims/nos3-simulator.xml
index 48d6308..87734e0 100644
--- a/cfg/sims/nos3-simulator.xml
+++ b/cfg/sims/nos3-simulator.xml
@@ -532,15 +532,15 @@
<tlm-port>6011</tlm-port>
-->
<!-- CryptoLib TC Only -->
+ <!--
<ip>cosmos</ip>
<cmd-port>8010</cmd-port>
<tlm-port>6011</tlm-port>
+ -->
<!-- CryptoLib TC & TM -->
- <!--
- <ip>cryptolib</ip>
+ <ip>172.17.0.1</ip>
<cmd-port>8010</cmd-port>
<tlm-port>8011</tlm-port>
- -->
</connection>
<connection>
<name>prox</name>
Submodule components/cryptolib contains modified content
diff --git a/components/cryptolib/src/core/crypto_config.c b/components/cryptolib/src/core/crypto_config.c
index 7dec1c9..ea1d40c 100644
--- a/components/cryptolib/src/core/crypto_config.c
+++ b/components/cryptolib/src/core/crypto_config.c
@@ -54,16 +54,17 @@ int32_t crypto_free_config_structs(void);
int32_t Crypto_SC_Init(void)
{
int32_t status = CRYPTO_LIB_SUCCESS;
- Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT,
- IV_INTERNAL, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE,
- TC_HAS_PUS_HDR, TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE,
- TC_UNIQUE_SA_PER_MAP_ID_FALSE, TC_CHECK_FECF_TRUE, 0x3F,
+ Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT,
+ IV_INTERNAL, CRYPTO_TC_CREATE_FECF_TRUE | CRYPTO_TM_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE,
+ TC_HAS_PUS_HDR, TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_TRUE,
+ TC_UNIQUE_SA_PER_MAP_ID_FALSE, TC_CHECK_FECF_TRUE, 0x3F,
SA_INCREMENT_NONTRANSMITTED_IV_TRUE);
// TC
Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_HAS_FECF, TC_HAS_SEGMENT_HDRS, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0);
- Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 4, TC_HAS_FECF, TC_HAS_SEGMENT_HDRS, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0);
+ Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 4, TC_HAS_FECF, TC_NO_SEGMENT_HDRS, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0);

// TM
+ // tfvn, scid, vcid, has_fecf, has_segmentation_hdr, max_frame_size, aos_has_fhec, aos_has_iz, aos_iz_len
Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TM_HAS_FECF, TM_SEGMENT_HDRS_NA, 1786, AOS_FHEC_NA, AOS_IZ_NA, 0);
status = Crypto_Init();
return status;
diff --git a/components/cryptolib/src/sa/internal/sa_interface_inmemory.template.c b/components/cryptolib/src/sa/internal/sa_interface_inmemory.template.c
index 060c501..cc0f6d9 100644
--- a/components/cryptolib/src/sa/internal/sa_interface_inmemory.template.c
+++ b/components/cryptolib/src/sa/internal/sa_interface_inmemory.template.c
@@ -88,14 +88,24 @@ int32_t sa_config(void)
sa[1].gvcid_blk.vcid = 0;
sa[1].gvcid_blk.mapid = TYPE_TC;

- // SA 2 - TM CLEAR MODE
- sa[2].spi = 8;
+ // SA 2 - TM authenc
+ sa[2].spi = 2;
+ sa[2].ekid = 130;
sa[2].sa_state = SA_OPERATIONAL;
- sa[2].est = 0;
- sa[2].ast = 0;
- sa[2].arsn_len = 1;
+ sa[2].est = 1;
+ sa[2].ast = 1;
+ sa[2].ecs_len = 1;
+ sa[2].ecs = CRYPTO_CIPHER_AES256_GCM;
+ sa[2].shivf_len = 12;
+ sa[2].iv_len = 12;
+ sa[2].stmacf_len = 16;
+ for (int i = 0; i < sa[2].iv_len; ++i)
+ sa[2].iv[i] = i+1;
+ sa[2].abm_len = ABM_SIZE; // 20
+ sa[2].abm[1] = 14;
sa[2].arsnw_len = 1;
sa[2].arsnw = 5;
+ sa[2].arsn_len = 0;
sa[2].gvcid_blk.tfvn = 0;
sa[2].gvcid_blk.scid = SCID & 0x3FF;
sa[2].gvcid_blk.vcid = 1;
@@ -130,7 +140,8 @@ int32_t sa_config(void)
sa[4].iv_len = 12;
sa[4].stmacf_len = 16;
*(sa[4].iv + 11) = 0;
- sa[4].abm_len = ABM_SIZE; // 20
+ sa[4].abm_len = 19; // 20
+ sa[4].abm[2] = 252;
sa[4].arsnw_len = 1;
sa[4].arsnw = 5;
sa[4].arsn_len = 0;
Submodule fsw/apps/to contains modified content
diff --git a/fsw/apps/to/fsw/examples/udp_tf/to_custom.c b/fsw/apps/to/fsw/examples/udp_tf/to_custom.c
index 48b9f80..9b22e89 100644
--- a/fsw/apps/to/fsw/examples/udp_tf/to_custom.c
+++ b/fsw/apps/to/fsw/examples/udp_tf/to_custom.c
@@ -269,8 +269,6 @@ int32 TO_CustomFrameSend(uint16 usRouteId, int32 iInStatus)
uint8* pMcFrameCnt = NULL;
uint8* pOcf = NULL;

- SecurityAssociation_t* sa_ptr = NULL;
-
pChnl = TO_CustomGetChnl(usRouteId);
if (!pChnl)
{
@@ -318,7 +316,7 @@ int32 TO_CustomFrameSend(uint16 usRouteId, int32 iInStatus)
}

/* Perform SDLS */
- iStatus = Crypto_TM_ApplySecurity(pFrameInfo->frame);
+ iStatus = Crypto_TM_ApplySecurity((uint8_t*) pFrameInfo->frame);
if (iStatus != TO_SUCCESS)
{
goto end_of_function;
95 changes: 95 additions & 0 deletions sdls-nos/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>org.yamcs</groupId>
<artifactId>nos3</artifactId>
<version>5.11.3-SNAPSHOT</version>
<packaging>jar</packaging>

<name>NOS3 simulator</name>
<url>https://github.com/nasa/nos3</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<yamcsVersion>5.11.3-SNAPSHOT</yamcsVersion>
</properties>

<dependencies>
<!-- Yamcs core framework -->
<dependency>
<groupId>org.yamcs</groupId>
<artifactId>yamcs-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<!-- Add this dependency to enable the web ui. -->
<dependency>
<groupId>org.yamcs</groupId>
<artifactId>yamcs-web</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.yamcs</groupId>
<artifactId>yamcs-tse</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.12.1</version>
</plugin>
<plugin>
<groupId>org.yamcs</groupId>
<artifactId>yamcs-maven-plugin</artifactId>
<version>1.3.1</version>
<executions>
<!-- Detect plugins, if any -->
<execution>
<goals>
<goal>detect</goal>
</goals>
</execution>
<!-- Tell Maven to bundle Yamcs into a tar.gz file
when the 'mvn package' command is run -->
<execution>
<id>bundle-yamcs</id>
<phase>package</phase>
<goals>
<goal>bundle</goal>
</goals>
<configuration>
<formats>
<format>tar.gz</format>
</formats>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.4.3</version>
</plugin>
</plugins>
</reporting>
</project>
82 changes: 82 additions & 0 deletions sdls-nos/simulator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env python3

import binascii
import io
import socket
import sys
from struct import unpack_from
from threading import Thread
from time import sleep


def send_tm(simulator):
tm_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

with io.open('/home/nm/Downloads/gaia-packets.raw', 'rb') as f:
simulator.tm_counter = 1
header = bytearray(6)
while f.readinto(header) == 6:
(len,) = unpack_from('>H', header, 4)

packet = bytearray(len + 7)
f.seek(-6, io.SEEK_CUR)
f.readinto(packet)

tm_socket.sendto(packet, ('127.0.0.1', 10015))
#tm_socket.sendto(packet, ('10.1.0.49', 10026))
simulator.tm_counter += 1

sleep(1)


def receive_tc(simulator):
tc_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
tc_socket.bind(('127.0.0.1', 10025))
while True:
data, _ = tc_socket.recvfrom(4096)
simulator.last_tc = data
simulator.tc_counter += 1


class Simulator():

def __init__(self):
self.tm_counter = 0
self.tc_counter = 0
self.tm_thread = None
self.tc_thread = None
self.last_tc = None

def start(self):
self.tm_thread = Thread(target=send_tm, args=(self,))
self.tm_thread.daemon = True
self.tm_thread.start()
self.tc_thread = Thread(target=receive_tc, args=(self,))
self.tc_thread.daemon = True
self.tc_thread.start()

def print_status(self):
cmdhex = None
if self.last_tc:
cmdhex = binascii.hexlify(self.last_tc).decode('ascii')
return 'Sent: {} packets. Received: {} commands. Last command: {}'.format(
self.tm_counter, self.tc_counter, cmdhex)


if __name__ == '__main__':
simulator = Simulator()
simulator.start()

try:
prev_status = None
while True:
status = simulator.print_status()
if status != prev_status:
sys.stdout.write('\r')
sys.stdout.write(status)
sys.stdout.flush()
prev_status = status
sleep(0.5)
except KeyboardInterrupt:
sys.stdout.write('\n')
sys.stdout.flush()
Loading