Funciones del maestro de llaves,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 de Keymaster está disponible esa función y describe la implementación predeterminada. Para etiquetas, consulte la página Etiquetas Keymaster .

Directrices 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 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 utilicen 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 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 del puntero de salida

Versión : 1, 2

De manera 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 considera 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 API

Versión : 1, 2, 3

Hay muchas maneras en que las personas que llaman pueden hacer solicitudes que no tienen sentido o que son tontas pero que no son técnicamente incorrectas. No es necesario que las implementaciones de Keymaster fallen en tales casos ni 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 deben diagnosticar la omisión de parámetros requeridos, la especificación de parámetros requeridos 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 Keymaster sean sensatas y útiles.

Funciones

obtener características de hardware

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 se abandonan.
  • supportsEllipticCurve es true si el hardware admite 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 este método puede devolver 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 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 utilizarlo. 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);

agregarRngEntropía

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como add_rng_entropy y se le cambió el nombre 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 tiene control completo de los bits proporcionados por addRngEntropy o de los bits generados por el hardware, pero no de ambos, no tenga ninguna ventaja no despreciable a la hora de predecir 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 le cambió el nombre 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 imposible el uso de una clave de cualquier forma incompatible 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 autorizaciones correctamente entre las listas impuestas 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 sean 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 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 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 compatibles. Los resúmenes no compatibles deben colocarse en la lista "aplicada por software" en las características clave devueltas. Esto se debe a que la clave se puede utilizar con esos otros resúmenes, pero el resumen se realiza en 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 impuesta por software si se especifica algún algoritmo de resumen no compatible.

Claves ECDSA

Solo es necesaria 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 NIST p-224, p-256, p-384 y p521, respectivamente.

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

claves AES

Solo es necesaria 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 sólo 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 múltiplo de 8 y está entre 96 y 128.

Teclas HMAC

Se requieren los siguientes parámetros 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 más grandes.
  • Tag::MIN_MAC_LENGTH especifica la longitud mínima de las MAC que se pueden generar o verificar con esta clave. El valor es 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, se devuelve ErrorCode::UNSUPPORTED_DIGEST . Si el trustlet no admite el resumen, 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 impuestas por hardware y por software. Consulte getKeyCharacteristics para obtener una descripción de qué características van en cada 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 a la reversión

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 más se podrá utilizar. Las implementaciones sin resistencia a la reversión generalmente devuelven el material de claves generado o importado al autor de la llamada 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 previamente 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 puedan restaurar más adelante. Esto generalmente se hace almacenando metadatos clave adicionales en una ubicación confiable que no puede ser manipulada por un atacante. En 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 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.

getKeyCaracterísticas

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como get_key_characteristics y se le cambió el nombre en Keymaster 3.

Devuelve parámetros y autorizaciones asociados con la clave proporcionada, divididos en dos conjuntos: aplicados por hardware y aplicados 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 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á totalmente garantizado por un hardware seguro, se aplica por hardware. De lo contrario, se aplica mediante 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 protegida por hardware, estas etiquetas estarán en la lista impuesta por hardware.
  • Los valores Tag::DIGEST que son compatibles con el hardware seguro se colocan en la lista de hardware compatible. Los resúmenes no compatibles van en la lista de software compatible.
  • Los valores de 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 a la lista impuesta 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 del 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 utilizada para firmar y validar tokens de autenticación. Consulte la página de 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 horaria 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 a 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 le cambió el nombre 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 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 discrepancia, el método devuelve ErrorCode::IMPORT_PARAMETER_MISMATCH .
  • El Tag::ORIGIN devuelto tiene el mismo valor que KeyOrigin::IMPORTED .

exportar clave

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como export_key y se le cambió el nombre en Keymaster 3.

Exporta una clave pública desde 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 importación, se proporciona el mismo valor a este método en el argumento appData .

eliminar clave

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como delete_key y se le cambió el nombre 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.

eliminar todas las claves

Versión : 1, 2, 3

Esta función se introdujo en Keymaster 1 como delete_all_keys y se le cambió el nombre 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.

destruirAtestaciónIds

