MAC Layer Security#

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

The NVIDIA MACsec(NvMACsec) implementation has two major entities: KaY entity (IEEE 802.1x standard) and SecY entity (IEEE 802.1AE standard). In NvMACsec, KaY entity is implemented in the nv_macsec_wpa_supplicant application and SecY entity is part of the NvMACsec hardware. The NvMACsec nv_macsec_wpa_supplicant tool is implemented using open source wpa_supplicant version 2.11 and supports the following:

  1. Authentication only, no confidentiality for Orin. Both Authentication and confidentiality for Thor

  2. Either GCM-AES-128 or GCM-AES-256 at a time

  3. 32-bit packet number, but it does not support Extended Packet Number (64-bit PN)

  4. The entire MACsec traffic path hardware accelerated. Software programs the keys, and hardware handles MACsec SecY entity roles.

  5. NvMACsec support 802.1X with pre-shared keys only

  6. Orin NvMACsec hardware can support maximum 8 secure channels (SCs) with 4 ANs in each secure channel or maximum 16 secure channels with 2 ANs in each secure channel. Thor NvMACsec hardware can support maximum 24 secure channels (SCs) with 4 ANs in each secure channel or maximum 48 secure channels with 2 ANs in each secure channel.

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

When MACsec is used over VLAN, the position of the VLAN header with respect to SECTAG is based on the DT parameter nvidia,macsec_vlan_in_clear=<0x1>. When this parameter is set to 1, the VLAN header is placed before SECTAG, and when this parameter is set to 0, the VLAN header is placed after the SECTAG.

NvMACsec can be used by launching a supplicant process in the background using the following command with root privileges. The NvMACsec supplicant process should not be killed abruptly and can be gracefully terminated with the SIGINT (Ctrl+C) signal.

nv_macsec_wpa_supplicant -i <interface_name> -D nv_macsec -c nv_wpa_supplicant_macsec.conf &

Following are the contents of template config 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. The lower the value, the higher the key server priority.

macsec_policy: Flag to enable or disable MACsec. Set it to 1 for MACsec to be enabled.

macsec_integ_only: Flag to specify if encryption/integrity check only should be enabled. Orin doesn’t support encryption. Set it to 1 for Orin NvMACsec. For Thor 0 or 1 can be used

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 the CAK handle from securely stored CAK using PKCS11# APIs. For details on programing the CAK to secure storage, refer to “Provisioning PKCS#11 Key Objects” in this NVIDIA DriveOS SDK Developer Guide.

mka_ckn: Any 32-byte network name used while forming the secure channel.

macsec_csindex: If the DUT is the key server, this parameter is used to decide the cipher suite. This parameter is configured to0 to select GCM_AES_128, and 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 statics with applications. The statics can be obtained by issuing the following command:

ethtool -S <intf_name>
  1. Below are the error counters with description of each error

/** 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;
  1. Below are the different functional counters with description of each counter

 /** 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[48];
/** 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 of octets after IVC passing and decryption */
nveul64_t rx_octets_decrypted;
/** This counter provides the number not valid packets */
nveul64_t rx_pkts_not_valid[48];
/** This counter provides the number of invalid packets */
nveul64_t in_pkts_invalid[48];
/** This counter provides the number of in packet delayed */
nveul64_t rx_pkts_delayed[48];
/** This counter provides the number of in packets un checked */
nveul64_t rx_pkts_unchecked[48];
/** This counter provides the number of in packets ok */
nveul64_t rx_pkts_ok[48];
/** 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[48];
/** This counter provides the number of out packets encrypted */
nveul64_t tx_pkts_encrypted[48];
/** This counter provides the number of out octets protected */
nveul64_t tx_octets_protected;
/** This counter provides the number of out octets encrypted */
nveul64_t tx_octets_encrypted;

If the MACsec key is not provisioned on the board, but MACsec is enabled from the Ethernet DT using nvidia,macsec-enable, then expect the following errors 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.