Funciones del maestro de llaves

Esta página proporciona detalles para ayudar a los implementadores de Keymaster Hardware Abstraction Layers (HAL). Cubre cada función en la API y en qué versión Keymaster está disponible esa función y describe la implementación predeterminada. Para las etiquetas, consulte la página Etiquetas de Keymaster .

Pautas generales de implementación

Las siguientes pautas se aplican a todas las funciones de la API.

Parámetros del puntero de entrada

Versión : 1, 2

Los parámetros del puntero de entrada que no se usan para una llamada determinada pueden ser NULL . La persona que llama no está obligada a proporcionar marcadores de posición. Por ejemplo, algunos tipos y modos de clave pueden no usar ningún valor del argumento inParams para comenzar , por lo que la persona que llama puede establecer inParams en NULL o proporcionar un conjunto de parámetros vacío. Las personas que llaman también pueden proporcionar parámetros no utilizados y los métodos Keymaster no deberían generar errores.

Si un parámetro de entrada requerido es NULL, los métodos Keymaster deben devolver ErrorCode::UNEXPECTED_NULL_POINTER .

A partir de Keymaster 3, no hay parámetros de puntero. Todos los parámetros se pasan por valor o referencias constantes.

Parámetros del puntero de salida

Versión : 1, 2

Al igual que los parámetros de puntero de entrada, los parámetros de puntero de salida no utilizados pueden ser NULL . Si un método necesita devolver datos en un parámetro de salida que es NULL , debe devolver ErrorCode::OUTPUT_PARAMETER_NULL .

A partir de Keymaster 3, no hay parámetros de puntero. Todos los parámetros se pasan por valor o referencias constantes.

mal uso de la API

Versión : 1, 2, 3

Hay muchas formas en que las personas que llaman pueden hacer solicitudes que no tienen sentido o que son tontas pero técnicamente no incorrectas. No es necesario que las implementaciones de Keymaster fallen en tales casos o emitan un diagnóstico. Las implementaciones no deben diagnosticar el uso de claves demasiado pequeñas, la especificación de parámetros de entrada irrelevantes, la reutilización de IV o nonces, la generación de claves sin propósito (por lo tanto, inútiles) y similares. Se debe diagnosticar la omisión de parámetros requeridos, la especificación de parámetros requeridos inválidos y errores similares.

Es responsabilidad de las aplicaciones, el marco y el almacén de claves de Android garantizar que las llamadas a los módulos Keymaster sean sensatas y útiles.

Funciones

getHardwareFeatures

Versión : 3

El nuevo método getHardwareFeatures expone a los clientes algunas características importantes del hardware seguro subyacente. El método no acepta argumentos y devuelve cuatro valores, todos booleanos:

  • isSecure es true si las claves se almacenan en hardware seguro (TEE, etc.) y nunca se abandonan.
  • supportsEllipticCurve es true si el hardware es compatible con la criptografía de curva elíptica con las curvas NIST (P-224, P-256, P-384 y P-521).
  • supportsSymmetricCryptography es true si el hardware admite criptografía simétrica, incluidos AES y HMAC.
  • supportsAttestation es true si el hardware admite la generación de certificados de atestación de clave pública Keymaster, firmados con una clave inyectada en un entorno seguro.

Los únicos códigos de error que puede devolver este método son ErrorCode:OK , ErrorCode::KEYMASTER_NOT_CONFIGURED o uno de los códigos de error que indica una falla en la comunicación con el hardware seguro.

getHardwareFeatures()
    generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
              bool supportsAttestation, bool supportsAllDigests, string keymasterName,
              string keymasterAuthorName);

configurar

Versión : 2

Esta función se introdujo en Keymaster 2 y quedó obsoleta en Keymaster 3, ya que esta información está disponible en los archivos de propiedades del sistema y las implementaciones del fabricante leen esos archivos durante el inicio.

Configura el maestro de llaves. Este método se llama una vez después de abrir el dispositivo y antes de usarlo. Se utiliza para proporcionar KM_TAG_OS_VERSION y KM_TAG_OS_PATCHLEVEL al maestro de claves. Hasta que se llame a este método, todos los demás métodos devuelven KM_ERROR_KEYMASTER_NOT_CONFIGURED . Keymaster solo acepta los valores proporcionados por este método una vez por arranque. Las llamadas posteriores devuelven KM_ERROR_OK , pero no hacen nada.

Si la implementación de keymaster está en hardware seguro y la versión del sistema operativo y los valores de nivel de parche proporcionados no coinciden con los valores proporcionados al hardware seguro por el cargador de arranque (o si el cargador de arranque no proporcionó valores), entonces este método devuelve KM_ERROR_INVALID_ARGUMENT y todos los demás los métodos continúan devolviendo KM_ERROR_KEYMASTER_NOT_CONFIGURED .

keymaster_error_t (*configure)(const struct keymaster2_device* dev,
                               const keymaster_key_param_set_t* params);

addRngEntropía

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como add_rng_entropy y se renombró en Keymaster 3.

Agrega entropía proporcionada por la persona que llama al grupo utilizado por la implementación de Keymaster 1 para generar números aleatorios, claves, IV, etc.

