MACsec Overview

The IEEE 802.1AE MACsec standard and its amendments provide the infrastructure for secure L2 network communication, offering authentication and confidentiality of the data communicated between two peers on the network.

The NVIDIA MACsec(NvMACsec) implementation for Orin has two (2) major entities: KaY entity (IEEE 802.1x standard) and SecY entity (IEEE 802.1AE standard). In NvMACsec, KaY entity is implemented in nv_macsec_wpa_supplicant application and SecY entity is part of the MACsec hardware. The NvMACsec nv_macsec_wpa_supplicant tool implemented using open source wpa_supplicant version 2.10 and supports:
  • Authentication only, no confidentiality

  • Either GCM-AES-128 or GCM-AES-256 at a time

  • 32-bit Packet number and does not support Extended Packet Number (64-bit PN)

NvMACsec is enabled by default in the ethernet DT variable “nvidia,macsec-enable = <0x1>”. When enabled, ethernet MTU size is reduced by 34 bytes to accommodate MACsec related headers.

NvMACsec can be used on Orin by launching a supplicant process in the background using below command with root privileges. NvMACsec supplicant process must not be killed abruptly and can be gracefully terminated with SIGINT(Ctrl+C) signal. In QNX, the below command can be prepended with SOCK=<sock_variable> to run the supplicant application on a specific interface, the same can be applied to run the supplicant on Guest OS0 or Guest OS1:
nv_macsec_wpa_supplicant -i <interface_name> -D nv_macsec -c nv_wpa_supplicant_macsec.conf &
The example below adds launch of supplicant from bootup scripts in QNX.
eqos_1_09: eqos_1_09 {
	cmd = "iolauncher -U 3333:3333,3660,3500,3350,3775,3640,2280,3000,2281,2282,2283,3780,3790,6025,6026,40002,40006,40007,45011,45037,45057,45066,45071,45040,40037,45112 --secpol-type supplicant_launch_t --set-var SOCK=/eqos_1 nv_macsec_wpa_supplicant -i eqos_1 -D nv_macsec -c /etc/nv_wpa_supplicant_macsec_template.conf";
	sc7 = "restart";
	critical_process = "no";
	heartbeat = "no";
	oneshot = "no";
};
The contents of template conf file (nv_wpa_supplicant_macsec.conf):
eapol_version=3
ap_scan=0
network={
        key_mgmt=NONE
        eapol_flags=0
        mka_priority=16
        macsec_policy=1
        macsec_integ_only=1
        macsec_cak_len=16
        mka_cak_pkcs_id=MACSEC_CAK_eqos_0
        mka_ckn=112233445566778899AABBCCDDEEFF112233445566778899AABBCCDDEEFF1122
}

key_mgmt: Don’t change the default value

eapol_flags: Don’t change the default value

mka_priority : It is the MKA key server priority. Lower the value, higher is the key server priority.

macsec_policy: Flag to enable or disable MACsec. Make sure to set it to 1 for MACsec to be enabled.

macsec_integ_only: Flag to specify if encryption/integrity check to be enabled only. Orin doesn’t support encryption. Make sure to set it to 1 for Nvmacsec.

macsec_cak_len: Length of the CAK in bytes programmed in secure storage.

mka_cak_pkcs_id: PKCS ID used while programming the CAK in secure storage. The NvMACsec will retrieve CAK handle from securely stored CAK using pkcs11 api’s. Details on programing the CAK to secure storage can be referred from “Provisioning PKCS#11 Key Objects” section under “Understanding Security” chapter of PDK.

mka_ckn: Any 32 byte network name used while forming the SC.

macsec_cs_index: If the DUT is the key server this parameter is used to decide the cipher suite. This parameter 0 is configured to 0 to select GCM_AES_128, 1 to select GCM_AES_256

macsec_pn_exhaustion: If the DUT is the key server this parameter is used to program the number of frames after which Re-Keying needs to be initiated.

For debugging, NvMACsec driver supports the error counters and functional stats with applications. The stats can be obtained by issuing DEVCTLs with below details:
msg.i.dcmd= SIOCGDRVSPEC

ifd.ifd_cmd = NV_MACSEC_DBG_CMD_READ_IRQ_STATS macro in nv_macsec.h for error stats of MACSEC.

The following details MACsec IRQ counters:
        /** Tx debug buffer capture done */
        nveu64_t tx_dbg_capture_done;
        /** Tx MTU check failed */
        nveu64_t tx_mtu_check_fail;
        /** Tx MAC CRC err */
        nveu64_t tx_mac_crc_error;
        /** Tx SC AN not valid */
        nveu64_t tx_sc_an_not_valid;
        /** Tx AES GCM buffer overflow */
        nveu64_t tx_aes_gcm_buf_ovf;
        /** Tx LUT lookup miss */
        nveu64_t tx_lkup_miss;
        /** Tx uninitialized key slot */
        nveu64_t tx_uninit_key_slot;
        /** Tx PN threshold reached */
        nveu64_t tx_pn_threshold;
        /** Tx PN exhausted */
        nveu64_t tx_pn_exhausted;
        /** Tx debug buffer capture done */
        nveu64_t rx_dbg_capture_done;
        /** Rx ICV error threshold */
        nveu64_t rx_icv_err_threshold;
        /** Rx replay error */
        nveu64_t rx_replay_error;
        /** Rx MTU check failed */
        nveu64_t rx_mtu_check_fail;
        /** Rx MAC CRC err */
        nveu64_t rx_mac_crc_error;
        /** Rx AES GCM buffer overflow */
        nveu64_t rx_aes_gcm_buf_ovf;
        /** Rx LUT lookup miss */
        nveu64_t rx_lkup_miss;
        /** Rx uninitialized key slot */
        nveu64_t rx_uninit_key_slot;
        /** Rx PN exhausted */
        nveu64_t rx_pn_exhausted;
        /** Secure reg violation */
        nveu64_t secure_reg_viol;

ifd.ifd_cmd = NV_MACSEC_DBG_CMD_READ_MMC_CNTRS macro in nv_macsec.h for functional stats of MACsec.

The following details MACsec MMC counters:
         /** This counter provides the number of controller port macsec
         * untaged packets */
        nveul64_t rx_pkts_no_tag;
        /** This counter provides the number of controller port macsec
         * untaged packets validateFrame != strict */
        nveul64_t rx_pkts_untagged;
        /** This counter provides the number of invalid tag or icv packets */
        nveul64_t rx_pkts_bad_tag;
        /** This counter provides the number of no sc lookup hit or sc match
         * packets */
        nveul64_t rx_pkts_no_sa_err;
        /** This counter provides the number of no sc lookup hit or sc match
         * packets validateFrame != strict */
        nveul64_t rx_pkts_no_sa;
        /** This counter provides the number of late packets
         *received PN < lowest PN */
        nveul64_t rx_pkts_late[16];
        /** This counter provides the number of overrun packets */
        nveul64_t rx_pkts_overrun;
        /** This counter provides the number of octets after IVC passing */
        nveul64_t rx_octets_validated;
        /** This counter provides the number not valid packets */
        nveul64_t rx_pkts_not_valid[16];
        /** This counter provides the number of invalid packets */
        nveul64_t in_pkts_invalid[16];
        /** This counter provides the number of in packet delayed */
        nveul64_t rx_pkts_delayed[16];
        /** This counter provides the number of in packets un checked */
        nveul64_t rx_pkts_unchecked[16];
        /** This counter provides the number of in packets ok */
        nveul64_t rx_pkts_ok[16];
        /** This counter provides the number of out packets untaged */
        nveul64_t tx_pkts_untaged;
        /** This counter provides the number of out too long */
        nveul64_t tx_pkts_too_long;
        /** This counter provides the number of out packets protected */
        nveul64_t tx_pkts_protected[16];
        /** This counter provides the number of out octets protected */
        nveul64_t tx_octets_protected;
If the MACSec Key is not already provisioned on the board but MACSec is enabled from the ethernet DT using "nvidia,macsec-enable", then expect the errors below to appear in boot logs. They not harmful if MACSec is not being used:
sessionSetup: C_FindObjects failed, 0x0
nvpkcs_session_setup: sessionSetup failed, 0x6
KaY-ieee802_1x_kay_create_mka: nvpkcs_session_setup() failed.