イーサネット機能の MACsec を有効にする

このページでは、イーサネット機能の MACsec を有効にする方法について説明します。

MACsec を使用して、さまざまな ECU ユニットの車載インフォテインメント(IVI)で使用されるイーサネット通信を認証して暗号化し、データを改ざん、リプレイ、情報開示から保護します。このためには、イーサネット ネットワークの MACsec IEEE 802.11AE を有効にします。

概要

MACsec を有効にするには、MACsec Key Agreement(MKA)ハンドシェイクを処理するためのデーモンとして wpa_supplicant が使用されます。MACsec HAL は、Connectivity Association Key(CAK)と呼ばれる、MACsec 事前共有キーを安全に保管するために定義されています。MACsec HAL は CAK のみをサポートします。このベンダー固有の MACsec HAL が、改ざん防止ストレージに CAK を安全に保管します。鍵のプロビジョニングはベンダーの実装によって異なります。

MACsec フロー

図 1 に、ヘッドユニットの MACsec フローを示します。

図 1: MACsec フロー。

MACsec を有効にする

MACsec CAK による機能のサポートを提供するには、ベンダー固有 MACsec HAL を使用してイーサネットの MACsec を明示的に有効にする必要があります。

この機能を有効にするには、wpa_supplicant_macsec を有効にしてベンダー固有の macsec-servicePRODUCT_PACKAGES に設定し、wpa_supplicant_macsec の構成ファイルを有効にして init rc スクリプトを PRODUCT_COPY_FILES に設定します。

たとえば、この [device-product].mk ファイルは次のようになります。

# MACSEC HAL

# This is a mock MACsec HAL implementation with keys embedded in it. Replace with vendor specific HAL
PRODUCT_PACKAGES += android.hardware.automotive.macsec-service

# wpa_supplicant build with MACsec support

PRODUCT_PACKAGES += wpa_supplicant_macsec

# configuration file for wpa_supplicant with MACsec

PRODUCT_COPY_FILES += \
    $(LOCAL_PATH)/wpa_supplicant_macsec.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wpa_supplicant_macsec.conf \
    $(LOCAL_PATH)/wpa_supplicant_macsec.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/wpa_supplicant_macsec.rc

たとえば、wpa_supplicant_macsec.conf は次のようになります。

# wpa_supplicant_macsec.conf
eapol_version=3
ap_scan=0
fast_reauth=1
# Example configuration for MACsec with preshared key
# mka_cak is not actual key but index for MACsec HAL to specify which key to use
# and make_cak must be either 16 digits or 32 digits depends the actually CAK key length.
network={
        key_mgmt=NONE
        eapol_flags=0
        macsec_policy=1
        macsec_replay_protect=1
        macsec_replay_window=0
        mka_cak=00000000000000000000000000000001
        mka_ckn=31323334
        mka_priority=128
}

eth0 での wpa_supplicant_macsec.conf の例です。複数のネットワーク インターフェースを MACsec で保護する必要がある場合は、複数のサービスを開始できます。

# wpa_supplicant_macsec.rc
service wpa_supplicant_macsec /vendor/bin/hw/wpa_supplicant_macsec \
        -dd -i eth0 -Dmacsec_linux -c /vendor/etc/wpa_supplicant_macsec.conf
        oneshot

イーサネット インターフェースの準備ができたら、wpa_supplicant_macsec を開始します。システム イーサネットの準備ができていないと、wpa_supplicant はすぐにエラーを返します。競合状態を回避するため、/sys//class/net/${eth_interface} の待機が必要となることがあります(デフォルトのタイムアウトは 5 秒です)。

# init.target.rc
on late-fs
    …
    wait /sys/class/net/eth0
    start wpa_supplicant_macsec
    …

MACsec インターフェースの IP アドレスを設定する

MACsec インターフェースの IP アドレスの設定は、zygote が開始したらシステム接続マネージャーによって実行できます。以下に、接続のオーバーレイ XML ファイルの例を示します。zygote の開始前に MACsec インターフェースの IP アドレスを準備する必要がある場合、システム接続マネージャーが起動するのは zygote の開始後のみであるため、代わりにベンダー固有のデーモンが macsec0 インターフェースをリッスンして設定する必要があります。