Versión : 3

El método destroyAttestationIds() se utiliza para deshabilitar permanentemente la nueva función de certificación de ID (opcional, pero muy recomendada). Si el TEE no tiene forma de garantizar que la atestación de ID esté permanentemente deshabilitada 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 identificación, es necesario implementar este método y debe deshabilitar permanentemente todos los intentos futuros de atestación de identificación. El método se puede llamar cualquier número de veces. 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 este método puede devolver 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 indican una falla en la comunicación con el hardware seguro.

comenzar

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 token de "desafío" en operaciones autenticadas y, para dichas operaciones, se incluye en el campo challenge del token de autenticación.

Una implementación de Keymaster admite al menos 16 operaciones simultáneas. El almacén de claves utiliza hasta 15, dejando uno para que vold lo use para cifrar la contraseña. Cuando Keystore tiene 15 operaciones en curso (se ha llamado a begin , pero aún no se ha llamado finish o abort ) y recibe una solicitud para comenzar una 16, llama a abort en la operación utilizada menos recientemente para reducir el número de operaciones activas. a 14 antes de begin a llamar para iniciar la nueva operació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 esas etiquetas con los valores especificados originalmente en el argumento inParams de este método.

Ejecución 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.

  • Etiqueta::PROPÓSITO : El propósito especificado en la llamada a begin() debe 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 hay 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 hay 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 .
  • Tag::USAGE_EXPIRE_DATETIME solo se puede aplicar si hay 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 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 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 ambas, entonces este método debe recibir una Tag::AUTH_TOKEN válida en inParams . Para que el token de autenticación sea válido, debe cumplirse todo lo siguiente:
    • 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 del 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 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 gestor de arranque puede usar la clave. Si se llama a este método con una clave exclusiva del gestor de arranque después de que el gestor 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 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 resumen o relleno no autorizado.

Con la excepción de PaddingMode::NONE , todos los modos de relleno RSA se aplican solo para ciertos propósitos. 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 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, se especifica Digest::NONE para el resumen. No es necesario ningún resumen para el cifrado o descifrado sin relleno.
  • PaddingMode::RSA_PKCS1_1_5_SIGN El 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 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 mayor que el mensaje; de ​​lo contrario, el método devuelve ErrorCode::INVALID_INPUT_LENGTH .
  • PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT El 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 .

llaves CE

Las operaciones clave de 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 . Se permiten operaciones de clave pública ( KeyPurpose::VERIFY ) con resumen o relleno no autorizados.

claves AES

Las operaciones de clave 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, devuelva ErrorCode::UNSUPPORTED_BLOCK_MODE o ErrorCode::UNSUPPORTED_PADDING_MODE . Los modos especificados deben estar autorizados mediante 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 clave. Para longitudes de MAC superiores a 128 o que no sean múltiplos de 8, devuelva ErrorCode::UNSUPPORTED_MAC_LENGTH . Para valores inferiores a la longitud mínima de la clave, devuelva ErrorCode::INVALID_MAC_LENGTH .

Si el modo de bloque 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, devuelva 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 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 IV CBC y CTR son de 16 bytes. Los nonces de GCM son de 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 se autoriza Tag::CALLER_NONCE , genere un IV/nonce aleatorio.

Teclas HMAC

Las operaciones de 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 del resumen o que no sean múltiplos de 8, devuelva ErrorCode::UNSUPPORTED_MAC_LENGTH . Para valores inferiores a la longitud mínima de la clave, devuelva ErrorCode::INVALID_MAC_LENGTH .

actualizar

Versión : 1, 2, 3

Proporciona datos para procesar en una operación en curso iniciada con start . 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 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, los llamadores consideran que esto es un error y cancelan 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 . Devuelva los datos lo antes posible, en lugar de almacenarlos en un buffer.

Manejo de errores

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

Ejecución de la autorización

La aplicación de la autorización de claves se realiza principalmente en el inicio . 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 sea válido y contenga una ID de usuario segura coincidente, coincida con la clave Tag::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, devuelva 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 así lo prefiere.

claves RSA