Las implementaciones de Keymaster deben mezclar de forma segura la entropía proporcionada en su grupo, que también debe contener entropía generada internamente a partir de un generador de números aleatorios de hardware. La combinación debe manejarse de modo que un atacante que tenga control total de los bits proporcionados por addRngEntropy o de los bits generados por hardware, pero no de ambos, no tenga una ventaja importante en la predicción de los bits generados a partir del grupo de entropía.

Las implementaciones de Keymaster que intentan estimar la entropía en su grupo interno asumen que los datos proporcionados por addRngEntropy no contienen entropía. Las implementaciones de Keymaster pueden devolver ErrorCode::INVALID_INPUT_LENGTH si reciben más de 2 KiB de datos en una sola llamada.

generar clave

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como generate_key y se renombró en Keymaster 3.

Genera una nueva clave criptográfica, especificando las autorizaciones asociadas, que están permanentemente vinculadas a la clave. Las implementaciones de Keymaster hacen que sea imposible usar una clave de cualquier manera que no sea compatible con las autorizaciones especificadas en el momento de la generación. Con respecto a las autorizaciones que el hardware seguro no puede hacer cumplir, la obligación del hardware seguro se limita a garantizar que las autorizaciones no ejecutables asociadas con la clave no puedan modificarse, de modo que cada llamada a getKeyCharacteristics devuelva el valor original. Además, las características devueltas por generateKey asignan las autorizaciones correctamente entre las listas forzadas por hardware y forzadas por software. Consulte getKeyCharacteristics para obtener más detalles.

Los parámetros proporcionados para generateKey dependen del tipo de clave que se genere. Esta sección resume las etiquetas necesarias y opcionales para cada tipo de llave. Tag::ALGORITHM siempre es necesario, para especificar el tipo.

Claves RSA

Los siguientes parámetros son necesarios para generar una clave RSA.

  • Tag::KEY_SIZE especifica el tamaño del módulo público, en bits. Si se omite, el método devuelve ErrorCode::UNSUPPORTED_KEY_SIZE . Los valores admitidos son 1024, 2048, 3072 y 4096. Los valores recomendados son todos los tamaños de clave que son múltiplos de 8.
  • Tag::RSA_PUBLIC_EXPONENT especifica el valor del exponente público de RSA. Si se omite, el método devuelve ErrorCode::INVALID_ARGUMENT . Los valores admitidos son 3 y 65537. Los valores recomendados son todos los valores primos hasta 2^64.

Los siguientes parámetros no son necesarios para generar una clave RSA, pero crear una clave RSA sin ellos produce una clave que no se puede utilizar. Sin embargo, la función generateKey no devuelve un error si se omiten estos parámetros.

  • Tag::PROPOSE especifica los propósitos permitidos. Todos los propósitos deben ser compatibles con las claves RSA, en cualquier combinación.
  • Tag::DIGEST especifica algoritmos de resumen que se pueden usar con la nueva clave. Las implementaciones que no admiten todos los algoritmos de resumen deben aceptar solicitudes de generación de claves que incluyan resúmenes no admitidos. Los resúmenes no admitidos deben colocarse en la lista "aplicada por software" en las características clave devueltas. Esto se debe a que la clave se puede usar con esos otros resúmenes, pero el resúmen se realiza en el software. Luego se llama al hardware para realizar la operación con Digest::NONE .
  • Tag::PADDING especifica los modos de relleno que se pueden usar con la nueva clave. Las implementaciones que no admiten todos los algoritmos de resumen deben colocar PaddingMode::RSA_PSS y PaddingMode::RSA_OAEP en la lista de características clave aplicada por software si se especifica algún algoritmo de resumen no compatible.

Claves ECDSA

Solo Tag::KEY_SIZE es necesario para generar una clave ECDSA. Se utiliza para seleccionar el grupo EC. Los valores admitidos son 224, 256, 384 y 521, que indican las curvas NIST p-224, p-256, p-384 y p521, respectivamente.

Tag::DIGEST también es necesario para una clave ECDSA útil, pero no se requiere para la generación.

claves AES

Solo Tag::KEY_SIZE es necesario para generar una clave AES. Si se omite, el método devuelve ErrorCode::UNSUPPORTED_KEY_SIZE . Los valores admitidos son 128 y 256, con compatibilidad opcional para claves AES de 192 bits.

Los siguientes parámetros son particularmente relevantes para las claves AES, pero no son necesarios para generar una:

  • Tag::BLOCK_MODE especifica los modos de bloque con los que se puede usar la nueva clave.
  • Tag::PADDING especifica los modos de relleno que se pueden usar. Esto solo es relevante para los modos ECB y CBC.

Si se especifica el modo de bloque GCM, proporcione Tag::MIN_MAC_LENGTH . Si se omite, el método devuelve ErrorCode::MISSING_MIN_MAC_LENGTH . El valor de la etiqueta es un múltiplo de 8 y entre 96 y 128.

Claves HMAC