# Example of com.google.android.connectivity.resources overlay config
<?xml version="1.0" encoding="utf-8"?>
<!-- Resources to configure the connectivity module based on each OEM's preference. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- Whether the internal vehicle network should remain active even when no
         apps requested it. -->
    <bool name="config_vehicleInternalNetworkAlwaysRequested">true</bool>
    <string-array translatable="false" name="config_ethernet_interfaces">
        <!-- Not metered, trusted, not vpn, vehicle, not vcn managed, restricted -->
        <item>macsec0;11,14,15,27,28;ip=10.10.10.2/24 gateway=10.10.10.1 dns=4.4.4.4,8.8.8.8</item>
    </string-array>
    <string translatable="false" name="config_ethernet_iface_regex">macsec\\d</string>
</resources>

MACsec HAL

MACsec のベンダー固有の HAL は、CAK を保護するため以下の機能を実装する必要があります。鍵による暗号化と復号化はすべて、鍵を wpa_supplicant に公開することなく直接おこなわれます。

/**
 * MACSEC pre-shared key plugin for wpa_applicant
 *
 * The goal of this service is to provide function for using the MACSEC CAK
 *
 */
@VintfStability
interface IMacsecPSKPlugin {
    /**
     * For xTS test only, not called in production
     *
     * @param keyId is key id to add
     * @param CAK, CAK key to set
     * @param CKN, CKN to set
     *
     * @return ICV.
     */
    void addTestKey(in byte[] keyId, in byte[] CAK, in byte[] CKN);

/** * Use ICV key do AES CMAC same as ieee802_1x_icv_aes_cmac in wpa_supplicant * * @param keyId is key id to be used for AES CMAC * @param data * * @return ICV. */ byte[] calcICV(in byte[] keyId, in byte[] data);
/** * KDF with CAK key to generate SAK key same as ieee802_1x_sak_aes_cmac in wpa_supplicant * * @param keyId is key id to be used for KDF * @param seed is key seed (random number) * @param sakLength generated SAK length (16 or 32) * * @return SAK key. */ byte[] generateSAK(in byte[] keyId, in byte[] data, in int sakLength);
/** * Encrypt using KEK key, this is same as aes_wrap with kek.key in wpa_supplicant * which used to wrap a SAK key * * @param keyId is key id to be used for encryption * @param sak is SAK key (16 or 32 bytes) to be wrapped. * * @return wrapped data using KEK key. */ byte[] wrapSAK(in byte[] keyId, in byte[] sak);
/** * Decrypt using KEK key, this is same as aes_unwrap with kek.key in wpa_supplicant * which used to unwrap a SAK key * * @param keyId is key id to be used for decryption * @param sak is wrapped SAK key. * * @return unwrapped data using KEK key. */ byte[] unwrapSAK(in byte[] keyId, in byte[] sak); }

リファレンス実装

リファレンス実装は hardware/interfaces/macsec/aidl/default で提供され、これにより、鍵が内部に埋め込まれた HAL のソフトウェア実装が実現されます。鍵は改ざん防止ストレージを基盤としていないため、この実装で提供されるのは HAL の機能リファレンスのみです。

MACsec HAL をテストする

MACsec HAL のテストは hardware/interfaces/automotive/macsec/aidl/vts/functional で提供されています。

テストを実行するコマンドは次のとおりです。

$ atest VtsHalMacsecPskPluginV1Test

addTestKey が呼び出されて、テスト鍵を HAL に挿入し、calcIcvgenerateSakwrapSakunwrapSak の予想される値と突き合わせて確認します。

MACsec が動作していることを確認するには、統合テストで、MACsec インターフェースの 2 つのマシン間で ping します。

# ping -I macsec0 10.10.10.1

ホストで Cuttlefish をテストするには、MACsec に必要な LLDP フレームのパススルーを許可するためにホスト内に echo 8 > /sys/devices/virtual/net/cvd-ebr/bridge/group_fwd_mask が必要です。