Network traffic encryption in Linux using MACsec and hardware offloading

MACsec is an IEEE standard (IEEE 802.1AE) for MAC security, introduced in 2006. It defines a way to establish a protocol independent connection between two hosts with data confidentiality, authenticity and/or integrity, using GCM-AES-128. MACsec operates on the Ethernet layer and as such is a layer 2 protocol, which means it’s designed to secure traffic within a layer 2 network, including DHCP or ARP requests. It does not compete with other security solutions such as IPsec (layer 3) or TLS (layer 4), as all those solutions are used for their own specific use cases.

We have recently worked on enabling hardware offloading of MACsec operations on a Microsemi VSC8584 Ethernet PHY in Linux, by contributing support for MACsec offloading to the Linux networking stack. In this blog post, we present this work through an introduction to MACsec, details on the current state of MACsec support in Linux and finally our work to support MACsec hardware offloading.

Introduction to MACsec

MACsec uses its own frame format with its own EtherType (a 2-bytes field found in Ethernet frames to indicate what the protocol encapsulated in the payload is). As an example, when encapsulating an IPv4 frame, we would have Ethernet<MACsec<IPv4 instead of Ethernet<IPv4.

The MACsec configuration within a node is represented at the top level by Secure Channels. A secure channel is identified by its SCI (Secure Channel Identifier) and contains parameters such as the encryption, protection and replay protection booleans. A secure channel is either a transmit or a receive one: the receive secure channel configuration on a given host should match the transmit one of another host for MACsec traffic to flow successfully.

Within each secure channel, security associations are described. They are identified by an association number and define the encryption/decryption keys used and the current packet number, which is used for replay protection.

MACsec support in Linux

Linux has a software implementation of MACsec, found at drivers/net/macsec.c, which was introduced by Red Hat engineer Sabrina Dubroca in 2016 and available since Linux 4.5. The support is implemented as full virtual network devices, on per transmit secure channel, attached to a parent network device. The parent interface only sees raw packets, which are in the MACsec case raw Ethernet packets with protected or encrypted content. This design is very similar to other supported protocols in Linux such as VLANs.

MACsec support was also introduced in iproute2, a collection of utilities aiming at configuring various networking parts of the kernel (interfaces management, IP configuration, routes…). The command to use is ip macsec.

If we were to configure a secure channel between two hosts we would first need to create a virtual MACsec interface (representing a transmit secure channel) on both hosts, on top of a physical network interface. Let’s say we use eth0 on both our hosts (Alice and Bob), and we want to encrypt the MACsec traffic:

Alice # ip macsec add link eth0 macsec0 type macsec encrypt on
  Bob # ip macsec add link eth0 macsec0 type macsec encrypt on

The next step would be to configure matching receiving secure channel on both hosts:

Alice # ip macsec add macsec0 rx port 1 address <Bob's eth0 MAC>
  Bob # ip macsec add macsec0 rx port 1 address <Alice's eth0 MAC>

We would then configure the transmit channels, and for each we would need to generate a key:

Alice # hexdump -n 16 -e '4/4 "%08x" 1 "\n"' /dev/random
d29a43c8cba96a325f6b6a40a214c58c
Alice # ip macsec add macsec0 tx sa 0 pn 1 \
        on key d29a43c8cba96a325f6b6a40a214c58c

Bob # hexdump -n 16 -e '4/4 "%08x" 1 "\n"' /dev/random
a1e15a1d91222196fde87b2d75a4fac0
Bob # ip macsec add macsec0 tx sa 0 pn 1 \
      on key a1e15a1d91222196fde87b2d75a4fac0

We finally need to configure the receive channels, so that the hosts can authenticate and decrypt packets:

Alice # ip macsec add macsec0 rx port 1 \
        address <Bob's MAC> sa 0 pn 1   \
        on key 00 a1e15a1d91222196fde87b2d75a4fac0
 
  Bob # ip macsec add macsec0 rx port 1 \
        address <Alice's MAC> sa 0 pn 1 \
        on key 00 d29a43c8cba96a325f6b6a40a214c58c

Once all of the MACsec configuration is done we would be able to exchange traffic between Alice and Bob, using authenticated and encrypted packets:

Alice # ip link set macsec0 up
Alice # ip addr add 192.168.42.1/24 dev macsec0

  Bob # ip link set macsec0 up
  Bob # ip addr add 192.168.42.2/24 dev macsec0

