Skip to content

Commit 6973a28

Browse files
committed
Squash
0 parents  commit 6973a28

File tree

88 files changed

+7726
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+7726
-0
lines changed

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Do not change line endings
2+
* text=false
3+

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
*.o
3+
*.so
4+
*.a
5+
*.bin
6+
.idea/
7+
cmake-build-debug/
8+
CMakeFiles/
9+
.idea/
10+
cmake_install.cmake
11+
CMakeCache.txt
12+
Makefile
13+
*.cbp
14+
15+
*.sealed_macsec_keypair
16+
*.report

README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
Trusted Network Interface
2+
3+
_________________________________________________________________________
4+
**Build Setup (Simulation Mode):**
5+
6+
This has been tested with Ubuntu 18.04.
7+
Please refer to the official Intel instructions if anything fails.
8+
9+
Install the packages:
10+
`make cmake git g++ cppcheck`
11+
`ocaml ocamlbuild automake autoconf libtool wget python libssl-dev`
12+
13+
Download, build and install the linux-sgx sdk:
14+
`git clone https://github.com/intel/linux-sgx.git`
15+
`cd linux-sgx`
16+
`./download_prebuilt.sh`
17+
`make sdk`
18+
`cd linux/installer/bin`
19+
`./build-installpkg.sh sdk`
20+
`./sgx_linux_x64_sdk_XXX.bin # install in "~" when asked`
21+
22+
Build and run the tests:
23+
24+
`./run_tests_locally.sh SIM`
25+
26+
_________________________________________________________________________
27+
**Build Setup (Hardware Mode):**
28+
29+
Please complete the simulation mode instructions before setting up the hardware mode.
30+
Hardware mode works only on SGX-supported platforms.
31+
32+
Configure your system to `SGX enabled`. You might need to enable SGX within your BIOS settings.
33+
34+
Build and install the SGX Driver according to the instructions in
35+
`https://github.com/intel/linux-sgx-driver`.
36+
Afterwards, check whether the SGX Driver is running:
37+
`lsmod | grep isgx`
38+
39+
Install the packages:
40+
`libprotobuf-dev protobuf-compiler libcurl4-openssl-dev`
41+
42+
Build and install the SGX Platform Service:
43+
`cd linux-sgx`
44+
`make`
45+
`cd linux/installer/bin`
46+
`./build-installpkg.sh psw`
47+
`sudo ./sgx_linux_x64_psw_XXX.bin`
48+
49+
Build and run the tests:
50+
51+
`git clean -xfd # cleanup for a fresh build`
52+
`./run_tests_locally.sh HW`
53+
54+
55+
_________________________________________________________________________
56+
**Future work:**
57+
Implementing those protocol validations in C is a bad idea with respect to security.
58+
The choice of C was only made for the sake of a quick implementation.
59+
I strongly recommend that future TEE implementations use a secure language from the beginning (e.g. Rust, Go, Java).
60+
61+
62+
_________________________________________________________________________
63+
**Limitations of SGX:**
64+
SGX cannot directly access any external hardware.
65+
Therefore, it is necessary to establish a cryptographic channel to securely communicate between an SGX enclave and external hardware.
66+
In this work, we used a "MACSec gateway" for this cryptographic channel.
67+
Other TEEs can be configured to avoid this issue altogether (e.g. ARM TrustZone).

build.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env bash
2+
set -e # abort if anything fails
3+
set -x # print commands
4+
5+
if [[ $EUID -eq 0 ]]; then
6+
echo "We do not recommend to build as root" 1>&2
7+
exit -1
8+
fi
9+
10+
if [ -z "$SGX_MODE" ]; then
11+
echo "SGX_MODE must be set to SIM or HW"
12+
exit -1
13+
fi
14+
15+
# Build the remote end stuff
16+
REMOTE_DIR=remote_end
17+
( cd ${REMOTE_DIR} && cmake . && make )
18+
19+
# Build the test app, test enclave and the libraries
20+
TEST_APP_DIR=tests
21+
( cd ${TEST_APP_DIR} && cmake . && make )