Para operaciones de firma y verificación con Digest::NONE , este método acepta que todo el bloque se firme o verifique en una sola actualización. No podrá consumir sólo una porción 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), devuelva ErrorCode::INVALID_INPUT_LENGTH .

Claves ECDSA

Para operaciones de firma y verificación con Digest::NONE , este método acepta que todo el bloque se firme o verifique en una sola actualización. Es posible que este método 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 utilizar, 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 van a cifrar o descifrar. Una llamada de actualización puede recibir tanto datos asociados como 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 al finalizar . Durante el descifrado, los últimos Tag::MAC_LENGTH bytes de los datos proporcionados a la última llamada de actualización son 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 el buffer los posibles datos de la etiqueta durante el proceso de finalización .

finalizar

Versión : 1, 2, 3

Finaliza una operación en curso iniciada con start , procesando todos los datos aún no procesados ​​proporcionados por las actualizaciones .

Este método es el último llamado en una operación, por lo que se devuelven todos los datos procesados.

Ya sea que se complete con éxito o devuelva un error, este método finaliza la operación y, por lo tanto, invalida el mango de operación proporcionado. Cualquier uso futuro del identificador, con este método o actualización o aborta , devuelve ErrorCode::INVALID_OPERATION_HANDLE .

Las operaciones de firma devuelven la firma como salida. Las operaciones de verificación aceptan la firma en el parámetro signature y no devuelven la salida.

Aplicación de la autorización

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

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 una identificación de usuario segura coincidente, coincide con la etiqueta de la clave :: user_auth_type y contiene el mango de operación de la operación actual en el campo de desafío. Si no se cumplen estas condiciones, devuelva ErrorCode::KEY_USER_NOT_AUTHENTICATED .

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

Teclas RSA

Algunos requisitos adicionales, dependiendo del modo de relleno:

  • PaddingMode::NONE . Para las operaciones de firma y encriptación no publicadas, si los datos proporcionados son más cortos que la clave, los datos se ponen a cero a la izquierda antes de firmar/cifrado. Si los datos tienen la misma longitud que la clave, pero numéricamente más grande, returación ErrorCode::INVALID_ARGUMENT . Para las operaciones de verificación y descifrado, los datos deben ser exactamente tan largos como la clave. De lo contrario, return ErrorCode::INVALID_INPUT_LENGTH.
  • PaddingMode::RSA_PSS . Para las operaciones de firma con PSS, la sal de PSS es del tamaño del digestor de mensajes y se genera aleatoriamente. El resumen especificado con TAG :: Digest en inputParams On Begin se usa como algoritmo de resumen de PSS, y como algoritmo MGF1 Digest.
  • PaddingMode::RSA_OAEP . El resumen especificado con TAG :: Digest en inputParams On Begin se usa como algoritmo OAEP Digest, y SHA1 se usa como algoritmo Digest MGF1.

Cayos de Ecdsa

Si los datos proporcionados para la firma o la verificación no lados son demasiado largos, trunca.

Llaves de AES

Algunas condiciones adicionales, dependiendo del modo de bloque:

  • BlockMode::ECB o BlockMode::CBC . Si el relleno es PaddingMode::NONE y la longitud de los datos no es un múltiplo del tamaño del bloque AES, devuelve ErrorCode::INVALID_INPUT_LENGTH . Si el relleno es PaddingMode::PKCS7 , rellen los datos según la especificación PKCS#7. Tenga en cuenta que PKCS#7 recomienda agregar un bloque de relleno adicional si los datos son un múltiplo de la longitud del bloque.
  • BlockMode::GCM . Durante el cifrado, después de procesar todo el texto sin formato, calcule la etiqueta ( etiqueta :: mac_length bytes) y agregua al texto cifrado devuelto. Durante el descifrado, procese la última etiqueta :: Mac_Length bytes como la etiqueta. Si la verificación de la etiqueta falla, devuelva ErrorCode::VERIFICATION_FAILED .

abortar

Versión : 1, 2, 3

Aborta la operación en progreso. Después de la llamada para abortar, devuelva ErrorCode::INVALID_OPERATION_HANDLE para cualquier uso posterior del mango de operación proporcionado con actualización , finalización o aborto .

