FIPS 140-3 可認證的 GKI 加密模組

GKI 核心包含名為 fips140.ko 的 Linux 核心模組,符合加密編譯軟體模組的 FIPS 140-3 規定。如果執行 GKI 核心的產品需要這個模組,則可提交 FIPS 認證。

您必須先滿足下列 FIPS 140-3 要求,才能使用加密常式:

  • 該模組必須先檢查其完整性,才能使用加密編譯演算法。
  • 該模組必須先使用已知的答案自我測試,演練並驗證已核准的加密編譯演算法,才能提供這些演算法。

為何要使用獨立的核心模組

FIPS 140-3 驗證是以軟體或硬體模組經過認證後,永遠不會改變的概念為基礎。如果變更,則必須重新認證。這與現今使用的軟體開發程序不符,因此一般而言,FIPS 軟體模組在設計上盡可能聚焦於加密編譯元件,確保與密碼編譯無關的變更不需要重新評估密碼編譯。

GKI 核心會在整個支援的生命週期內定期更新。因此整個核心無法納入 FIPS 模組邊界,因此這類模組會在每次更新核心時重新認證。將「FIPS 模組」定義為核心映像檔的子集可以緩解這個問題,但不會解決,因為「FIPS 模組」的二進位內容仍會比所需更頻繁地變更。

在核心 6.1 版之前,另一個考量是 GKI 是在啟用 LTO (連結時間最佳化) 的情況下進行編譯,因為 LTO 是控制流程完整性的先決條件,這是一項重要的安全性功能。

因此,FIPS 140-3 要求涵蓋的所有程式碼都會封裝到單獨的核心模組 fips140.ko 中,而這只依賴於建構的 GKI 核心來源所公開的穩定介面。這可以保證模組可與相同代別的不同 GKI 版本搭配使用,而且只有在模組本身執行的程式碼中修正任何問題時,才需要更新及重新提交認證。

模組的使用時機

GKI 核心本身會產生程式碼,而程式碼依附於 FIPS 140-3 核心模組中的加密常式。因此,內建加密處理常式實際上不會從 GKI 核心移出,而是複製到模組中。載入模組時,內建加密處理常式會從 Linux CryptoAPI 中取消註冊,並取代由模組執行的處理常式。

這表示 fips140.ko 模組是完全選擇性的,而且只有在 FIPS 140-3 認證的情況下才適合部署模組。此外,該模組並未提供其他功能,在沒有必要的情況下載入模組只會影響啟動時間,而且沒有任何好處。

如何部署模組

您可以利用下列步驟,將模組整合至 Android 建構作業中:

  • 將模組名稱新增至 BOARD_VENDOR_RAMDISK_KERNEL_MODULES。這會導致模組複製到廠商 ramdisk。
  • 將模組名稱新增至 BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD。如此一來,模組名稱就會新增至目標的 modules.load 中。modules.load 會保存 init 在裝置啟動時載入的模組清單。

完整性自我檢查

FIPS 140-3 核心模組會在模組載入時間時,取得其 .code.rodata 區段的 HMAC-SHA256 摘要,並將該摘要與模組中記錄的摘要進行比較。在 Linux 模組載入器完成一般修改後 (例如 ELF 重新配置處理,以及為 CPU 錯誤修補的替代方法修補這些區段) 後,就會發生上述情況。請採取以下額外步驟,確保可以正確重現摘要:

  • ELF 重定位會在模組中保留,以便能夠反向套用至 HMAC 的輸入內容。
  • 這個模組會反轉由 Dynamic Shaadow Call Stack 核心做出的任何程式碼修補程式。具體來說,這個模組會將任何從影子呼叫堆疊中推送或彈出的指示,替換為原本提供的指標驗證碼 (PAC) 指令。
  • 系統會停用模組的所有其他程式碼修補功能,包括靜態金鑰、追蹤點和供應商掛鉤。

已知答案自我測試

任何受 FIPS 140-3 規定規範的實作演算法,均必須在使用之前執行已知答案自我測試。根據 FIPS 140-3 實作指南 10.3.A,使用任一支援的金鑰長度的每個演算法的單一測試向量就足以使用加密,但前提是必須同時測試加密和解密。

