Módulo criptográfico GKI certificable FIPS 140-3

El kernel de GKI incluye un módulo de kernel de Linux llamado fips140.ko que cumple con los requisitos de 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 de FIPS 140-3 antes de que se puedan utilizar las rutinas criptográficas:

  • El módulo debe comprobar su propia integridad antes de poner a disposición algoritmos criptográficos.
  • El módulo debe ejercitar y verificar sus algoritmos criptográficos aprobados mediante autoevaluaciones de respuesta conocida antes de ponerlos a disposición.

¿Por qué un módulo 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 cambia. Si se cambia, debe ser recertificado. 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 estrictamente 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 regularmente durante toda su vida útil. Esto hace que no sea factible que todo el kernel esté dentro de los límites del módulo FIPS, ya que dicho módulo debe volver a certificarse en cada actualización del kernel. Además, GKI se compila con LTO (Link Time Optimization) habilitado, ya que LTO es un requisito previo para CFI , que es una función de seguridad importante. Esto hace que no sea factible dibujar el límite del módulo FIPS solo alrededor del código criptográfico del kernel, ya que dicho código no está en una ubicación claramente definida en el binario resultante. Las actualizaciones del kernel también pueden cambiar el código criptográfico.

Por lo tanto, todo el código que está 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 de kernel de GKI a partir de la cual se creó. Esto garantiza que el módulo se puede usar con diferentes versiones de GKI de la misma generación, y que debe actualizarse y volver a enviarse para la certificación solo si se solucionó algún problema en el código que lleva el propio módulo.

Cuándo usar el módulo

El núcleo GKI en sí lleva un código que depende de las rutinas criptográficas que también están empaquetadas en el módulo del núcleo FIPS 140-3. Por lo tanto, las rutinas criptográficas integradas en realidad no se sacan del núcleo 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 CryptoAPI de Linux y se reemplazan 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 es probable que cargarlo innecesariamente 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 al ramdisk 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 a modules.load en el destino. modules.load contiene la lista de módulos que son cargados por init cuando el dispositivo arranca.

La autocomprobación de la integridad

El módulo kernel FIPS 140-3 toma el resumen HMAC-SHA256 de sus propias secciones .code y .rodata en el momento de 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 autoevaluaciones de respuesta conocida

Cualquier algoritmo implementado que esté cubierto por los requisitos de FIPS 140-3 debe realizar una autocomprobación de respuesta conocida antes de ser utilizado. De acuerdo con la Guía de implementación 10.3.A de FIPS 140-3 , un solo vector de prueba por algoritmo que use 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 lo tanto, existe la necesidad de probar todas las implementaciones del mismo algoritmo. Esto es necesario porque Linux CryptoAPI permite eludir la selección basada en la 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 cuando se compilan a partir de las fuentes de android13-5.10 se enumeran a continuación.

Algoritmo Implementaciones Digno de aprobación Definición
aes aes-generic , aes-arm64 , aes-ce , biblioteca AES Cifrado de bloque 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 que no sean 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 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 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 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 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 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 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 son iguales.
gcm(aes) gcm (plantilla), gcm-aes-ce1 AES-GCM: se admiten todos los tamaños de clave AES. Solo se admiten IV de 96 bits. Al igual que con todos los demás modos AES en 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 Función hash criptográfica SHA-1
sha224 sha224-generic , sha224-arm64 , sha224-ce 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 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 Función hash criptográfica SHA-384: El código se comparte con SHA-512.
sha512 sha512-generic , sha512-arm64 , sha512-ce Función hash criptográfica SHA-512
hmac hmac (plantilla) HMAC (Código de autenticación de mensajes hash con clave): la plantilla hmac se puede componer con cualquier algoritmo SHA o implementación mediante hmac(<sha-alg>) o hmac(<sha-impl>) .
stdrng drbg_pr_hmac_sha1 , drbg_pr_hmac_sha256 , drbg_pr_hmac_sha384 , drbg_pr_hmac_sha512 HMAC_DRBG instanciado con la función hash con nombre y con la resistencia de predicción habilitada: se incluyen comprobaciones de estado. Los usuarios de esta interfaz obtienen sus propias instancias de DRBG.
stdrng drbg_nopr_hmac_sha1 , drbg_nopr_hmac_sha256 , drbg_nopr_hmac_sha384 , drbg_nopr_hmac_sha512 Igual que los algoritmos drbg_pr_* , pero con la resistencia de predicción deshabilitada. El código se comparte con la variante resistente a predicciones. El DRBG de mayor prioridad es drbg_nopr_hmac_sha256 .
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 usan los DRBG.
xcbc(aes) xcbc-aes-neon , xcbc-aes-ce No
cbcmac(aes) cbcmac-aes-neon , cbcmac-aes-ce No
essiv(cbc(aes),sha256) essiv-cbc-aes-sha256-neon , essiv-cbc-aes-sha256-ce No

Construyendo el módulo desde la fuente

El módulo fips140.ko se puede compilar a partir de las fuentes del kernel de GKI con el siguiente comando:

BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh

Esto realiza la compilación completa con el kernel y el módulo fips140.ko , con el resumen HMAC-SHA256 correcto de su contenido incrustado.

Guía para el usuario final

Orientación del oficial criptográfico

Para operar el módulo 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. Solo funciona en un modo de operación aprobado.

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 usar algoritmos criptográficos. El módulo del núcleo 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 el cumplimiento de FIPS se limita a los algoritmos aprobados. Para satisfacer el requisito de "indicador de servicio" de FIPS 140-3, el módulo proporciona una función fips140_is_approved_service que indica si un algoritmo está aprobado.

Errores de autodiagnóstico

En caso de que falle la autocomprobación, el módulo del kernel hace que el kernel entre en pánico y el dispositivo no continúa arrancando. Si un reinicio del dispositivo no resuelve el problema, el dispositivo debe iniciarse en modo de recuperación para corregir el problema volviendo a actualizar el dispositivo.


  1. 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 se puede considerar 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.