Los siguientes parámetros son necesarios para la generación de claves HMAC:

  • Tag::KEY_SIZE especifica el tamaño de la clave en bits. No se admiten valores inferiores a 64 ni valores que no sean múltiplos de 8. Se admiten todos los múltiplos de 8, desde 64 hasta 512. Es posible que se admitan valores mayores.
  • Tag::MIN_MAC_LENGTH especifica la longitud mínima de MAC que se pueden generar o verificar con esta clave. El valor es un múltiplo de 8 y al menos 64.
  • Tag::DIGEST especifica el algoritmo de resumen para la clave. Se especifica exactamente un resumen; de lo contrario, devuelve ErrorCode::UNSUPPORTED_DIGEST . Si el resumen no es compatible con el trustlet, devuelva ErrorCode::UNSUPPORTED_DIGEST .

Caracteristicas claves

Si el argumento de características no es NULL, generateKey devuelve las características de la clave recién generada divididas adecuadamente en listas forzadas por hardware y forzadas por software. Consulte getKeyCharacteristics para obtener una descripción de qué características van en qué lista. Las características devueltas incluyen todos los parámetros especificados para la generación de claves, excepto Tag::APPLICATION_ID y Tag::APPLICATION_DATA . Si estas etiquetas se incluyeron en los parámetros clave, se eliminan de las características devueltas para que no sea posible encontrar sus valores examinando el blob de clave devuelto. Sin embargo, están vinculados criptográficamente al blob de claves, de modo que si no se proporcionan los valores correctos cuando se usa la clave, el uso falla. De manera similar, Tag::ROOT_OF_TRUST está vinculado criptográficamente a la clave, pero no se puede especificar durante la creación o importación de la clave y nunca se devuelve.

Además de las etiquetas proporcionadas, el trustlet también agrega Tag::ORIGIN , con el valor KeyOrigin::GENERATED , y si la clave es resistente a la reversión,

Etiqueta::ROLLBACK_RESISTANT .

resistencia al retroceso

La resistencia a la reversión significa que una vez que se elimina una clave con deleteKey o deleteAllKeys , el hardware seguro garantiza que nunca se podrá volver a utilizar. Las implementaciones sin resistencia a la reversión generalmente devuelven material de claves generado o importado a la persona que llama como un blob de claves, una forma cifrada y autenticada. Cuando el almacén de claves elimina el blob de claves, la clave desaparece, pero un atacante que haya logrado recuperar previamente el material de la clave puede potencialmente restaurarla en el dispositivo.

Una clave es resistente a la reversión si el hardware seguro garantiza que las claves eliminadas no se pueden restaurar más tarde. Esto generalmente se hace almacenando metadatos clave adicionales en una ubicación confiable que un atacante no puede manipular. En los dispositivos móviles, el mecanismo utilizado para esto suele ser Replay Protected Memory Blocks (RPMB). Debido a que la cantidad de claves que se pueden crear es esencialmente ilimitada y el almacenamiento de confianza utilizado para la resistencia a la reversión puede tener un tamaño limitado, este método debe tener éxito incluso si no se puede proporcionar la resistencia a la reversión para la nueva clave. En ese caso, Tag::ROLLBACK_RESISTANT no debe agregarse a las características clave.

getKeyCharacteristics

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como get_key_characteristics y se renombró en Keymaster 3.

Devuelve los parámetros y las autorizaciones asociados con la clave proporcionada, divididos en dos conjuntos: forzados por hardware y forzados por software. La descripción aquí se aplica igualmente a las listas de características clave devueltas por generateKey e importKey .

Si se proporcionó Tag::APPLICATION_ID durante la generación o importación de claves, se proporciona el mismo valor a este método en el argumento clientId . De lo contrario, el método devuelve ErrorCode::INVALID_KEY_BLOB . De manera similar, si se proporcionó Tag::APPLICATION_DATA durante la generación o la importación, se proporciona el mismo valor a este método en el argumento appData .

Las características devueltas por este método describen completamente el tipo y uso de la clave especificada.

La regla general para decidir si una etiqueta determinada pertenece a la lista aplicada por hardware o por software es que si el hardware seguro asegura completamente el significado de la etiqueta, se aplica por hardware. De lo contrario, se aplica el software. A continuación se muestra una lista de etiquetas específicas cuya asignación correcta puede no estar clara:

  • Tag ::ALGORITHM , Tag::KEY_SIZE y Tag::RSA_PUBLIC_EXPONENT son propiedades intrínsecas de la clave. Para cualquier clave que esté protegida por hardware, estas etiquetas estarán en la lista forzada por hardware.
  • Tag::Los valores DIGEST que son compatibles con el hardware seguro se colocan en la lista de hardware compatible. Los resúmenes no admitidos van en la lista de software admitido.
  • Los valores Tag::PADDING generalmente van en la lista compatible con hardware, a menos que exista la posibilidad de que el software deba realizar un modo de relleno específico. En ese caso, van en la lista de programas forzados. Esta posibilidad surge para las claves RSA que permiten el relleno de PSS u OAEP con algoritmos de resumen que no son compatibles con el hardware seguro.
  • Tag::USER_SECURE_ID y Tag::USER_AUTH_TYPE se aplican por hardware solo si la autenticación de usuario se aplica por hardware. Para lograr esto, el fideicomiso Keymaster y el fideicomiso de autenticación relevante deben ser seguros y compartir una clave HMAC secreta que se utiliza para firmar y validar tokens de autenticación. Vea la página de Autenticación para más detalles.
  • Las etiquetas Tag::ACTIVE_DATETIME , Tag:: ORIGINATION_EXPIRE_DATETIME y Tag::USAGE_EXPIRE_DATETIME requieren acceso a un reloj de pared correcto verificable. La mayoría del hardware seguro solo tiene acceso a la información de tiempo proporcionada por el sistema operativo no seguro, lo que significa que las etiquetas se aplican mediante software.
  • Tag::ORIGIN siempre está en la lista de hardware para claves vinculadas al hardware. Su presencia en esa lista es la forma en que las capas superiores determinan que una clave está respaldada por hardware.

Importar clave

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como import_key y se renombró en Keymaster 3.

Importa material clave al hardware Keymaster. Los parámetros de definición de clave y las características de salida se manejan de la misma manera que para generateKey , con las siguientes excepciones:

  • Tag::KEY_SIZE y Tag::RSA_PUBLIC_EXPONENT (solo para claves RSA) no son necesarios en los parámetros de entrada. Si no se proporciona, el trustlet deduce los valores del material clave proporcionado y agrega etiquetas y valores apropiados a las características clave. Si se proporcionan los parámetros, el trustlet los valida contra el material clave. En caso de discrepancia, el método devuelve ErrorCode::IMPORT_PARAMETER_MISMATCH .
  • El Tag::ORIGIN devuelto tiene el mismo valor que KeyOrigin::IMPORTED .

clave de exportación

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como export_key y se renombró en Keymaster 3.

Exporta una clave pública de un par de claves Keymaster RSA o EC.

Si se proporcionó Tag::APPLICATION_ID durante la generación o importación de claves, se proporciona el mismo valor a este método en el argumento clientId . De lo contrario, el método devuelve ErrorCode::INVALID_KEY_BLOB . De manera similar, si se proporcionó Tag::APPLICATION_DATA durante la generación o la importación, se proporciona el mismo valor a este método en el argumento appData .

borrar clave

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como delete_key y se renombró en Keymaster 3.

Elimina la clave proporcionada. Este método es opcional y solo lo implementan los módulos Keymaster que proporcionan resistencia a la reversión.

eliminarTodasLasClaves

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como delete_all_keys y se renombró en Keymaster 3.

Elimina todas las claves. Este método es opcional y solo lo implementan los módulos Keymaster que proporcionan resistencia a la reversión.

destroyAttestationIds

Versión : 3

El método destroyAttestationIds() se usa para deshabilitar permanentemente la nueva función de certificación de ID (opcional, pero muy recomendable). Si el TEE no tiene forma de garantizar que la atestación de ID esté deshabilitada permanentemente después de llamar a este método, entonces la atestación de ID no debe implementarse en absoluto, en cuyo caso este método no hace nada y devuelve ErrorCode::UNIMPLEMENTED . Si se admite la atestación de ID, este método debe implementarse y debe deshabilitarse permanentemente todos los intentos futuros de atestación de ID. El método se puede llamar cualquier número de veces. Si la atestación de ID ya está deshabilitada de forma permanente, el método no hace nada y devuelve ErrorCode::OK .

Los únicos códigos de error que puede devolver este método son ErrorCode::UNIMPLEMENTED (si no se admite la atestación de ID), ErrorCode:OK , ErrorCode::KEYMASTER_NOT_CONFIGURED o uno de los códigos de error que indica una falla en la comunicación con el hardware seguro.

empezar

Versión : 1, 2, 3

Comienza una operación criptográfica, usando la clave especificada, para el propósito especificado, con los parámetros especificados (según corresponda) y devuelve un identificador de operación que se usa con actualizar y finalizar para completar la operación. El identificador de operación también se usa como el token de "desafío" en las operaciones autenticadas, y para tales operaciones se incluye en el campo de challenge del token de autenticación.

Una implementación de Keymaster admite al menos 16 operaciones simultáneas. Keystore usa hasta 15, dejando uno para que vold lo use para el cifrado de contraseña. Cuando Keystore tiene 15 operaciones en curso (se ha llamado a begin , pero aún no se ha llamado a finish o abort ) y recibe una solicitud para comenzar una 16, llama a abort en la operación utilizada menos recientemente para reducir la cantidad de operaciones activas a 14 antes de begin a llamar para iniciar la operación recién solicitada.

Si Tag::APPLICATION_ID o Tag::APPLICATION_DATA se especificaron durante la generación o importación de claves, las llamadas para begin incluyen esas etiquetas con los valores especificados originalmente en el argumento inParams de este método.

Cumplimiento de la autorización

