Skip to content

Hardware accelerated crypto engine for MACsec encryption/ decryption per device or per LAG member port at line rate. #459

Open
sasubrata wants to merge 140 commits intomasterfrom
dev_macsec
Open

Hardware accelerated crypto engine for MACsec encryption/ decryption per device or per LAG member port at line rate. #459
sasubrata wants to merge 140 commits intomasterfrom
dev_macsec

Conversation

@sasubrata
Copy link
Contributor

@sasubrata sasubrata commented Feb 18, 2026

Feature Overview

Support for hardware accelerated crypto engine for MACsec encryption/ decryption at line rate. Such crypto engine can both encrypt and decrypt protocol/ traffic packets at Tx and Rx respectively at line rate. Both per device and per LAG member port MACsec support is provided in this PR.

Also support is provided for encrypted or cleartext VLAN(s) for Ethernet device configured with MACsec.


Previous MACsec/ MKA related PRs

Support for a) Line rate encrypt only MACsec crypto engine b) Key generation protocol MKA or static key is described in following PR. Such engine can only encrypt traffic packets at Tx at line rate but cannot decrypt MACsec packets at Rx.( #412 )


Feature Details

  1. config/devices/macsec/ ( pre-existing with secure_entity/data_plane/encapsulation/crypto_engine added for support for h/w accelerated mode ) "encrypt_decrypt . MKA configuration is optional , alongwith static as choice of Key Generation protocol within macsec.

  2. config/lags/port/macsec added. ( Re-uses macsec and mka attributes from device macsec )

  3. monitor/get_metrics/macsec and monitor/get_metrics/mka ( pre-existing metrics for tracking macsec / mka sessions )

  • Dev-Snappi branch reference
  • Example command to fetch the dev-snappi branch:
    go get github.com/open-traffic-generator/snappi/gosnappi@dev-macsec
    

This feature aims to support MACsec for following feature profile (FP) test cases:

IPSEC-1.1: IPSec with MACSec over aggregated links: https://github.com/openconfig/featureprofiles/blob/main/feature/ipsec/otg_tests/ipsec_base/README.md

IPSEC-1.3: IPSec Packet-Order with MACSec over aggregated links:
https://github.com/openconfig/featureprofiles/blob/main/feature/ipsec/otg_tests/ipsec_packetorder/README.md

IPSEC-1.2: IPSec Scaling with MACSec over aggregated links: https://github.com/openconfig/featureprofiles/blob/main/feature/ipsec/otg_tests/ipsec_scale/README.md 


Other/ advance configs

For both LAG member port or Ethernet devices configured with MACsec:

  • MKA only tests can be run by setting secure_entity.data_plane.choice to "no_encapsulation" so that data packets are sent without MACsec encapsulation.
  • Both MKA and static key are supported to generate MACsec keys
  • MACsec rekey can be trigged using both static key or MKA
  • Extended packet number (XPN) ciphers GCM-AES-XPN-128 GCM-AES-XPN-256 are both supported using MKA or static key
  • Confidentiality offset can be set in MKA or static key to send a fixed number of bytes in MACsec payload as unencrypted

For Ethernet devices configured with MACsec:

  • All Ethernet VLANs can be sent either in encrypted or in cleartext by setting secure_entity.data_plane.encapsulation.vlan_options.encrypt_interface_vlans to true or false respectively.

  • For hardware accelerated inline_crypto engine, there are following configurable parameters:
    -- Rx secTAG offset i.e. the offset of first byte of MACsec header starting from Ethernet frame
    -- Rx SC identifying field type which is primarily used to find SC of sender and hence decryption key on Rx path
    -- CA (connectivity association) type i.e. pairwise (CA) or group CA can be configured in options.per_port_options[].protocols[].macsec.hardware_acceleration.inline_crypto.type_of_ca.
    -- Group CA related configuration is also in the same configuration path.

gosnappi example configuration for MACsec on LAG member port


Example script for MACsec/ MKA  on LAG member port(s) with line rate encryption/ decryption
	...
	p1 := config.Ports().Add().SetName("p1").SetLocation(...)

	// add lags
	l1 := config.Lags().Add().SetName("Lag1")
	lagPort1 := l1.Ports().Add().SetPortName(p1.Name())
	lagPort1.Lacp().
		SetActorActivity("active").
		SetActorPortNumber(1)
	lagPort1.Ethernet().
		SetName("lag1Eth").
		SetMac("00:00:01:01:01:01").
		SetMtu(1500)
	l1.Protocol().Lacp().
		SetActorSystemId("00:00:00:00:00:01").
		SetActorSystemPriority(0).
		SetActorKey(1)
	
	/* Add macsec / mka configuraration on the lag member port */
	secy1 := lagPort1.Macsec().SecureEntity().SetName("Macsec1")
	/* Need to switch to InlineCrypto hardware assist mode to enable line rate MACSec emulation etc. from default 'none' */
	secy1.DataPlane().Encapsulation().CryptoEngine().EncryptDecrypt().HardwareAcceleration().InlineCrypto()
	/* Other attributes that user can control for the MacSec SecureEntity are
		a) secy1.Tx() -> Include SCI and indicate EndStation.
		b) secy1.Rx() -> Enable Replay Protection and specify Replay window
		c) secy1.DataPlane().Encapsulation().CryptoEngine().EncryptDecrypt().TxPn()-> control starting pn and xpn
		d) lagPort1.Macsec().ExcludeProtocols().PerProtocol() -> lacp = false to have cleartext frames only for LACP
	*/
	
        // Either static macsec (default) or MKA must be configured as the Key Generation protocol
	mka := secy1.KeyGenerationProtocol().Mka().SetName("Mka1")
	mka.Basic().KeySource().Psk()
	onePsk := mka.Basic().KeySource().Psks().Add()
	/* If default of mka.Basic(): key_generation_function = aes_cmac_128 is used then max 32 hex byte value
	   should be provided, if this is set to 256 bit then should be set to max 64 hex byte value.
	   The Cak settings must match with DUT configuration to achieve successful decryption at DUT side.
	*/
	onePsk.SetCakValue("0123456789ABCDEF0123456789ABCDEF")
	onePsk.SetCakName("0123456789ABCDEF0123456789ABCDEF")
	/* By default the start time for this key is immediately after the key_chain start start time with lifetime validity */

	secureChannel := mka.Tx().SecureChannels().Add()
	secureChannel.SetName("SecureChannel1").
	              SetSystemId(lagPort1.Ethernet().Mac())
                      
	/* Add more member ports with Macsec/MKA as needed */
	...
                      
	/* Add Device with emulated interface and IP on top of lag */        
	d1 := config.Devices().Add().SetName("d1")          
	d1Eth1 := d1.Ethernets().Add().
			SetName("d1Eth").
			SetMac("00:00:11:01:01:01")
	d1Eth1.Connection().SetLagName(l1.Name())
	d1Eth1.Ipv4Addresses().Add().
		SetName("p1d1ipv4").
		SetAddress("1.1.1.1").
		SetGateway("1.1.1.2").
		SetPrefix(24)
              
	/* Add MACSec encrypted flow from the src IP of the emulated interface to some destination endpoint */     
	f1 := config.Flows().Add()
	f1.Metrics().SetEnable(true)
	...
	f1.SetName("MacSecFlow1").
		TxRx().Device().
		SetTxNames([]string{"p1d1ipv4"}).
		SetRxNames(...)       
	f1Eth := f1.Packet().Add().Ethernet()
	f1Eth.Src().SetValue(d1Eth1.Mac())    
	/* This is must to indicate that packets for these flows should be macsec encrypted
	   wherein the encryption/protection will be performed using h/w assisted inline_crypto
	   as configured for the member link out of which the flow packets are being Txed */
	f1.Packet().Add().Macsec()
        f1Ip := f1.Packet().Add().Ipv4()
         ...
       
	/* Push config and start protocols */
	...
	/* Verify LACP and MKA via metrics ( corresponding gnmi metrics will be available via gnmi telemetry as well )
	
	reqMetrics := gosnappi.NewMetricsRequest()
	reqMetrics.Lacp().SetLagNames([]string{"Lag1"}).
			  SetLagMemberPortNames([]string{"p1"})
	lacpMetrics, err := client.GetMetrics(reqMetrics)
	...
	
	reqMetrics = gosnappi.NewMetricsRequest()
	reqMetrics.Mka().SetPeerNames([]string{"Mka1"})
	mkaMetrics, err := client.GetMetrics(reqMetrics)
	/* Validate against expectation using session_state/mkpdu_tx/mkpdu_rx and other available stats */
	
	...
	
	/* Start traffic and run for duration/fixed packets as needed and verify flow pkts tx/rx as per expectation */
	
	reqMetrics = gosnappi.NewMetricsRequest()
	reqMetrics.Macsec().SetSecureEntityNames([]string{"Macsec1"})
	macsecMetrics, err := client.GetMetrics(reqMetrics)
	/*Validate against expectation using session_state/out_pkts_protected/out_pkts_encrypted/in_pkts_ok/in_pkts_bad and other Macsec stats */


gosnappi example configuration for MACsec on Device ethernet .


	p1 := config.Ports().Add().SetName("p1").SetLocation(opts.IxiaCPorts()[0])
	d1 := config.Devices().Add().SetName("d1")          
	d1Eth1 := d1.Ethernets().
                Add().
                SetName("d1Eth").
                SetMac("00:00:11:01:01:01")
	d1Eth1.Connection().SetPortName(p1.Name())
	d1Eth1.Ipv4Addresses().
                Add().
                SetName("p1d1ipv4").
                SetAddress("1.1.1.1").
                SetGateway("1.1.1.2").
                SetPrefix(24)
	/* Enabling Macsec/MKA on device ethernet when LAG is not configured on test port */
	macSecIntf := d1.Macsec().EthernetInterfaces().Add().
					SetEthName(d1Eth.Name())
	secy1 := macSecIntf.SecureEntity().SetName("Macsec1")
	secy1.DataPlane().Encapsulation().CryptoEngine().EncryptDecrypt().HardwareAcceleration().InlineCrypto()
    mka := secy1.KeyGenerationProtocol().Mka().SetName("Mka1")
	mka.Basic().KeySource().Psk()
	onePsk := mka.Basic().KeySource().Psks().Add()
	onePsk.SetCakValue("0123456789ABCDEF0123456789ABCDEF")
	onePsk.SetCakName("AABB")    
    secureChannel := mka.Tx().SecureChannels().Add()
    secureChannel.SetName("SecureChannel1").
                      SetSystemId(d1Eth.Mac())
                      
                   
    /* The apis for retrieving macsec / mka metrics and adding macsec encapsulation for flows will be same as that for Macsec for LAG member ports */

JSON view for MACsec configuration on single LAG member port

 "lags":  [
    {
      "ports":  [
        {
          "port_name":  "p1",
          "lacp":  {
            "actor_port_number":  1,
            "actor_port_priority":  1,
            "actor_activity":  "active",
            "lacpdu_periodic_time_interval":  0,
            "lacpdu_timeout":  0
          },
          "ethernet":  {
            "mac":  "00:00:01:01:01:01",
            "mtu":  1500,
            "name":  "lag1Eth"
          },
          "macsec":  {
            "secure_entity":  {
              "name":  "Macsec1",
              "key_generation_protocol":  {
                "choice":  "mka",
                "mka":  {
                  "name":  "Mka1",
                  "basic":  {
                    "key_derivation_function":  "aes_cmac_128",
                    "key_source":  {
                      "choice":  "psk",
                      "psks":  [
                        {
                          "cak_value":  "0123456789ABCDEF0123456789ABCDEF",
                          "cak_name":  "0123456789ABCDEF0123456789ABCDEF"
                        }
                      ]
                    },
                    "actor_priority":  "70",
                    "macsec_desired":  true,
                    "macsec_capability":  "macsec_integrity_with_confidentiality_offset",
                    "eapol_ethernet_type":  "888E",
                    "mka_version":  3,
                    "mka_hello_time":  2000,
                    "mka_life_time":  6,
                    "send_icv_indicatior_in_mkpdu":  true,
                    "delay_protect":  true
                  },
                  "tx":  {
                    "secure_channels":  [
                      {
                        "name":  "SecureChannel1",
                        "system_id":  "00:00:01:01:01:01",
                        "port_id":  1,
                        "starting_message_number":  "1"
                      }
                    ]
                  }
                }
              },
              "data_plane":  {
                "choice":  "encapsulation",
                "encapsulation":  {
                  "crypto_engine":  {
                    "encrypt_decrypt":  {
                      "hardware_acceleration":  {
                        "choice":  "inline_crypto",
                        "inline_crypto":  {
                          "rx_sc_identifying_field":  "source_mac"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      ],

apratimmukherjee

This comment was marked as resolved.

@apratimmukherjee apratimmukherjee self-requested a review February 26, 2026 12:10
sasubrata and others added 4 commits February 26, 2026 12:43
…extensiblity. Remove inline_crypto config per LAG member port.
… 1) Change CAK name to simple short string. 2) Make PSK chain start time description to cover single and multiple keys scenario. 3) Set key chain default start time to Unix epoch time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants