Automotive usage

Note

All automotive related features are only supported on linux systems, yet. CAN and ISOTP sockets in kamene are based on linux kernel modules. This guide explains the hardware setup on a BeagleBone Black. The BeagleBone Black was chosen because of its two CAN interfaces on the main processor. The presence of two CAN interfaces in one device gives the possibility of CAN MITM attacks and session hijacking. The Cannelloni framework turns a BeagleBone Black into a CAN-to-UDP interface, which gives you the freedom to run kamene on a more powerful machine.

Setup

Hardware Setup

Beagle Bone Black Operating System Setup

  1. Download an Image
    The latest Debian Linux image can be found at the website
    https://beagleboard.org/latest-images. Choose the BeagleBone Black IoT version and download it.
    wget https://debian.beagleboard.org/images/bone-debian-8.7\
    -iot-armhf-2017-03-19-4gb.img.xz
    

    After the download, copy it to an SD-Card with minimum 4 GB storage.

    xzcat bone-debian-8.7-iot-armhf-2017-03-19-4gb.img.xz | \
    sudo dd of=/dev/xvdj
    
  2. Enable WiFi
    USB-WiFi dongles are well supported by Debian Linux. Login over SSH on the BBB and add the WiFi network credentials to the file /var/lib/connman/wifi.config. If a USB-WiFi dongle is not available, it is also possible to share the host’s internet connection with the Ethernet connection of the BBB emulated over USB. A tutorial to share the host network connection can be found on this page:
    https://elementztechblog.wordpress.com/2014/12/22/sharing-internet -using-network-over-usb-in-beaglebone-black/.
    Login as root onto the BBB:
    ssh debian@192.168.7.2
    sudo su
    

    Provide the WiFi login credentials to connman:

    echo "[service_home]
    Type = wifi
    Name = ssid
    Security = wpa
    Passphrase = xxxxxxxxxxxxx" \
    > /var/lib/connman/wifi.config
    

    Restart the connman service:

    systemctl restart connman.service
    
  3. Install Required Packages
    This step is required to install all necessary software packages to continue with the modification of the BBB device tree overlay.
    apt-get update
    apt-get -y upgrade
    exit
    git clone https://github.com/beagleboard/bb.org-overlays
    cd ./bb.org-overlays
    

    Verify the installed DTC1 version to ensure that the DTC1 is suitable for the downloaded overlays. Version 1.4.1 or higher is required.

    dtc --version
    

    Update the installed DTC1 with an update script in the cloned repository.

    ./dtc-overlay.sh
    

    Compile all delivered DTS files and install the DTBO onto the current system. Again, a delivered script simplifies this job.

    ./install.sh
    

    Now, the operating system and the device tree are ready for modifications.

Dual-CAN Setup

  1. Create a CAN0 Overlay
    Inside the DTS folder, create a file with the content of the following listing.
    cd ~/bb.org-overlays/src/arm
    cat <<EOF > BB-CAN0-00A0.dts
    
    /dts-v1/;
    /plugin/;
    
    #include <dt-bindings/board/am335x-bbw-bbb-base.h>
    #include <dt-bindings/pinctrl/am33xx.h>
    
    / {
        compatible = "ti,beaglebone", \
        "ti,beaglebone-black", "ti,beaglebone-green";
    
        /* identification */
        part-number = "BB-CAN0";
        version = "00A0";
    
        /* state the resources this cape uses */
        exclusive-use =
        /* the pin header uses */
        "P9.19", /* can0_rx */
        "P9.20", /* can0_tx */
        /* the hardware ip uses */
        "dcan0";
    
        fragment@0 {
            target = <&am33xx_pinmux>;
            __overlay__ {
             bb_dcan0_pins: pinmux_dcan0_pins {
                pinctrl-single,pins = <
                 0x178 0x12 /* d_can0_tx */
                 0x17C 0x32 /* d_can0_rx */
                 >;
                };
            };
        };
    
        fragment@1 {
            target = <&dcan0>;
            __overlay__ {
             status = "okay";
             pinctrl-names = "default";
             pinctrl-0 = <&bb_dcan0_pins>;
            };
        };
    };
    EOF
    

    Compile the generated file with the delivered Makefile from the repository.

    cd ../../
    make
    sudo make install
    
  2. Modify the Boot Device Tree Blob
    Backup and decompile the current device tree blob.
    cp /boot/dtbs/4.4.54-ti-r93/am335x-boneblack.dtb ~/
    dtc -I dtb -O dts ~/am335x-boneblack.dtb > ~/am335x-boneblack.dts
    

    To free the CAN0 pins of the BBB, used I2C2 pins need to be disabled. This can be done by commenting out the appropriate lines in the DTS file. Search for the pinmux_i2c2_pins section and save the modified file with a new name. The BeagleBone community uses the I2C2 peripheral module for the communication and identification of extension modules, so called capes. This modification disables the compatibility to any of these capes.

    vim am335x-boneblack.dts
    
    895 /* pinmux_i2c2_pins {
    896     pinctrl-single,pins = <0x178 0x33 0x17c 0x33>;
    897     linux,phandle = <0x35>;
    898     phandle = <0x35>;
    899 };*/
    
    : wq am335x-boneblack_new.dts
    

    Compile the modified DTS file and replace the original file in the boot partition of the BBB. Reboot the BBB after the replacement.

    dtc -O dtb -o ~/am335x-boneblack_new.dtb -b 0 ~/am335x-boneblack_new.dts
    
    cp ~/am335x-boneblack_new.dtb /boot/dtbs/4.4.54-ti-r93/am335x-boneblack.dtb
    
    reboot
    
  3. Test the Dual-CAN Setup
    Load the CAN kernel modules and the overlays.
    sudo su
    modprobe can
    modprobe can-dev
    modprobe can-raw
    
    echo BB-CAN0 > /sys/devices/platform/bone_capemgr/slots
    echo BB-CAN1 > /sys/devices/platform/bone_capemgr/slots
    

    Check the output of the Capemanager if both CAN interfaces have been loaded.

    cat /sys/devices/platform/bone_capemgr/slots
    
    0: PF----  -1
    1: PF----  -1
    2: PF----  -1
    3: PF----  -1
    4: P-O-L-   0 Override Board Name,00A0,Override Manuf, BB-CAN0
    5: P-O-L-   1 Override Board Name,00A0,Override Manuf, BB-CAN1
    

    If something went wrong, dmesg provides kernel messages to analyze the root of failure.

  4. Optional: Enable Dual-CAN Setup at Boot

    echo "modprobe can \
    modprobe can-dev \
    modprobe can-raw" >> /etc/modules
    
    echo "cape_enable=bone_capemgr.enable_partno=BB-CAN0,BB-CAN1" >> /boot/uEnv.txt
    
    update-initramfs -u
    