Linux CryptoAPI 具有演算法優先順序的概念,其中幾項實作 (例如使用特殊加密指令的實作,以及未採用這些指示的 CPU 備用方案) 可能會同時存在。因此,需要測試相同演算法的所有實作項目。這是必要操作,因為 Linux CryptoAPI 允許側重優先選取,並改為選取優先順序較低的演算法。

模組所含的演算法

以下列出 FIPS 140-3 模組中包含的所有演算法。這適用於 android12-5.10android13-5.10android13-5.15android14-5.15android14-6.1android15-6.6 核心分支版本,但會視情況註明核心版本之間的差異。

演算法 導入 可核准 定義
aes aes-genericaes-arm64aes-ce、AES 程式庫 簡單的 AES 區塊加密,沒有作業模式:支援所有金鑰大小 (128 位元、192 位元與 256 位元)。除了程式庫實作項目,所有實作項目都能透過範本以作業模式編寫。
cmac(aes) cmac (範本)、cmac-aes-neoncmac-aes-ce AES-CMAC:支援所有 AES 金鑰大小。cmac 範本可透過 cmac(<aes-impl>),透過任何實作的 aes 編寫。其他導入作業各自獨立。
ecb(aes) ecb (範本)、ecb-aes-neonecb-aes-neonbsecb-aes-ce AES-ECB:支援所有 AES 金鑰大小。ecb 範本可透過 ecb(<aes-impl>),透過任何實作的 aes 編寫。其他導入作業各自獨立。
cbc(aes) cbc (範本)、cbc-aes-neoncbc-aes-neonbscbc-aes-ce AES-CBC:支援所有 AES 金鑰大小。cbc 範本可透過 ctr(<aes-impl>),透過任何實作的 aes 編寫。其他導入作業各自獨立。
cts(cbc(aes)) cts (範本)、cts-cbc-aes-neoncts-cbc-aes-ce 使用密文竊取的 AES-CBC-CTS 或 AES-CBC:採用的慣例是 CS3;最後兩個密文區塊無條件交換。系統支援所有 AES 金鑰大小。您可以使用 cts(<cbc(aes)-impl>),透過任何實作 cbc 編寫 cts 範本。其他導入作業各自獨立。
ctr(aes) ctr (範本)、ctr-aes-neonctr-aes-neonbsctr-aes-ce AES-CTR:支援所有 AES 金鑰大小。ctr 範本可透過 ctr(<aes-impl>),透過任何實作的 aes 編寫。其他導入作業各自獨立。
xts(aes) xts (範本)、xts-aes-neonxts-aes-neonbsxts-aes-ce AES-XTS:核心 6.1 以下版本支援所有 AES 金鑰大小;核心 6.6 以上版本中只支援 AES-128 和 AES-256。xts 範本可透過 xts(<ecb(aes)-impl>),透過任何實作的 ecb(aes) 編寫。其他導入作業各自獨立。所有的實作都會實作 FIPS 所需的弱式金鑰檢查,也就是說,第一和第二組相等的 XTS 金鑰會遭到拒絕。
gcm(aes) gcm (範本),gcm-aes-ce 1 AES-GCM:支援所有 AES 金鑰大小。僅支援 96 位元 IV。如同該模組中的其他所有 AES 模式,呼叫端必須負責提供 IV。gcm 範本可透過使用 gcm_base(<ctr(aes)-impl>,<ghash-impl>),透過任何實作 ctr(aes)ghash 編寫編寫。其他導入作業各自獨立。
sha1 sha1-genericsha1-ce SHA-1 加密編譯雜湊函式
sha224 sha224-genericsha224-arm64sha224-ce SHA-224 加密編譯雜湊函式:程式碼會與 SHA-256 共用。
sha256 sha256-genericsha256-arm64sha256-ce、SHA-256 程式庫 SHA-256 加密編譯雜湊函式:除了傳統 CryptoAPI 介面之外,系統還會向 SHA-256 提供程式庫介面。這個程式庫介面採用的實作方式不同。
sha384 sha384-genericsha384-arm64sha384-ce SHA-384 加密編譯雜湊函式:程式碼會與 SHA-512 共用。
sha512 sha512-genericsha512-arm64sha512-ce SHA-512 加密編譯雜湊函式
sha3-224 sha3-224-generic SHA3-224 加密編譯雜湊函式。僅在核心 6.6 以上版本中顯示。
sha3-256 sha3-256-generic 與上述相同,但採用 256 位元摘要長度 (SHA3-256)。所有摘要長度都使用相同的 Keccak 實作方式。
sha3-384 sha3-384-generic 與上述相同,但採用 384 位元摘要長度 (SHA3-384)。所有摘要長度都使用相同的 Keccak 實作方式。
sha3-512 sha3-512-generic 與上述相同,但採用 512 位元摘要長度 (SHA3-512)。所有摘要長度都使用相同的 Keccak 實作方式。
hmac hmac (範本) HMAC (金鑰雜湊訊息驗證碼):hmac 範本可透過任何 SHA 演算法,也可使用 hmac(<sha-alg>)hmac(<sha-impl>) 進行實作。
stdrng drbg_pr_hmac_sha1drbg_pr_hmac_sha256drbg_pr_hmac_sha384drbg_pr_hmac_sha512 HMAC_DRBG 使用已命名的雜湊函式進行例項化,並啟用預測阻抗:納入健康狀態檢查。這個介面的使用者會取得自己的 DRBG 執行個體。
stdrng drbg_nopr_hmac_sha1drbg_nopr_hmac_sha256drbg_nopr_hmac_sha384drbg_nopr_hmac_sha512 drbg_pr_* 演算法相同,但停用預測阻力功能。此程式碼會與可預測的變化版本共用。在核心 5.10 版中,優先順序最高的 DRBG 為 drbg_nopr_hmac_sha256。在核心 5.15 以上版本中,則為 drbg_pr_hmac_sha512
jitterentropy_rng jitterentropy_rng Jitter RNG,可以是 2.2.0 版 (核心版本 6.1 以下) 或版本 3.4.0 (核心版本 6.6 以上)。這個介面的使用者會取得自己的 Jitter RNG 執行個體。不會重複使用 DRBG 使用的執行個體。
xcbc(aes) xcbc-aes-neonxcbc-aes-ce
xctr(aes) xctr-aes-neonxctr-aes-ce 僅在核心 5.15 以上版本中顯示。
cbcmac(aes) cbcmac-aes-neoncbcmac-aes-ce
essiv(cbc(aes),sha256) essiv-cbc-aes-sha256-neonessiv-cbc-aes-sha256-ce