Durante este método, el trustlet aplica las siguientes autorizaciones clave si la implementación las colocó en las características "aplicadas por hardware" y si la operación no es una operación de clave pública. Las operaciones de clave pública, es decir, KeyPurpose::ENCRYPT y KeyPurpose::VERIFY , con claves RSA o EC, pueden tener éxito incluso si no se cumplen los requisitos de autorización.

  • Tag::PROPOSE : El propósito especificado en la llamada begin() tiene que coincidir con uno de los propósitos en las autorizaciones de clave, a menos que la operación solicitada sea una operación de clave pública. Si el propósito especificado no coincide y la operación no es una operación de clave pública, begin devolverá ErrorCode::UNSUPPORTED_PURPOSE . Las operaciones de clave pública son operaciones asimétricas de encriptación o verificación.
  • Tag::ACTIVE_DATETIME solo se puede aplicar si hay disponible una fuente horaria UTC de confianza. Si la fecha y la hora actuales son anteriores al valor de la etiqueta, el método devuelve ErrorCode::KEY_NOT_YET_VALID .
  • Tag::ORIGINATION_EXPIRE_DATETIME solo se puede aplicar si hay disponible una fuente horaria UTC de confianza. Si la fecha y la hora actuales son posteriores al valor de la etiqueta y el propósito es KeyPurpose::ENCRYPT o KeyPurpose::SIGN , el método devuelve ErrorCode::KEY_EXPIRED .
  • Tag::USAGE_EXPIRE_DATETIME solo se puede aplicar si hay disponible una fuente horaria UTC de confianza. Si la fecha y la hora actuales son posteriores al valor de la etiqueta y el propósito es KeyPurpose::DECRYPT o KeyPurpose::VERIFY , el método devuelve ErrorCode::KEY_EXPIRED .
  • Tag::MIN_SECONDS_BETWEEN_OPS se compara con un temporizador relativo de confianza que indica el último uso de la clave. Si la hora del último uso más el valor de la etiqueta es menor que la hora actual, el método devuelve ErrorCode::KEY_RATE_LIMIT_EXCEEDED . Consulte la descripción de la etiqueta para obtener detalles importantes de implementación.
  • Tag::MAX_USES_PER_BOOT se compara con un contador seguro que rastrea los usos de la clave desde el momento del arranque. Si el recuento de usos anteriores supera el valor de la etiqueta, el método devuelve ErrorCode::KEY_MAX_OPS_EXCEEDED .
  • Este método aplica Tag::USER_SECURE_ID solo si la clave también tiene Tag::AUTH_TIMEOUT . Si la clave tiene ambos, este método debe recibir un Tag::AUTH_TOKEN válido en inParams . Para que el token de autenticación sea válido, todo lo siguiente debe ser cierto:
    • El campo HMAC se valida correctamente.
    • Al menos uno de los valores Tag::USER_SECURE_ID de la clave coincide con al menos uno de los valores de ID seguro en el token.
    • La clave tiene una etiqueta::USER_AUTH_TYPE que coincide con el tipo de autenticación en el token.

    Si alguna de estas condiciones no se cumple, el método devuelve ErrorCode::KEY_USER_NOT_AUTHENTICATED .

  • Tag::CALLER_NONCE permite a la persona que llama especificar un nonce o vector de inicialización (IV). Si la clave no tiene esta etiqueta, pero la persona que llama proporcionó Tag::NONCE a este método, se devuelve ErrorCode::CALLER_NONCE_PROHIBITED .
  • Tag::BOOTLOADER_ONLY especifica que solo el cargador de arranque puede usar la clave. Si se llama a este método con una clave solo del cargador de arranque después de que el cargador de arranque haya terminado de ejecutarse, devuelve ErrorCode::INVALID_KEY_BLOB .

Claves RSA

Todas las operaciones de clave RSA especifican exactamente un modo de relleno en inParams . Si no se especifica o se especifica más de una vez, el método devuelve ErrorCode::UNSUPPORTED_PADDING_MODE .

Las operaciones de firma y verificación de RSA necesitan un resumen, al igual que las operaciones de cifrado y descifrado de RSA con el modo de relleno OAEP. Para esos casos, la persona que llama especifica exactamente un resumen en inParams . Si no se especifica o se especifica más de una vez, el método devuelve ErrorCode::UNSUPPORTED_DIGEST .

Las operaciones de clave privada ( KeyPurpose::DECYPT y KeyPurpose::SIGN ) necesitan autorización de resumen y relleno, lo que significa que las autorizaciones de clave deben contener los valores especificados. De lo contrario, el método devuelve ErrorCode::INCOMPATIBLE_DIGEST o ErrorCode::INCOMPATIBLE_PADDING , según corresponda. Las operaciones de clave pública ( KeyPurpose::ENCRYPT y KeyPurpose::VERIFY ) están permitidas con resumen o relleno no autorizados.

Con la excepción de PaddingMode::NONE , todos los modos de relleno de RSA se aplican solo para ciertos fines. Específicamente, PaddingMode::RSA_PKCS1_1_5_SIGN y PaddingMode::RSA_PSS solo admiten firma y verificación, mientras que PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT y PaddingMode::RSA_OAEP solo admiten cifrado y descifrado. El método devuelve ErrorCode::UNSUPPORTED_PADDING_MODE si el modo especificado no es compatible con el propósito especificado.