common/key_file_definitions.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#pragma once
2+
3+
// Definition of our macsec key pair file format used for installing and sealing macsec key pairs
4+
5+
// The macsec key pair file format is specified as follows: key_file_header || ENCLAVE_TX_KEY || ENCLAVE_RX_KEY
6+
// The size of a macsec key pair file must be (sizeof(key_file_header) + 16 + 16)
7+
8+
static const char key_file_header[] = "macsec_keypair_2*128bit"; // the terminating null byte is also included in the key file
9+
#define KEY_FILE_SIZE (2 * MACSEC_KEY_SIZE + sizeof(key_file_header))
10+
11+
#define ERROR_INVALID_KEY_FILE_SIZE (-2)
12+
#define ERROR_INVALID_KEY_FILE_HEADER (-3)
13+
#define ERROR_SEALING_OPERATION_FAILED (-3)
14+
#define ERROR_UNSEALING_OPERATION_FAILED (-4)
15+
#define ERROR_INVALID_SEALED_KEY_FILE_SIZE (-5)
16+
#define ERROR_KEYPAIR_NOT_DIFFERENT (-6)
17+
18+
#define MACSEC_OVERHEAD 32 // overhead per packet: 16 bytes sectag + 16 bytes icv, may need to be changed for new cipher suites
19+
#define MACSEC_KEY_SIZE 16
20+
21+
#define MAX_PACK_SIZE 10000 // should not be too large, since this is used as local buffer on the stack
22+
23+
#define MAC_HEADER_LEN 12 // dest mac || source mac
24+
#define MIN_PACKET_LEN (MAC_HEADER_LEN + 2) // dest mac || source mac || ether type
25+
#define MIN_MACSEC_LEN (MIN_PACKET_LEN + MACSEC_OVERHEAD)
26+
27+
#define ETHER_TYPE_MACSEC 0xE588

common/logging.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
#include <string.h>
4+
#include <stdio.h>
5+
6+
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
7+
8+
#define TEST_LOG(...) printf("%s: ", __FILENAME__); printf(__VA_ARGS__)
9+
10+
#define DEBUG_LOG(...) TEST_LOG(__VA_ARGS__)

common/netutils.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include "netutils.h"
2+
#include <stdio.h>
3+
#include <string.h>
4+
#include <unistd.h>
5+
#include <net/if.h>
6+
#include <sys/ioctl.h>
7+
#include <fcntl.h>
8+
#include <arpa/inet.h>
9+
#include <linux/if_packet.h>
10+
#include <net/ethernet.h>
11+
#include <stdlib.h>
12+
#include <errno.h>
13+
14+
static int interface_exists(const char* iface) {
15+
return if_nametoindex(iface);
16+
}
17+
18+
int open_raw_socket(const char *iface) {
19+
20+
if (!interface_exists(iface)) {
21+
DEBUG_LOG("The interface %s does not exist! Available interfaces:\n", iface);
22+
run_cmd("ip link");
23+
return -1;
24+
}
25+
26+
int raw_fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
27+
if (raw_fd == -1) {
28+
perror("socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))");
29+
return -1;
30+
}
31+
32+
struct sockaddr_ll socket_address = {0};
33+
socket_address.sll_family = PF_PACKET;
34+
socket_address.sll_ifindex = if_nametoindex(iface);
35+
socket_address.sll_protocol = htons(ETH_P_ALL);
36+
37+
int ret = bind(raw_fd, (struct sockaddr *) &socket_address, sizeof(socket_address));
38+
if (ret) {
39+
perror("bind()");
40+
return -1;
41+
}
42+
43+
return raw_fd;
44+
}
45+
46+
47+
int get_mac_address(const char* iface, const int raw_fd, char* mac) {
48+
49+
struct ifreq ifr = {0};
50+
strncpy(ifr.ifr_name, iface, IFNAMSIZ - 1);
51+
if ((ioctl(raw_fd, SIOCGIFHWADDR, &ifr)) < 0) {
52+
perror("ioctl()");
53+
return -1;
54+
}
55+
memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
56+
return 0;
57+
}

common/netutils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include "utils.h"
4+
5+
int open_raw_socket(const char* iface);
6+
7+
int get_mac_address(const char* iface, const int raw_fd, char* mac);

common/pn_definitions.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include <inttypes.h>
4+
5+
// Profinet related definitions, used by enclave, test app, remote simulation
6+
7+
struct dcp_packet {
8+
struct ether_header ether;
9+
uint16_t frame_id;
10+
uint8_t service_id;
11+
uint8_t service_type;
12+
uint32_t xid;
13+
uint16_t response_delay;
14+
uint16_t dcp_data_length;
15+
} __attribute__((packed));
16+
17+
#define ETHER_TYPE_PROFINET 0x9288
18+
#define DCP_IDENTIFY_MULTICAST_REQUEST 0xfefe
19+
#define DCP_IDENTIFY_RESPONSE 0xfffe
20+
#define DCP_SERVICE_ID_IDENTIFY 5
21+
#define DCP_SERVICE_TYPE_REQUEST 0
22+
#define DCP_SERVICE_TYPE_RESPONSE 1
23+
24+
#define DCP_DATA_LENGTH_REQUEST 4
25+
26+
static const uint8_t pn_multicast[] = {0x01,0x0e,0xcf,0x00,0x00,0x00};

