Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.
此页面由 Cloud Translation API 翻译。
Switch to English

Funciones de Keymaster

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

Directrices generales de implementación

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

Parámetros de puntero de entrada

Versión : 1, 2

Los parámetros de puntero de entrada que no se utilizan para una llamada determinada pueden ser NULL . La persona que llama no está obligada a proporcionar marcadores de posición. Por ejemplo, es posible que algunos tipos y modos de clave no usen 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 de Keymaster no deberían generar errores.

Si un parámetro de entrada requerido es NULL, los métodos de 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 de puntero de salida

Versión : 1, 2

De forma similar a los parámetros del puntero de entrada, los parámetros del puntero de salida no utilizados pueden ser NULL . Si un método necesita devolver datos en un parámetro de salida que se encuentra como NULL , debería 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 API

Versión : 1, 2, 3

Hay muchas formas en que las personas que llaman pueden realizar solicitudes que no tienen sentido o que son tontas pero no técnicamente incorrectas. No es necesario que las implementaciones de Keymaster fallen en tales casos o emitan un diagnóstico. El uso de claves demasiado pequeñas, la especificación de parámetros de entrada irrelevantes, la reutilización de IVs o nonces, la generación de claves sin propósito (por lo tanto, inútiles) y similares no deben ser diagnosticadas por implementaciones. Se debe diagnosticar la omisión de parámetros obligatorios, la especificación de parámetros obligatorios no vá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 de 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 toma argumentos y devuelve cuatro valores, todos booleanos:

  • isSecure es true si las claves se almacenan en hardware seguro (TEE, etc.) y nunca lo dejan.
  • 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, incluidas AES y HMAC.
  • supportsAttestation es true si el hardware admite la generación de certificados de atestación de clave pública de 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 indican 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 en desuso 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 keymaster. 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 keymaster. 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);

addRngEntropy

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, para claves, IV, etc.

Las implementaciones de Keymaster necesitan 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 mezcla debe manejarse de manera que un atacante que tenga el control completo de los bits proporcionados por addRngEntropy o de los bits generados por hardware, pero no de ambos, no tenga una ventaja nada despreciable 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.

generateKey

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 vinculadas permanentemente a la clave. Las implementaciones de Keymaster hacen que sea imposible utilizar una clave de alguna 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 exigibles asociadas con la clave no se puedan modificar, 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 aplicadas por hardware y por software. Consulte getKeyCharacteristics para obtener más detalles.

Los parámetros proporcionados para generateKey dependen del tipo de clave que se genera. Esta sección resume las etiquetas necesarias y opcionales para cada tipo de clave. 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 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 :: PURPOSE especifica los propósitos permitidos. Todos los propósitos deben ser compatibles con las claves RSA, en cualquier combinación.
  • Tag :: DIGEST especifica los algoritmos de resumen que pueden usarse con la nueva clave. Las implementaciones que no son compatibles con 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 "impuesta por software" en las características clave devueltas. Esto se debe a que la clave se puede utilizar con esos otros resúmenes, pero la descomposición se realiza en software. Entonces 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 admitido.

Claves ECDSA

Solo se necesita Tag :: KEY_SIZE 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 p-224, p-256, p-384 y p521 del NIST, respectivamente.

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

Claves AES

Solo se necesita Tag :: KEY_SIZE para generar una clave AES. Si se omite, el método devuelve ErrorCode::UNSUPPORTED_KEY_SIZE . Los valores admitidos son 128 y 256, con soporte 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 utilizar la nueva clave.
  • Tag::PADDING especifica los modos de relleno que se pueden utilizar. Esto solo es relevante para los modos ECB y CBC.

Si se especifica el modo de bloque GCM, proporcione la etiqueta :: 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 está entre 96 y 128.