Hay algunas interacciones importantes entre los modos de relleno y los resúmenes:

  • PaddingMode::NONE indica que se realiza una operación RSA "sin procesar". Si firma o verifica, se especifica Digest::NONE para el resumen. No se necesita resumen para el cifrado o descifrado sin relleno.
  • PaddingMode::RSA_PKCS1_1_5_SIGN relleno requiere un resumen. El resumen puede ser Digest::NONE , en cuyo caso la implementación de Keymaster no puede crear una estructura de firma PKCS#1 v1.5 adecuada, porque no puede agregar la estructura DigestInfo. En su lugar, la implementación construye 0x00 || 0x01 || PS || 0x00 || M , donde M es el mensaje proporcionado y PS es la cadena de relleno. El tamaño de la clave RSA debe ser al menos 11 bytes más grande que el mensaje; de ​​lo contrario, el método devuelve ErrorCode::INVALID_INPUT_LENGTH .
  • PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT relleno no requiere un resumen.
  • El relleno PaddingMode::RSA_PSS requiere un resumen, que puede no ser Digest::NONE . Si se especifica Digest::NONE , el método devuelve ErrorCode::INCOMPATIBLE_DIGEST . Además, el tamaño de la clave RSA debe ser al menos 2 + D bytes mayor que el tamaño de salida del resumen, donde D es el tamaño del resumen, en bytes. De lo contrario, el método devuelve ErrorCode::INCOMPATIBLE_DIGEST . El tamaño de la sal es D.
  • El relleno PaddingMode::RSA_OAEP requiere un resumen, que puede no ser Digest::NONE . Si se especifica Digest::NONE , el método devuelve ErrorCode::INCOMPATIBLE_DIGEST .

claves CE

Las operaciones de tecla EC especifican exactamente un modo de relleno en inParams . Si no se especifica o se especifica más de una vez, el método devuelve ErrorCode::UNSUPPORTED_PADDING_MODE .

Las operaciones de clave privada ( KeyPurpose::SIGN ) necesitan autorización de resumen y relleno, lo que significa que las autorizaciones de clave deben contener los valores especificados. Si no, devuelve ErrorCode::INCOMPATIBLE_DIGEST . Las operaciones de clave pública ( KeyPurpose::VERIFY ) están permitidas con resumen o relleno no autorizados.

claves AES

Las operaciones de tecla AES especifican exactamente un modo de bloque y un modo de relleno en inParams . Si alguno de los valores no se especifica o se especifica más de una vez, devuelve ErrorCode::UNSUPPORTED_BLOCK_MODE o ErrorCode::UNSUPPORTED_PADDING_MODE . Los modos especificados deben estar autorizados por la clave, de lo contrario, el método devuelve ErrorCode::INCOMPATIBLE_BLOCK_MODE o ErrorCode::INCOMPATIBLE_PADDING_MODE .

Si el modo de bloque es BlockMode::GCM , inParams especifica Tag::MAC_LENGTH , y el valor especificado es un múltiplo de 8 que no es mayor que 128 ni menor que el valor de Tag::MIN_MAC_LENGTH en las autorizaciones de claves. Para longitudes de MAC superiores a 128 o que no sean múltiplos de 8, devuelve ErrorCode::UNSUPPORTED_MAC_LENGTH . Para valores inferiores a la longitud mínima de la clave, devuelve ErrorCode::INVALID_MAC_LENGTH .

Si el modo de bloque es BlockMode::GCM o BlockMode::CTR , el modo de relleno especificado debe ser PaddingMode::NONE . Para BlockMode::ECB o BlockMode::CBC , el modo puede ser PaddingMode::NONE o PaddingMode::PKCS7 . Si el modo de relleno no cumple con estas condiciones, devuelve ErrorCode::INCOMPATIBLE_PADDING_MODE .

Si el modo de bloque es BlockMode::CBC , BlockMode::CTR o BlockMode::GCM , se necesita un vector de inicialización o nonce. En la mayoría de los casos, las personas que llaman no deben proporcionar un IV o un nonce. En ese caso, la implementación de Keymaster genera un IV o nonce aleatorio y lo devuelve a través de Tag::NONCE en outParams . Los CBC y CTR IV tienen 16 bytes. Los nonces GCM son 12 bytes. Si las autorizaciones clave contienen Tag::CALLER_NONCE , la persona que llama puede proporcionar un IV/nonce con Tag::NONCE en inParams . Si se proporciona un nonce cuando Tag::CALLER_NONCE no está autorizado, devuelve ErrorCode::CALLER_NONCE_PROHIBITED . Si no se proporciona un nonce cuando Tag::CALLER_NONCE está autorizado, genere un IV/nonce aleatorio.

Claves HMAC

Las operaciones clave de HMAC especifican Tag::MAC_LENGTH en inParams . El valor especificado debe ser un múltiplo de 8 que no sea mayor que la longitud del resumen ni menor que el valor de Tag::MIN_MAC_LENGTH en las autorizaciones de clave. Para longitudes de MAC mayores que la longitud del resumen o no múltiplos de 8, devuelve ErrorCode::UNSUPPORTED_MAC_LENGTH . Para valores inferiores a la longitud mínima de la clave, devuelve ErrorCode::INVALID_MAC_LENGTH .

actualizar

Versión : 1, 2, 3