What’s coming next: hardware offloading

There are hardware devices featuring a MACsec transformation implementation which can be used to offload the frame generation and encryption / authentication of MACsec frames (for both ingress and egress frames). The benefit of hardware offloading is to discharge the CPU from doing certain operations (in our case MACsec transformations) by doing them in a dedicated hardware engine, which may or may not provide better performance. The idea is essentially to free the CPU from being used by a single application so that the system in its whole runs better.

MACsec offloading devices aren’t currently supported in the Linux kernel and no generic infrastructure is available to delegate MACsec operation to a given hardware device. At Bootlin over the last months we worked on adding such an infrastructure and support for offloading MACsec operations to a first device.

This work was done in two steps. First we needed to extend the current MACsec implementation to propagate commands and configuration to hardware drivers. Our idea was to leverage the current MACsec software implementation to use the exact same commands described above to setup an hardware accelerated MACsec connection, when a Linux networking port supports it. This should allow to have a more maintainable implementation as well.

We then worked on implementing a MACsec specific helper in a networking PHY driver : the Microsemi VSC8584 Ethernet PHY. This PHY has a MACsec engine which can be used to match flows and to perform MACsec transformations and operations. When configured packets can be encrypted and decrypted, protected and validated, without the CPU intervention.

Conclusion

We recently sent a first version of patch series to the Linux network mailing list, which is currently being discussed. This series of patches introduces both the hardware offloading support for MACsec and the ability to offload MACsec operations to a first hardware engine. We hope support for other MACsec engines will come after!

Author: Antoine Ténart

Antoine is a kernel and embedded Linux engineer at Bootlin, which he joined in 2014. See More details...

12 thoughts on “Network traffic encryption in Linux using MACsec and hardware offloading”

  1. I would be interested to know if at some point it would be possible to offload the encryption/decryption to an on-board engine such as the Intel Quick Assist Technology (QAT) engine. This would make offloading of this from the CPU possible regardless of the capability of the NIC as long as the motherboard chip set has this capability.

    1. Hello Georges. I believe what you suggest is already possible today, even without the HW offloading work we’re doing. Indeed:
      – QAT has a Linux kernel driver in drivers/crypto/, so it implements the Linux kernel crypto API
      – The existing software based implementation of macsec (in drivers/net/macsec.c) uses the Crypto API, so it can already leverage HW crypto accelerators

      The work we’re doing is for cases where MacSEC is fully offloaded to the PHY (or possibly the MAC). If you just have a crypto accelerator, then you don’t need our work, and you can already use your crypto accelerators with the existing macsec implementation.

  2. Hi All,

    I have a Phy with Macsec engine. And I want to configure the Macsec using MDC/MDIO . How to access the Macsec chip in linux using MDC/MDIO .

    Thanks
    Bhagaban

  3. Is there anything in the works to support 802.1Q Tag in the Clear for both the software-based and HW offload MACsec on Linux?

    1. Hello Richard. We are not aware of any effort in this direction, but you can also check the linux-netdev mailing list to see if there’s ongoing work in this area. Otherwise, do not hesitate to contact us at Bootlin if this is something you need, we can offer our engineering services to implement such additional feature.

      1. Thank you for the quick response Thomas! I will look into it and reach out to Bootlin if we need to pursue it further.

  4. Thank you for the introduction. Is there any known implementaion of the MKA in linux? I need a way to automate the key exchange procedure for scalability issues.

    1. Yes, there is an implementation of MKA (MACsec Key Agreement) in Linux called “OpenMAC” which is available as a kernel module. OpenMAC provides an implementation of the MKA protocol and is compatible with the MACsec implementation in Linux. It also provides an interface for automating the key exchange procedure, which can help to improve scalability. To use OpenMAC, you will need to install the kernel module and configure it according to your requirements. You can find more information about OpenMAC and its usage on the Linux Kernel documentation website or on the OpenMAC GitHub page.

  5. Hi,
    Do we need a specific vendor NIC for establishing MACsec? I have VM ware NIC card. Can I use this to establish MACsec?

    1. No, you can use a purely software implementation of MACsec, which was the only supported mechanism in the Linux kernel until our work on offloading MACsec to HW, which is described in this blog post.

Leave a Reply