El kernel GKI incluye un módulo del kernel de Linux llamado fips140.ko
que cumple con los requisitos FIPS 140-3 para módulos de software criptográfico. Este módulo se puede enviar para la certificación FIPS si el producto que ejecuta el kernel GKI lo requiere.
En particular, se deben cumplir los siguientes requisitos FIPS 140-3 antes de poder utilizar las rutinas criptográficas:
- El módulo debe comprobar su propia integridad antes de que los algoritmos criptográficos estén disponibles.
- El módulo debe ejercitar y verificar sus algoritmos criptográficos aprobados mediante autopruebas de respuesta conocida antes de ponerlos a disposición.
¿Por qué un módulo de kernel separado?
La validación FIPS 140-3 se basa en la idea de que una vez que se ha certificado un módulo basado en software o hardware, nunca se modifica. Si se modifica, se debe recertificar. Esto no coincide fácilmente con los procesos de desarrollo de software que se utilizan hoy en día y, como resultado de este requisito, los módulos de software FIPS generalmente están diseñados para centrarse lo más estrechamente posible en los componentes criptográficos, para garantizar que los cambios que no están relacionados con la criptografía no se realicen. No requiere una reevaluación de la criptografía.
El kernel de GKI está diseñado para actualizarse periódicamente durante toda su vida útil. Esto hace que sea inviable que todo el kernel esté dentro de los límites del módulo FIPS, ya que dicho módulo necesitaría ser recertificado en cada actualización del kernel. Definir el "módulo FIPS" como un subconjunto de la imagen del kernel mitigaría este problema pero no lo resolvería, ya que el contenido binario del "módulo FIPS" aún cambiaría con mucha más frecuencia de lo necesario.
Antes de la versión 6.1 del kernel, otra consideración era que GKI se compilaba con LTO (optimización de tiempo de enlace) habilitado, ya que LTO era un requisito previo para la integridad del flujo de control , que es una característica de seguridad importante.
Por lo tanto, todo el código cubierto por los requisitos de FIPS 140-3 se empaqueta en un módulo de kernel separado fips140.ko
que solo se basa en interfaces estables expuestas por la fuente del kernel GKI a partir del cual se creó. Esto garantiza que el módulo se puede utilizar con diferentes versiones de GKI de la misma generación, y que se debe actualizar y volver a enviar para certificación solo si se solucionó algún problema en el código que lleva el propio módulo.
Cuándo utilizar el módulo
El propio kernel GKI lleva código que depende de las rutinas criptográficas que también están empaquetadas en el módulo del kernel FIPS 140-3. Por lo tanto, las rutinas criptográficas integradas en realidad no se eliminan del kernel GKI, sino que se copian en el módulo. Cuando se carga el módulo, las rutinas criptográficas integradas se cancelan del registro de Linux CryptoAPI y son reemplazadas por las que lleva el módulo.
Esto significa que el módulo fips140.ko
es completamente opcional y solo tiene sentido implementarlo si la certificación FIPS 140-3 es un requisito. Más allá de eso, el módulo no proporciona ninguna funcionalidad adicional y cargarlo innecesariamente probablemente solo afecte el tiempo de arranque, sin proporcionar ningún beneficio.
Cómo implementar el módulo
El módulo se puede incorporar a la compilación de Android siguiendo los siguientes pasos:
- Agregue el nombre del módulo a
BOARD_VENDOR_RAMDISK_KERNEL_MODULES
. Esto hace que el módulo se copie en el disco ram del proveedor. - Agregue el nombre del módulo a
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
. Esto hace que el nombre del módulo se agregue amodules.load
en el destino.modules.load
contiene la lista de módulos queinit
carga cuando se inicia el dispositivo.
El autocontrol de integridad
El módulo del kernel FIPS 140-3 toma el resumen HMAC-SHA256 de sus propias secciones .code
y .rodata
en el momento de la carga del módulo y lo compara con el resumen registrado en el módulo. Esto tiene lugar después de que el cargador de módulos de Linux ya haya realizado las modificaciones habituales, como el procesamiento de reubicación de ELF y parches alternativos para erratas de CPU en esas secciones. Se toman los siguientes pasos adicionales para garantizar que el resumen se pueda reproducir correctamente:
- Las reubicaciones de ELF se conservan dentro del módulo para que puedan aplicarse a la inversa a la entrada del HMAC.
- Todos los demás parches de código están deshabilitados para el módulo, incluidas las claves estáticas y, por lo tanto, los puntos de seguimiento, así como los enlaces de proveedores.
Las autopruebas de respuesta conocida
Cualquier algoritmo implementado que esté cubierto por los requisitos de FIPS 140-3 debe realizar una autoprueba de respuesta conocida antes de usarse. Según la Guía de implementación 10.3.A de FIPS 140-3 , un único vector de prueba por algoritmo que utilice cualquiera de las longitudes de clave admitidas es suficiente para los cifrados, siempre que se prueben tanto el cifrado como el descifrado.
Linux CryptoAPI tiene una noción de prioridades de algoritmo, donde pueden coexistir varias implementaciones (como una que usa instrucciones criptográficas especiales y una alternativa para CPU que no implementan esas instrucciones) del mismo algoritmo. Por tanto, es necesario probar todas las implementaciones del mismo algoritmo. Esto es necesario porque Linux CryptoAPI permite eludir la selección basada en prioridad y, en su lugar, seleccionar un algoritmo de menor prioridad.
Algoritmos incluidos en el módulo
Todos los algoritmos que se incluyen en el módulo FIPS 140-3 se enumeran a continuación. Esto se aplica a las ramas del kernel android12-5.10
, android13-5.10
, android13-5.15
, android14-5.15
y android14-6.1
, aunque las diferencias entre las versiones del kernel se indican cuando corresponde.
Algoritmo | Implementaciones | Digno de aprobación | Definición |
---|---|---|---|
aes | aes-generic , aes-arm64 , aes-ce , biblioteca AES | Sí | Cifrado de bloques AES simple, sin modo de operación: se admiten todos los tamaños de clave (128 bits, 192 bits y 256 bits). Todas las implementaciones distintas a la implementación de la biblioteca se pueden componer con un modo de operación a través de una plantilla. |
cmac(aes) | cmac (plantilla), cmac-aes-neon , cmac-aes-ce | Sí | AES-CMAC: se admiten todos los tamaños de clave AES. La plantilla cmac se puede componer con cualquier implementación de aes usando cmac(<aes-impl>) . Las otras implementaciones son independientes. |
ecb(aes) | ecb (plantilla), ecb-aes-neon , ecb-aes-neonbs , ecb-aes-ce | Sí | AES-ECB: se admiten todos los tamaños de clave AES. La plantilla ecb se puede componer con cualquier implementación de aes usando ecb(<aes-impl>) . Las otras implementaciones son independientes. |
cbc(aes) | cbc (plantilla), cbc-aes-neon , cbc-aes-neonbs , cbc-aes-ce | Sí | AES-CBC: se admiten todos los tamaños de clave AES. La plantilla cbc se puede componer con cualquier implementación de aes usando ctr(<aes-impl>) . Las otras implementaciones son independientes. |
cts(cbc(aes)) | cts (plantilla), cts-cbc-aes-neon , cts-cbc-aes-ce | Sí | AES-CBC-CTS o AES-CBC con robo de texto cifrado: La convención utilizada es CS3 ; los dos últimos bloques de texto cifrado se intercambian incondicionalmente. Se admiten todos los tamaños de clave AES. La plantilla cts se puede componer con cualquier implementación de cbc usando cts(<cbc(aes)-impl>) . Las otras implementaciones son independientes. |
ctr(aes) | ctr (plantilla), ctr-aes-neon , ctr-aes-neonbs , ctr-aes-ce | Sí | AES-CTR: se admiten todos los tamaños de clave AES. La plantilla ctr se puede componer con cualquier implementación de aes usando ctr(<aes-impl>) . Las otras implementaciones son independientes. |
xts(aes) | xts (plantilla), xts-aes-neon , xts-aes-neonbs , xts-aes-ce | Sí | AES-XTS: se admiten todos los tamaños de clave AES. La plantilla xts se puede componer con cualquier implementación de ecb(aes) usando xts(<ecb(aes)-impl>) . Las otras implementaciones son independientes. Todas las implementaciones implementan la verificación de clave débil requerida por FIPS; es decir, se rechazan las claves XTS cuya primera y segunda mitad sean iguales. |
gcm(aes) | gcm (plantilla), gcm-aes-ce | número 1 | AES-GCM: se admiten todos los tamaños de clave AES. Sólo se admiten IV de 96 bits. Como ocurre con todos los demás modos AES de este módulo, la persona que llama es responsable de proporcionar los IV. La plantilla gcm se puede componer con cualquier implementación de ctr(aes) y ghash usando gcm_base(<ctr(aes)-impl>,<ghash-impl>) . Las otras implementaciones son independientes. |
sha1 | sha1-generic , sha1-ce | Sí | Función hash criptográfica SHA-1 |
sha224 | sha224-generic , sha224-arm64 , sha224-ce | Sí | Función hash criptográfica SHA-224: El código se comparte con SHA-256. |
sha256 | sha256-generic , sha256-arm64 , sha256-ce , biblioteca SHA-256 | Sí | Función hash criptográfica SHA-256: se proporciona una interfaz de biblioteca para SHA-256 además de la interfaz CryptoAPI tradicional. Esta interfaz de biblioteca utiliza una implementación diferente. |
sha384 | sha384-generic , sha384-arm64 , sha384-ce | Sí | Función hash criptográfica SHA-384: El código se comparte con SHA-512. |
sha512 | sha512-generic , sha512-arm64 , sha512-ce | Sí | Función hash criptográfica SHA-512 |
hmac | hmac (plantilla) | Sí | HMAC (Código de autenticación de mensajes hash con clave): la plantilla hmac se puede componer con cualquier algoritmo o implementación SHA usando hmac(<sha-alg>) o hmac(<sha-impl>) . |
stdrng | drbg_pr_hmac_sha1 , drbg_pr_hmac_sha256 , drbg_pr_hmac_sha384 , drbg_pr_hmac_sha512 | Sí | HMAC_DRBG instanciado con la función hash nombrada y con la resistencia a la predicción habilitada: se incluyen comprobaciones de estado. Los usuarios de esta interfaz obtienen sus propias instancias DRBG. |
stdrng | drbg_nopr_hmac_sha1 , drbg_nopr_hmac_sha256 , drbg_nopr_hmac_sha384 , drbg_nopr_hmac_sha512 | Sí | Igual que los algoritmos drbg_pr_* , pero con la resistencia a la predicción deshabilitada. El código se comparte con la variante resistente a las predicciones. En la versión 5.10 del kernel, el DRBG de mayor prioridad es drbg_nopr_hmac_sha256 . En la versión del kernel 5.15 y posteriores, es drbg_pr_hmac_sha512 . |
jitterentropy_rng | jitterentropy_rng | No | Versión 2.2.0 de Jitter RNG : los usuarios de esta interfaz obtienen sus propias instancias de Jitter RNG. No reutilizan las instancias que utilizan los DRBG. |
xcbc(aes) | xcbc-aes-neon , xcbc-aes-ce | No | |
xctr(aes) | xctr-aes-neon , xctr-aes-ce | No | Sólo presente en la versión del kernel 5.15 y posteriores. |
cbcmac(aes) | cbcmac-aes-neon , cbcmac-aes-ce | No | |
essiv(cbc(aes),sha256) | essiv-cbc-aes-sha256-neon , essiv-cbc-aes-sha256-ce | No |
Construya el módulo desde la fuente
Para Android 14 o posterior (incluido android-mainline
), cree el módulo fips140.ko
desde el código fuente utilizando los siguientes comandos.
Construir con Bazel:
tools/bazel run //common:fips140_dist
Construir con
build.sh
(heredado):BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
Estos comandos realizan una compilación completa que incluye el kernel y el módulo fips140.ko
con el contenido del resumen HMAC-SHA256 incrustado en él.
Guía para el usuario final
Orientación del oficial criptográfico
Para operar el módulo del kernel, el sistema operativo debe estar restringido a un modo de operación de un solo operador. Android maneja esto automáticamente usando hardware de administración de memoria en el procesador.
El módulo del kernel no se puede instalar por separado; se incluye como parte del firmware del dispositivo y se carga automáticamente al arrancar. Sólo funciona en un modo de funcionamiento aprobado.
El Crypto Officer puede hacer que las autopruebas se ejecuten en cualquier momento reiniciando el dispositivo.
Guía del usuario
El usuario del módulo del kernel son otros componentes del kernel que necesitan utilizar algoritmos criptográficos. El módulo del kernel no proporciona lógica adicional en el uso de los algoritmos y no almacena ningún parámetro más allá del tiempo necesario para realizar una operación criptográfica.
El uso de los algoritmos para fines de cumplimiento de FIPS se limita a los algoritmos aprobados. Para satisfacer el requisito de "indicador de servicio" FIPS 140-3, el módulo proporciona una función fips140_is_approved_service
que indica si un algoritmo está aprobado.
Errores de autoprueba
En caso de una falla en la autoprueba, el módulo del kernel hace que el kernel entre en pánico y el dispositivo no continúa arrancando. Si reiniciar el dispositivo no resuelve el problema, el dispositivo debe iniciarse en modo de recuperación para corregir el problema volviendo a actualizar el dispositivo.
Se espera que las implementaciones AES-GCM del módulo puedan ser "aprobadas por algoritmo" pero no "aprobadas por módulo". Se pueden validar, pero AES-GCM no puede considerarse un algoritmo aprobado desde el punto de vista del módulo FIPS. Esto se debe a que los requisitos del módulo FIPS para GCM son incompatibles con las implementaciones de GCM que no generan sus propios IV. ↩