FIPS 140-3 可认证 GKI 加密模块

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.loadmodules.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-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模板可以使用cts(<cbc(aes)-impl>)与任何cbc实现组成。其他实现是独立的。
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:支持所有 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-genericsha224-arm64sha224-ce是的SHA-224 加密哈希函数:代码与 SHA-256 共享。
sha256 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 加密哈希函数
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_rngJitter 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来指示算法是否被批准。

自检错误

如果自检失败,内核模块会导致内核崩溃,并且设备无法继续引导。如果重新启动设备不能解决问题,则设备必须启动进入恢复模式,通过重新刷写设备来纠正问题。


  1. 预计模块的 AES-GCM 实现可以是“算法批准”但不是“模块批准”。它们可以被验证,但从 FIPS 模块的角度来看,AES-GCM 不能被视为一种认可的算法。这是因为 GCM 的 FIPS 模块要求与不生成自己的 IV 的 GCM 实现不兼容。