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 的輸入。
- 該模組的所有其他程式碼修補均已停用,包括靜態金鑰、追蹤點以及供應商掛鉤。
已知答案自測
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
核心分支,但會在適當的地方註明核心版本之間的差異。
演算法 | 實施 | 可批准 | 定義 |
---|---|---|---|
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:支援所有 AES 金鑰大小。 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 加密雜湊函數 |
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 版:此介面的使用者可以獲得自己的 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 實作不相容。 ↩