Proporciona datos para procesar en una operación en curso iniciada con begin . La operación se especifica mediante el parámetro operationHandle .

Para proporcionar más flexibilidad para el manejo del búfer, las implementaciones de este método tienen la opción de consumir menos datos de los proporcionados. La persona que llama es responsable del bucle para alimentar el resto de los datos en llamadas posteriores. La cantidad de entrada consumida se devuelve en el parámetro inputConsumed . Las implementaciones siempre consumen al menos un byte, a menos que la operación no pueda aceptar más; si se proporcionan más de cero bytes y se consumen cero bytes, las personas que llaman lo consideran un error y anulan la operación.

Las implementaciones también pueden elegir cuántos datos devolver como resultado de la actualización. Esto solo es relevante para las operaciones de cifrado y descifrado, porque la firma y la verificación no devuelven datos hasta que finaliza . Devuelva los datos lo antes posible, en lugar de almacenarlos en un búfer.

Manejo de errores

Si este método devuelve un código de error que no sea ErrorCode::OK , la operación se cancela y el identificador de la operación se invalida. Cualquier uso futuro del identificador, con este método, finish o abort , devuelve ErrorCode::INVALID_OPERATION_HANDLE .

Cumplimiento de la autorización

La aplicación de la autorización de clave se realiza principalmente en begin . La única excepción es el caso en que la clave tiene:

En este caso, la clave requiere una autorización por operación y el método de actualización recibe un Tag::AUTH_TOKEN en el argumento inParams . HMAC verifica que el token sea válido y contenga un ID de usuario seguro coincidente, coincida con la etiqueta de la clave ::USER_AUTH_TYPE y contenga el identificador de operación de la operación actual en el campo de desafío. Si no se cumplen estas condiciones, devuelve ErrorCode::KEY_USER_NOT_AUTHENTICATED .

La persona que llama proporciona el token de autenticación a cada llamada para actualizar y finalizar . La implementación solo necesita validar el token una vez si lo prefiere.

Claves RSA

Para las operaciones de firma y verificación con Digest::NONE , este método acepta que todo el bloque sea firmado o verificado en una sola actualización. No puede consumir solo una parte del bloque. Sin embargo, si la persona que llama elige proporcionar los datos en varias actualizaciones, este método lo acepta. Si la persona que llama proporciona más datos para firmar de los que se pueden usar (la longitud de los datos excede el tamaño de la clave RSA), devuelve ErrorCode::INVALID_INPUT_LENGTH .

Claves ECDSA

Para las operaciones de firma y verificación con Digest::NONE , este método acepta que todo el bloque sea firmado o verificado en una sola actualización. Este método no puede consumir solo una parte del bloque.

Sin embargo, si la persona que llama elige proporcionar los datos en varias actualizaciones, este método lo acepta. Si la persona que llama proporciona más datos para firmar de los que se pueden usar, los datos se truncan silenciosamente. (Esto difiere del manejo del exceso de datos proporcionado en operaciones RSA similares. La razón de esto es la compatibilidad con clientes heredados).

claves AES

El modo AES GCM admite "datos de autenticación asociados", proporcionados a través de la etiqueta Tag::ASSOCIATED_DATA en el argumento inParams . Los datos asociados se pueden proporcionar en llamadas repetidas (importante si los datos son demasiado grandes para enviarlos en un solo bloque), pero siempre preceden a los datos que se cifrarán o descifrarán. Una llamada de actualización puede recibir datos asociados y datos para cifrar/descifrar, pero es posible que las actualizaciones posteriores no incluyan datos asociados. Si la persona que llama proporciona datos asociados a una llamada de actualización después de una llamada que incluye datos para cifrar/descifrar, devuelve ErrorCode::INVALID_TAG .

Para el cifrado GCM, la etiqueta se agrega al texto cifrado mediante finish . Durante el descifrado, el último Tag::MAC_LENGTH bytes de los datos proporcionados a la última llamada de actualización es la etiqueta. Dado que una invocación dada de actualización no puede saber si es la última invocación, procesa todo menos la longitud de la etiqueta y almacena en búfer los posibles datos de la etiqueta durante finish .

finalizar

Versión : 1, 2, 3

Finishes an ongoing operation started with begin , processing all of the as-yet-unprocessed data provided by update (s).

This method is the last one called in an operation, so all processed data is returned.

Whether it completes successfully or returns an error, this method finalizes the operation and therefore invalidates the provided operation handle. Any future use of the handle, with this method or update or abort , returns ErrorCode::INVALID_OPERATION_HANDLE .

Signing operations return the signature as the output. Verification operations accept the signature in the signature parameter, and return no output.

Authorization enforcement

Key authorization enforcement is performed primarily in begin . The one exception is the case where the key has:

In this case, the key requires an authorization per operation, and the update method receives a Tag::AUTH_TOKEN in the inParams argument. HMAC verifies that the token is valid and contains a matching secure user ID, matches the key's Tag::USER_AUTH_TYPE , and contains the operation handle of the current operation in the challenge field. If these conditions aren't met, return ErrorCode::KEY_USER_NOT_AUTHENTICATED .

The caller provides the authentication token to every call to update and finish . The implementation need only validate the token once if it prefers.