get_supported_algorithms

Versión 1

Devuelve la lista de algoritmos compatibles con la implementación de hardware de KeyMaster. Una implementación de software devuelve una lista vacía; Una implementación híbrida devuelve una lista que contiene solo los algoritmos que son compatibles con el hardware.

Las implementaciones de KeyMaster 1 admiten RSA, EC, AES y HMAC.

get_supported_block_modes

Versión 1

Devuelve la lista de modos de bloque AES admitidos por la implementación de hardware de KeyMaster para un algoritmo y propósito especificados.

Para RSA, EC y HMAC, que no son cifrados de bloques, el método devuelve una lista vacía para todos los fines válidos. Los propósitos no válidos deben hacer que el método devuelva ErrorCode::INVALID_PURPOSE .

Las implementaciones de KeyMaster 1 admiten ECB, CBC, CTR y GCM para el cifrado y descifrado AES.

get_supported_padding_modes

Versión 1

Devuelve la lista de modos de acolchado compatibles con la implementación de hardware de KeyMaster para un algoritmo y propósito especificados.

HMAC y EC no tienen noción de relleno, por lo que el método devuelve una lista vacía para todos los fines válidos. Los propósitos no válidos deben hacer que el método devuelva ErrorCode::INVALID_PURPOSE .

Para RSA, Keymaster 1 Soporte de implementaciones:

  • Cifrado, descifrado, firma y verificación sin lados. Para el cifrado y la firma no listados, si el mensaje es más corto que el módulo público, las implementaciones deben hacer que la izquierda lo haga con ceros. Para el descifrado y la verificación no lados, la longitud de entrada debe coincidir con el tamaño del módulo público.
  • PKCS#1 V1.5 Cifrado y firma de modos de relleno
  • PSS con una longitud mínima de sal de 20
  • OAEP

Para los AES en los modos de ECB y CBC, las implementaciones de KeMySaster 1 admiten el relleno y PKCS#7-Padding. Los modos CTR y GCM solo admiten acolchado.

get_supported_digests

Versión 1

Devuelve la lista de modos de resumen admitidos por la implementación de hardware de KeyMaster para un algoritmo y propósito especificados.

No hay modos AES o requieren digerir, por lo que el método devuelve una lista vacía para fines válidos.

Las implementaciones de KeyMaster 1 pueden implementar un subconjunto de los digestos definidos. Las implementaciones proporcionan SHA-256 y pueden proporcionar MD5, SHA1, SHA-224, SHA-256, SHA384 y SHA512 (el conjunto completo de digestiones definidas).

get_supported_import_formats

Versión 1

Devuelve la lista de formatos de importación compatibles con la implementación de hardware de KeyMaster de un algoritmo especificado.

Las implementaciones de KeyMaster 1 admiten el formato PKCS#8 (sin protección de contraseña) para importar pares de claves RSA y EC, y admite la importación sin procesar de material de clave AES y HMAC.

get_supported_export_formats

Versión 1

Devuelve la lista de formatos de exportación compatibles con la implementación de hardware de KeyMaster de un algoritmo especificado.

Las implementaciones de KeyMaster1 admiten el formato X.509 para exportar claves públicas RSA y EC. La exportación de claves privadas o claves asimétricas no es compatible.

Funciones históricas

KeyMaster 0

Las siguientes funciones pertenecen a la definición original de KeyMaster 0. Estaban presentes en KeyMaster 1 struct keyMaster1_device_t. Sin embargo, en Keymaster 1.0 no se implementaron, y sus punteros de función se establecieron en NULL.

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

Keymaster 1

Las siguientes funciones pertenecen a la definición de KeyMaster 1, pero se eliminaron en Keymaster 2, junto con las funciones de KeyMaster 0 enumeradas anteriormente.

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

Keymaster 2

Las siguientes funciones pertenecen a la definición de KeyMaster 2, pero se eliminaron en Keymaster 3, junto con las funciones de Keymaster 1 enumeradas anteriormente.

  • configure