Módulo criptográfico de GKI certificado con FIPS 140-3

El kernel GKI incluye un módulo de 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 de GKI lo requiere.

Se deben cumplir los siguientes requisitos del FIPS 140-3 antes de que se puedan usar las rutinas criptográficas:

  • El módulo debe verificar su propia integridad antes de que los algoritmos criptográficos estén disponibles.
  • El módulo debe ejecutar y verificar sus algoritmos criptográficos aprobados mediante autopruebas de respuesta conocida antes de que estén disponibles.

Por qué usar un módulo de kernel independiente

La validación del estándar FIPS 140-3 se basa en la idea de que una vez que se certifica un módulo de software o hardware, nunca se modifica. Si se cambia, se debe volver a certificar. Esto no coincide fácilmente con los procesos de desarrollo de software que se usan en la actualidad y, como resultado de este requisito, los módulos de software FIPS, por lo general, están diseñados para enfocarse lo más estrechamente posible en los componentes criptográficos y garantizar que los cambios no relacionados con la criptografía no requieran una reevaluación de la criptografía.

El kernel de GKI está diseñado para actualizarse con regularidad durante toda su vida útil admitida. Esto hace que sea inviable que todo el kernel esté dentro del límite del módulo FIPS, ya que este módulo deberá volver a certificarse con 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" cambiaría con mucha más frecuencia de la necesaria.

Antes de la versión 6.1 de kernel, se debía tener en cuenta que GKI se compiló con la LTO (optimización del tiempo de vinculación) habilitada, ya que LTO era un requisito previo para la Integridad del flujo de control, que es una importante función de seguridad.

Por lo tanto, todo el código cubierto por los requisitos del estándar FIPS 140-3 se empaqueta en un módulo de kernel fips140.ko independiente que solo se basa en interfaces estables expuestas por la fuente del kernel de GKI desde la que se compiló. Esto garantiza que el módulo se pueda usar con diferentes versiones de GKI de la misma generación, y que se deba actualizar y volver a enviar para la certificación solo si se corrigieron problemas en el código que contiene el módulo.

Cuándo usar el módulo

El kernel de GKI lleva un código que depende de las rutinas criptográficas que también se empaquetan en el módulo de kernel del FIPS 140-3. Por lo tanto, las rutinas criptográficas integradas no se quitan del kernel de GKI, sino que se copian en el módulo. Cuando se carga el módulo, las rutinas criptográficas integradas se anulan del registro de la CryptoAPI de Linux y se reemplazan por las que incluye 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 solo es probable que afecte el tiempo de inicio, sin proporcionar ningún beneficio.

Cómo implementar el módulo

El módulo puede incorporarse a la compilación de Android mediante los siguientes pasos:

  • Agrega el nombre del módulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES. De esta manera, el módulo se copia en el ramdisk del proveedor.
  • Agrega el nombre del módulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD. De esta manera, el nombre del módulo se agrega a modules.load en el destino. modules.load contiene la lista de módulos que carga init cuando se inicia el dispositivo.

La autoverificación de integridad

El módulo de kernel del FIPS 140-3 toma el resumen HMAC-SHA256 de sus propias secciones .code y .rodata en el tiempo de carga del módulo, y lo compara con el resumen registrado en el módulo. Esto ocurre después de que el cargador de módulos de Linux ya realiza las modificaciones habituales, como el procesamiento de reubicación de ELF y la aplicación de parches alternativas para errata de CPU de 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 se puedan aplicar en sentido inverso a la entrada de HMAC.
  • El módulo revierte los parches de código creados por el kernel para la pila de llamadas paralelas dinámicas. Específicamente, el módulo reemplaza las instrucciones que envían o se resaltan de la pila de llamadas paralelas por las instrucciones del código de autenticación del puntero (PAC) que estaban presentes en un principio.
  • Todos los demás parches de código están inhabilitados para el módulo, incluidas las claves estáticas y, por lo tanto, los puntos de seguimiento, así como los hooks del proveedor.

Las autopruebas de respuesta conocida

Todos los algoritmos implementados que estén cubiertos por los requisitos del estándar FIPS 140-3 deben realizar una autoprueba de respuesta conocida antes de usarse. De acuerdo con la Guía de implementación 10.3.A del FIPS 140-3, un solo vector de prueba por algoritmo que usa cualquiera de las longitudes de clave admitidas es suficiente para los algoritmos de cifrado, siempre que se prueben tanto la encriptación como la desencriptación.

La CryptoAPI de Linux tiene una noción de prioridades de algoritmo, en la que pueden coexistir varias implementaciones (como una que usa instrucciones criptográficas especiales y un resguardo para las CPU que no las tienen) del mismo algoritmo. Por lo tanto, es necesario probar todas las implementaciones del mismo algoritmo. Esto es necesario porque la CryptoAPI de Linux permite que se evite la selección basada en la prioridad y que se seleccione un algoritmo de menor prioridad en su lugar.

Algoritmos incluidos en el módulo

A continuación, se indican todos los algoritmos incluidos en el módulo del estándar FIPS 140-3. Esto se aplica a las ramas de kernel android12-5.10, android13-5.10, android13-5.15, android14-5.15, android14-6.1 y android15-6.6, aunque las diferencias entre las versiones de kernel se indican cuando corresponda.