從來源建構模組

如果是 Android 14 以上版本 (包括 android-mainline),請使用下列指令從來源建構 fips140.ko 模組。

  • 使用 Bazel 建構:

    tools/bazel run //common:fips140_dist
    
  • 使用 build.sh 建構 (舊版):

    BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
    

這些指令會執行完整建構作業,包含核心和 fips140.ko 模組,其中嵌入了 HMAC-SHA256 摘要內容。

使用者指引

加密貨幣長指引

如要操作核心模組,作業系統必須限制為使用單一運算子作業模式。Android 會使用處理器的記憶體管理硬體自動處理這項作業。

核心模組無法單獨安裝;該模組已包含在裝置韌體中,並且會在開機時自動載入。只會在核准的作業模式下運作。

加密貨幣長可能會因重新啟動裝置而隨時執行自我測試。

使用指南

核心模組的使用者是需要使用加密編譯演算法的其他核心元件。核心模組不會在使用演算法時提供其他邏輯,在執行加密編譯作業的這段時間過後,也不會儲存任何參數。

為了遵守 FIPS 規範而使用演算法,只有經過核准的演算法才有作用。為了滿足 FIPS 140-3「服務指標」要求,模組會提供 fips140_is_approved_service 函式,指出演算法是否已獲核准。

自我測試錯誤

如果自我測試失敗,核心模組會導致核心發生恐慌,裝置也不會繼續啟動。如果重新啟動裝置無法解決問題,則裝置必須啟動進入復原模式,才能透過重新刷新裝置的方式修正問題。


  1. 模組的 AES-GCM 實作項目應該可以「經過演算法核准」,而不是「模組已核准」。這些類型可以驗證,但從 FIPS 模組的角度來看,AES-GCM 無法視為已核准的演算法。這是因為 GCM 的 FIPS 模組要求與不會產生自身 IV 的 GCM 實作不相容。