Llaves 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 y valores que no sean múltiplos de 8. Se admiten todos los múltiplos de 8, de 64 a 512. Es posible que se admitan valores más grandes.
  • 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 las características no es NULL, generateKey devuelve las características de la clave recién generada divididas adecuadamente en listas aplicadas por hardware y 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 claves 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 es posible que no se especifique 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 volverá a utilizar. Las implementaciones sin resistencia a la reversión generalmente devuelven el material de claves generado o importado a la persona que llama como un blob de claves, un formulario encriptado y autenticado. Cuando el almacén de claves elimina el blob de claves, la clave desaparece, pero un atacante que haya logrado recuperar el material de claves puede potencialmente restaurarlo 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 pueda manipular. En los dispositivos móviles, el mecanismo utilizado para esto suele ser la reproducción de bloques de memoria protegidos (RPMB). Debido a que la cantidad de claves que se pueden crear es esencialmente ilimitada y el almacenamiento confiable 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 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 autorizaciones asociados con la clave proporcionada, divididos en dos conjuntos: reforzados por hardware y 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 la clave, 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 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 impuesta por hardware o por software es que si el significado de la etiqueta está completamente asegurado por hardware seguro, es impuesta 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 impuesta por hardware.
  • Etiqueta :: Los valores DIGEST que son compatibles con el hardware seguro se colocan en la lista compatible con hardware. Los resúmenes no admitidos se incluyen en la lista de programas admitidos.
  • Los valores de Tag :: PADDING generalmente van en la lista de soporte de hardware, a menos que exista la posibilidad de que el software deba realizar un modo de relleno específico. En ese caso, se incluyen en la lista aplicada por software. 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 trustlet de Keymaster y el trustlet de autenticación relevante deben ser seguros y compartir una clave HMAC secreta que se utiliza para firmar y validar los tokens de autenticación. Consulte la página Autenticación para obtener más detalles.
  • Las etiquetas Tag :: ACTIVE_DATETIME , Tag :: ORIGINATION_EXPIRE_DATETIME y Tag :: USAGE_EXPIRE_DATETIME requieren acceso a un reloj de pared verificablemente correcto. La mayoría del hardware seguro solo tiene acceso a la información de la hora 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 las 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.

importKey

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 claves 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 las etiquetas y valores apropiados a las características clave. Si se proporcionan los parámetros, el trustlet los valida con el material clave. En caso de una discrepancia, el método devuelve ErrorCode::IMPORT_PARAMETER_MISMATCH .
  • La etiqueta devuelta :: ORIGIN tiene el mismo valor que KeyOrigin::IMPORTED .

exportKey

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 la clave, 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 importación, se proporciona el mismo valor a este método en el argumento appData .

deleteKey

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 brindan resistencia a la reversión.

deleteAllKeys

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 brindan resistencia a la reversión.

destroyAttestationIds

Versión : 3

El método destroyAttestationIds() se usa para deshabilitar permanentemente la nueva característica de atestación de ID (opcional, pero muy recomendable). Si el TEE no tiene forma de garantizar que la atestación de ID se deshabilite 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 deshabilitar permanentemente todos los intentos futuros de atestación de ID. El método puede llamarse tantas veces como desee. Si la atestación de ID ya está deshabilitada permanentemente, 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, utilizando 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 utiliza como símbolo de "desafío" en operaciones autenticadas, y para tales operaciones se incluye en el campo de challenge del símbolo de autenticación.

Una implementación de Keymaster admite al menos 16 operaciones simultáneas. El almacén de claves usa hasta 15, dejando uno para que vold lo use para el cifrado de contraseñas. Cuando el almacén de claves 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 un decimosexto, llama a abort en la operación utilizada menos recientemente para reducir el número de operaciones activas a 14 antes de begin llamada para iniciar la operación recién solicitada.

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

Aplicación de la autorización