RSA keys

Some additional requirements, depending on the padding mode:

  • PaddingMode::NONE . For unpadded signing and encryption operations, if the provided data is shorter than the key, the data is be zero-padded on the left before signing/encryption. If the data is the same length as the key, but numerically larger, return ErrorCode::INVALID_ARGUMENT . For verification and decryption operations, the data must be exactly as long as the key. Otherwise, return ErrorCode::INVALID_INPUT_LENGTH.
  • PaddingMode::RSA_PSS . For PSS-padded signature operations, the PSS salt is at least 20 bytes in length and randomly generated. The salt may be longer; the reference implementation uses maximally sized salt. The digest specified with Tag::DIGEST in inputParams on begin is used as the PSS digest algorithm, and SHA1 is used as the MGF1 digest algorithm.
  • PaddingMode::RSA_OAEP . The digest specified with Tag::DIGEST in inputParams on begin is used as the OAEP digest algorithm, and SHA1 is used as the MGF1 digest algorithm.

ECDSA keys

If the data provided for unpadded signing or verification is too long, truncate it.

AES keys

Some additional conditions, depending on block mode:

  • BlockMode::ECB or BlockMode::CBC . If padding is PaddingMode::NONE and the data length is not a multiple of the AES block size, return ErrorCode::INVALID_INPUT_LENGTH . If padding is PaddingMode::PKCS7 , pad the data per the PKCS#7 specification. Note that PKCS#7 recommends adding an additional padding block if the data is a multiple of the block length.
  • BlockMode::GCM . During encryption, after processing all plaintext, compute the tag ( Tag::MAC_LENGTH bytes) and append it to the returned ciphertext. During decryption, process the last Tag::MAC_LENGTH bytes as the tag. If tag verification fails, return ErrorCode::VERIFICATION_FAILED .

abort

Version : 1, 2, 3

Aborts the in-progress operation. After the call to abort, return ErrorCode::INVALID_OPERATION_HANDLE for any subsequent use of the provided operation handle with update , finish , or abort .

get_supported_algorithms

Version : 1

Returns the list of algorithms supported by the Keymaster hardware implementation. A software implementation returns an empty list; a hybrid implementation returns a list containing only the algorithms that are supported by hardware.

Keymaster 1 implementations support RSA, EC, AES and HMAC.

get_supported_block_modes

Version : 1

Returns the list of AES block modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

For RSA, EC and HMAC, which are not block ciphers, the method returns an empty list for all valid purposes. Invalid purposes should cause the method to return ErrorCode::INVALID_PURPOSE .

Keymaster 1 implementations support ECB, CBC, CTR and GCM for AES encryption and decryption.

get_supported_padding_modes

Version : 1

Returns the list of padding modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

HMAC and EC have no notion of padding so the method returns an empty list for all valid purposes. Invalid purposes should cause the method to return ErrorCode::INVALID_PURPOSE .

For RSA, Keymaster 1 implementations support:

  • Unpadded encryption, decryption, signing and verification. For unpadded encryption and signing, if the message is shorter than the public modulus, implementations must left-pad it with zeros. For unpadded decryption and verification, the input length must match the public modulus size.
  • PKCS#1 v1.5 encryption and signing padding modes
  • PSS with a minimum salt length of 20
  • OAEP

For AES in ECB and CBC modes, Keymaster 1 implementations support no padding and PKCS#7-padding. CTR and GCM modes support only no padding.

get_supported_digests

Version : 1

Returns the list of digest modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

No AES modes support or require digesting, so the method returns an empty list for valid purposes.

Keymaster 1 implementations can implement a subset of the defined digests. Implementations provide SHA-256 and can provide MD5, SHA1, SHA-224, SHA-256, SHA384 and SHA512 (the full set of defined digests).

get_supported_import_formats

Version : 1

Returns the list of import formats supported by the Keymaster hardware implementation of a specified algorithm.

Keymaster 1 implementations support the PKCS#8 format (without password protection) for importing RSA and EC key pairs, and support RAW import of AES and HMAC key material.

get_supported_export_formats

Version : 1

Returns the list of export formats supported by the Keymaster hardware implementation of a specified algorithm.

Keymaster1 implementations support the X.509 format for exporting RSA and EC public keys. Export of private keys or asymmetric keys is not supported.

Historical functions

Keymaster 0

The following functions belong to the original Keymaster 0 definition. They were present in Keymaster 1 struct keymaster1_device_t. However, in Keymaster 1.0 they were not implemented, and their function pointers were set to NULL.

  • generate_keypair
  • import_keypair
  • get_keypair_public
  • delete_keypair
  • delete_all
  • sign_data
  • Verify_data

Keymaster 1

The following functions belong to the Keymaster 1 definition, but were removed in Keymaster 2, along with the Keymaster 0 functions listed above.

  • get_supported_algorithms
  • get_supported_block_modes
  • get_supported_padding_modes
  • get_supported_digests
  • get_supported_import_formats
  • get_supported_export_formats

Keymaster 2

The following functions belong to the Keymaster 2 definition, but were removed in Keymaster 3, along with the Keymaster 1 functions listed above.

  • configure