common/snmp_definitions.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include <inttypes.h>
4+
5+
// snmp related definitions
6+
7+
struct snmp_hdr {
8+
uint8_t snmp_id;
9+
uint8_t snmp_len;
10+
uint8_t version_id;
11+
uint8_t version_len;
12+
uint8_t version;
13+
uint8_t community_id;
14+
uint8_t community_len;
15+
uint8_t community[6];
16+
uint8_t body_id;
17+
uint8_t body_len;
18+
uint8_t request_id_id;
19+
uint8_t request_id_len;
20+
uint32_t request_id;
21+
uint8_t error_status_id;
22+
uint8_t error_status_len;
23+
uint8_t error_status;
24+
uint8_t error_index_id;
25+
uint8_t error_index_len;
26+
uint8_t error_index;
27+
} __attribute__((packed));
28+
29+
#define SNMP_SNMP_ID 0x30
30+
#define SNMP_VERSION_ID 0x02
31+
#define SNMP_COMMUNITY_ID 0x04
32+
#define SNMP_BODY_ID_GET_REQUEST 0xa0
33+
#define SNMP_BODY_ID_GET_NEXT_REQUEST 0xa1
34+
#define SNMP_BODY_ID_GET_RESPONSE 0xa2
35+
#define SNMP_REQUEST_ID_ID 0x02
36+
#define SNMP_ERROR_STATUS_ID 0x02
37+
#define SNMP_ERROR_INDEX_ID 0x02
38+
39+
#define SNMP_PORT 161
40+
41+
static const uint8_t snmp_community_public[] = "\x70\x75\x62\x6c\x69\x63";
42+
43+
static const uint8_t snmp_fake_bindings_scalance_x200[] = "\x30\x0f\x30\x0d" \
44+
"\x06\x08\x2b\x06\x01\x02\x01\x01\x02\x00\x06\x01\x00";

common/tcp_definitions.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#pragma once
2+
3+
#include <inttypes.h>
4+
#include <stdlib.h> // size_t
5+
#include <unistd.h> // ssize_t
6+
7+
#define ETHER_TYPE_ARP 0x0608
8+
#define ETHER_TYPE_IPV4 0x0008
9+
#define IP_PROTO_TCP 0x06
10+
#define IP_PROTO_UDP 0x11
11+
12+
// This ether_header is compatible with the Linux definition in <net/ethernet.h>
13+
struct ether_header
14+
{
15+
uint8_t ether_dhost[6];
16+
uint8_t ether_shost[6];
17+
uint16_t ether_type;
18+
} __attribute__((packed));
19+
20+
21+
struct ip_header {
22+
uint8_t ver_ihl; // Version (4 bits) + Internet header length (4 bits)
23+
uint8_t tos; // Type of service
24+
uint16_t tlen; // Total length
25+
uint16_t identification; // Identification
26+
uint16_t flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
27+
uint8_t ttl; // Time to live
28+
uint8_t proto; // Protocol
29+
uint16_t crc; // Header checksum
30+
uint32_t saddr; // Source address
31+
uint32_t daddr; // Destination address
32+
//uint32_t op_pad; // Option + Padding
33+
} __attribute__((packed));
34+
35+
36+
struct tcp_header {
37+
uint16_t source;
38+
uint16_t dest;
39+
uint32_t seq;
40+
uint32_t ack_seq;
41+
uint16_t res1 : 4,
42+
doff : 4,
43+
fin : 1,
44+
syn : 1,
45+
rst : 1,
46+
psh : 1,
47+
ack : 1,
48+
urg : 1,
49+
ece : 1,
50+
cwr : 1;
51+
uint16_t window;
52+
uint16_t check;
53+
uint16_t urg_ptr;
54+
} __attribute__((packed));
55+
56+
struct tcp_packet {
57+
struct ether_header ether;
58+
struct ip_header ip;
59+
struct tcp_header tcp;
60+
} __attribute__((packed));
61+
62+
63+
struct arp_packet {
64+
struct ether_header ether;
65+
uint16_t hw_type; // hardware type
66+
uint16_t proto_type; // protocol type
67+
uint8_t hw_size; // hardware address len
68+
uint8_t prot_size; // protocol address len
69+
uint16_t opcode; // arp opcode
70+
uint8_t mac_sender[6];
71+
uint32_t ip_sender;
72+
uint8_t mac_target[6];
73+
uint32_t ip_target;
74+
} __attribute__((packed));
75+
76+
77+
struct ipv4_packet {
78+
struct ether_header ether;
79+
struct ip_header ip;
80+
} __attribute__((packed));
81+
82+
83+
struct udphdr {
84+
uint16_t source;
85+
uint16_t dest;
86+
uint16_t len;
87+
uint16_t check;
88+
} __attribute__((packed));
89+
90+
struct udp_packet {
91+
struct ether_header ether;
92+
struct ip_header ip;
93+
struct udphdr udp;
94+
} __attribute__((packed));

0 commit comments

Comments
 (0)