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 的輸入內容。
- 這個模組會還原核心為動態陰影呼叫堆疊所做的任何程式碼修補程式。具體來說,這個模組會將任何從陰影呼叫堆疊推送或彈出的指令,替換為原本存在的指標驗證碼 (PAC) 指令。
- 模組會停用所有其他程式碼修補作業,包括靜態金鑰,因此也會停用追蹤點和供應商掛鉤。
已知答案的自我測試
凡是實作的演算法符合 FIPS 140-3 規定,都必須先執行已知答案自我測試,才能使用。根據 FIPS 140-3 實作指南 10.3.A,只要測試加密和解密,每個演算法使用任何支援的金鑰長度,都只需要一個測試向量。
Linux CryptoAPI 具有演算法優先順序的概念,其中相同演算法的多種實作方式 (例如使用特殊加密指令的實作方式,以及 CPU 未實作這些指令時的回溯機制) 可能會共存。因此,您需要測試相同演算法的所有實作項目。這是必要步驟,因為 Linux CryptoAPI 允許略過優先順序選取作業,改為選取優先順序較低的演算法。
模組中包含的演算法
FIPS 140-3 模組中包含的所有演算法如下所示。
這適用於 android12-5.10
、android13-5.10
、android13-5.15
、android14-5.15
、android14-6.1
和 android15-6.6
核心分支版本,但我們會視情況註明核心版本之間的差異。
演算法 | 導入 | 可核准 | 定義 |
---|---|---|---|
aes |
aes-generic 、aes-arm64 、aes-ce 、AES 程式庫 |
是 | 純 AES 區塊加密,不含作業模式:支援所有金鑰大小 (128 位元、192 位元和 256 位元)。除了程式庫實作項目外,所有實作項目都可以透過範本,以作業模式組成。 |
cmac(aes) |
cmac (範本)、cmac-aes-neon 、cmac-aes-ce |
是 | AES-CMAC:支援所有 AES 金鑰大小。cmac 範本可使用 cmac(<aes-impl>) ,與 aes 的任何實作項目組成。其他實作方式則為獨立。 |
ecb(aes) |
ecb (範本)、ecb-aes-neon 、ecb-aes-neonbs 、ecb-aes-ce |
是 | AES-ECB:支援所有 AES 金鑰大小。ecb 範本可使用 ecb(<aes-impl>) ,與 aes 的任何實作項目組成。其他實作方式則為獨立。 |
cbc(aes) |
cbc (範本)、cbc-aes-neon 、cbc-aes-neonbs 、cbc-aes-ce |
是 | AES-CBC:支援所有 AES 金鑰大小。cbc 範本可使用 ctr(<aes-impl>) ,與 aes 的任何實作項目組成。其他實作方式則為獨立。 |
cts(cbc(aes)) |
cts (範本)、cts-cbc-aes-neon 、cts-cbc-aes-ce |
是 | AES-CBC-CTS 或 AES-CBC (密文竊取):使用的慣例是 CS3 ;最後兩個密文區塊會無條件交換。支援所有 AES 金鑰大小。cts 範本可使用 cts(<cbc(aes)-impl>) ,與 cbc 的任何實作項目組成。其他實作方式則為獨立。 |
ctr(aes) |
ctr (範本)、ctr-aes-neon 、ctr-aes-neonbs 、ctr-aes-ce |
是 | AES-CTR:支援所有 AES 金鑰大小。ctr 範本可使用 ctr(<aes-impl>) ,與 aes 的任何實作項目組成。其他實作方式則為獨立。 |
xts(aes) |
xts (範本)、xts-aes-neon 、xts-aes-neonbs 、xts-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-generic 、sha1-ce |
是 | SHA-1 密碼編譯雜湊函式 |
sha224 |
sha224-generic 、sha224-arm64 、sha224-ce |
是 | SHA-224 加密雜湊函式:程式碼與 SHA-256 共用。 |
sha256 |
sha256-generic 、sha256-arm64 、sha256-ce 、SHA-256 程式庫 |
是 | SHA-256 加密雜湊函式:除了標準 CryptoAPI 介面外,還提供 SHA-256 的程式庫介面。這個程式庫介面使用不同的實作方式。 |
sha384 |
sha384-generic 、sha384-arm64 、sha384-ce |
是 | SHA-384 密碼編譯雜湊函式:程式碼與 SHA-512 共用。 |
sha512 |
sha512-generic 、sha512-arm64 、sha512-ce |
是 | SHA-512 加密編譯雜湊函式 |
sha3-224 |
sha3-224-generic |
是 | SHA3-224 加密雜湊函式。僅適用於 6.6 以上的 Kernel 版本。 |
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 範本可使用 hmac(<sha-alg>) 或 hmac(<sha-impl>) ,以任何 SHA 演算法或實作方式組成。 |
stdrng |
drbg_pr_hmac_sha1 、drbg_pr_hmac_sha256 、drbg_pr_hmac_sha384 、drbg_pr_hmac_sha512 |
是 | 使用具名雜湊函式例項化 HMAC_DRBG,並啟用預測抗性:包含健康狀態檢查。這個介面的使用者會取得自己的 DRBG 執行個體。 |
stdrng |
drbg_nopr_hmac_sha1 、drbg_nopr_hmac_sha256 、drbg_nopr_hmac_sha384 、drbg_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-neon 、xcbc-aes-ce |
否 | |
xctr(aes) |
xctr-aes-neon 、xctr-aes-ce |
否 | 僅適用於核心版本 5.15 以上。 |
cbcmac(aes) |
cbcmac-aes-neon 、cbcmac-aes-ce |
否 | |
essiv(cbc(aes),sha256) |
essiv-cbc-aes-sha256-neon 、essiv-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
函式,可指出演算法是否已獲核准。
自我測試錯誤
如果自我測試失敗,核心模組會導致核心恐慌,裝置不會繼續啟動。如果重新啟動裝置無法解決問題,裝置必須進入復原模式,才能透過重新刷機修正問題。
-
預期模組的 AES-GCM 實作項目可「通過演算法核准」,但「未通過模組核准」。可以驗證,但從 FIPS 模組的角度來看,AES-GCM 並不算是核准的演算法。這是因為 GCM 的 FIPS 模組規定與未產生自有 IV 的 GCM 實作不相容。 ↩