Durante este método, el trustlet aplica las siguientes autorizaciones de clave si la implementación las colocó en las características "impuestas 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.

  • Etiqueta :: PROPÓSITO : 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 de verificación o cifrado asimétrico.
  • Tag :: ACTIVE_DATETIME solo se puede aplicar si está disponible una fuente de hora UTC confiable. Si la fecha y 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 está disponible una fuente de hora UTC confiable. Si la fecha y 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 .
  • Etiqueta :: USAGE_EXPIRE_DATETIME solo se puede hacer cumplir si está disponible una fuente de hora UTC confiable. Si la fecha y 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 confiable 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 sobre la 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 excede el valor de la etiqueta, el método devuelve ErrorCode::KEY_MAX_OPS_EXCEEDED .
  • Tag :: USER_SECURE_ID se aplica mediante este método 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 no se cumple alguna de estas condiciones, el método devuelve ErrorCode::KEY_USER_NOT_AUTHENTICATED .

  • Tag :: CALLER_NONCE permite a la persona que llama especificar un vector de inicialización o nonce (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 exclusiva del cargador de arranque después de que el cargador de arranque ha terminado de ejecutarse, devuelve ErrorCode::INVALID_KEY_BLOB .

Claves RSA

Todas las operaciones de la tecla 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 RSA necesitan un resumen, al igual que las operaciones de cifrado y descifrado 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 un resumen o relleno no autorizado.

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

Existen 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, Digest::NONE se especifica para el resumen. No es necesario un 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 construir una estructura de firma PKCS # 1 v1.5 adecuada, porque no puede agregar la estructura DigestInfo. En cambio, 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 PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT no requiere un resumen.
  • PaddingMode::RSA_PSS 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 más grande 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.
  • PaddingMode::RSA_OAEP padding requiere un resumen, que puede no ser Digest::NONE . Si se especifica Digest::NONE , el método devuelve ErrorCode::INCOMPATIBLE_DIGEST .

Claves EC

Las operaciones de la 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. De lo contrario, devuelva ErrorCode::INCOMPATIBLE_DIGEST . Las operaciones de clave pública ( KeyPurpose::VERIFY ) están permitidas con un resumen o relleno no autorizado.

Claves AES

Las operaciones de la tecla AES especifican exactamente un modo de bloque y un modo de relleno en inParams . Si alguno de los valores no está especificado o se especifica más de una vez, devuelve ErrorCode::UNSUPPORTED_BLOCK_MODE o ErrorCode::UNSUPPORTED_PADDING_MODE . Los modos especificados deben ser 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 no múltiplos de 8, devuelve ErrorCode::UNSUPPORTED_MAC_LENGTH . Para valores menores que la longitud mínima de la clave, devuelve ErrorCode::INVALID_MAC_LENGTH .

Si el modo de bloqueo es BlockMode::GCM o BlockMode::CTR , el modo de relleno especificado tiene que 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 una vía intravenosa o un nonce. En ese caso, la implementación de Keymaster genera un IV o un nonce aleatorio y lo devuelve a través de Tag :: NONCE en outParams . CBC y CTR IV tienen 16 bytes. Los nonces de GCM son 12 bytes. Si las autorizaciones clave contienen Tag :: CALLER_NONCE , entonces 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.

Llaves HMAC

Las operaciones de la clave 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 de resumen o no múltiplos de 8, devuelve ErrorCode::UNSUPPORTED_MAC_LENGTH . Para valores menores que 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 comenzada 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 que se proporcionaron. La persona que llama es responsable de realizar un 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 abortan 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 el final . Devuelve los datos lo antes posible, en lugar de almacenarlos en 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, finalizar o abortar , devuelve ErrorCode::INVALID_OPERATION_HANDLE .

Aplicación de la autorización

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

En este caso, la clave requiere una autorización por operación y el método de actualización recibe una Etiqueta :: AUTH_TOKEN en el argumento inParams . HMAC verifica que el token es válido y contiene un ID de usuario seguro coincidente, coincide con el Tag :: USER_AUTH_TYPE de la clave y contiene 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 única actualización. Puede que no consuma solo una parte del bloque. Sin embargo, si la persona que llama elige proporcionar los datos en varias actualizaciones, este método los 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 única 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 los 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 pueden proporcionarse en llamadas repetidas (importante si los datos son demasiado grandes para enviarlos en un solo bloque) pero siempre preceden a los datos que se deben cifrar o descifrar. Una llamada de actualización puede recibir tanto datos asociados como datos para cifrar / descifrar, pero las actualizaciones posteriores pueden no incluir 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 adjunta al texto cifrado al finalizar . Durante el descifrado, la última Tag::MAC_LENGTH bytes de los datos proporcionados a la última llamada de actualización es la etiqueta. Dado que una determinada invocación 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 el final .

terminar

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