ISO-TP Kernel Module Installation

A Linux ISO-TP kernel module can be downloaded from this website: https://github.com/ hartkopp/can-isotp.git. The file README.isotp in this repository provides all information and necessary steps for downloading and building this kernel module. The ISO-TP kernel module should also be added to the /etc/modules file, to load this module automatically at system boot of the BBB.

CAN-Interface Setup

As final step to prepare the BBB’s CAN interfaces for usage, these interfaces have to be setup through some terminal commands. The bitrate can be chosen to fit the bitrate of a CAN bus under test.

ip link set can0 up type can bitrate 500000
ip link set can1 up type can bitrate 500000
ifconfig can0 up
ifconfig can1 up

Software Setup

Cannelloni Framework Installation

The Cannelloni framework is a small application written in C++ to transfer CAN data over UDP. In this way, a researcher can map the CAN communication of a remote device to its workstation, or even combine multiple remote CAN devices on his machine. The framework can be downloaded from this website: https://github.com/mguentner/cannelloni.git. The README.md file explains the installation and usage in detail. Cannelloni needs virtual CAN interfaces on the operators machine. The next listing shows the setup of virtual CAN interfaces.

modprobe vcan

ip link add name vcan0 type vcan
ip link add name vcan1 type vcan

ip link set dev vcan0 up
ip link set dev vcan1 up

tc qdisc add dev vcan0 root tbf rate 300kbit latency 100ms burst 1000
tc qdisc add dev vcan1 root tbf rate 300kbit latency 100ms burst 1000

cannelloni -I vcan0 -R <remote-IP> -r 20000 -l 20000 &
cannelloni -I vcan1 -R <remote-IP> -r 20001 -l 20001 &

Examples

CAN Layer

Setup

This commands enable a virtual CAN interface on your machine

from kamene.layers.can import *
import os

bashCommand = "/bin/bash -c 'sudo modprobe vcan; sudo ip link add name vcan0 type vcan; sudo ip link set dev vcan0 up'"
os.system(bashCommand)

If it’s required, the CAN interface can be set into an listen-only or loop back mode with ip link set commands:

ip link set vcan0 type can help  # shows additional information

CAN Frame

Creating a standard CAN frame:

frame = CAN(id=0x200, dlc=8, data=b'\x01\x02\x03\x04\x05\x06\x07\x08')

Creating an extended CAN frame:

frame = CAN(flags='EFF', id=0x10010000, dlc=8, data=b'\x01\x02\x03\x04\x05\x06\x07\x08')

Writing and reading to pcap files:

x = CAN(id=0x7ff,dlc=8,data=b'\x01\x02\x03\x04\x05\x06\x07\x08')
wrpcap('/tmp/scapyPcapTest.pcap', x, append=False)
y = rdpcap('/tmp/scapyPcapTest.pcap', 1)

CAN Socket

Ways of creating a CAN socket:

# Simple Socket
socket = CANSocket(iface="vcan0")
# Socket only listen for messages with Id == 0x200
socket = CANSocket(iface="vcan0", filter=[{'can_id': 0x200, 'can_mask': 0x7FF}])
# Socket only listen for messages with Id >= 0x200 and Id <= 0x2ff
socket = CANSocket(iface="vcan0", filter=[{'can_id': 0x200, 'can_mask': 0x700}])
# Socket only listen for messages with Id != 0x200
socket = CANSocket(iface="vcan0", filter=[{'can_id': 0x200 | CAN_INV_FILTER, 'can_mask': 0x7FF}])
# Socket with multiple filters
socket = CANSocket(iface='vcan0', filter=[{'can_id': 0x200, 'can_mask': 0x7ff},
                                                 {'can_id': 0x400, 'can_mask': 0x7ff},
                                                 {'can_id': 0x600, 'can_mask': 0x7ff},
                                                 {'can_id': 0x7ff, 'can_mask': 0x7ff}])
# Socket which also receives its own messages
socket = CANSocket(iface="vcan0", receive_own_messages=True)