Algoritmo Implementaciones Aprobable Definición
aes aes-generic, aes-arm64, aes-ce, biblioteca AES Cifrado por 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 que no sean la 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 que se usa es CS3; los dos últimos bloques de texto cifrado se intercambian de forma incondicional.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: En la versión de kernel 6.1 y anteriores, se admiten todos los tamaños de clave AES. En la versión de kernel 6.6 y posteriores, solo se admiten AES-128 y AES-256. 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 comprobación de clave débil requerida por el FIPS; es decir, se rechazan las claves XTS cuyos dos mitades son iguales.
gcm(aes) gcm (plantilla), gcm-aes-ce No1 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 de este módulo, el llamador es responsable de proporcionar los IV. La plantilla gcm se puede componer con cualquier implementación de ctr(aes) y ghash a través de gcm_base(<ctr(aes)-impl>,<ghash-impl>). Las otras implementaciones son independientes.
sha1 sha1-generic, sha1-ce Función de hash de criptografía SHA-1
sha224 sha224-generic, sha224-arm64, sha224-ce Función de hash de criptografía SHA-224: El código se comparte con SHA-256.
sha256 sha256-generic, sha256-arm64, sha256-ce, biblioteca SHA-256 Función de hash de criptografía SHA-256: Además de la interfaz CryptoAPI tradicional, se proporciona una interfaz de biblioteca a SHA-256. Esta interfaz de biblioteca usa una implementación diferente.
sha384 sha384-generic, sha384-arm64, sha384-ce Función de hash de criptografía SHA-384: El código se comparte con SHA-512.
sha512 sha512-generic, sha512-arm64, sha512-ce Función de hash de criptografía SHA-512
sha3-224 sha3-224-generic Función de hash criptográfico SHA3-224. Solo está presente en la versión de kernel 6.6 y versiones posteriores.
sha3-256 sha3-256-generic Igual al anterior, pero con longitud de resumen de 256 bits (SHA3-256). Todas las longitudes de resumen usan la misma implementación de Keccak.
sha3-384 sha3-384-generic Igual al anterior, pero con longitud de resumen de 384 bits (SHA3-384). Todas las longitudes de resumen usan la misma implementación de Keccak.
sha3-512 sha3-512-generic Igual al anterior, pero con longitud de resumen de 512 bits (SHA3-512). Todas las longitudes de resumen usan la misma implementación de Keccak.
hmac hmac (plantilla) HMAC (código de autenticación de mensajes en clave hash): La plantilla hmac se puede redactar con cualquier implementación o algoritmo de SHA mediante hmac(<sha-alg>) o hmac(<sha-impl>).
stdrng drbg_pr_hmac_sha1, drbg_pr_hmac_sha256, drbg_pr_hmac_sha384 y drbg_pr_hmac_sha512 Se creó una instancia de HMAC_DRBG con la función hash con nombre y con la resistencia a la predicción habilitada: Se incluyen las verificaciones 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 y drbg_nopr_hmac_sha512 Igual que los algoritmos drbg_pr_*, pero con la resistencia a las predicciones inhabilitada. El código se comparte con la variante resistente a las predicciones. En la versión de kernel 5.10, el DRBG de mayor prioridad es drbg_nopr_hmac_sha256. En la versión de kernel 5.15 y posteriores, es drbg_pr_hmac_sha512.
jitterentropy_rng jitterentropy_rng No Jitter RNG, ya sea la versión 2.2.0 (kernel versión 6.1 y anterior) o versión 3.4.0 (kernel versión 6.6 y posterior) 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
xctr(aes) xctr-aes-neon, xctr-aes-ce No Solo está presente en la versión de kernel 5.15 y versiones 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

Compila el módulo a partir del código fuente

Para Android 14 y versiones posteriores (incluido android-mainline), compila el módulo fips140.ko desde la fuente con los siguientes comandos.

  • Compila con Bazel:

    tools/bazel run //common:fips140_dist
    
  • Compila 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 de resumen HMAC-SHA256 incorporado.

Orientación para usuarios finales

Guía para agentes criptográficos

Para operar el módulo de kernel, el sistema operativo debe estar restringido a un modo de operación de operador único. Android se encarga de esto automáticamente mediante 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 durante el inicio. Solo funciona en un modo de operación aprobado.

El oficial de criptografía puede hacer que las autopruebas se ejecuten en cualquier momento reiniciando el dispositivo.

Orientación para el usuario

El usuario del módulo del kernel son otros componentes del kernel que deben usar algoritmos criptográficos. El módulo de 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 con fines de cumplimiento del estándar FIPS se limita a algoritmos aprobados. Para cumplir con el requisito de "indicador de servicio" del FIPS 140-3, el módulo proporciona una función fips140_is_approved_service que indica si se aprobó un algoritmo.

Errores de autoprueba

En el caso de una falla en la autoprueba, el módulo del kernel provoca el pánico y el dispositivo no continúa con el proceso de inicio. Si reiniciar el dispositivo no resuelve el problema, este debe iniciarse en el modo de recuperación para corregir el problema volviendo a escribir en la memoria flash del dispositivo.


  1. Se espera que las implementaciones AES-GCM del módulo puedan estar "aprobadas por el algoritmo", pero no "aprobadas por el módulo". Pueden validarse, 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 IVs.