GKI內核包括一個名為fips140.ko
的 Linux 內核模塊,它符合FIPS 140-3對加密軟件模塊的要求。如果運行 GKI 內核的產品需要此模塊,可以提交 FIPS 認證。
在使用加密例程之前,必須滿足以下 FIPS 140-3 要求:
- 在使加密算法可用之前,模塊必須檢查其自身的完整性。
- 該模塊必須使用已知答案自測來執行和驗證其批准的密碼算法,然後才能使其可用。
為什麼要單獨的內核模塊
FIPS 140-3 驗證基於這樣的理念,即一旦基於軟件或硬件的模塊經過認證,就永遠不會改變。如果更改,則必須重新認證。這與當今使用的軟件開發流程並不匹配,因此,由於此要求,FIPS 軟件模塊通常設計為盡可能緊密地關注加密組件,以確保與加密無關的更改能夠執行不需要重新評估密碼學。
GKI 內核旨在在其支持的整個生命週期內定期更新。這使得整個內核在 FIPS 模塊邊界內是不可行的,因為這樣的模塊需要在每次內核更新時重新認證。此外,GKI 編譯時啟用了 LTO(鏈接時間優化),因為 LTO 是 CFI 的先決條件,而CFI是一項重要的安全功能。這使得僅圍繞內核的加密代碼繪製 FIPS 模塊邊界是不可行的,因為此類代碼在生成的二進製文件中沒有明確定義的位置。內核更新也可能會更改加密代碼。
因此,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 允許迴避基於優先級的選擇,而是選擇較低優先級的算法。
模塊中包含的算法
從android13-5.10 源構建時包含在 FIPS 140-3 模塊中的所有算法如下所列。
算法 | 實現 | 可批准 | 定義 |
---|---|---|---|
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- 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(Keyed-Hash Message Authentication Code): hmac 模板可以由任何 SHA 算法或使用hmac(<sha-alg>) 或hmac(<sha-impl>) 組成。 |
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_* 算法相同,但禁用了預測阻力。該代碼與抗預測變體共享。最高優先級的 DRBG 是drbg_nopr_hmac_sha256 。 |
jitterentropy_rng | jitterentropy_rng | 不 | Jitter RNG 2.2.0 版:此接口的用戶獲得自己的 Jitter RNG 實例。他們不重用 DRBG 使用的實例。 |
xcbc(aes) | xcbc-aes-neon , xcbc-aes-ce | 不 | |
cbcmac(aes) | cbcmac-aes-neon , cbcmac-aes-ce | 不 | |
essiv(cbc(aes),sha256) | essiv-cbc-aes-sha256-neon , essiv-cbc-aes-sha256-ce | 不 |
從源代碼構建模塊
fips140.ko
模塊可以使用以下命令從 GKI 內核源代碼構建:
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 實現不兼容。 ↩